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,4 +1,5 @@
1
1
  from wbcore import filters as wb_filters
2
+
2
3
  from wbportfolio.models import Custodian
3
4
 
4
5
 
@@ -1,5 +1,6 @@
1
1
  from wbcore import filters as wb_filters
2
2
  from wbfdm.analysis.esg.enums import ESGAggregation
3
+
3
4
  from wbportfolio.models import AssetPosition
4
5
 
5
6
  from .assets import get_latest_asset_position
@@ -5,6 +5,7 @@ from wbcore.pandas.filterset import PandasFilterSetMixin
5
5
  from wbcore.utils.date import current_financial_month
6
6
  from wbfdm.filters.utils import last_period_date_range
7
7
  from wbfdm.models import Instrument
8
+
8
9
  from wbportfolio.models import Product
9
10
 
10
11
  from .products import BaseProductFilterSet
@@ -38,9 +39,9 @@ class PerformancePandasFilter(PandasFilterSetMixin, BaseProductFilterSet):
38
39
  clearable=False,
39
40
  required=True,
40
41
  )
41
- white_label_customers = (
42
- classifications
43
- ) = classifications_neq = unclassified = invested = portfolio = content_type = tags = None
42
+ white_label_customers = classifications = classifications_neq = unclassified = invested = portfolio = (
43
+ content_type
44
+ ) = tags = None
44
45
 
45
46
  class Meta:
46
47
  model = Product
@@ -136,9 +137,9 @@ class ProductPerformanceNetNewMoneyFilter(PandasFilterSetMixin, BaseProductFilte
136
137
 
137
138
  return queryset
138
139
 
139
- white_label_customers = (
140
- classifications
141
- ) = classifications_neq = unclassified = invested = portfolio = content_type = tags = None
140
+ white_label_customers = classifications = classifications_neq = unclassified = invested = portfolio = (
141
+ content_type
142
+ ) = tags = None
142
143
 
143
144
  class Meta:
144
145
  model = Product
@@ -1,9 +1,12 @@
1
1
  from wbcore import filters as wb_filters
2
2
  from wbfdm.models import Instrument
3
+
4
+ from wbportfolio.filters.assets import get_latest_asset_position
3
5
  from wbportfolio.models import Portfolio
4
6
 
5
7
 
6
8
  class PortfolioFilterSet(wb_filters.FilterSet):
9
+ is_tracked = wb_filters.BooleanFilter(default=True, label="Is tracked")
7
10
  instrument = wb_filters.ModelChoiceFilter(
8
11
  label="Instrument",
9
12
  queryset=Instrument.objects.all(),
@@ -21,4 +24,21 @@ class PortfolioFilterSet(wb_filters.FilterSet):
21
24
 
22
25
  class Meta:
23
26
  model = Portfolio
24
- fields = {"currency": ["exact"], "is_manageable": ["exact"]}
27
+ fields = {
28
+ "currency": ["exact"],
29
+ "hedged_currency": ["exact"],
30
+ "is_manageable": ["exact"],
31
+ "only_weighting": ["exact"],
32
+ "is_lookthrough": ["exact"],
33
+ "is_composition": ["exact"],
34
+ "bank_accounts": ["exact"],
35
+ "depends_on": ["exact"],
36
+ }
37
+
38
+
39
+ class PortfolioTreeGraphChartFilterSet(wb_filters.FilterSet):
40
+ date = wb_filters.DateFilter(method="fake_filter", default=get_latest_asset_position, required=True)
41
+
42
+ class Meta:
43
+ model = Portfolio
44
+ fields = {}
@@ -6,6 +6,7 @@ from wbcore import filters as wb_filters
6
6
  from wbcore.contrib.currency.models import CurrencyFXRates
7
7
  from wbcore.pandas.filterset import PandasFilterSetMixin
8
8
  from wbcore.utils.date import current_financial_month
9
+
9
10
  from wbportfolio.filters.assets import (
10
11
  DateFilterMixin,
11
12
  get_latest_end_quarter_date_asset_position,
@@ -4,6 +4,7 @@ from wbcore.contrib.directory.models import Company, Entry
4
4
  from wbfdm.filters.instruments import InstrumentFilterSet
5
5
  from wbfdm.filters.utils import last_period_date_range
6
6
  from wbfdm.models import Classification
7
+
7
8
  from wbportfolio.models import Product, ProductGroup
8
9
 
9
10
 
@@ -1,6 +1,7 @@
1
1
  from django.db.models import Q
2
2
  from django.utils import timezone
3
3
  from wbcore import filters as wb_filters
4
+
4
5
  from wbportfolio.models import PortfolioRole
5
6
 
6
7
 
@@ -6,6 +6,7 @@ from wbcore import filters as wb_filters
6
6
  from wbcore.signals.filters import add_filters
7
7
  from wbfdm.filters import BaseClassifiedInstrumentFilterSet, ClassificationFilter
8
8
  from wbfdm.models import InstrumentClassificationThroughModel
9
+
9
10
  from wbportfolio.models import AssetPosition, Portfolio
10
11
 
11
12
 
@@ -7,6 +7,7 @@ from wbcore.utils.date import current_financial_quarter
7
7
  from wbcrm.models.accounts import Account, AccountRole
8
8
  from wbfdm.models import Classification, ClassificationGroup
9
9
  from wbfdm.preferences import get_default_classification_group
10
+
10
11
  from wbportfolio.filters.transactions.mixins import OppositeSharesFieldMethodMixin
11
12
  from wbportfolio.models import Product, ProductGroup
12
13
  from wbportfolio.models.transactions.claim import Claim, ClaimGroupbyChoice
@@ -1,6 +1,7 @@
1
1
  from wbcore import filters as wb_filters
2
2
  from wbcore.filters.defaults import current_quarter_date_range
3
3
  from wbcore.pandas.filterset import PandasFilterSetMixin
4
+
4
5
  from wbportfolio.models import Fees
5
6
 
6
7
  from .transactions import TransactionFilterSet, get_transaction_default_date_range
@@ -4,10 +4,11 @@ from django.db.models import Count, OuterRef, Subquery
4
4
  from wbcore import filters as wb_filters
5
5
  from wbcrm.models.accounts import Account
6
6
  from wbfdm.models import Instrument
7
+
7
8
  from wbportfolio.models import Product, Trade
8
9
  from wbportfolio.models.transactions.claim import Claim
9
- from .mixins import OppositeSharesFieldMethodMixin
10
10
 
11
+ from .mixins import OppositeSharesFieldMethodMixin
11
12
  from .transactions import TransactionFilterSet
12
13
 
13
14
 
@@ -2,6 +2,7 @@ from datetime import date, timedelta
2
2
 
3
3
  from psycopg.types.range import DateRange
4
4
  from wbcore import filters as wb_filters
5
+
5
6
  from wbportfolio.models import Fees, Portfolio, Trade, Transaction
6
7
 
7
8
 
@@ -1,6 +1,7 @@
1
1
  from datetime import date
2
2
 
3
3
  from django.db import models
4
+
4
5
  from wbportfolio.models.products import Product
5
6
 
6
7
 
@@ -6,6 +6,7 @@ from django.core.serializers.json import DjangoJSONEncoder
6
6
  from pandas.tseries.offsets import BDay
7
7
  from wbcore.contrib.io.backends import AbstractDataBackend, register
8
8
  from wbfdm.models import Instrument
9
+
9
10
  from wbportfolio.import_export.backends.utils import (
10
11
  get_timedelta_import_instrument_price,
11
12
  )
@@ -1,4 +1,5 @@
1
1
  from collections import defaultdict
2
+ from contextlib import suppress
2
3
  from datetime import datetime
3
4
  from decimal import Decimal
4
5
  from itertools import chain
@@ -6,8 +7,6 @@ from typing import Any, Dict, List, Optional
6
7
 
7
8
  from django.core.exceptions import ObjectDoesNotExist
8
9
  from django.db import models
9
- from contextlib import suppress
10
-
11
10
  from wbcore.contrib.authentication.authentication import User
12
11
  from wbcore.contrib.currency.import_export.handlers import CurrencyImportHandler
13
12
  from wbcore.contrib.io.exceptions import DeserializationError
@@ -16,6 +15,7 @@ from wbcore.contrib.notifications.dispatch import send_notification
16
15
  from wbfdm.import_export.handlers.instrument import InstrumentImportHandler
17
16
  from wbfdm.import_export.handlers.instrument_price import InstrumentPriceImportHandler
18
17
  from wbfdm.models.exchanges import Exchange
18
+
19
19
  from wbportfolio.models.roles import PortfolioRole
20
20
 
21
21
 
@@ -34,7 +34,7 @@ class AssetPositionImportHandler(ImportExportHandler):
34
34
  from wbportfolio.models import Portfolio
35
35
 
36
36
  portfolio_data = data.pop("portfolio", None)
37
- underlying_instrument_data = data.pop("underlying_instrument", None)
37
+ underlying_quote_data = data.pop("underlying_quote", data.pop("underlying_instrument", None))
38
38
  if "currency" in data:
39
39
  data["currency"] = self.currency_handler.process_object(data["currency"], read_only=True)[0]
40
40
  data["date"] = datetime.strptime(data["date"], "%Y-%m-%d").date()
@@ -49,8 +49,8 @@ class AssetPositionImportHandler(ImportExportHandler):
49
49
  data["exchange"] = Exchange.dict_to_model(sanitized_dict)
50
50
 
51
51
  data["portfolio"] = Portfolio._get_or_create_portfolio(self.instrument_handler, portfolio_data)
52
- data["underlying_instrument"] = self.instrument_handler.process_object(
53
- underlying_instrument_data, only_security=False, read_only=True
52
+ data["underlying_quote"] = self.instrument_handler.process_object(
53
+ underlying_quote_data, only_security=False, read_only=True
54
54
  )[0]
55
55
 
56
56
  # number type deserialization and sanitization
@@ -69,13 +69,13 @@ class AssetPositionImportHandler(ImportExportHandler):
69
69
  # if the initial price is not provided, we try to get it directly from the dataloader
70
70
  if data.get("initial_price") is None:
71
71
  try:
72
- data["initial_price"] = data["underlying_instrument"].get_price(
72
+ data["initial_price"] = data["underlying_quote"].get_price(
73
73
  data["date"], price_date_timedelta=self.PRICE_DATE_TIMEDELTA
74
74
  )
75
75
  except ValueError:
76
76
  # If we cannot find a price with the default timedelta, we try with a bigger range (in case the instrument stopped trading for some time for instance)
77
77
  try:
78
- data["initial_price"] = data["underlying_instrument"].get_price(
78
+ data["initial_price"] = data["underlying_quote"].get_price(
79
79
  data["date"], price_date_timedelta=self.MAX_PRICE_DATE_TIMEDELTA
80
80
  )
81
81
  except ValueError:
@@ -88,9 +88,7 @@ class AssetPositionImportHandler(ImportExportHandler):
88
88
 
89
89
  def _get_instance(self, data: Dict[str, Any], history: Optional[models.QuerySet] = None, **kwargs) -> models.Model:
90
90
  self.import_source.log += "\nTrying to get asset position instance"
91
- position = data["portfolio"].assets.filter(
92
- date=data["date"], underlying_instrument=data["underlying_instrument"]
93
- )
91
+ position = data["portfolio"].assets.filter(date=data["date"], underlying_quote=data["underlying_quote"])
94
92
  if position.exists():
95
93
  self.import_source.log += "\nAsset Position found."
96
94
  if position.count() > 1:
@@ -104,7 +102,7 @@ class AssetPositionImportHandler(ImportExportHandler):
104
102
  def _create_instance(self, data: Dict[str, Any], **kwargs) -> models.Model:
105
103
  instance = self.model(
106
104
  portfolio=data["portfolio"],
107
- underlying_instrument=data["underlying_instrument"],
105
+ underlying_quote=data["underlying_quote"],
108
106
  date=data["date"],
109
107
  asset_valuation_date=data["asset_valuation_date"],
110
108
  weighting=data.get("weighting", None),
@@ -118,10 +116,10 @@ class AssetPositionImportHandler(ImportExportHandler):
118
116
  return self._save_object(instance, **kwargs)
119
117
 
120
118
  def _save_object(self, _object, **kwargs):
121
- _object.underlying_instrument_price = (
119
+ _object.underlying_quote_price = (
122
120
  None # detech possibly already attached instrument price to retrigger the save mechanism
123
121
  )
124
- _object.save(create_underlying_instrument_price_if_missing=True)
122
+ _object.save(create_underlying_quote_price_if_missing=True)
125
123
  return _object
126
124
 
127
125
  def _post_processing_objects(
@@ -3,6 +3,7 @@ from datetime import datetime
3
3
  from wbcore.contrib.currency.import_export.handlers import CurrencyImportHandler
4
4
  from wbcore.contrib.io.imports import ImportExportHandler
5
5
  from wbfdm.models.instruments import Cash
6
+
6
7
  from wbportfolio.models.products import Product
7
8
 
8
9
 
@@ -7,6 +7,7 @@ from django.contrib.auth import get_user_model
7
7
  from django.db.models import Q
8
8
  from wbcore.contrib.io.imports import ImportExportHandler
9
9
  from wbcore.contrib.notifications.dispatch import send_notification
10
+
10
11
  from wbportfolio.models import Portfolio
11
12
 
12
13
  if TYPE_CHECKING:
@@ -9,6 +9,7 @@ from wbcore.contrib.io.exceptions import DeserializationError
9
9
  from wbcore.contrib.io.imports import ImportExportHandler
10
10
  from wbfdm.import_export.handlers.instrument import InstrumentImportHandler
11
11
  from wbfdm.models import InstrumentType
12
+
12
13
  from wbportfolio.models.portfolio import Portfolio
13
14
  from wbportfolio.models.products import update_outstanding_shares_as_task
14
15
  from wbportfolio.utils import string_matching
@@ -3,6 +3,7 @@ import re
3
3
 
4
4
  import numpy as np
5
5
  import pandas as pd
6
+
6
7
  from wbportfolio.import_export.utils import convert_string_to_number
7
8
  from wbportfolio.models import Product, Trade
8
9
 
@@ -4,6 +4,7 @@ import re
4
4
 
5
5
  import numpy as np
6
6
  import pandas as pd
7
+
7
8
  from wbportfolio.import_export.utils import convert_string_to_number
8
9
  from wbportfolio.models import Fees, Product
9
10
 
@@ -4,6 +4,7 @@ import re
4
4
 
5
5
  import numpy as np
6
6
  import pandas as pd
7
+
7
8
  from wbportfolio.import_export.utils import convert_string_to_number
8
9
 
9
10
  logger = logging.getLogger("importers.parsers.jp_morgan.strategy")
@@ -30,7 +31,7 @@ def manually_create_100_position(parent_strategies, valuation_date):
30
31
  last_price = float(valuations.latest("date").net_value)
31
32
  data.append(
32
33
  {
33
- "underlying_instrument": index.id,
34
+ "underlying_quote": index.id,
34
35
  "portfolio": {"instrument_type": "product", "id": product.id},
35
36
  "currency__key": index.currency.key,
36
37
  "initial_currency_fx_rate": 1.0,
@@ -84,7 +85,7 @@ def parse(import_source):
84
85
  weighting = convert_string_to_number(strategy_data["Weight In Percent"].replace("%", "")) / 100
85
86
  except Exception:
86
87
  weighting = 0.0
87
- underlying_instrument = {
88
+ underlying_quote = {
88
89
  "ticker": ticker,
89
90
  "exchange": exchange,
90
91
  "isin": isin,
@@ -93,10 +94,10 @@ def parse(import_source):
93
94
  "instrument_type": instrument_type.lower(),
94
95
  }
95
96
  if isin:
96
- underlying_instrument["isin"] = isin
97
+ underlying_quote["isin"] = isin
97
98
  data.append(
98
99
  {
99
- "underlying_instrument": underlying_instrument,
100
+ "underlying_quote": underlying_quote,
100
101
  "portfolio": {
101
102
  "instrument_type": "index",
102
103
  "ticker": strategy,
@@ -4,6 +4,7 @@ import re
4
4
 
5
5
  import numpy as np
6
6
  import pandas as pd
7
+
7
8
  from wbportfolio.import_export.utils import convert_string_to_number
8
9
  from wbportfolio.models import Product
9
10
 
@@ -1,6 +1,7 @@
1
1
  from contextlib import suppress
2
2
 
3
3
  import pandas as pd
4
+
4
5
  from wbportfolio.models import Product, Trade
5
6
 
6
7
 
@@ -4,6 +4,7 @@ from io import BytesIO
4
4
 
5
5
  import numpy as np
6
6
  import pandas as pd
7
+
7
8
  from wbportfolio.models import Product
8
9
 
9
10
  FIELD_MAP = {
@@ -11,9 +12,9 @@ FIELD_MAP = {
11
12
  "CURRENT PRICE": "initial_price",
12
13
  "FX": "initial_currency_fx_rate",
13
14
  "TOTAL UNITS": "initial_shares",
14
- "TYPE": "underlying_instrument__instrument_type",
15
- "NAME": "underlying_instrument__name",
16
- "ISIN": "underlying_instrument__isin",
15
+ "TYPE": "underlying_quote__instrument_type",
16
+ "NAME": "underlying_quote__name",
17
+ "ISIN": "underlying_quote__isin",
17
18
  "WEIGHT (%)": "weighting",
18
19
  }
19
20
 
@@ -34,11 +35,11 @@ def parse(import_source):
34
35
  df = df.rename(columns=df.iloc[0]).drop(df.index[0]).dropna(how="all").rename(columns=FIELD_MAP)
35
36
 
36
37
  df = df[
37
- (df["underlying_instrument__instrument_type"].isin(["CASH", "SHARE"]))
38
+ (df["underlying_quote__instrument_type"].isin(["CASH", "SHARE"]))
38
39
  & (df["N"].astype("str").str.isnumeric())
39
40
  ]
40
41
 
41
- equities_index = df["underlying_instrument__instrument_type"] == "SHARE"
42
+ equities_index = df["underlying_quote__instrument_type"] == "SHARE"
42
43
  df.loc[~equities_index, "initial_shares"] = df.loc[~equities_index, "TOTAL VALUE"]
43
44
  df.loc[~equities_index, "initial_price"] = 1.0
44
45
  df.initial_currency_fx_rate = df.initial_currency_fx_rate.fillna(1.0)
@@ -46,25 +47,25 @@ def parse(import_source):
46
47
  # df["weighting"] = df.weighting / df.weighting.sum()
47
48
  product = Product.objects.get(isin=sheet_name)
48
49
  for position in df.to_dict("records"):
49
- if position["underlying_instrument__instrument_type"] == "CASH":
50
+ if position["underlying_quote__instrument_type"] == "CASH":
50
51
  ticker = exchange = "CASH"
51
52
  else:
52
53
  ticker, exchange, _ = str(position["BBG TICKER / IDENTIFIER"]).split(" ")
53
54
 
54
- if position["underlying_instrument__instrument_type"] == "SHARE":
55
- underlying_instrument = {
55
+ if position["underlying_quote__instrument_type"] == "SHARE":
56
+ underlying_quote = {
56
57
  "ticker": ticker,
57
58
  "exchange": {"bbg_exchange_codes": exchange},
58
- "name": position["underlying_instrument__name"],
59
+ "name": position["underlying_quote__name"],
59
60
  "currency__key": position["currency__key"],
60
61
  "instrument_type": "equity",
61
- "isin": position["underlying_instrument__isin"],
62
+ "isin": position["underlying_quote__isin"],
62
63
  }
63
64
  else:
64
- underlying_instrument = {"currency__key": position["currency__key"], "instrument_type": "cash"}
65
+ underlying_quote = {"currency__key": position["currency__key"], "instrument_type": "cash"}
65
66
  data.append(
66
67
  {
67
- "underlying_instrument": underlying_instrument,
68
+ "underlying_quote": underlying_quote,
68
69
  "currency__key": position["currency__key"],
69
70
  "is_estimated": False,
70
71
  "date": valuation_date.strftime("%Y-%m-%d"),
@@ -1,4 +1,5 @@
1
1
  import pandas as pd
2
+
2
3
  from wbportfolio.models import Fees, Product
3
4
 
4
5
 
@@ -3,6 +3,7 @@ from io import BytesIO
3
3
 
4
4
  import numpy as np
5
5
  import pandas as pd
6
+
6
7
  from wbportfolio.models import Product
7
8
 
8
9
 
@@ -2,6 +2,7 @@ from io import BytesIO
2
2
 
3
3
  import numpy as np
4
4
  import pandas as pd
5
+
5
6
  from wbportfolio.models import Product
6
7
 
7
8
 
@@ -1,5 +1,6 @@
1
1
  import numpy as np
2
2
  import pandas as pd
3
+
3
4
  from wbportfolio.models import Trade
4
5
 
5
6
  from .utils import file_name_parse
@@ -1,6 +1,7 @@
1
1
  import datetime
2
2
 
3
3
  import xlrd
4
+
4
5
  from wbportfolio.models import Product, Trade
5
6
 
6
7
 
@@ -1,4 +1,5 @@
1
1
  import xlrd
2
+
2
3
  from wbportfolio.models import Product
3
4
 
4
5
 
@@ -45,7 +46,7 @@ def parse(import_source):
45
46
 
46
47
  data.append(
47
48
  {
48
- "underlying_instrument": {"instrument_type": "product", "ticker": ticker},
49
+ "underlying_quote": {"instrument_type": "product", "ticker": ticker},
49
50
  "currency__key": currency_key,
50
51
  "date": valuation_date.strftime("%Y-%m-%d"),
51
52
  "asset_valuation_date": valuation_date.strftime("%Y-%m-%d"),
@@ -58,7 +59,7 @@ def parse(import_source):
58
59
 
59
60
  data.append(
60
61
  {
61
- "underlying_instrument": {
62
+ "underlying_quote": {
62
63
  "instrument_type": "cash",
63
64
  "ticker": "CASH",
64
65
  "name": f"1 {product.currency.key} AMC",
@@ -1,4 +1,5 @@
1
1
  import xlrd
2
+
2
3
  from wbportfolio.models import Fees, Product
3
4
 
4
5
 
@@ -1,4 +1,5 @@
1
1
  import xlrd
2
+
2
3
  from wbportfolio.models import Product, Trade
3
4
 
4
5
 
@@ -1,4 +1,5 @@
1
1
  import xlrd
2
+
2
3
  from wbportfolio.models import Product
3
4
 
4
5
 
@@ -10,7 +10,7 @@ FIELD_MAP = {
10
10
  "Valuation Date": "asset_valuation_date",
11
11
  "Quoted Crncy": "currency__key",
12
12
  "exchange": "exchange",
13
- "underlying_instrument": "underlying_instrument",
13
+ "underlying_quote": "underlying_quote",
14
14
  }
15
15
 
16
16
 
@@ -20,7 +20,7 @@ def _apply_adjusting_factor(row):
20
20
 
21
21
  No idea why though
22
22
  """
23
- if row["underlying_instrument"]["instrument_type"] == "product":
23
+ if row["underlying_quote"]["instrument_type"] == "product":
24
24
  return pd.Series([row["initial_price"], row["initial_shares"] * row["Quotity/Adj. factor"]])
25
25
  else:
26
26
  return pd.Series([row["initial_price"] * row["Quotity/Adj. factor"], row["initial_shares"]])
@@ -39,14 +39,14 @@ def parse(import_source):
39
39
  df = df.rename(columns=FIELD_MAP)
40
40
  df = df.dropna(subset=["initial_price"])
41
41
  df["initial_price"] = df["initial_price"].astype("str").str.replace(" ", "").astype("float")
42
- df["underlying_instrument"] = df[["Ticker", "Name", "currency__key"]].apply(
42
+ df["underlying_quote"] = df[["Ticker", "Name", "currency__key"]].apply(
43
43
  lambda x: _get_underlying_instrument(*x), axis=1
44
44
  )
45
45
  df["initial_price"] = df["initial_price"].replace(0, np.nan).fillna(1.0)
46
46
  df[["initial_price", "initial_shares"]] = df[
47
- ["initial_price", "initial_shares", "Quotity/Adj. factor", "underlying_instrument"]
47
+ ["initial_price", "initial_shares", "Quotity/Adj. factor", "underlying_quote"]
48
48
  ].apply(lambda x: _apply_adjusting_factor(x), axis=1)
49
- df["exchange"] = df.underlying_instrument.apply(lambda x: x.get("exchange", None))
49
+ df["exchange"] = df.underlying_quote.apply(lambda x: x.get("exchange", None))
50
50
  df = df.drop(columns=df.columns.difference(FIELD_MAP.values()))
51
51
 
52
52
  df["portfolio__instrument_type"] = "product"
@@ -1,4 +1,5 @@
1
1
  import pandas as pd
2
+
2
3
  from wbportfolio.models import Trade
3
4
 
4
5
  from .utils import _get_underlying_instrument, file_name_parse
@@ -2,6 +2,7 @@ import datetime
2
2
  import re
3
3
 
4
4
  from django.db.models import Q
5
+
5
6
  from wbportfolio.models import Product
6
7
 
7
8
  INSTRUMENT_MAP_NAME = {"EDA23_AtonRa Z class": Product.objects.get(isin="LU2170995018")}
@@ -28,9 +29,9 @@ def _get_underlying_instrument(bbg_code, name, currency, instrument_type="equity
28
29
 
29
30
  cash_position = cash_position or "CASH" == bbg_code or len(re.findall("(CASH [A-Z]{3})", bbg_code)) > 0
30
31
  if cash_position:
31
- underlying_instrument = {"instrument_type": "cash", "currency__key": currency}
32
+ underlying_quote = {"instrument_type": "cash", "currency__key": currency}
32
33
  else:
33
- underlying_instrument = {
34
+ underlying_quote = {
34
35
  "exchange": {"bbg_exchange_codes": exchange},
35
36
  "currency__key": currency,
36
37
  "name": name.split(" @")[0].split("/")[
@@ -44,13 +45,13 @@ def _get_underlying_instrument(bbg_code, name, currency, instrument_type="equity
44
45
  if len(isin_re) > 0:
45
46
  isin = isin_re[0]
46
47
  # Natixis gives us ISIN as ticker for product. in that case, we registered the isin but we remove the ticker
47
- underlying_instrument["instrument_type"] = "product"
48
- del underlying_instrument["ticker"]
48
+ underlying_quote["instrument_type"] = "product"
49
+ del underlying_quote["ticker"]
49
50
  elif Product.objects.filter(ticker=ticker).exists():
50
- underlying_instrument["instrument_type"] = "product"
51
+ underlying_quote["instrument_type"] = "product"
51
52
  if isin:
52
- underlying_instrument["isin"] = isin
53
- return underlying_instrument
53
+ underlying_quote["isin"] = isin
54
+ return underlying_quote
54
55
 
55
56
 
56
57
  def file_name_parse(file_name):
@@ -3,6 +3,7 @@ from typing import TYPE_CHECKING
3
3
  import pandas as pd
4
4
  from pandas.tseries.offsets import BDay
5
5
  from schwifty import IBAN
6
+
6
7
  from wbportfolio.models.portfolio import Portfolio
7
8
 
8
9
  if TYPE_CHECKING:
@@ -4,6 +4,7 @@ from io import BytesIO
4
4
  import msoffcrypto
5
5
  import numpy as np
6
6
  import pandas as pd
7
+
7
8
  from wbportfolio.models import Product, Trade
8
9
 
9
10
 
@@ -5,9 +5,10 @@ from io import StringIO
5
5
  import numpy as np
6
6
  import pandas as pd
7
7
  from wbfdm.models import InstrumentPrice
8
- from wbportfolio.models import Product, Register, Trade
9
8
  from xlrd import xldate_as_datetime
10
9
 
10
+ from wbportfolio.models import Product, Register, Trade
11
+
11
12
  from .sylk import SYLK
12
13
  from .utils import assemble_transaction_reference, get_portfolio_id
13
14