wbportfolio 1.52.5__tar.gz → 1.52.6__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 (525) hide show
  1. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/PKG-INFO +1 -1
  2. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/asset.py +1 -1
  3. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/portfolio.py +1 -1
  4. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/transactions/trade_proposals.py +59 -68
  5. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/transactions/trades.py +26 -17
  6. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/pms/trading/handler.py +37 -56
  7. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/pms/typing.py +27 -9
  8. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/rebalancing/models/model_portfolio.py +11 -14
  9. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/serializers/transactions/trade_proposals.py +18 -1
  10. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/serializers/transactions/trades.py +30 -3
  11. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/models/transactions/test_trade_proposals.py +7 -5
  12. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/rebalancing/test_models.py +10 -16
  13. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/buttons/trade_proposals.py +9 -1
  14. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/display/trade_proposals.py +5 -4
  15. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/display/trades.py +36 -0
  16. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/transactions/trade_proposals.py +3 -1
  17. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/transactions/trades.py +51 -45
  18. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/.gitignore +0 -0
  19. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/LICENSE +0 -0
  20. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/pyproject.toml +0 -0
  21. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/__init__.py +0 -0
  22. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/admin/__init__.py +0 -0
  23. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/admin/asset.py +0 -0
  24. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/admin/custodians.py +0 -0
  25. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/admin/indexes.py +0 -0
  26. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/admin/portfolio.py +0 -0
  27. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/admin/portfolio_relationships.py +0 -0
  28. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/admin/product_groups.py +0 -0
  29. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/admin/products.py +0 -0
  30. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/admin/reconciliations.py +0 -0
  31. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/admin/registers.py +0 -0
  32. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/admin/roles.py +0 -0
  33. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/admin/transactions/__init__.py +0 -0
  34. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/admin/transactions/claim.py +0 -0
  35. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/admin/transactions/dividends.py +0 -0
  36. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/admin/transactions/fees.py +0 -0
  37. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/admin/transactions/rebalancing.py +0 -0
  38. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/admin/transactions/trades.py +0 -0
  39. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/analysis/__init__.py +0 -0
  40. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/analysis/claims.py +0 -0
  41. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/apps.py +0 -0
  42. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/contrib/__init__.py +0 -0
  43. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/contrib/company_portfolio/__init__.py +0 -0
  44. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/contrib/company_portfolio/admin.py +0 -0
  45. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/contrib/company_portfolio/apps.py +0 -0
  46. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/contrib/company_portfolio/configs/__init__.py +0 -0
  47. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/contrib/company_portfolio/configs/display.py +0 -0
  48. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/contrib/company_portfolio/configs/endpoints.py +0 -0
  49. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/contrib/company_portfolio/configs/previews.py +0 -0
  50. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/contrib/company_portfolio/constants.py +0 -0
  51. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/contrib/company_portfolio/dynamic_preferences_registry.py +0 -0
  52. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/contrib/company_portfolio/factories.py +0 -0
  53. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/contrib/company_portfolio/filters.py +0 -0
  54. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/contrib/company_portfolio/management.py +0 -0
  55. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/contrib/company_portfolio/migrations/0001_initial.py +0 -0
  56. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/contrib/company_portfolio/migrations/__init__.py +0 -0
  57. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/contrib/company_portfolio/models.py +0 -0
  58. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/contrib/company_portfolio/scripts.py +0 -0
  59. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/contrib/company_portfolio/serializers.py +0 -0
  60. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/contrib/company_portfolio/tasks.py +0 -0
  61. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/contrib/company_portfolio/tests/__init__.py +0 -0
  62. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/contrib/company_portfolio/tests/conftest.py +0 -0
  63. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/contrib/company_portfolio/tests/test_models.py +0 -0
  64. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/contrib/company_portfolio/urls.py +0 -0
  65. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/contrib/company_portfolio/viewsets.py +0 -0
  66. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/defaults/__init__.py +0 -0
  67. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/defaults/fees/__init__.py +0 -0
  68. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/defaults/fees/default.py +0 -0
  69. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/dynamic_preferences_registry.py +0 -0
  70. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/factories/__init__.py +0 -0
  71. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/factories/adjustments.py +0 -0
  72. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/factories/assets.py +0 -0
  73. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/factories/claim.py +0 -0
  74. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/factories/custodians.py +0 -0
  75. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/factories/dividends.py +0 -0
  76. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/factories/fees.py +0 -0
  77. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/factories/indexes.py +0 -0
  78. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/factories/portfolio_cash_flow.py +0 -0
  79. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/factories/portfolio_cash_targets.py +0 -0
  80. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/factories/portfolio_swing_pricings.py +0 -0
  81. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/factories/portfolios.py +0 -0
  82. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/factories/product_groups.py +0 -0
  83. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/factories/products.py +0 -0
  84. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/factories/rebalancing.py +0 -0
  85. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/factories/reconciliations.py +0 -0
  86. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/factories/roles.py +0 -0
  87. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/factories/trades.py +0 -0
  88. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/fdm/__init__.py +0 -0
  89. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/fdm/tasks.py +0 -0
  90. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/filters/__init__.py +0 -0
  91. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/filters/assets.py +0 -0
  92. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/filters/assets_and_net_new_money_progression.py +0 -0
  93. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/filters/custodians.py +0 -0
  94. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/filters/esg.py +0 -0
  95. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/filters/performances.py +0 -0
  96. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/filters/portfolios.py +0 -0
  97. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/filters/positions.py +0 -0
  98. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/filters/products.py +0 -0
  99. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/filters/roles.py +0 -0
  100. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/filters/signals.py +0 -0
  101. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/filters/transactions/__init__.py +0 -0
  102. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/filters/transactions/claim.py +0 -0
  103. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/filters/transactions/fees.py +0 -0
  104. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/filters/transactions/mixins.py +0 -0
  105. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/filters/transactions/trades.py +0 -0
  106. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/filters/transactions/utils.py +0 -0
  107. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/fixtures/product_factsheets.yaml +0 -0
  108. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/fixtures/wbportfolio.yaml.gz +0 -0
  109. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/fixtures/wbrisk_management.yaml.gz +0 -0
  110. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/__init__.py +0 -0
  111. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/backends/__init__.py +0 -0
  112. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/backends/refinitiv/adjustment.py +0 -0
  113. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/backends/ubs/__init__.py +0 -0
  114. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/backends/ubs/asset_position.py +0 -0
  115. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/backends/ubs/fees.py +0 -0
  116. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/backends/ubs/instrument_price.py +0 -0
  117. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/backends/ubs/mixin.py +0 -0
  118. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/backends/utils.py +0 -0
  119. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/backends/wbfdm/__init__.py +0 -0
  120. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/backends/wbfdm/adjustment.py +0 -0
  121. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/backends/wbfdm/dividend.py +0 -0
  122. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/backends/wbfdm/mixin.py +0 -0
  123. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/handlers/__init__.py +0 -0
  124. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/handlers/adjustment.py +0 -0
  125. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/handlers/asset_position.py +0 -0
  126. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/handlers/dividend.py +0 -0
  127. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/handlers/fees.py +0 -0
  128. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/handlers/portfolio_cash_flow.py +0 -0
  129. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/handlers/register.py +0 -0
  130. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/handlers/trade.py +0 -0
  131. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/__init__.py +0 -0
  132. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/default_mapping.py +0 -0
  133. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/jpmorgan/__init__.py +0 -0
  134. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/jpmorgan/customer_trade.py +0 -0
  135. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/jpmorgan/fees.py +0 -0
  136. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/jpmorgan/strategy.py +0 -0
  137. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/jpmorgan/valuation.py +0 -0
  138. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/leonteq/__init__.py +0 -0
  139. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/leonteq/customer_trade.py +0 -0
  140. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/leonteq/equity.py +0 -0
  141. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/leonteq/fees.py +0 -0
  142. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/leonteq/trade.py +0 -0
  143. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/leonteq/valuation.py +0 -0
  144. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/natixis/__init__.py +0 -0
  145. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/natixis/customer_trade.py +0 -0
  146. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/natixis/d1_customer_trade.py +0 -0
  147. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/natixis/d1_equity.py +0 -0
  148. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/natixis/d1_fees.py +0 -0
  149. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/natixis/d1_trade.py +0 -0
  150. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/natixis/d1_valuation.py +0 -0
  151. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/natixis/dividend.py +0 -0
  152. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/natixis/equity.py +0 -0
  153. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/natixis/fees.py +0 -0
  154. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/natixis/trade.py +0 -0
  155. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/natixis/utils.py +0 -0
  156. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/natixis/valuation.py +0 -0
  157. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/refinitiv/__init__.py +0 -0
  158. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/refinitiv/adjustment.py +0 -0
  159. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/sg_lux/__init__.py +0 -0
  160. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/sg_lux/custodian_positions.py +0 -0
  161. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/sg_lux/customer_trade.py +0 -0
  162. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/sg_lux/customer_trade_pending_slk.py +0 -0
  163. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/sg_lux/customer_trade_slk.py +0 -0
  164. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/sg_lux/customer_trade_without_pw.py +0 -0
  165. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/sg_lux/equity.py +0 -0
  166. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/sg_lux/fees.py +0 -0
  167. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/sg_lux/perf_fees.py +0 -0
  168. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/sg_lux/portfolio_cash_flow.py +0 -0
  169. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/sg_lux/portfolio_future_cash_flow.py +0 -0
  170. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/sg_lux/registers.py +0 -0
  171. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/sg_lux/sylk.py +0 -0
  172. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/sg_lux/utils.py +0 -0
  173. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/sg_lux/valuation.py +0 -0
  174. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/societe_generale/__init__.py +0 -0
  175. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/societe_generale/customer_trade.py +0 -0
  176. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/societe_generale/strategy.py +0 -0
  177. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/societe_generale/valuation.py +0 -0
  178. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/tellco/__init__.py +0 -0
  179. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/tellco/customer_trade.py +0 -0
  180. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/tellco/equity.py +0 -0
  181. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/tellco/valuation.py +0 -0
  182. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/ubs/__init__.py +0 -0
  183. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/ubs/api/__init__.py +0 -0
  184. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/ubs/api/asset_position.py +0 -0
  185. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/ubs/api/fees.py +0 -0
  186. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/ubs/api/instrument_price.py +0 -0
  187. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/ubs/api/utils.py +0 -0
  188. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/ubs/customer_trade.py +0 -0
  189. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/ubs/equity.py +0 -0
  190. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/ubs/historical_customer_trade.py +0 -0
  191. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/ubs/valuation.py +0 -0
  192. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/vontobel/__init__.py +0 -0
  193. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/vontobel/asset_position.py +0 -0
  194. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/vontobel/customer_trade.py +0 -0
  195. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/vontobel/historical_customer_trade.py +0 -0
  196. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/vontobel/instrument.py +0 -0
  197. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/vontobel/management_fees.py +0 -0
  198. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/vontobel/performance_fees.py +0 -0
  199. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/vontobel/trade.py +0 -0
  200. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/vontobel/utils.py +0 -0
  201. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/vontobel/valuation.py +0 -0
  202. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/parsers/vontobel/valuation_api.py +0 -0
  203. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/resources/__init__.py +0 -0
  204. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/resources/assets.py +0 -0
  205. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/resources/trades.py +0 -0
  206. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/import_export/utils.py +0 -0
  207. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/jinja2/wbportfolio/sql/aum_nnm.sql +0 -0
  208. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/kpi_handlers/nnm.py +0 -0
  209. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/locale/de/LC_MESSAGES/django.mo +0 -0
  210. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/locale/de/LC_MESSAGES/django.po +0 -0
  211. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/locale/en/LC_MESSAGES/django.mo +0 -0
  212. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/locale/en/LC_MESSAGES/django.po +0 -0
  213. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/locale/fr/LC_MESSAGES/django.mo +0 -0
  214. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/locale/fr/LC_MESSAGES/django.po +0 -0
  215. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/metric/__init__.py +0 -0
  216. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/metric/backends/__init__.py +0 -0
  217. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/metric/backends/base.py +0 -0
  218. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/metric/backends/constants.py +0 -0
  219. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/metric/backends/portfolio_base.py +0 -0
  220. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/metric/backends/portfolio_esg.py +0 -0
  221. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/metric/tests/__init__.py +0 -0
  222. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/metric/tests/conftest.py +0 -0
  223. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/metric/tests/test_portfolio_base.py +0 -0
  224. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/metric/tests/test_portfolio_esg.py +0 -0
  225. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0001_initial_squashed.py +0 -0
  226. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0002_product_default_sub_account_squashed_0039_alter_assetallocation_company_and_more.py +0 -0
  227. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0040_instrument_financial_instrument.py +0 -0
  228. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0041_remove_listresearch_research_ptr_and_more.py +0 -0
  229. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0042_instrumentlist_instrumentlistthroughmodel_and_more.py +0 -0
  230. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0043_alter_instrumentlistthroughmodel_options_and_more.py +0 -0
  231. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0044_alter_instrumentlist_identifier.py +0 -0
  232. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0045_alter_instrument_financial_instrument.py +0 -0
  233. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0046_add_product_default_account.py +0 -0
  234. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0047_remove_product_default_sub_account.py +0 -0
  235. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0048_alter_trade_status.py +0 -0
  236. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0049_trade_claimed_shares.py +0 -0
  237. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0050_fees_fee_date_fees_wbportfolio_transac_1f7a29_idx.py +0 -0
  238. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0051_delete_macroreview.py +0 -0
  239. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0052_remove_cash_instrument_ptr_and_more.py +0 -0
  240. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0053_remove_product_group.py +0 -0
  241. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0054_portfolioinstrumentpreferredclassificationthroughmodel_and_more.py +0 -0
  242. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0055_remove_product__custom_management_rebates_and_more.py +0 -0
  243. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0056_remove_companyportfoliodata_assets_under_management_currency_and_more.py +0 -0
  244. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0057_alter_portfolio_preferred_instrument_classifications_and_more.py +0 -0
  245. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0058_pmsinstrument.py +0 -0
  246. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0059_fees_unique_fees.py +0 -0
  247. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0060_alter_portfolioportfoliothroughmodel_type.py +0 -0
  248. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0061_portfolio_bank_accounts_product_bank_account_and_more.py +0 -0
  249. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0062_alter_dailyportfoliocashflow_options.py +0 -0
  250. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0063_accountreconciliation_accountreconciliationline_and_more.py +0 -0
  251. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0064_alter_portfolio_managers_portfolio_is_tracked_and_more.py +0 -0
  252. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0065_alter_portfolio_managers_claim_as_shares_and_more.py +0 -0
  253. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0066_assetposition_initial_shares_at_custodian_and_more.py +0 -0
  254. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0067_assetposition_unique_asset_position.py +0 -0
  255. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0068_trade_internal_trade_trade_marked_as_internal_and_more.py +0 -0
  256. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0069_remove_portfolio_is_invested_and_more.py +0 -0
  257. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0070_remove_assetposition_unique_asset_position_and_more.py +0 -0
  258. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0071_alter_trade_options_alter_trade_order.py +0 -0
  259. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0072_trade_diff_shares.py +0 -0
  260. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0073_remove_product_price_computation_and_more.py +0 -0
  261. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0074_alter_rebalancer_frequency_and_more.py +0 -0
  262. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0075_portfolio_initial_position_date_and_more.py +0 -0
  263. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0076_alter_dividendtransaction_price_and_more.py +0 -0
  264. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/0077_remove_transaction_currency_and_more.py +0 -0
  265. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/migrations/__init__.py +0 -0
  266. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/__init__.py +0 -0
  267. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/adjustments.py +0 -0
  268. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/custodians.py +0 -0
  269. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/exceptions.py +0 -0
  270. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/graphs/__init__.py +0 -0
  271. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/graphs/portfolio.py +0 -0
  272. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/graphs/utils.py +0 -0
  273. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/indexes.py +0 -0
  274. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/llm/wbcrm/analyze_relationship.py +0 -0
  275. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/mixins/__init__.py +0 -0
  276. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/mixins/instruments.py +0 -0
  277. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/mixins/liquidity_stress_test.py +0 -0
  278. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/portfolio_cash_flow.py +0 -0
  279. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/portfolio_cash_targets.py +0 -0
  280. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/portfolio_relationship.py +0 -0
  281. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/portfolio_swing_pricings.py +0 -0
  282. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/product_groups.py +0 -0
  283. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/products.py +0 -0
  284. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/reconciliations/__init__.py +0 -0
  285. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/reconciliations/account_reconciliation_lines.py +0 -0
  286. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/reconciliations/account_reconciliations.py +0 -0
  287. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/reconciliations/reconciliations.py +0 -0
  288. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/registers.py +0 -0
  289. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/roles.py +0 -0
  290. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/signals.py +0 -0
  291. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/transactions/__init__.py +0 -0
  292. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/transactions/claim.py +0 -0
  293. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/transactions/dividends.py +0 -0
  294. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/transactions/fees.py +0 -0
  295. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/transactions/rebalancing.py +0 -0
  296. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/transactions/transactions.py +0 -0
  297. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/models/utils.py +0 -0
  298. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/permissions.py +0 -0
  299. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/pms/__init__.py +0 -0
  300. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/pms/analytics/__init__.py +0 -0
  301. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/pms/analytics/portfolio.py +0 -0
  302. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/pms/statistics/__init__.py +0 -0
  303. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/pms/trading/__init__.py +0 -0
  304. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/preferences.py +0 -0
  305. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/rebalancing/__init__.py +0 -0
  306. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/rebalancing/base.py +0 -0
  307. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/rebalancing/decorators.py +0 -0
  308. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/rebalancing/models/__init__.py +0 -0
  309. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/rebalancing/models/composite.py +0 -0
  310. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/rebalancing/models/equally_weighted.py +0 -0
  311. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/rebalancing/models/market_capitalization_weighted.py +0 -0
  312. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/reports/__init__.py +0 -0
  313. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/reports/monthly_position_report.py +0 -0
  314. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/risk_management/__init__.py +0 -0
  315. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/risk_management/backends/__init__.py +0 -0
  316. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/risk_management/backends/accounts.py +0 -0
  317. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/risk_management/backends/controversy_portfolio.py +0 -0
  318. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/risk_management/backends/exposure_portfolio.py +0 -0
  319. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/risk_management/backends/instrument_list_portfolio.py +0 -0
  320. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/risk_management/backends/liquidity_risk.py +0 -0
  321. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/risk_management/backends/liquidity_stress_instrument.py +0 -0
  322. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/risk_management/backends/mixins.py +0 -0
  323. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/risk_management/backends/product_integrity.py +0 -0
  324. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/risk_management/backends/stop_loss_instrument.py +0 -0
  325. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/risk_management/backends/stop_loss_portfolio.py +0 -0
  326. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/risk_management/backends/ucits_portfolio.py +0 -0
  327. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/risk_management/tests/__init__.py +0 -0
  328. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/risk_management/tests/conftest.py +0 -0
  329. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/risk_management/tests/test_accounts.py +0 -0
  330. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/risk_management/tests/test_controversy_portfolio.py +0 -0
  331. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/risk_management/tests/test_exposure_portfolio.py +0 -0
  332. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/risk_management/tests/test_instrument_list_portfolio.py +0 -0
  333. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/risk_management/tests/test_liquidity_risk.py +0 -0
  334. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/risk_management/tests/test_product_integrity.py +0 -0
  335. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/risk_management/tests/test_stop_loss_instrument.py +0 -0
  336. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/risk_management/tests/test_stop_loss_portfolio.py +0 -0
  337. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/risk_management/tests/test_ucits_portfolio.py +0 -0
  338. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/serializers/__init__.py +0 -0
  339. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/serializers/adjustments.py +0 -0
  340. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/serializers/assets.py +0 -0
  341. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/serializers/custodians.py +0 -0
  342. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/serializers/portfolio_cash_flow.py +0 -0
  343. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/serializers/portfolio_cash_targets.py +0 -0
  344. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/serializers/portfolio_relationship.py +0 -0
  345. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/serializers/portfolio_swing_pricing.py +0 -0
  346. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/serializers/portfolios.py +0 -0
  347. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/serializers/positions.py +0 -0
  348. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/serializers/product_group.py +0 -0
  349. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/serializers/products.py +0 -0
  350. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/serializers/rebalancing.py +0 -0
  351. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/serializers/reconciliations.py +0 -0
  352. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/serializers/registers.py +0 -0
  353. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/serializers/roles.py +0 -0
  354. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/serializers/signals.py +0 -0
  355. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/serializers/transactions/__init__.py +0 -0
  356. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/serializers/transactions/claim.py +0 -0
  357. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/serializers/transactions/dividends.py +0 -0
  358. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/serializers/transactions/fees.py +0 -0
  359. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/static/wbportfolio/css/macro_review.css +0 -0
  360. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/static/wbportfolio/markdown/documentation/account_holding_reconciliation.md +0 -0
  361. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/static/wbportfolio/markdown/documentation/aggregate_asset_position_liquidity.md +0 -0
  362. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/static/wbportfolio/markdown/documentation/company.md +0 -0
  363. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/static/wbportfolio/markdown/documentation/earnings_instrument.md +0 -0
  364. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/static/wbportfolio/markdown/documentation/financial_analysis_instrument_ratios.md +0 -0
  365. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/static/wbportfolio/markdown/documentation/financial_statistics.md +0 -0
  366. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/static/wbportfolio/markdown/documentation/person.md +0 -0
  367. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tasks.py +0 -0
  368. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/templates/portfolio/email/customer_report.html +0 -0
  369. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/templates/portfolio/email/customer_trade_notification.html +0 -0
  370. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/templates/portfolio/email/email_base_template.html +0 -0
  371. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/templates/portfolio/email/rebalancing_report.html +0 -0
  372. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/templates/portfolio/macro/macro_review.html +0 -0
  373. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/__init__.py +0 -0
  374. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/conftest.py +0 -0
  375. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/models/__init__.py +0 -0
  376. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/models/test_account_reconciliation.py +0 -0
  377. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/models/test_assets.py +0 -0
  378. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/models/test_custodians.py +0 -0
  379. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/models/test_customer_trades.py +0 -0
  380. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/models/test_dividends.py +0 -0
  381. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/models/test_imports.py +0 -0
  382. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/models/test_instrument_mixins.py +0 -0
  383. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/models/test_merge.py +0 -0
  384. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/models/test_portfolio_cash_flow.py +0 -0
  385. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/models/test_portfolio_cash_targets.py +0 -0
  386. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/models/test_portfolio_swing_pricings.py +0 -0
  387. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/models/test_portfolios.py +0 -0
  388. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/models/test_product_groups.py +0 -0
  389. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/models/test_products.py +0 -0
  390. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/models/test_roles.py +0 -0
  391. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/models/test_splits.py +0 -0
  392. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/models/transactions/__init__.py +0 -0
  393. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/models/transactions/test_claim.py +0 -0
  394. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/models/transactions/test_fees.py +0 -0
  395. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/models/transactions/test_rebalancing.py +0 -0
  396. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/models/transactions/test_trades.py +0 -0
  397. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/models/utils.py +0 -0
  398. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/pms/__init__.py +0 -0
  399. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/pms/test_analytics.py +0 -0
  400. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/rebalancing/__init__.py +0 -0
  401. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/serializers/__init__.py +0 -0
  402. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/serializers/test_claims.py +0 -0
  403. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/signals.py +0 -0
  404. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/tests.py +0 -0
  405. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/viewsets/__init__.py +0 -0
  406. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/viewsets/test_assets.py +0 -0
  407. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/viewsets/test_performances.py +0 -0
  408. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/viewsets/test_products.py +0 -0
  409. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/viewsets/transactions/__init__.py +0 -0
  410. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/tests/viewsets/transactions/test_claims.py +0 -0
  411. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/urls.py +0 -0
  412. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/utils.py +0 -0
  413. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/__init__.py +0 -0
  414. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/adjustments.py +0 -0
  415. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/assets.py +0 -0
  416. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/assets_and_net_new_money_progression.py +0 -0
  417. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/charts/__init__.py +0 -0
  418. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/charts/assets.py +0 -0
  419. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/__init__.py +0 -0
  420. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/buttons/__init__.py +0 -0
  421. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/buttons/adjustments.py +0 -0
  422. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/buttons/assets.py +0 -0
  423. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/buttons/claims.py +0 -0
  424. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/buttons/custodians.py +0 -0
  425. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/buttons/fees.py +0 -0
  426. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/buttons/mixins.py +0 -0
  427. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/buttons/portfolios.py +0 -0
  428. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/buttons/products.py +0 -0
  429. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/buttons/reconciliations.py +0 -0
  430. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/buttons/registers.py +0 -0
  431. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/buttons/signals.py +0 -0
  432. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/buttons/trades.py +0 -0
  433. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/display/__init__.py +0 -0
  434. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/display/adjustments.py +0 -0
  435. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/display/assets.py +0 -0
  436. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/display/claim.py +0 -0
  437. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/display/custodians.py +0 -0
  438. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/display/esg.py +0 -0
  439. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/display/fees.py +0 -0
  440. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/display/portfolio_cash_flow.py +0 -0
  441. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/display/portfolio_relationship.py +0 -0
  442. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/display/portfolios.py +0 -0
  443. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/display/positions.py +0 -0
  444. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/display/product_groups.py +0 -0
  445. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/display/product_performance.py +0 -0
  446. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/display/products.py +0 -0
  447. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/display/rebalancing.py +0 -0
  448. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/display/reconciliations.py +0 -0
  449. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/display/registers.py +0 -0
  450. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/display/roles.py +0 -0
  451. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/endpoints/__init__.py +0 -0
  452. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/endpoints/adjustments.py +0 -0
  453. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/endpoints/assets.py +0 -0
  454. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/endpoints/claim.py +0 -0
  455. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/endpoints/custodians.py +0 -0
  456. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/endpoints/esg.py +0 -0
  457. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/endpoints/fees.py +0 -0
  458. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/endpoints/portfolio_relationship.py +0 -0
  459. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/endpoints/portfolios.py +0 -0
  460. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/endpoints/positions.py +0 -0
  461. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/endpoints/product_groups.py +0 -0
  462. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/endpoints/product_performance.py +0 -0
  463. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/endpoints/products.py +0 -0
  464. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/endpoints/rebalancing.py +0 -0
  465. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/endpoints/reconciliations.py +0 -0
  466. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/endpoints/roles.py +0 -0
  467. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/endpoints/trade_proposals.py +0 -0
  468. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/endpoints/trades.py +0 -0
  469. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/menu/__init__.py +0 -0
  470. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/menu/adjustments.py +0 -0
  471. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/menu/assets.py +0 -0
  472. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/menu/claim.py +0 -0
  473. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/menu/custodians.py +0 -0
  474. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/menu/fees.py +0 -0
  475. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/menu/instrument_prices.py +0 -0
  476. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/menu/portfolio_cash_flow.py +0 -0
  477. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/menu/portfolios.py +0 -0
  478. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/menu/positions.py +0 -0
  479. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/menu/product_groups.py +0 -0
  480. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/menu/product_performance.py +0 -0
  481. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/menu/products.py +0 -0
  482. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/menu/reconciliations.py +0 -0
  483. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/menu/registers.py +0 -0
  484. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/menu/roles.py +0 -0
  485. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/menu/trades.py +0 -0
  486. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/previews/__init__.py +0 -0
  487. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/previews/portfolios.py +0 -0
  488. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/titles/__init__.py +0 -0
  489. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/titles/adjustments.py +0 -0
  490. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/titles/assets.py +0 -0
  491. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/titles/assets_and_net_new_money_progression.py +0 -0
  492. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/titles/claim.py +0 -0
  493. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/titles/custodians.py +0 -0
  494. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/titles/esg.py +0 -0
  495. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/titles/fees.py +0 -0
  496. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/titles/instrument_prices.py +0 -0
  497. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/titles/portfolios.py +0 -0
  498. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/titles/positions.py +0 -0
  499. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/titles/product_groups.py +0 -0
  500. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/titles/product_performance.py +0 -0
  501. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/titles/products.py +0 -0
  502. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/titles/registers.py +0 -0
  503. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/titles/roles.py +0 -0
  504. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/configs/titles/trades.py +0 -0
  505. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/custodians.py +0 -0
  506. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/esg.py +0 -0
  507. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/mixins.py +0 -0
  508. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/portfolio_cash_flow.py +0 -0
  509. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/portfolio_cash_targets.py +0 -0
  510. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/portfolio_relationship.py +0 -0
  511. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/portfolio_swing_pricing.py +0 -0
  512. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/portfolios.py +0 -0
  513. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/positions.py +0 -0
  514. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/product_groups.py +0 -0
  515. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/product_performance.py +0 -0
  516. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/products.py +0 -0
  517. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/reconciliations.py +0 -0
  518. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/registers.py +0 -0
  519. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/roles.py +0 -0
  520. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/signals.py +0 -0
  521. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/transactions/__init__.py +0 -0
  522. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/transactions/claim.py +0 -0
  523. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/transactions/fees.py +0 -0
  524. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/transactions/mixins.py +0 -0
  525. {wbportfolio-1.52.5 → wbportfolio-1.52.6}/wbportfolio/viewsets/transactions/rebalancing.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wbportfolio
3
- Version: 1.52.5
3
+ Version: 1.52.6
4
4
  Author-email: Christopher Wittlinger <c.wittlinger@stainly.com>
5
5
  License-File: LICENSE
6
6
  Requires-Dist: cryptography==3.4.*
@@ -708,7 +708,7 @@ class AssetPosition(ImportMixin, models.Model):
708
708
  instrument_type=self.underlying_quote.security_instrument_type.id,
709
709
  currency=self.underlying_quote.currency.id,
710
710
  country=self.underlying_quote.country.id if self.underlying_quote.country else None,
711
- is_cash=self.underlying_quote.is_cash,
711
+ is_cash=self.underlying_quote.is_cash or self.underlying_quote.is_cash_equivalent,
712
712
  primary_classification=(
713
713
  self.underlying_quote.primary_classification.id
714
714
  if self.underlying_quote.primary_classification
@@ -926,7 +926,7 @@ class Portfolio(DeleteToDisableMixin, WBModel):
926
926
  if self.is_composition:
927
927
  assets = list(self.get_lookthrough_positions(val_date, **kwargs))
928
928
  else:
929
- assets = self.assets.filter(date=val_date)
929
+ assets = list(self.assets.filter(date=val_date))
930
930
  return assets
931
931
 
932
932
  def compute_lookthrough(self, from_date: date, to_date: date | None = None):
@@ -2,10 +2,9 @@ import logging
2
2
  from contextlib import suppress
3
3
  from datetime import date, timedelta
4
4
  from decimal import Decimal
5
- from typing import TypeVar
5
+ from typing import Any, TypeVar
6
6
 
7
7
  from celery import shared_task
8
- from django.contrib.messages import error, info
9
8
  from django.core.exceptions import ValidationError
10
9
  from django.db import models
11
10
  from django.utils.functional import cached_property
@@ -92,14 +91,14 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
92
91
  )
93
92
  super().save(*args, **kwargs)
94
93
 
95
- @property
96
- def checked_object(self):
97
- return self.portfolio
98
-
99
94
  @property
100
95
  def check_evaluation_date(self):
101
96
  return self.trade_date
102
97
 
98
+ @property
99
+ def checked_object(self) -> Any:
100
+ return self.portfolio
101
+
103
102
  @cached_property
104
103
  def portfolio_total_asset_value(self) -> Decimal:
105
104
  return self.portfolio.get_total_asset_value(self.last_effective_date)
@@ -109,10 +108,13 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
109
108
  """
110
109
  This property holds the validated trading services and cache it.This property expect to be set only if is_valid return True
111
110
  """
111
+ target_portfolio = self._build_dto().convert_to_portfolio()
112
+
112
113
  return TradingService(
113
114
  self.trade_date,
114
115
  effective_portfolio=self.portfolio._build_dto(self.last_effective_date),
115
- target_portfolio=self._build_dto().convert_to_portfolio(),
116
+ target_portfolio=target_portfolio,
117
+ total_target_weight=target_portfolio.total_weight,
116
118
  )
117
119
 
118
120
  @cached_property
@@ -197,25 +199,30 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
197
199
 
198
200
  return trade_proposal_clone
199
201
 
200
- def normalize_trades(self):
202
+ def normalize_trades(self, total_target_weight: Decimal = Decimal("1.0")):
201
203
  """
202
204
  Call the trading service with the existing trades and normalize them in order to obtain a total sum target weight of 100%
203
205
  The existing trade will be modified directly with the given normalization factor
204
206
  """
205
- service = TradingService(self.trade_date, trades_batch=self._build_dto())
206
- service.normalize()
207
+ service = TradingService(
208
+ self.trade_date,
209
+ effective_portfolio=self.portfolio._build_dto(self.last_effective_date),
210
+ target_portfolio=self._build_dto().convert_to_portfolio(),
211
+ total_target_weight=total_target_weight,
212
+ )
207
213
  leftovers_trades = self.trades.all()
208
- total_target_weight = Decimal("0.0")
209
214
  for underlying_instrument_id, trade_dto in service.trades_batch.trades_map.items():
210
215
  with suppress(Trade.DoesNotExist):
211
216
  trade = self.trades.get(underlying_instrument_id=underlying_instrument_id)
212
217
  trade.weighting = round(trade_dto.delta_weight, 6)
213
218
  trade.save()
214
- total_target_weight += trade._target_weight
215
219
  leftovers_trades = leftovers_trades.exclude(id=trade.id)
216
220
  leftovers_trades.delete()
221
+ t_weight = self.trades.all().annotate_base_info().aggregate(models.Sum("target_weight"))[
222
+ "target_weight__sum"
223
+ ] or Decimal("0.0")
217
224
  # we handle quantization error due to the decimal max digits. In that case, we take the biggest trade (highest weight) and we remove the quantization error
218
- if quantize_error := (total_target_weight - Decimal("1.0")):
225
+ if quantize_error := (t_weight - total_target_weight):
219
226
  biggest_trade = self.trades.latest("weighting")
220
227
  biggest_trade.weighting -= quantize_error
221
228
  biggest_trade.save()
@@ -234,7 +241,12 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
234
241
  # Return the current portfolio by default
235
242
  return self.portfolio._build_dto(self.last_effective_date)
236
243
 
237
- def reset_trades(self, target_portfolio: PortfolioDTO | None = None, validate_trade: bool = True):
244
+ def reset_trades(
245
+ self,
246
+ target_portfolio: PortfolioDTO | None = None,
247
+ validate_trade: bool = True,
248
+ total_target_weight: Decimal = Decimal("1.0"),
249
+ ):
238
250
  """
239
251
  Will delete all existing trades and recreate them from the method `create_or_update_trades`
240
252
  """
@@ -249,6 +261,7 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
249
261
  self.trade_date,
250
262
  effective_portfolio=effective_portfolio,
251
263
  target_portfolio=target_portfolio,
264
+ total_target_weight=total_target_weight,
252
265
  )
253
266
  if validate_trade:
254
267
  service.is_valid()
@@ -279,6 +292,11 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
279
292
  status=Trade.Status.DRAFT,
280
293
  currency_fx_rate=currency_fx_rate,
281
294
  )
295
+ trade.price = trade.get_price()
296
+ # if we cannot automatically find a price, we consider the stock is invalid and we sell it
297
+ if trade.price is None:
298
+ trade.price = Decimal("0.0")
299
+ trade.weighting = -trade_dto.effective_weight
282
300
  trade.save()
283
301
 
284
302
  def replay(self):
@@ -329,7 +347,7 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
329
347
  last_trade_proposal_created = False
330
348
  last_trade_proposal = next_trade_proposal
331
349
 
332
- def get_estimated_shares(self, weight: Decimal, underlying_quote: Instrument) -> Decimal:
350
+ def get_estimated_shares(self, weight: Decimal, underlying_quote: Instrument, quote_price: Decimal) -> Decimal:
333
351
  """
334
352
  Estimates the number of shares for a trade based on the given weight and underlying quote.
335
353
 
@@ -342,23 +360,19 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
342
360
  Returns:
343
361
  Decimal | None: The estimated number of shares or None if the calculation fails.
344
362
  """
345
- try:
346
- # Retrieve the price of the underlying quote on the trade date TODO: this is very slow and probably due to the to_date argument to the dl which slowdown drastically the query
347
- quote_price = Decimal(underlying_quote.get_price(self.trade_date))
363
+ # Retrieve the price of the underlying quote on the trade date TODO: this is very slow and probably due to the to_date argument to the dl which slowdown drastically the query
348
364
 
349
- # Calculate the trade's total value in the portfolio's currency
350
- trade_total_value_fx_portfolio = self.portfolio_total_asset_value * weight
365
+ # Calculate the trade's total value in the portfolio's currency
366
+ trade_total_value_fx_portfolio = self.portfolio_total_asset_value * weight
351
367
 
352
- # Convert the quote price to the portfolio's currency
353
- price_fx_portfolio = quote_price * underlying_quote.currency.convert(
354
- self.trade_date, self.portfolio.currency, exact_lookup=False
355
- )
368
+ # Convert the quote price to the portfolio's currency
369
+ price_fx_portfolio = quote_price * underlying_quote.currency.convert(
370
+ self.trade_date, self.portfolio.currency, exact_lookup=False
371
+ )
356
372
 
357
- # If the price is valid, calculate and return the estimated shares
358
- if price_fx_portfolio:
359
- return trade_total_value_fx_portfolio / price_fx_portfolio
360
- except Exception:
361
- raise ValueError("We couldn't estimate the number of shares")
373
+ # If the price is valid, calculate and return the estimated shares
374
+ if price_fx_portfolio:
375
+ return trade_total_value_fx_portfolio / price_fx_portfolio
362
376
 
363
377
  def get_estimated_target_cash(self, currency: Currency) -> AssetPosition:
364
378
  """
@@ -399,7 +413,7 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
399
413
 
400
414
  # Estimate the target shares for the cash component
401
415
  with suppress(ValueError):
402
- total_target_shares = self.get_estimated_shares(target_cash_weight, cash_component)
416
+ total_target_shares = self.get_estimated_shares(target_cash_weight, cash_component, Decimal("1.0"))
403
417
 
404
418
  cash_component = Cash.objects.get_or_create(
405
419
  currency=self.portfolio.currency, defaults={"name": self.portfolio.currency.title}
@@ -447,46 +461,23 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
447
461
  },
448
462
  )
449
463
  def submit(self, by=None, description=None, **kwargs):
450
- self.reset_trades(target_portfolio=self._build_dto().convert_to_portfolio())
451
464
  trades = []
452
- trades_validation_errors = []
465
+ trades_validation_warnings = []
453
466
  for trade in self.trades.all():
454
- if not trade.last_underlying_quote_price:
455
- trade.status = Trade.Status.FAILED
456
- trades_validation_errors.append(
457
- f"Trade failed because no price is found for {trade.underlying_instrument.computed_str} on {trade.transaction_date:%Y-%m-%d}"
458
- )
459
- else:
460
- trade.status = Trade.Status.SUBMIT
467
+ trade_warnings = trade.submit(by=by, description=description, **kwargs)
468
+ if trade_warnings:
469
+ trades_validation_warnings.extend(trade_warnings)
461
470
  trades.append(trade)
462
471
 
463
- Trade.objects.bulk_update(trades, ["status"])
472
+ Trade.objects.bulk_update(trades, ["status", "shares", "weighting"])
464
473
 
465
474
  # If we estimate cash on this trade proposal, we make sure to create the corresponding cash component
466
475
  estimated_cash_position = self.get_estimated_target_cash(self.portfolio.currency)
467
- target_portfolio = self.validated_trading_service.target_portfolio
468
- if estimated_cash_position.weighting:
469
- if existing_cash_position := target_portfolio.positions_map.get(
470
- estimated_cash_position.underlying_quote.id
471
- ):
472
- existing_cash_position += estimated_cash_position
473
- else:
474
- target_portfolio.positions_map[estimated_cash_position.underlying_quote.id] = (
475
- estimated_cash_position._build_dto()
476
- )
477
- target_portfolio = PortfolioDTO(positions=tuple(target_portfolio.positions_map.values()))
476
+ target_portfolio = self.validated_trading_service.trades_batch.convert_to_portfolio(
477
+ estimated_cash_position._build_dto()
478
+ )
478
479
  self.evaluate_active_rules(self.trade_date, target_portfolio, asynchronously=True)
479
-
480
- if (
481
- trades_validation_errors
482
- and (fsm_context := getattr(self, "fsm_context", None))
483
- and (request := fsm_context.get("request", None))
484
- ):
485
- msg = f"""The reason for the failed trades are: <ul>
486
- {''.join(map(lambda o: '<li>' + o + '</li>', trades_validation_errors))}
487
- </ul>
488
- """
489
- error(request, msg, extra_tags="auto_close=0")
480
+ return trades_validation_warnings
490
481
 
491
482
  def can_submit(self):
492
483
  errors = dict()
@@ -496,7 +487,7 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
496
487
  service = self.validated_trading_service
497
488
  try:
498
489
  service.is_valid(ignore_error=True)
499
- # if service.trades_batch.totat_abs_delta_weight == 0:
490
+ # if service.trades_batch.total_abs_delta_weight == 0:
500
491
  # errors_list.append(
501
492
  # "There is no change detected in this trade proposal. Please submit at last one valid trade"
502
493
  # )
@@ -542,6 +533,7 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
542
533
  raise ValueError("Non-Rebalanceable portfolio cannot be traded manually.")
543
534
  trades = []
544
535
  assets = []
536
+ warnings = []
545
537
  # We do not want to create the estimated cash position if there is not trades in the trade proposal (shouldn't be possible anyway)
546
538
  estimated_cash_position = self.get_estimated_target_cash(self.portfolio.currency)
547
539
 
@@ -556,13 +548,11 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
556
548
 
557
549
  # if there is cash leftover, we create an extra asset position to hold the cash component
558
550
  if estimated_cash_position.weighting and len(trades) > 0:
551
+ warnings.append(
552
+ f"We created automatically a cash position of weight {estimated_cash_position.weighting:.2%}"
553
+ )
559
554
  estimated_cash_position.pre_save()
560
555
  assets.append(estimated_cash_position)
561
- if (fsm_context := getattr(self, "fsm_context", None)) and (request := fsm_context.get("request", None)):
562
- info(
563
- request,
564
- f"We created automatically a cash position of weight {estimated_cash_position.weighting:.2%}",
565
- )
566
556
 
567
557
  Trade.objects.bulk_update(trades, ["status"])
568
558
  self.portfolio.bulk_create_positions(
@@ -570,6 +560,7 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
570
560
  )
571
561
  if replay and self.portfolio.is_manageable:
572
562
  replay_as_task.delay(self.id, user_id=by.id if by else None)
563
+ return warnings
573
564
 
574
565
  def can_approve(self):
575
566
  errors = dict()
@@ -249,9 +249,7 @@ class Trade(TransactionMixin, ImportMixin, OrderedModel, models.Model):
249
249
  field=status,
250
250
  source=Status.DRAFT,
251
251
  target=GET_STATE(
252
- lambda self, **kwargs: (
253
- self.Status.SUBMIT if self.last_underlying_quote_price is not None else self.Status.FAILED
254
- ),
252
+ lambda self, **kwargs: (self.Status.SUBMIT if self.price else self.Status.FAILED),
255
253
  states=[Status.SUBMIT, Status.FAILED],
256
254
  ),
257
255
  permission=lambda instance, user: PortfolioRole.is_portfolio_manager(
@@ -271,7 +269,12 @@ class Trade(TransactionMixin, ImportMixin, OrderedModel, models.Model):
271
269
  on_error="FAILED",
272
270
  )
273
271
  def submit(self, by=None, description=None, **kwargs):
274
- pass
272
+ errors = []
273
+ if not self.price:
274
+ errors.append(
275
+ f"Trade failed because no price is found for {self.underlying_instrument.computed_str} on {self.transaction_date:%Y-%m-%d}"
276
+ )
277
+ return errors
275
278
 
276
279
  def can_submit(self):
277
280
  pass
@@ -287,6 +290,7 @@ class Trade(TransactionMixin, ImportMixin, OrderedModel, models.Model):
287
290
  def fail(self, **kwargs):
288
291
  pass
289
292
 
293
+ # TODO To be removed
290
294
  @cached_property
291
295
  def last_underlying_quote_price(self) -> InstrumentPrice | None:
292
296
  try:
@@ -343,7 +347,7 @@ class Trade(TransactionMixin, ImportMixin, OrderedModel, models.Model):
343
347
  )
344
348
 
345
349
  def can_execute(self):
346
- if not self.last_underlying_quote_price:
350
+ if not self.price:
347
351
  return {"underlying_instrument": [_("Cannot execute a trade without a valid quote price")]}
348
352
  if not self.portfolio.is_manageable:
349
353
  return {
@@ -531,19 +535,22 @@ class Trade(TransactionMixin, ImportMixin, OrderedModel, models.Model):
531
535
 
532
536
  def save(self, *args, **kwargs):
533
537
  if self.trade_proposal:
538
+ if not self.underlying_instrument.is_investable_universe:
539
+ self.underlying_instrument.is_investable_universe = True
540
+ self.underlying_instrument.save()
534
541
  self.portfolio = self.trade_proposal.portfolio
535
542
  self.transaction_date = self.trade_proposal.trade_date
536
543
  self.value_date = self.trade_proposal.last_effective_date
537
- if not self.portfolio.only_weighting:
538
- with suppress(ValueError):
539
- self.shares = self.trade_proposal.get_estimated_shares(self.weighting, self.underlying_instrument)
544
+ if self.price is None:
545
+ # we try to get the price if not provided directly from the underlying instrument
546
+ self.price = self.get_price()
547
+ if self.trade_proposal and not self.portfolio.only_weighting:
548
+ self.shares = self.trade_proposal.get_estimated_shares(
549
+ self.weighting, self.underlying_instrument, self.price
550
+ )
540
551
 
541
552
  if not self.custodian and self.bank:
542
553
  self.custodian = Custodian.get_by_mapping(self.bank)
543
- if self.price is None:
544
- # we try to get the price if not provided directly from the underlying instrument
545
- with suppress(Exception):
546
- self.price = self.underlying_instrument.get_price(self.value_date)
547
554
 
548
555
  if self.transaction_subtype is None or self.trade_proposal:
549
556
  # if subtype not provided, we extract it automatically from the existing data.
@@ -588,9 +595,6 @@ class Trade(TransactionMixin, ImportMixin, OrderedModel, models.Model):
588
595
  """
589
596
 
590
597
  def get_asset(self) -> AssetPosition:
591
- last_underlying_quote_price = self.last_underlying_quote_price
592
- if not last_underlying_quote_price:
593
- raise ValueError("No price found")
594
598
  asset = AssetPosition(
595
599
  underlying_quote=self.underlying_instrument,
596
600
  portfolio_created=None,
@@ -598,9 +602,8 @@ class Trade(TransactionMixin, ImportMixin, OrderedModel, models.Model):
598
602
  date=self.transaction_date,
599
603
  initial_currency_fx_rate=self.currency_fx_rate,
600
604
  weighting=self._target_weight,
601
- initial_price=self.last_underlying_quote_price.net_value,
605
+ initial_price=self.price,
602
606
  initial_shares=None,
603
- underlying_quote_price=self.last_underlying_quote_price,
604
607
  asset_valuation_date=self.transaction_date,
605
608
  currency=self.currency,
606
609
  is_estimated=False,
@@ -609,6 +612,11 @@ class Trade(TransactionMixin, ImportMixin, OrderedModel, models.Model):
609
612
  asset.pre_save()
610
613
  return asset
611
614
 
615
+ def get_price(self) -> Decimal | None:
616
+ if self.value_date:
617
+ with suppress(ValueError):
618
+ return Decimal(self.underlying_instrument.get_price(self.value_date))
619
+
612
620
  def delete(self, **kwargs):
613
621
  pre_collection.send(sender=self.__class__, instance=self)
614
622
  super().delete(**kwargs)
@@ -631,6 +639,7 @@ class Trade(TransactionMixin, ImportMixin, OrderedModel, models.Model):
631
639
  instrument_type=self.underlying_instrument.security_instrument_type.id,
632
640
  currency=self.underlying_instrument.currency,
633
641
  date=self.transaction_date,
642
+ is_cash=self.underlying_instrument.is_cash or self.underlying_instrument.is_cash_equivalent,
634
643
  )
635
644
 
636
645
  def get_alternative_valid_trades(self, share_delta: float = 0):
@@ -17,25 +17,20 @@ class TradingService:
17
17
  trade_date: date,
18
18
  effective_portfolio: Portfolio | None = None,
19
19
  target_portfolio: Portfolio | None = None,
20
- trades_batch: TradeBatch | None = None,
21
- total_value: Decimal = None,
20
+ total_target_weight: Decimal = Decimal("1.0"),
22
21
  ):
23
- self.total_value = total_value
24
22
  self.trade_date = trade_date
25
23
  if target_portfolio is None:
26
24
  target_portfolio = Portfolio(positions=())
27
25
  if effective_portfolio is None:
28
26
  effective_portfolio = Portfolio(positions=())
29
- # If effective portfoolio and trades batch is provided, we ensure the trade batch contains at least one trade for every position
30
- trades_batch = self.build_trade_batch(effective_portfolio, target_portfolio, trades_batch=trades_batch)
31
- # if no trade but a effective portfolio is provided, we get the trade batch only from the effective portofolio (and the target portfolio if provided, but optional. Without it, the trade delta weight will be 0 )
32
- # Finally, we compute the target portfolio
33
- if trades_batch and not target_portfolio:
34
- target_portfolio = trades_batch.convert_to_portfolio()
27
+ # If effective portfolio and trades batch is provided, we ensure the trade batch contains at least one trade for every position
28
+ self.trades_batch = self.build_trade_batch(effective_portfolio, target_portfolio).normalize(
29
+ total_target_weight
30
+ )
35
31
 
36
- self.trades_batch = trades_batch
37
- self.effective_portfolio = effective_portfolio
38
- self.target_portfolio = target_portfolio
32
+ self._effective_portfolio = effective_portfolio
33
+ self._target_portfolio = target_portfolio
39
34
 
40
35
  @property
41
36
  def errors(self) -> list[str]:
@@ -62,12 +57,11 @@ class TradingService:
62
57
  Test the given value against all the validators on the field,
63
58
  and either raise a `ValidationError` or simply return.
64
59
  """
65
- # TradeBatch(validated_trades).validate()
66
- if self.effective_portfolio:
60
+ if self._effective_portfolio:
67
61
  for trade in validated_trades:
68
62
  if (
69
63
  trade.effective_weight
70
- and trade.underlying_instrument not in self.effective_portfolio.positions_map
64
+ and trade.underlying_instrument not in self._effective_portfolio.positions_map
71
65
  ):
72
66
  raise ValidationError("All effective position needs to be matched with a validated trade")
73
67
 
@@ -75,7 +69,6 @@ class TradingService:
75
69
  self,
76
70
  effective_portfolio: Portfolio,
77
71
  target_portfolio: Portfolio,
78
- trades_batch: TradeBatch | None = None,
79
72
  ) -> TradeBatch:
80
73
  """
81
74
  Given combination of effective portfolio and either a trades batch or a target portfolio, ensure all theres variables are set
@@ -87,39 +80,35 @@ class TradingService:
87
80
 
88
81
  Returns: The normalized trades batch
89
82
  """
90
- instruments = list(effective_portfolio.positions_map.keys())
91
- instruments.extend(list(target_portfolio.positions_map.keys()))
92
- if trades_batch:
93
- instruments.extend(list(trades_batch.trades_map.keys()))
94
- _trades: list[Trade] = []
95
- for instrument in set(instruments):
96
- effective_weight = target_weight = 0
97
- effective_shares = 0
98
- instrument_type = currency = None
99
- if effective_pos := effective_portfolio.positions_map.get(instrument, None):
100
- effective_weight = effective_pos.weighting
101
- effective_shares = effective_pos.shares
102
- instrument_type, currency = effective_pos.instrument_type, effective_pos.currency
103
- if target_pos := target_portfolio.positions_map.get(instrument, None):
104
- target_weight = target_pos.weighting
105
- instrument_type, currency = target_pos.instrument_type, target_pos.currency
106
- if trades_batch and (trade := trades_batch.trades_map.get(instrument, None)):
107
- effective_weight, target_weight = trade.effective_weight, trade.target_weight
108
- effective_shares = trade.effective_shares
109
- instrument_type, currency = trade.instrument_type, trade.currency
110
-
111
- _trades.append(
112
- Trade(
113
- underlying_instrument=instrument,
114
- effective_weight=effective_weight,
115
- target_weight=target_weight,
116
- effective_shares=effective_shares,
117
- date=self.trade_date,
118
- instrument_type=instrument_type,
119
- currency=currency,
83
+ instruments = effective_portfolio.positions_map.copy()
84
+ instruments.update(target_portfolio.positions_map)
85
+
86
+ trades: list[Trade] = []
87
+ for instrument_id, pos in instruments.items():
88
+ if not pos.is_cash:
89
+ effective_weight = target_weight = 0
90
+ effective_shares = 0
91
+ instrument_type = currency = None
92
+ if effective_pos := effective_portfolio.positions_map.get(instrument_id, None):
93
+ effective_weight = effective_pos.weighting
94
+ effective_shares = effective_pos.shares
95
+ instrument_type, currency = effective_pos.instrument_type, effective_pos.currency
96
+ if target_pos := target_portfolio.positions_map.get(instrument_id, None):
97
+ target_weight = target_pos.weighting
98
+ instrument_type, currency = target_pos.instrument_type, target_pos.currency
99
+
100
+ trades.append(
101
+ Trade(
102
+ underlying_instrument=instrument_id,
103
+ effective_weight=effective_weight,
104
+ target_weight=target_weight,
105
+ effective_shares=effective_shares,
106
+ date=self.trade_date,
107
+ instrument_type=instrument_type,
108
+ currency=currency,
109
+ )
120
110
  )
121
- )
122
- return TradeBatch(tuple(_trades))
111
+ return TradeBatch(tuple(trades))
123
112
 
124
113
  def is_valid(self, ignore_error: bool = False) -> bool:
125
114
  """
@@ -151,11 +140,3 @@ class TradingService:
151
140
  raise ValidationError(self.errors)
152
141
 
153
142
  return not bool(self._errors)
154
-
155
- def normalize(self):
156
- """
157
- Normalize the instantiate trades batch so that the target weight is 100%
158
- """
159
- self.trades_batch = TradeBatch(
160
- [trade.normalize_target(self.trades_batch.total_target_weight) for trade in self.trades_batch.trades]
161
- )
@@ -48,7 +48,7 @@ class Position:
48
48
  @dataclass(frozen=True)
49
49
  class Portfolio:
50
50
  positions: tuple[Position] | tuple
51
- positions_map: dict[Position] = field(init=False, repr=False)
51
+ positions_map: dict[int, Position] = field(init=False, repr=False)
52
52
 
53
53
  def __post_init__(self):
54
54
  positions_map = {}
@@ -80,7 +80,7 @@ class Portfolio:
80
80
  @dataclass(frozen=True)
81
81
  class Trade:
82
82
  underlying_instrument: int
83
- instrument_type: str
83
+ instrument_type: int
84
84
  currency: int
85
85
  date: date_lib
86
86
 
@@ -88,6 +88,7 @@ class Trade:
88
88
  target_weight: Decimal
89
89
  id: int | None = None
90
90
  effective_shares: Decimal = None
91
+ is_cash: bool = False
91
92
 
92
93
  def __add__(self, other):
93
94
  return Trade(
@@ -121,9 +122,9 @@ class Trade:
121
122
  # if self.target_weight < 0 or self.target_weight > 1.0:
122
123
  # raise ValidationError("Target Weight needs to be in range [0, 1]")
123
124
 
124
- def normalize_target(self, total_target_weight: Decimal):
125
+ def normalize_target(self, factor: Decimal):
125
126
  t = Trade(
126
- target_weight=self.target_weight / total_target_weight if total_target_weight else self.target_weight,
127
+ target_weight=self.target_weight * factor,
127
128
  **{f.name: getattr(self, f.name) for f in fields(Trade) if f.name not in ["target_weight"]},
128
129
  )
129
130
  return t
@@ -145,15 +146,15 @@ class TradeBatch:
145
146
 
146
147
  @property
147
148
  def total_target_weight(self) -> Decimal:
148
- return round(sum([trade.target_weight for trade in self.trades]), 6)
149
+ return round(sum([trade.target_weight for trade in self.trades], Decimal("0")), 6)
149
150
 
150
151
  @property
151
152
  def total_effective_weight(self) -> Decimal:
152
- return round(sum([trade.effective_weight for trade in self.trades]), 6)
153
+ return round(sum([trade.effective_weight for trade in self.trades], Decimal("0")), 6)
153
154
 
154
155
  @property
155
- def totat_abs_delta_weight(self) -> Decimal:
156
- return sum([abs(trade.delta_weight) for trade in self.trades])
156
+ def total_abs_delta_weight(self) -> Decimal:
157
+ return sum([abs(trade.delta_weight) for trade in self.trades], Decimal("0"))
157
158
 
158
159
  def __add__(self, other):
159
160
  return TradeBatch(tuple(self.trades + other.trades))
@@ -165,7 +166,7 @@ class TradeBatch:
165
166
  if round(float(self.total_target_weight), 4) != 1: # we do that to remove decimal over precision
166
167
  raise ValidationError(f"Total Weight cannot be different than 1 ({float(self.total_target_weight)})")
167
168
 
168
- def convert_to_portfolio(self):
169
+ def convert_to_portfolio(self, *extra_positions):
169
170
  positions = []
170
171
  for instrument, trade in self.trades_map.items():
171
172
  positions.append(
@@ -175,6 +176,23 @@ class TradeBatch:
175
176
  weighting=trade.target_weight,
176
177
  currency=trade.currency,
177
178
  date=trade.date,
179
+ is_cash=trade.is_cash,
178
180
  )
179
181
  )
182
+ for position in extra_positions:
183
+ if position.weighting:
184
+ positions.append(position)
180
185
  return Portfolio(tuple(positions))
186
+
187
+ def normalize(self, total_target_weight: Decimal = Decimal("1.0")):
188
+ """
189
+ Normalize the instantiate trades batch so that the target weight is 100%
190
+ """
191
+ normalization_factor = (
192
+ total_target_weight / self.total_target_weight if self.total_target_weight else Decimal("0.0")
193
+ )
194
+ normalized_trades = []
195
+ for trade in self.trades:
196
+ normalized_trades.append(trade.normalize_target(normalization_factor))
197
+ tb = TradeBatch(normalized_trades)
198
+ return tb