wbportfolio 1.44.5__py2.py3-none-any.whl → 1.45.0__py2.py3-none-any.whl

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.

Potentially problematic release.


This version of wbportfolio might be problematic. Click here for more details.

Files changed (315) hide show
  1. wbportfolio/admin/__init__.py +1 -1
  2. wbportfolio/admin/asset.py +2 -1
  3. wbportfolio/admin/custodians.py +1 -0
  4. wbportfolio/admin/indexes.py +15 -0
  5. wbportfolio/admin/portfolio.py +12 -7
  6. wbportfolio/admin/portfolio_relationships.py +1 -0
  7. wbportfolio/admin/product_groups.py +2 -0
  8. wbportfolio/admin/products.py +2 -1
  9. wbportfolio/admin/reconciliations.py +1 -0
  10. wbportfolio/admin/registers.py +1 -0
  11. wbportfolio/admin/roles.py +1 -0
  12. wbportfolio/admin/transactions/__init__.py +1 -0
  13. wbportfolio/admin/transactions/claim.py +1 -0
  14. wbportfolio/admin/transactions/dividends.py +1 -0
  15. wbportfolio/admin/transactions/fees.py +1 -0
  16. wbportfolio/admin/transactions/rebalancing.py +26 -0
  17. wbportfolio/admin/transactions/trades.py +4 -3
  18. wbportfolio/admin/transactions/transactions.py +1 -0
  19. wbportfolio/analysis/claims.py +2 -1
  20. wbportfolio/contrib/company_portfolio/models.py +3 -6
  21. wbportfolio/contrib/company_portfolio/tests/conftest.py +0 -12
  22. wbportfolio/contrib/company_portfolio/tests/test_models.py +1 -0
  23. wbportfolio/defaults/fees/default.py +1 -0
  24. wbportfolio/factories/__init__.py +1 -7
  25. wbportfolio/factories/adjustments.py +1 -0
  26. wbportfolio/factories/assets.py +13 -7
  27. wbportfolio/factories/claim.py +1 -0
  28. wbportfolio/factories/custodians.py +1 -0
  29. wbportfolio/factories/dividends.py +1 -0
  30. wbportfolio/factories/fees.py +1 -0
  31. wbportfolio/factories/indexes.py +1 -0
  32. wbportfolio/factories/portfolio_cash_flow.py +1 -0
  33. wbportfolio/factories/portfolio_cash_targets.py +1 -0
  34. wbportfolio/factories/portfolio_swing_pricings.py +1 -0
  35. wbportfolio/factories/portfolios.py +3 -0
  36. wbportfolio/factories/product_groups.py +1 -0
  37. wbportfolio/factories/products.py +1 -0
  38. wbportfolio/factories/rebalancing.py +23 -0
  39. wbportfolio/factories/reconciliations.py +1 -0
  40. wbportfolio/factories/roles.py +1 -0
  41. wbportfolio/factories/trades.py +1 -0
  42. wbportfolio/factories/transactions.py +1 -0
  43. wbportfolio/fdm/tasks.py +1 -0
  44. wbportfolio/filters/__init__.py +1 -1
  45. wbportfolio/filters/assets.py +8 -9
  46. wbportfolio/filters/assets_and_net_new_money_progression.py +1 -0
  47. wbportfolio/filters/custodians.py +1 -0
  48. wbportfolio/filters/esg.py +1 -0
  49. wbportfolio/filters/performances.py +7 -6
  50. wbportfolio/filters/portfolios.py +21 -1
  51. wbportfolio/filters/positions.py +1 -0
  52. wbportfolio/filters/products.py +1 -0
  53. wbportfolio/filters/roles.py +1 -0
  54. wbportfolio/filters/signals.py +1 -0
  55. wbportfolio/filters/transactions/claim.py +1 -0
  56. wbportfolio/filters/transactions/fees.py +1 -0
  57. wbportfolio/filters/transactions/trades.py +2 -1
  58. wbportfolio/filters/transactions/transactions.py +1 -0
  59. wbportfolio/import_export/backends/ubs/mixin.py +1 -0
  60. wbportfolio/import_export/backends/wbfdm/adjustment.py +1 -0
  61. wbportfolio/import_export/handlers/asset_position.py +11 -13
  62. wbportfolio/import_export/handlers/fees.py +1 -0
  63. wbportfolio/import_export/handlers/portfolio_cash_flow.py +1 -0
  64. wbportfolio/import_export/handlers/trade.py +1 -0
  65. wbportfolio/import_export/parsers/jpmorgan/customer_trade.py +1 -0
  66. wbportfolio/import_export/parsers/jpmorgan/fees.py +1 -0
  67. wbportfolio/import_export/parsers/jpmorgan/strategy.py +5 -4
  68. wbportfolio/import_export/parsers/jpmorgan/valuation.py +1 -0
  69. wbportfolio/import_export/parsers/leonteq/customer_trade.py +1 -0
  70. wbportfolio/import_export/parsers/leonteq/equity.py +13 -12
  71. wbportfolio/import_export/parsers/leonteq/fees.py +1 -0
  72. wbportfolio/import_export/parsers/leonteq/trade.py +1 -0
  73. wbportfolio/import_export/parsers/leonteq/valuation.py +1 -0
  74. wbportfolio/import_export/parsers/natixis/customer_trade.py +1 -0
  75. wbportfolio/import_export/parsers/natixis/d1_customer_trade.py +1 -0
  76. wbportfolio/import_export/parsers/natixis/d1_equity.py +3 -2
  77. wbportfolio/import_export/parsers/natixis/d1_fees.py +1 -0
  78. wbportfolio/import_export/parsers/natixis/d1_trade.py +1 -0
  79. wbportfolio/import_export/parsers/natixis/d1_valuation.py +1 -0
  80. wbportfolio/import_export/parsers/natixis/equity.py +5 -5
  81. wbportfolio/import_export/parsers/natixis/trade.py +1 -0
  82. wbportfolio/import_export/parsers/natixis/utils.py +8 -7
  83. wbportfolio/import_export/parsers/sg_lux/custodian_positions.py +1 -0
  84. wbportfolio/import_export/parsers/sg_lux/customer_trade.py +1 -0
  85. wbportfolio/import_export/parsers/sg_lux/customer_trade_pending_slk.py +2 -1
  86. wbportfolio/import_export/parsers/sg_lux/customer_trade_slk.py +2 -1
  87. wbportfolio/import_export/parsers/sg_lux/customer_trade_without_pw.py +1 -0
  88. wbportfolio/import_export/parsers/sg_lux/equity.py +7 -8
  89. wbportfolio/import_export/parsers/sg_lux/portfolio_cash_flow.py +1 -0
  90. wbportfolio/import_export/parsers/sg_lux/portfolio_future_cash_flow.py +1 -0
  91. wbportfolio/import_export/parsers/sg_lux/registers.py +2 -1
  92. wbportfolio/import_export/parsers/societe_generale/customer_trade.py +1 -0
  93. wbportfolio/import_export/parsers/societe_generale/strategy.py +8 -9
  94. wbportfolio/import_export/parsers/societe_generale/valuation.py +1 -0
  95. wbportfolio/import_export/parsers/tellco/equity.py +5 -4
  96. wbportfolio/import_export/parsers/ubs/api/asset_position.py +15 -14
  97. wbportfolio/import_export/parsers/ubs/api/fees.py +1 -0
  98. wbportfolio/import_export/parsers/ubs/customer_trade.py +1 -0
  99. wbportfolio/import_export/parsers/ubs/equity.py +3 -2
  100. wbportfolio/import_export/parsers/ubs/historical_customer_trade.py +1 -0
  101. wbportfolio/import_export/parsers/ubs/valuation.py +1 -0
  102. wbportfolio/import_export/parsers/vontobel/asset_position.py +19 -19
  103. wbportfolio/import_export/parsers/vontobel/customer_trade.py +1 -0
  104. wbportfolio/import_export/parsers/vontobel/historical_customer_trade.py +1 -0
  105. wbportfolio/import_export/parsers/vontobel/management_fees.py +1 -0
  106. wbportfolio/import_export/parsers/vontobel/performance_fees.py +1 -0
  107. wbportfolio/import_export/parsers/vontobel/trade.py +1 -0
  108. wbportfolio/import_export/parsers/vontobel/valuation_api.py +20 -0
  109. wbportfolio/import_export/resources/assets.py +4 -3
  110. wbportfolio/import_export/resources/trades.py +1 -0
  111. wbportfolio/metric/backends/base.py +1 -0
  112. wbportfolio/metric/backends/portfolio_base.py +1 -0
  113. wbportfolio/metric/backends/portfolio_esg.py +1 -0
  114. wbportfolio/metric/tests/test_portfolio_base.py +1 -0
  115. wbportfolio/migrations/0052_remove_cash_instrument_ptr_and_more.py +1 -131
  116. wbportfolio/migrations/0067_assetposition_unique_asset_position.py +1 -1
  117. wbportfolio/migrations/0070_remove_assetposition_unique_asset_position_and_more.py +1 -1
  118. wbportfolio/migrations/0073_remove_product_price_computation_and_more.py +407 -0
  119. wbportfolio/models/__init__.py +0 -5
  120. wbportfolio/models/adjustments.py +8 -2
  121. wbportfolio/models/asset.py +117 -98
  122. wbportfolio/models/graphs/portfolio.py +144 -0
  123. wbportfolio/models/graphs/utils.py +83 -0
  124. wbportfolio/models/indexes.py +2 -13
  125. wbportfolio/models/mixins/instruments.py +28 -8
  126. wbportfolio/models/portfolio.py +538 -332
  127. wbportfolio/models/portfolio_cash_flow.py +1 -0
  128. wbportfolio/models/portfolio_relationship.py +6 -2
  129. wbportfolio/models/product_groups.py +3 -2
  130. wbportfolio/models/products.py +3 -17
  131. wbportfolio/models/reconciliations/account_reconciliation_lines.py +1 -0
  132. wbportfolio/models/reconciliations/account_reconciliations.py +1 -0
  133. wbportfolio/models/registers.py +1 -0
  134. wbportfolio/models/transactions/__init__.py +1 -0
  135. wbportfolio/models/transactions/claim.py +8 -8
  136. wbportfolio/models/transactions/dividends.py +1 -0
  137. wbportfolio/models/transactions/fees.py +1 -0
  138. wbportfolio/models/transactions/rebalancing.py +153 -0
  139. wbportfolio/models/transactions/trade_proposals.py +153 -155
  140. wbportfolio/models/transactions/trades.py +48 -40
  141. wbportfolio/models/transactions/transactions.py +6 -12
  142. wbportfolio/models/utils.py +1 -0
  143. wbportfolio/pms/analytics/__init__.py +0 -0
  144. wbportfolio/pms/analytics/portfolio.py +28 -0
  145. wbportfolio/pms/trading/handler.py +13 -16
  146. wbportfolio/pms/typing.py +13 -29
  147. wbportfolio/rebalancing/__init__.py +0 -0
  148. wbportfolio/rebalancing/base.py +16 -0
  149. wbportfolio/rebalancing/decorators.py +17 -0
  150. wbportfolio/rebalancing/models/__init__.py +3 -0
  151. wbportfolio/rebalancing/models/composite.py +31 -0
  152. wbportfolio/rebalancing/models/equally_weighted.py +21 -0
  153. wbportfolio/rebalancing/models/model_portfolio.py +35 -0
  154. wbportfolio/reports/monthly_position_report.py +1 -1
  155. wbportfolio/risk_management/backends/accounts.py +7 -6
  156. wbportfolio/risk_management/backends/controversy_portfolio.py +1 -0
  157. wbportfolio/risk_management/backends/exposure_portfolio.py +1 -0
  158. wbportfolio/risk_management/backends/instrument_list_portfolio.py +1 -0
  159. wbportfolio/risk_management/backends/liquidity_risk.py +1 -0
  160. wbportfolio/risk_management/backends/liquidity_stress_instrument.py +1 -0
  161. wbportfolio/risk_management/backends/mixins.py +1 -0
  162. wbportfolio/risk_management/backends/product_integrity.py +6 -1
  163. wbportfolio/risk_management/backends/stop_loss_instrument.py +1 -0
  164. wbportfolio/risk_management/backends/stop_loss_portfolio.py +1 -0
  165. wbportfolio/risk_management/backends/ucits_portfolio.py +1 -0
  166. wbportfolio/risk_management/tests/test_accounts.py +1 -0
  167. wbportfolio/risk_management/tests/test_controversy_portfolio.py +1 -0
  168. wbportfolio/risk_management/tests/test_exposure_portfolio.py +1 -0
  169. wbportfolio/risk_management/tests/test_instrument_list_portfolio.py +1 -0
  170. wbportfolio/risk_management/tests/test_liquidity_risk.py +1 -0
  171. wbportfolio/risk_management/tests/test_product_integrity.py +1 -0
  172. wbportfolio/risk_management/tests/test_stop_loss_instrument.py +1 -0
  173. wbportfolio/risk_management/tests/test_stop_loss_portfolio.py +1 -0
  174. wbportfolio/risk_management/tests/test_ucits_portfolio.py +1 -0
  175. wbportfolio/serializers/__init__.py +5 -5
  176. wbportfolio/serializers/adjustments.py +1 -0
  177. wbportfolio/serializers/assets.py +18 -19
  178. wbportfolio/serializers/custodians.py +1 -0
  179. wbportfolio/serializers/portfolio_cash_flow.py +1 -0
  180. wbportfolio/serializers/portfolio_cash_targets.py +1 -0
  181. wbportfolio/serializers/portfolio_relationship.py +1 -0
  182. wbportfolio/serializers/portfolio_swing_pricing.py +1 -0
  183. wbportfolio/serializers/portfolios.py +61 -40
  184. wbportfolio/serializers/positions.py +1 -0
  185. wbportfolio/serializers/product_group.py +1 -0
  186. wbportfolio/serializers/products.py +4 -7
  187. wbportfolio/serializers/rebalancing.py +57 -0
  188. wbportfolio/serializers/reconciliations.py +2 -1
  189. wbportfolio/serializers/registers.py +1 -0
  190. wbportfolio/serializers/roles.py +1 -0
  191. wbportfolio/serializers/signals.py +10 -15
  192. wbportfolio/serializers/transactions/__init__.py +1 -1
  193. wbportfolio/serializers/transactions/claim.py +1 -0
  194. wbportfolio/serializers/transactions/fees.py +1 -0
  195. wbportfolio/serializers/transactions/trade_proposals.py +85 -0
  196. wbportfolio/serializers/transactions/trades.py +9 -51
  197. wbportfolio/serializers/transactions/transactions.py +4 -3
  198. wbportfolio/tasks.py +1 -78
  199. wbportfolio/tests/conftest.py +6 -13
  200. wbportfolio/tests/models/test_account_reconciliation.py +2 -0
  201. wbportfolio/tests/models/test_assets.py +27 -19
  202. wbportfolio/tests/models/test_customer_trades.py +1 -0
  203. wbportfolio/tests/models/test_imports.py +5 -1
  204. wbportfolio/tests/models/test_merge.py +5 -4
  205. wbportfolio/tests/models/test_portfolio_cash_flow.py +8 -6
  206. wbportfolio/tests/models/test_portfolios.py +594 -154
  207. wbportfolio/tests/models/test_product_groups.py +1 -0
  208. wbportfolio/tests/models/test_products.py +6 -3
  209. wbportfolio/tests/models/test_roles.py +1 -0
  210. wbportfolio/tests/models/test_splits.py +1 -0
  211. wbportfolio/tests/models/transactions/test_claim.py +1 -0
  212. wbportfolio/tests/models/transactions/test_fees.py +1 -0
  213. wbportfolio/tests/models/transactions/test_rebalancing.py +81 -0
  214. wbportfolio/tests/models/transactions/test_trades.py +1 -0
  215. wbportfolio/tests/models/utils.py +1 -0
  216. wbportfolio/tests/pms/__init__.py +0 -0
  217. wbportfolio/tests/pms/test_analytics.py +35 -0
  218. wbportfolio/tests/rebalancing/__init__.py +0 -0
  219. wbportfolio/tests/rebalancing/test_models.py +127 -0
  220. wbportfolio/tests/serializers/test_claims.py +1 -0
  221. wbportfolio/tests/signals.py +1 -7
  222. wbportfolio/tests/tests.py +2 -0
  223. wbportfolio/tests/viewsets/test_assets.py +1 -0
  224. wbportfolio/tests/viewsets/test_performances.py +1 -0
  225. wbportfolio/tests/viewsets/test_products.py +1 -0
  226. wbportfolio/tests/viewsets/transactions/test_claims.py +1 -0
  227. wbportfolio/urls.py +26 -12
  228. wbportfolio/viewsets/__init__.py +2 -5
  229. wbportfolio/viewsets/adjustments.py +1 -0
  230. wbportfolio/viewsets/assets.py +62 -51
  231. wbportfolio/viewsets/assets_and_net_new_money_progression.py +1 -0
  232. wbportfolio/viewsets/charts/assets.py +3 -1
  233. wbportfolio/viewsets/configs/buttons/__init__.py +1 -1
  234. wbportfolio/viewsets/configs/buttons/assets.py +1 -0
  235. wbportfolio/viewsets/configs/buttons/custodians.py +1 -0
  236. wbportfolio/viewsets/configs/buttons/mixins.py +1 -20
  237. wbportfolio/viewsets/configs/buttons/portfolios.py +90 -76
  238. wbportfolio/viewsets/configs/buttons/signals.py +1 -0
  239. wbportfolio/viewsets/configs/buttons/trades.py +1 -0
  240. wbportfolio/viewsets/configs/display/__init__.py +2 -1
  241. wbportfolio/viewsets/configs/display/adjustments.py +1 -0
  242. wbportfolio/viewsets/configs/display/assets.py +7 -6
  243. wbportfolio/viewsets/configs/display/claim.py +1 -0
  244. wbportfolio/viewsets/configs/display/portfolios.py +127 -79
  245. wbportfolio/viewsets/configs/display/product_performance.py +1 -0
  246. wbportfolio/viewsets/configs/display/rebalancing.py +27 -0
  247. wbportfolio/viewsets/configs/display/trade_proposals.py +7 -4
  248. wbportfolio/viewsets/configs/display/trades.py +75 -42
  249. wbportfolio/viewsets/configs/endpoints/__init__.py +3 -1
  250. wbportfolio/viewsets/configs/endpoints/claim.py +1 -0
  251. wbportfolio/viewsets/configs/endpoints/portfolios.py +23 -7
  252. wbportfolio/viewsets/configs/endpoints/rebalancing.py +6 -0
  253. wbportfolio/viewsets/configs/endpoints/reconciliations.py +1 -0
  254. wbportfolio/viewsets/configs/endpoints/trade_proposals.py +1 -0
  255. wbportfolio/viewsets/configs/endpoints/trades.py +1 -0
  256. wbportfolio/viewsets/configs/menu/adjustments.py +1 -0
  257. wbportfolio/viewsets/configs/menu/assets.py +1 -0
  258. wbportfolio/viewsets/configs/menu/fees.py +1 -0
  259. wbportfolio/viewsets/configs/menu/portfolio_cash_flow.py +1 -0
  260. wbportfolio/viewsets/configs/menu/portfolios.py +4 -2
  261. wbportfolio/viewsets/configs/menu/positions.py +1 -0
  262. wbportfolio/viewsets/configs/menu/roles.py +1 -0
  263. wbportfolio/viewsets/configs/menu/transactions.py +1 -0
  264. wbportfolio/viewsets/configs/previews/portfolios.py +1 -6
  265. wbportfolio/viewsets/configs/titles/__init__.py +1 -1
  266. wbportfolio/viewsets/configs/titles/assets.py +1 -0
  267. wbportfolio/viewsets/configs/titles/fees.py +1 -0
  268. wbportfolio/viewsets/configs/titles/instrument_prices.py +1 -0
  269. wbportfolio/viewsets/configs/titles/portfolios.py +13 -11
  270. wbportfolio/viewsets/configs/titles/roles.py +1 -0
  271. wbportfolio/viewsets/configs/titles/trades.py +1 -0
  272. wbportfolio/viewsets/configs/titles/transactions.py +1 -0
  273. wbportfolio/viewsets/custodians.py +1 -0
  274. wbportfolio/viewsets/esg.py +1 -0
  275. wbportfolio/viewsets/mixins.py +1 -0
  276. wbportfolio/viewsets/portfolio_cash_flow.py +1 -0
  277. wbportfolio/viewsets/portfolio_cash_targets.py +1 -0
  278. wbportfolio/viewsets/portfolio_relationship.py +1 -0
  279. wbportfolio/viewsets/portfolio_swing_pricing.py +1 -0
  280. wbportfolio/viewsets/portfolios.py +228 -61
  281. wbportfolio/viewsets/positions.py +3 -2
  282. wbportfolio/viewsets/product_groups.py +1 -0
  283. wbportfolio/viewsets/product_performance.py +1 -0
  284. wbportfolio/viewsets/products.py +1 -0
  285. wbportfolio/viewsets/reconciliations.py +1 -0
  286. wbportfolio/viewsets/registers.py +1 -0
  287. wbportfolio/viewsets/roles.py +1 -0
  288. wbportfolio/viewsets/signals.py +1 -0
  289. wbportfolio/viewsets/transactions/__init__.py +1 -0
  290. wbportfolio/viewsets/transactions/claim.py +2 -1
  291. wbportfolio/viewsets/transactions/fees.py +1 -0
  292. wbportfolio/viewsets/transactions/mixins.py +1 -0
  293. wbportfolio/viewsets/transactions/rebalancing.py +31 -0
  294. wbportfolio/viewsets/transactions/trade_proposals.py +25 -5
  295. wbportfolio/viewsets/transactions/trades.py +16 -9
  296. wbportfolio/viewsets/transactions/transactions.py +1 -0
  297. {wbportfolio-1.44.5.dist-info → wbportfolio-1.45.0.dist-info}/METADATA +4 -1
  298. {wbportfolio-1.44.5.dist-info → wbportfolio-1.45.0.dist-info}/RECORD +301 -288
  299. wbportfolio/admin/synchronization/__init__.py +0 -2
  300. wbportfolio/admin/synchronization/admin.py +0 -114
  301. wbportfolio/admin/synchronization/portfolio_synchronization.py +0 -18
  302. wbportfolio/admin/synchronization/price_computation.py +0 -21
  303. wbportfolio/defaults/portfolio/default_rebalancing.py +0 -45
  304. wbportfolio/factories/pytest_utils.py +0 -121
  305. wbportfolio/factories/synchronization.py +0 -40
  306. wbportfolio/models/synchronization/__init__.py +0 -3
  307. wbportfolio/models/synchronization/portfolio_synchronization.py +0 -292
  308. wbportfolio/models/synchronization/price_computation.py +0 -200
  309. wbportfolio/models/synchronization/synchronization.py +0 -188
  310. wbportfolio/serializers/synchronization.py +0 -18
  311. wbportfolio/tests/models/test_synchronization.py +0 -617
  312. wbportfolio/viewsets/synchronization.py +0 -25
  313. /wbportfolio/{defaults/portfolio → models/graphs}/__init__.py +0 -0
  314. {wbportfolio-1.44.5.dist-info → wbportfolio-1.45.0.dist-info}/WHEEL +0 -0
  315. {wbportfolio-1.44.5.dist-info → wbportfolio-1.45.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,31 @@
1
+ from wbcore import viewsets
2
+ from wbcore.permissions.permissions import InternalUserPermissionMixin
3
+
4
+ from wbportfolio.models import Rebalancer, RebalancingModel
5
+ from wbportfolio.serializers import (
6
+ RebalancerModelSerializer,
7
+ RebalancerRepresentationSerializer,
8
+ RebalancingModelRepresentationSerializer,
9
+ )
10
+
11
+ from ..configs.display import RebalancerDisplayConfig
12
+ from ..configs.endpoints import RebalancerEndpointConfig
13
+
14
+
15
+ class RebalancingModelRepresentationViewSet(InternalUserPermissionMixin, viewsets.RepresentationViewSet):
16
+ IDENTIFIER = "wbportfolio:rebalancingmodel"
17
+ queryset = RebalancingModel.objects.all()
18
+ serializer_class = RebalancingModelRepresentationSerializer
19
+
20
+
21
+ class RebalancerRepresentationViewSet(InternalUserPermissionMixin, viewsets.RepresentationViewSet):
22
+ IDENTIFIER = "wbportfolio:rebalancingmodel"
23
+ queryset = Rebalancer.objects.all()
24
+ serializer_class = RebalancerRepresentationSerializer
25
+
26
+
27
+ class RebalancerModelViewSet(InternalUserPermissionMixin, viewsets.ModelViewSet):
28
+ queryset = Rebalancer.objects.select_related("rebalancing_model", "portfolio")
29
+ serializer_class = RebalancerModelSerializer
30
+ display_config_class = RebalancerDisplayConfig
31
+ endpoint_config_class = RebalancerEndpointConfig
@@ -1,4 +1,9 @@
1
+ from contextlib import suppress
2
+ from datetime import date
3
+
1
4
  from django.shortcuts import get_object_or_404
5
+ from django.utils.functional import cached_property
6
+ from pandas._libs.tslibs.offsets import BDay
2
7
  from rest_framework.decorators import action
3
8
  from rest_framework.response import Response
4
9
  from wbcompliance.viewsets.risk_management.mixins import RiskCheckViewSetMixin
@@ -9,11 +14,13 @@ from wbcore.metadata.configs.display.instance_display import (
9
14
  )
10
15
  from wbcore.permissions.permissions import InternalUserPermissionMixin
11
16
  from wbcore.utils.views import CloneMixin
12
- from wbportfolio.models import TradeProposal
17
+
18
+ from wbportfolio.models import AssetPosition, TradeProposal
13
19
  from wbportfolio.models.transactions.trade_proposals import (
14
- apply_trades_proposal_as_task,
20
+ replay_as_task,
15
21
  )
16
22
  from wbportfolio.serializers import (
23
+ ReadOnlyTradeProposalModelSerializer,
17
24
  TradeProposalModelSerializer,
18
25
  TradeProposalRepresentationSerializer,
19
26
  )
@@ -24,6 +31,7 @@ from ..configs import (
24
31
  TradeProposalEndpointConfig,
25
32
  TradeProposalPortfolioEndpointConfig,
26
33
  )
34
+ from ..mixins import UserPortfolioRequestPermissionMixin
27
35
 
28
36
 
29
37
  class TradeProposalRepresentationViewSet(InternalUserPermissionMixin, viewsets.RepresentationViewSet):
@@ -38,12 +46,19 @@ class TradeProposalModelViewSet(CloneMixin, RiskCheckViewSetMixin, InternalUserP
38
46
  search_fields = ("comment",)
39
47
  filterset_fields = {"trade_date": ["exact", "gte", "lte"], "status": ["exact"]}
40
48
 
41
- queryset = TradeProposal.objects.select_related("model_portfolio", "portfolio")
49
+ queryset = TradeProposal.objects.select_related("rebalancing_model", "portfolio")
42
50
  serializer_class = TradeProposalModelSerializer
43
51
  display_config_class = TradeProposalDisplayConfig
44
52
  button_config_class = TradeProposalButtonConfig
45
53
  endpoint_config_class = TradeProposalEndpointConfig
46
54
 
55
+ def get_serializer_class(self):
56
+ if self.new_mode or (
57
+ "pk" in self.kwargs and (obj := self.get_object()) and obj.status == TradeProposal.Status.DRAFT
58
+ ):
59
+ return TradeProposalModelSerializer
60
+ return ReadOnlyTradeProposalModelSerializer
61
+
47
62
  @classmethod
48
63
  def get_clone_instance_display(cls) -> Display:
49
64
  return create_simple_display(
@@ -75,7 +90,7 @@ class TradeProposalModelViewSet(CloneMixin, RiskCheckViewSetMixin, InternalUserP
75
90
  def replay(self, request, pk=None):
76
91
  trade_proposal = get_object_or_404(TradeProposal, pk=pk)
77
92
  if trade_proposal.portfolio.is_manageable:
78
- apply_trades_proposal_as_task.delay(trade_proposal.id)
93
+ replay_as_task.delay(trade_proposal.id)
79
94
  return Response({"send": True})
80
95
 
81
96
  @action(detail=True, methods=["PATCH"])
@@ -86,8 +101,13 @@ class TradeProposalModelViewSet(CloneMixin, RiskCheckViewSetMixin, InternalUserP
86
101
  return Response({"send": True})
87
102
 
88
103
 
89
- class TradeProposalPortfolioModelViewSet(TradeProposalModelViewSet):
104
+ class TradeProposalPortfolioModelViewSet(UserPortfolioRequestPermissionMixin, TradeProposalModelViewSet):
90
105
  endpoint_config_class = TradeProposalPortfolioEndpointConfig
91
106
 
107
+ @cached_property
108
+ def default_trade_date(self) -> date | None:
109
+ with suppress(AssetPosition.DoesNotExist):
110
+ return (self.portfolio.assets.latest("date").date + BDay(1)).date()
111
+
92
112
  def get_queryset(self):
93
113
  return TradeProposal.objects.filter(portfolio=self.kwargs["portfolio_id"])
@@ -2,18 +2,18 @@ from decimal import Decimal
2
2
 
3
3
  import pandas as pd
4
4
  import plotly.graph_objects as go
5
- from django.contrib.messages import warning
5
+ from django.contrib.messages import error, warning
6
6
  from django.db.models import (
7
7
  BooleanField,
8
8
  Case,
9
+ DecimalField,
10
+ ExpressionWrapper,
9
11
  F,
10
12
  OuterRef,
11
13
  Subquery,
12
14
  Sum,
13
15
  Value,
14
16
  When,
15
- DecimalField,
16
- ExpressionWrapper,
17
17
  )
18
18
  from django.db.models.functions import Coalesce
19
19
  from django.shortcuts import get_object_or_404
@@ -23,8 +23,9 @@ from wbcore import viewsets
23
23
  from wbcore.contrib.currency.models import CurrencyFXRates
24
24
  from wbcore.permissions.permissions import InternalUserPermissionMixin
25
25
  from wbcore.utils.strings import format_number
26
- from wbcrm.models import Account
27
26
  from wbcore.viewsets.mixins import OrderableMixin
27
+ from wbcrm.models import Account
28
+
28
29
  from wbportfolio.filters import (
29
30
  SubscriptionRedemptionFilterSet,
30
31
  SubscriptionRedemptionPortfolioFilterSet,
@@ -365,6 +366,7 @@ class TradeTradeProposalModelViewSet(
365
366
  "trade_proposal",
366
367
  "order",
367
368
  )
369
+ ordering_fields = ("target_weight", "effective_weight", "effective_shares", "target_shares", "shares", "weighting")
368
370
  IDENTIFIER = "wbportfolio:tradeproposal"
369
371
  search_fields = ("underlying_instrument__name",)
370
372
  filterset_fields = {}
@@ -376,8 +378,8 @@ class TradeTradeProposalModelViewSet(
376
378
  button_config_class = TradeTradeProposalButtonConfig
377
379
 
378
380
  @cached_property
379
- def trade_proposal_status(self):
380
- return get_object_or_404(TradeProposal, pk=self.kwargs["trade_proposal_id"]).status
381
+ def trade_proposal(self):
382
+ return get_object_or_404(TradeProposal, pk=self.kwargs["trade_proposal_id"])
381
383
 
382
384
  def get_resource_class(self):
383
385
  return TradeProposalTradeResource
@@ -397,15 +399,20 @@ class TradeTradeProposalModelViewSet(
397
399
  return {}
398
400
 
399
401
  def get_serializer_class(self):
400
- if self.trade_proposal_status != TradeProposal.Status.DRAFT:
402
+ if self.trade_proposal.status != TradeProposal.Status.DRAFT:
401
403
  return ReadOnlyTradeTradeProposalModelSerializer
402
404
  return TradeTradeProposalModelSerializer
403
405
 
404
406
  def add_messages(self, request, queryset=None, paginated_queryset=None, instance=None, initial=False):
405
- if queryset:
406
- total_target_weight = float(queryset.aggregate(c=Sum(F("target_weight")))["c"]) or 0
407
+ if queryset is not None:
408
+ total_target_weight = queryset.aggregate(c=Sum(F("target_weight")))["c"] or Decimal(0)
407
409
  if round(total_target_weight, 3) != 1:
408
410
  warning(request, "The total target weight does not equals to 1")
411
+ if queryset.filter(status=Trade.Status.FAILED):
412
+ error(
413
+ request,
414
+ "Some Trades couldn't be succesfully prepared. Please revert back to draft and correct these trades accordingly.",
415
+ )
409
416
 
410
417
  def get_queryset(self):
411
418
  if self.is_portfolio_manager:
@@ -14,6 +14,7 @@ from wbcore import viewsets
14
14
  from wbcore.contrib.currency.models import CurrencyFXRates
15
15
  from wbcore.permissions.permissions import InternalUserPermissionMixin
16
16
  from wbcore.utils.strings import format_number
17
+
17
18
  from wbportfolio.filters import TransactionFilterSet, TransactionPortfolioFilterSet
18
19
  from wbportfolio.models import Fees, Trade, Transaction
19
20
  from wbportfolio.serializers import (
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wbportfolio
3
- Version: 1.44.5
3
+ Version: 1.45.0
4
4
  Author-email: Christopher Wittlinger <c.wittlinger@stainly.com>
5
5
  License-File: LICENSE
6
6
  Requires-Dist: cryptography==3.4.*
@@ -9,9 +9,12 @@ Requires-Dist: django-storages==1.14.*
9
9
  Requires-Dist: fuzzywuzzy==0.*
10
10
  Requires-Dist: jinjasql2==0.1.*
11
11
  Requires-Dist: msoffcrypto-tool==4.10.*
12
+ Requires-Dist: networkx>=3.4.2
13
+ Requires-Dist: pydot>=3.0.4
12
14
  Requires-Dist: python-levenshtein==0.*
13
15
  Requires-Dist: reportlab==3.*
14
16
  Requires-Dist: scipy>=1
17
+ Requires-Dist: skfolio==0.6.*
15
18
  Requires-Dist: wbcompliance
16
19
  Requires-Dist: wbcore
17
20
  Requires-Dist: wbcrm