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
@@ -1,123 +1,6 @@
1
1
  # Generated by Django 4.2.7 on 2023-12-12 16:27
2
2
  import django.db.models.deletion
3
- from django.db import migrations, models, transaction
4
- from django.db.utils import IntegrityError
5
-
6
-
7
- def move_private_equity_type(apps, schema_editor):
8
- Instrument = apps.get_model("wbportfolio", "Instrument")
9
- Equity = apps.get_model("wbportfolio", "Equity")
10
- private_equities = Equity.objects.filter(status="PRIVATE")
11
- Instrument.objects.filter(id__in=private_equities.values("instrument_ptr_id")).update(
12
- instrument_type="PrivateEquity"
13
- )
14
-
15
-
16
- def migrate_price_computation(apps, schema_editor):
17
- Product = apps.get_model("wbportfolio", "Product")
18
- Index = apps.get_model("wbportfolio", "Index")
19
- PriceComputation = apps.get_model("wbportfolio", "PriceComputation")
20
- Instrument = apps.get_model("wbportfolio", "Instrument")
21
- ExchangeInstrumentThroughModel = apps.get_model("wbportfolio", "ExchangeInstrumentThroughModel")
22
- for pc in PriceComputation.objects.all():
23
- for instrument in Instrument.objects.filter(old_price_computation=pc):
24
- try:
25
- product = Product.objects.get(instrument_ptr_id=instrument.id)
26
- product.price_computation = pc
27
- product.save()
28
- except Product.DoesNotExist:
29
- pass
30
- try:
31
- index = Index.objects.get(instrument_ptr_id=instrument.id)
32
- index.price_computation = pc
33
- index.save()
34
- except Index.DoesNotExist:
35
- pass
36
- for rel in ExchangeInstrumentThroughModel.objects.filter(is_primary=True):
37
- rel.instrument.exchange = rel.exchange
38
- rel.save()
39
-
40
-
41
- def refactor_io_resources(apps, schema_editor):
42
- from django_celery_beat.models import PeriodicTask
43
- from wbcore.contrib.io.models import (
44
- DataBackend,
45
- ImportSource,
46
- ParserHandler,
47
- Source,
48
- )
49
-
50
- for provider in ["cbinsights", "refinitiv"]:
51
- for backend in DataBackend.objects.filter(backend_class_path__contains=provider):
52
- if "adjustments" not in backend.backend_class_path:
53
- backend.backend_class_path = backend.backend_class_path.replace("wbportfolio", "wbfdm")
54
- backend.save()
55
- for parser_handler in ParserHandler.objects.filter(
56
- models.Q(parser__contains=provider) | models.Q(handler__contains=provider)
57
- ):
58
- if "adjustments" not in parser_handler.parser:
59
- parser_handler.parser = parser_handler.parser.replace("wbportfolio", "wbfdm")
60
- if "adjustments" not in parser_handler.handler:
61
- parser_handler.handler = parser_handler.handler.replace("wbportfolio", "wbfdm")
62
- parser_handler.save()
63
-
64
- for handler in [
65
- "wbportfolio.Cash",
66
- "wbportfolio.Instrument",
67
- "wbportfolio.InstrumentList",
68
- "wbportfolio.InstrumentPrice",
69
- "wbportfolio.Deal",
70
- "wbportfolio.InstrumentListThroughModel",
71
- "wbportfolio.IncomeStatement",
72
- "wbportfolio.Fundamental",
73
- "wbportfolio.Forecast",
74
- "wbportfolio.FiscalQuarterPeriod",
75
- "wbportfolio.DailyFundamental",
76
- "wbportfolio.FiscalPeriod",
77
- "wbportfolio.Equity",
78
- ]:
79
- for parser_handler in ParserHandler.objects.filter(handler=handler):
80
- try:
81
- with transaction.atomic():
82
- parser_handler.handler = parser_handler.handler.replace("wbportfolio", "wbfdm")
83
- parser_handler.save()
84
- except IntegrityError:
85
- ImportSource.objects.filter(parser_handler=parser_handler).delete()
86
- Source.objects.filter(parser_handler=parser_handler).delete()
87
- parser_handler.delete()
88
-
89
- for parser_handler in ParserHandler.objects.filter(parser="wbportfolio.import_export.resources.instruments"):
90
- parser_handler.parser = parser_handler.parser.replace("wbportfolio", "wbfdm")
91
- try:
92
- parser_handler.save()
93
- except IntegrityError:
94
- ImportSource.objects.filter(parser_handler=parser_handler).delete()
95
- Source.objects.filter(parser_handler=parser_handler).delete()
96
- parser_handler.delete()
97
-
98
- for handler in [
99
- "wbfdm.IncomeStatement",
100
- "wbfdm.Fundamental",
101
- "wbfdm.Forecast",
102
- "wbfdm.FiscalQuarterPeriod",
103
- "wbfdm.DailyFundamental",
104
- "wbfdm.FiscalPeriod",
105
- "wbfdm.GeographicSegment",
106
- ]:
107
- for parser_handler in ParserHandler.objects.filter(handler=handler):
108
- ImportSource.objects.filter(parser_handler=parser_handler).delete()
109
- Source.objects.filter(parser_handler=parser_handler).delete()
110
- parser_handler.delete()
111
-
112
- Source.objects.filter(
113
- data_backend__backend_class_path="wbportfolio.import_export.backends.wbfdm.instrument"
114
- ).delete()
115
- PeriodicTask.objects.filter(
116
- task="wbportfolio.models.instruments.instruments.bulk_recompute_outstanding_shares_as_task"
117
- ).update(task="wbportfolio.models.products.bulk_recompute_outstanding_shares_as_task")
118
- PeriodicTask.objects.filter(task="wbportfolio.tasks.daily_prefered_classificaiton_per_instrument_update").update(
119
- task="wbportfolio.tasks.update_preferred_classification_per_instrument_and_portfolio_as_task"
120
- )
3
+ from django.db import migrations, models
121
4
 
122
5
 
123
6
  class Migration(migrations.Migration):
@@ -127,7 +10,6 @@ class Migration(migrations.Migration):
127
10
  ]
128
11
 
129
12
  operations = [
130
- migrations.RunPython(move_private_equity_type),
131
13
  migrations.AlterUniqueTogether(
132
14
  name="dailyfundamental",
133
15
  unique_together=None,
@@ -355,7 +237,6 @@ class Migration(migrations.Migration):
355
237
  to="wbportfolio.exchange",
356
238
  ),
357
239
  ),
358
- migrations.RunPython(migrate_price_computation),
359
240
  migrations.RemoveField(
360
241
  model_name="instrument",
361
242
  name="old_price_computation",
@@ -874,15 +755,4 @@ class Migration(migrations.Migration):
874
755
  ],
875
756
  database_operations=[migrations.AlterModelTable(name="Deal", table="wbfdm_deal")],
876
757
  ),
877
- migrations.RunSQL("ALTER TABLE wbportfolio_instrument_tags RENAME TO wbfdm_instrument_tags;"),
878
- migrations.RunSQL(
879
- "ALTER TABLE wbportfolio_instrumentfavoritegroup_instruments RENAME TO wbfdm_instrumentfavoritegroup_instruments;"
880
- ),
881
- migrations.RunSQL("ALTER TABLE wbportfolio_deal_investors RENAME TO wbfdm_deal_investors;"),
882
- migrations.RunSQL(
883
- "ALTER TABLE wbportfolio_instrumentclassificationthroughmodel_tags RENAME TO wbfdm_instrumentclassificationthroughmodel_tags;"
884
- ),
885
- migrations.RunSQL(sql="SET CONSTRAINTS ALL IMMEDIATE;"),
886
- migrations.RunPython(refactor_io_resources),
887
- migrations.RunSQL(sql="SET CONSTRAINTS ALL DEFERRED;"),
888
758
  ]
@@ -48,7 +48,7 @@ def remove_duplicates(apps, schema_editor):
48
48
  for portfolio, dates in tqdm(changed_portfolios.items()):
49
49
  portfolio = Portfolio.all_objects.get(id=portfolio.id)
50
50
  for _d in dates:
51
- portfolio.change_at_date(_d, recompute_weighting=True, force_recompute_weighting=True, synchronize=False)
51
+ portfolio.change_at_date(_d)
52
52
 
53
53
 
54
54
  class Migration(migrations.Migration):
@@ -48,7 +48,7 @@ def remove_duplicates(apps, schema_editor):
48
48
  for portfolio, dates in tqdm(changed_portfolios.items()):
49
49
  portfolio = Portfolio.all_objects.get(id=portfolio.id)
50
50
  for _d in dates:
51
- portfolio.change_at_date(_d, recompute_weighting=True, force_recompute_weighting=True, synchronize=False)
51
+ portfolio.change_at_date(_d)
52
52
 
53
53
 
54
54
  class Migration(migrations.Migration):
@@ -0,0 +1,407 @@
1
+ # Generated by Django 5.0.10 on 2024-12-16 15:32
2
+
3
+ from django.db import migrations, models
4
+ import django.db.models.deletion
5
+ from datetime import date
6
+
7
+ from django.db.models import Exists
8
+
9
+
10
+ def migrate_path(apps, schema_editor):
11
+ Product = apps.get_model("wbportfolio", "Product")
12
+ Index = apps.get_model("wbportfolio", "Index")
13
+ for product in Product.objects.filter(price_computation__import_path="restbench.price.peers"):
14
+ product.custom_net_asset_value_computation_method_path = "restbench.price.peers" + ".get_estimate_net_value"
15
+ product.save()
16
+ for index in Index.objects.filter(price_computation__import_path="restbench.price.peers"):
17
+ index.custom_net_asset_value_computation_method_path = "restbench.price.peers" + ".get_estimate_net_value"
18
+ index.save()
19
+
20
+
21
+ def migrate_data(apps, schema_editor):
22
+ Portfolio = apps.get_model("wbportfolio", "Portfolio")
23
+ RebalancingModel = apps.get_model("wbportfolio", "RebalancingModel")
24
+ PortfolioPortfolioThroughModel = apps.get_model("wbportfolio", "PortfolioPortfolioThroughModel")
25
+ Rebalancer = apps.get_model("wbportfolio", "Rebalancer")
26
+ equally_weighted_model, _ = RebalancingModel.objects.get_or_create(
27
+ class_path="wbportfolio.rebalancing.models.equally_weighted.EquallyWeightedRebalancing",
28
+ defaults={"name": "Equally Weighted Rebalancing"},
29
+ )
30
+ composite_model, _ = RebalancingModel.objects.get_or_create(
31
+ class_path="wbportfolio.rebalancing.models.composite.CompositeRebalancing",
32
+ defaults={"name": "Composite Rebalancing"},
33
+ )
34
+ PortfolioPortfolioThroughModel.objects.filter(portfolio=models.F("dependency_portfolio")).delete()
35
+ Portfolio.objects.annotate(has_primary=Exists(PortfolioPortfolioThroughModel.objects.filter(portfolio=models.OuterRef("pk"), type="PRIMARY"))).filter(has_primary=True, portfolio_synchronization__name="Default Portfolio Synchronization").update(
36
+ is_lookthrough=True
37
+ )
38
+ for portfolio in Portfolio.objects.filter(portfolio_synchronization__name="Composite synchronization"):
39
+ try:
40
+ activation_date = portfolio.assets.earliest("date").date
41
+ except Exception:
42
+ activation_date = date.today()
43
+ Rebalancer.objects.create(
44
+ portfolio=portfolio,
45
+ rebalancing_model=composite_model,
46
+ approve_trade_proposal_automatically=True,
47
+ frequency="RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=1",
48
+ activation_date=activation_date,
49
+ )
50
+ for portfolio in Portfolio.objects.filter(portfolio_synchronization__name="Equally-weighted Synchronization"):
51
+ try:
52
+ activation_date = portfolio.assets.earliest("date").date
53
+ except Exception:
54
+ activation_date = date.today()
55
+ Rebalancer.objects.create(
56
+ portfolio=portfolio,
57
+ rebalancing_model=equally_weighted_model,
58
+ approve_trade_proposal_automatically=True,
59
+ frequency="RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=1",
60
+ activation_date=activation_date,
61
+ )
62
+
63
+ def set_composition(apps, schema_editor):
64
+ Portfolio = apps.get_model("wbportfolio", "Portfolio")
65
+ for portfolio in Portfolio.objects.all():
66
+ if portfolio.assets.filter(underlying_instrument__instrument_type__key__in=["index", "product", "product_group"]).exists():
67
+ portfolio.is_composition = True
68
+ portfolio.save()
69
+
70
+ class Migration(migrations.Migration):
71
+ dependencies = [
72
+ ('directory', '0009_remove_entry_external_identfier_and_more'),
73
+ ('io', '0007_alter_exportsource_query_params'),
74
+ ('wbfdm', '0028_instrumentprice_annualized_daily_volatility'),
75
+ ("wbportfolio", "0072_trade_diff_shares"),
76
+ ]
77
+
78
+ operations = [
79
+ migrations.AddField(
80
+ model_name="index",
81
+ name="custom_net_asset_value_computation_method_path",
82
+ field=models.CharField(blank=True, null=True, verbose_name="Custom NAV Computation Method"),
83
+ ),
84
+ migrations.AddField(
85
+ model_name="product",
86
+ name="custom_net_asset_value_computation_method_path",
87
+ field=models.CharField(blank=True, null=True, verbose_name="Custom NAV Computation Method"),
88
+ ),
89
+ migrations.RunSQL(
90
+ sql="SET CONSTRAINTS ALL IMMEDIATE;",
91
+ ),
92
+ migrations.RunPython(migrate_path),
93
+ migrations.RunSQL(
94
+ sql="SET CONSTRAINTS ALL DEFERRED;",
95
+ ),
96
+ migrations.RemoveField(
97
+ model_name="product",
98
+ name="price_computation",
99
+ ),
100
+ migrations.RemoveField(
101
+ model_name="index",
102
+ name="price_computation",
103
+ ),
104
+ migrations.DeleteModel(
105
+ name="PriceComputation",
106
+ ),
107
+ migrations.CreateModel(
108
+ name="RebalancingModel",
109
+ fields=[
110
+ ("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
111
+ ("name", models.CharField(max_length=64, verbose_name="Name")),
112
+ ("class_path", models.CharField(max_length=512, verbose_name="Class path")),
113
+ ],
114
+ options={
115
+ "verbose_name": "Rebalancing Model",
116
+ "verbose_name_plural": "Rebalancing Models",
117
+ },
118
+ ),
119
+ migrations.RenameField(
120
+ model_name="portfolio",
121
+ old_name="last_synchronization",
122
+ new_name="updated_at",
123
+ ),
124
+ migrations.AddField(
125
+ model_name="portfolio",
126
+ name="is_lookthrough",
127
+ field=models.BooleanField(
128
+ default=False, help_text="Indicates that this portfolio is a look-through portfolio"
129
+ ),
130
+ ),
131
+ migrations.AddField(
132
+ model_name="tradeproposal",
133
+ name="rebalancing_model",
134
+ field=models.ForeignKey(
135
+ blank=True,
136
+ help_text="Rebalancing Model to use to generate the target portfolio",
137
+ null=True,
138
+ on_delete=django.db.models.deletion.SET_NULL,
139
+ related_name="trade_proposals",
140
+ to="wbportfolio.rebalancingmodel",
141
+ verbose_name="Rebalancing Model",
142
+ ),
143
+ ),
144
+ migrations.CreateModel(
145
+ name="Rebalancer",
146
+ fields=[
147
+ ("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
148
+ ("parameters", models.JSONField(default=dict, verbose_name="Parameters")),
149
+ (
150
+ "approve_trade_proposal_automatically",
151
+ models.BooleanField(default=False, verbose_name="Apply Trade Proposal Automatically"),
152
+ ),
153
+ ("activation_date", models.DateField(verbose_name="Activation Date")),
154
+ (
155
+ "frequency",
156
+ models.CharField(
157
+ default="RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=1",
158
+ help_text="The Evaluation Frequency in RRULE format",
159
+ max_length=56,
160
+ verbose_name="Evaluation Frequency",
161
+ ),
162
+ ),
163
+ (
164
+ "portfolio",
165
+ models.OneToOneField(
166
+ on_delete=django.db.models.deletion.CASCADE,
167
+ related_name="automatic_rebalancer",
168
+ to="wbportfolio.portfolio",
169
+ ),
170
+ ),
171
+ (
172
+ "rebalancing_model",
173
+ models.ForeignKey(
174
+ on_delete=django.db.models.deletion.PROTECT,
175
+ related_name="rebalancers",
176
+ to="wbportfolio.rebalancingmodel",
177
+ verbose_name="Rebalancing Model",
178
+ ),
179
+ ),
180
+ ("computed_str", models.CharField(blank=True, max_length=512, null=True, verbose_name="Name")),
181
+ ],
182
+ options={
183
+ "verbose_name": "Rebalancer",
184
+ "verbose_name_plural": "Rebalancers",
185
+ },
186
+ ),
187
+ migrations.RunSQL(
188
+ sql="SET CONSTRAINTS ALL IMMEDIATE;",
189
+ ),
190
+ migrations.RunPython(migrate_data),
191
+ migrations.RunSQL(
192
+ sql="SET CONSTRAINTS ALL DEFERRED;",
193
+ ),
194
+ migrations.RemoveField(
195
+ model_name="tradeproposal",
196
+ name="model_portfolio",
197
+ ),
198
+ migrations.RemoveField(
199
+ model_name="portfolio",
200
+ name="portfolio_synchronization",
201
+ ),
202
+ migrations.RemoveField(
203
+ model_name="synchronizationtask",
204
+ name="dependent_task",
205
+ ),
206
+ migrations.RemoveField(
207
+ model_name="synchronizationtask",
208
+ name="periodictask_ptr",
209
+ ),
210
+ migrations.DeleteModel(
211
+ name="PortfolioSynchronization",
212
+ ),
213
+ migrations.DeleteModel(
214
+ name="SynchronizationTask",
215
+ ),
216
+ migrations.AlterUniqueTogether(
217
+ name='adjustment',
218
+ unique_together=set(),
219
+ ),
220
+ migrations.AlterUniqueTogether(
221
+ name='instrumentportfoliothroughmodel',
222
+ unique_together=set(),
223
+ ),
224
+ migrations.AlterUniqueTogether(
225
+ name='portfolioinstrumentpreferredclassificationthroughmodel',
226
+ unique_together=set(),
227
+ ),
228
+ migrations.AlterUniqueTogether(
229
+ name='tradeproposal',
230
+ unique_together=set(),
231
+ ),
232
+ migrations.RemoveField(
233
+ model_name='index',
234
+ name='custom_net_asset_value_computation_method_path',
235
+ ),
236
+ migrations.RemoveField(
237
+ model_name='product',
238
+ name='custom_net_asset_value_computation_method_path',
239
+ ),
240
+ migrations.AddField(
241
+ model_name='index',
242
+ name='net_asset_value_computation_method_path',
243
+ field=models.CharField(blank=True, default='wbportfolio.models.portfolio.default_estimate_net_value',
244
+ null=True, verbose_name='NAV Computation Method'),
245
+ ),
246
+ migrations.AddField(
247
+ model_name='product',
248
+ name='net_asset_value_computation_method_path',
249
+ field=models.CharField(blank=True, default='wbportfolio.models.portfolio.default_estimate_net_value',
250
+ null=True, verbose_name='NAV Computation Method'),
251
+ ),
252
+ migrations.AlterField(
253
+ model_name='portfolio',
254
+ name='is_tracked',
255
+ field=models.BooleanField(default=True,
256
+ help_text='True if the internal updating mechanism (e.g., Next weights or Look-Through computation, rebalancing etc...) needs to apply to this portfolio'),
257
+ ),
258
+ migrations.AlterField(
259
+ model_name='portfolio',
260
+ name='updated_at',
261
+ field=models.DateTimeField(blank=True, null=True, verbose_name='Updated At'),
262
+ ),
263
+ migrations.AlterField(
264
+ model_name='tradeproposal',
265
+ name='rebalancing_model',
266
+ field=models.ForeignKey(blank=True, help_text='Rebalancing Model that generates the target portfolio',
267
+ null=True, on_delete=django.db.models.deletion.SET_NULL,
268
+ related_name='trade_proposals', to='wbportfolio.rebalancingmodel',
269
+ verbose_name='Rebalancing Model'),
270
+ ),
271
+ migrations.AddConstraint(
272
+ model_name='adjustment',
273
+ constraint=models.UniqueConstraint(fields=('date', 'instrument'), name='unique_date_instrument'),
274
+ ),
275
+ migrations.AddConstraint(
276
+ model_name='portfolioinstrumentpreferredclassificationthroughmodel',
277
+ constraint=models.UniqueConstraint(fields=('portfolio', 'instrument', 'classification_group'),
278
+ name='unique_prefered_classification_relationship'),
279
+ ),
280
+ migrations.AddConstraint(
281
+ model_name='tradeproposal',
282
+ constraint=models.UniqueConstraint(fields=('portfolio', 'trade_date'), name='unique_trade_proposal'),
283
+ ),
284
+ migrations.AddField(
285
+ model_name='productgroup',
286
+ name='net_asset_value_computation_method_path',
287
+ field=models.CharField(blank=True, default='wbportfolio.models.portfolio.default_estimate_net_value',
288
+ null=True, verbose_name='NAV Computation Method'),
289
+ ),
290
+ migrations.AddField(
291
+ model_name='productgroup',
292
+ name='risk_scale',
293
+ field=models.IntegerField(default=4, validators=[django.core.validators.MinValueValidator(1),
294
+ django.core.validators.MaxValueValidator(7)],
295
+ verbose_name='Risk Scale'),
296
+ ),
297
+ migrations.AlterField(
298
+ model_name='index',
299
+ name='risk_scale',
300
+ field=models.IntegerField(default=4, validators=[django.core.validators.MinValueValidator(1),
301
+ django.core.validators.MaxValueValidator(7)],
302
+ verbose_name='Risk Scale'),
303
+ ),
304
+ migrations.AlterField(
305
+ model_name='index',
306
+ name='net_asset_value_computation_method_path',
307
+ field=models.CharField(blank=True, default='wbportfolio.models.portfolio.default_estimate_net_value',
308
+ null=True, verbose_name='NAV Computation Method'),
309
+ ),
310
+ migrations.AlterField(
311
+ model_name='product',
312
+ name='net_asset_value_computation_method_path',
313
+ field=models.CharField(blank=True, default='wbportfolio.models.portfolio.default_estimate_net_value',
314
+ null=True, verbose_name='NAV Computation Method'),
315
+ ),
316
+ migrations.AlterField(
317
+ model_name='productgroup',
318
+ name='net_asset_value_computation_method_path',
319
+ field=models.CharField(blank=True, default='wbportfolio.models.portfolio.default_estimate_net_value',
320
+ null=True, verbose_name='NAV Computation Method'),
321
+ ),
322
+ migrations.RemoveConstraint(
323
+ model_name='assetposition',
324
+ name='wbportfolio_assetposition_weekday_constraint',
325
+ ),
326
+ migrations.RemoveConstraint(
327
+ model_name='assetposition',
328
+ name='unique_asset_position',
329
+ ),
330
+ migrations.RemoveIndex(
331
+ model_name='assetposition',
332
+ name='wbportfolio_date_0a7c0a_idx',
333
+ ),
334
+ migrations.RemoveIndex(
335
+ model_name='assetposition',
336
+ name='wbportfolio_date_da82d2_idx',
337
+ ),
338
+ migrations.AddField(
339
+ model_name='assetposition',
340
+ name='underlying_quote',
341
+ field=models.ForeignKey(blank=True, help_text='The quote that is this asset.',
342
+ limit_choices_to=models.Q(('children__isnull', True)), null=True,
343
+ on_delete=django.db.models.deletion.PROTECT, related_name='assets',
344
+ to='wbfdm.instrument', verbose_name='Underlying Quote'),
345
+ ),
346
+ migrations.AlterField(
347
+ model_name='assetposition',
348
+ name='underlying_instrument',
349
+ field=models.ForeignKey(help_text='The instrument that is this asset.',
350
+ on_delete=django.db.models.deletion.PROTECT, related_name='instrument_assets',
351
+ to='wbfdm.instrument', verbose_name='Underlying Instrument'),
352
+ ),
353
+ migrations.RunSQL(
354
+ sql="UPDATE wbportfolio_assetposition SET underlying_quote_id = underlying_instrument_id",
355
+ reverse_sql=migrations.RunSQL.noop
356
+ ),
357
+ migrations.AlterField(
358
+ model_name='assetposition',
359
+ name='underlying_quote',
360
+ field=models.ForeignKey(help_text='The quote that is this asset.',
361
+ limit_choices_to=models.Q(('children__isnull', True)),
362
+ on_delete=django.db.models.deletion.PROTECT, related_name='assets',
363
+ to='wbfdm.instrument', verbose_name='Underlying Quote'),
364
+ ),
365
+ migrations.AddIndex(
366
+ model_name='assetposition',
367
+ index=models.Index(fields=['date', 'underlying_instrument', 'portfolio'],
368
+ name='wbportfolio_date_0a7c0a_idx'),
369
+ ),
370
+ migrations.AddIndex(
371
+ model_name='assetposition',
372
+ index=models.Index(fields=['date', 'underlying_instrument'], name='wbportfolio_date_da82d2_idx'),
373
+ ),
374
+ migrations.AddConstraint(
375
+ model_name='assetposition',
376
+ constraint=models.CheckConstraint(check=models.Q(('date__week_day__in', [1, 7]), _negated=True),
377
+ name='wbportfolio_assetposition_weekday_constraint'),
378
+ ),
379
+ migrations.AddConstraint(
380
+ model_name='assetposition',
381
+ constraint=models.UniqueConstraint(fields=('portfolio', 'date', 'underlying_quote', 'portfolio_created'),
382
+ name='unique_asset_position', nulls_distinct=False),
383
+ ),
384
+ migrations.RenameField(
385
+ model_name='assetposition',
386
+ old_name='underlying_instrument_price',
387
+ new_name='underlying_quote_price',
388
+ ),
389
+ migrations.AlterField(
390
+ model_name='portfolioportfoliothroughmodel',
391
+ name='type',
392
+ field=models.CharField(choices=[('PRIMARY', 'Primary'), ('MODEL', 'Model'), ('CUSTODIAN', 'Custodian')],
393
+ default='PRIMARY', verbose_name='Type'),
394
+ ),
395
+ migrations.AlterField(
396
+ model_name='rebalancer',
397
+ name='parameters',
398
+ field=models.JSONField(blank=True, default=dict, verbose_name='Parameters'),
399
+ ),
400
+ migrations.AddField(
401
+ model_name='portfolio',
402
+ name='is_composition',
403
+ field=models.BooleanField(default=False,
404
+ help_text='If true, this portfolio is a composition of other portfolio'),
405
+ ),
406
+ migrations.RunPython(set_composition)
407
+ ]
@@ -17,10 +17,5 @@ from .portfolio_cash_flow import DailyPortfolioCashFlow
17
17
  from .portfolio_swing_pricings import PortfolioSwingPricing
18
18
  from .registers import Register
19
19
  from .roles import PortfolioRole
20
- from .synchronization import (
21
- PortfolioSynchronization,
22
- PriceComputation,
23
- SynchronizationTask,
24
- )
25
20
  from .transactions import *
26
21
  from .reconciliations import AccountReconciliation, AccountReconciliationLine
@@ -20,10 +20,11 @@ from wbcore.enums import RequestType
20
20
  from wbcore.metadata.configs.buttons import ActionButton
21
21
  from wbcore.signals import pre_merge
22
22
  from wbfdm.models.instruments.instruments import Instrument, import_prices_as_task
23
+
23
24
  from wbportfolio.import_export.handlers.adjustment import AdjustmentImportHandler
24
25
  from wbportfolio.models.roles import PortfolioRole
25
26
 
26
- logger = logging.getLogger(__name__)
27
+ logger = logging.getLogger("pms")
27
28
 
28
29
 
29
30
  class Adjustment(ImportMixin, models.Model):
@@ -165,7 +166,12 @@ class Adjustment(ImportMixin, models.Model):
165
166
  class Meta:
166
167
  verbose_name = "Datum Adjustment"
167
168
  verbose_name_plural = "Data Adjustment"
168
- unique_together = ("date", "instrument")
169
+ constraints = [
170
+ models.UniqueConstraint(
171
+ fields=["date", "instrument"],
172
+ name="unique_date_instrument",
173
+ ),
174
+ ]
169
175
  indexes = [
170
176
  models.Index(
171
177
  name="instrument_adjustment_idx",