wbportfolio 1.44.4__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 +30 -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.4.dist-info → wbportfolio-1.45.0.dist-info}/METADATA +4 -1
  298. {wbportfolio-1.44.4.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.4.dist-info → wbportfolio-1.45.0.dist-info}/WHEEL +0 -0
  315. {wbportfolio-1.44.4.dist-info → wbportfolio-1.45.0.dist-info}/licenses/LICENSE +0 -0
@@ -3,9 +3,10 @@ from io import StringIO
3
3
 
4
4
  import numpy as np
5
5
  import pandas as pd
6
- from wbportfolio.models import Product, Trade
7
6
  from xlrd import xldate_as_datetime
8
7
 
8
+ from wbportfolio.models import Product, Trade
9
+
9
10
  from .sylk import SYLK
10
11
  from .utils import get_portfolio_id
11
12
 
@@ -1,5 +1,6 @@
1
1
  import numpy as np
2
2
  import pandas as pd
3
+
3
4
  from wbportfolio.models import Product, Trade
4
5
 
5
6
 
@@ -4,6 +4,7 @@ from contextlib import suppress
4
4
 
5
5
  import numpy as np
6
6
  import pandas as pd
7
+
7
8
  from wbportfolio.models import ProductGroup
8
9
 
9
10
 
@@ -29,7 +30,7 @@ def get_exchange(row):
29
30
  return None
30
31
 
31
32
 
32
- def get_underlying_instrument(row):
33
+ def get_underlying_quote(row):
33
34
  if str(row["Asset type code"]) == "VMOB":
34
35
  data = {
35
36
  "instrument_type": "equity",
@@ -58,7 +59,7 @@ def parse(import_source):
58
59
  df = df.replace([np.inf, -np.inf, np.nan], None)
59
60
  columns_map = {
60
61
  "Code": "portfolio",
61
- "underlying_instrument": "underlying_instrument",
62
+ "underlying_quote": "underlying_quote",
62
63
  "exchange__bbg_exchange_codes": "exchange__bbg_exchange_codes",
63
64
  "NAV Date": "date",
64
65
  "Quantity / Amount": "initial_shares",
@@ -99,9 +100,7 @@ def parse(import_source):
99
100
  )
100
101
  .reset_index()
101
102
  ).copy()
102
- cash["underlying_instrument"] = cash["currency__key"].apply(
103
- lambda x: {"currency__key": x, "instrument_type": "cash"}
104
- )
103
+ cash["underlying_quote"] = cash["currency__key"].apply(lambda x: {"currency__key": x, "instrument_type": "cash"})
105
104
 
106
105
  # cash_equivalents_mask, all asset type code that match TRES and which don't have accounting category T111
107
106
  cash_equivalents_mask = df["Asset type code"].str.match("TRES") & ~df["Accounting category"].str.match("T111")
@@ -127,14 +126,14 @@ def parse(import_source):
127
126
  )
128
127
  .reset_index()
129
128
  ).copy()
130
- cash_equivalents["underlying_instrument"] = cash_equivalents["currency__key"].apply(
129
+ cash_equivalents["underlying_quote"] = cash_equivalents["currency__key"].apply(
131
130
  lambda x: {"currency__key": x, "instrument_type": "cash_equivalent"}
132
131
  )
133
132
 
134
133
  # equities = df.loc[df["Accounting category"].str.match("010"), :].copy() # Historically, we filter out equity base on the "accounting category" that matches "010", we had issue with equity having the code "020". We decided to use the column "Asset type code" and filter out with the code "VCOM"
135
134
  equities = df.loc[df["Asset type code"].str.match("VMOB"), :].copy()
136
135
  if not equities.empty:
137
- equities["underlying_instrument"] = equities.apply(lambda x: get_underlying_instrument(x), axis=1)
136
+ equities["underlying_quote"] = equities.apply(lambda x: get_underlying_quote(x), axis=1)
138
137
  equities["exchange"] = equities.apply(lambda x: get_exchange(x), axis=1)
139
138
  del equities["Accounting category"]
140
139
  del equities["Asset type code"]
@@ -149,7 +148,7 @@ def parse(import_source):
149
148
 
150
149
  df["is_estimated"] = False
151
150
  df = df.replace([np.inf, -np.inf, np.nan], None)
152
- df = df[df["underlying_instrument"].notnull()]
151
+ df = df[df["underlying_quote"].notnull()]
153
152
 
154
153
  df["weighting"] = df.initial_currency_fx_rate * df.initial_price * df.initial_shares
155
154
  portfolio_weights = df.groupby("portfolio")["weighting"].sum()
@@ -1,6 +1,7 @@
1
1
  from datetime import datetime
2
2
 
3
3
  import pandas as pd
4
+
4
5
  from wbportfolio.models import ProductGroup
5
6
 
6
7
 
@@ -2,6 +2,7 @@ from contextlib import suppress
2
2
  from datetime import datetime
3
3
 
4
4
  import pandas as pd
5
+
5
6
  from wbportfolio.models import Portfolio
6
7
 
7
8
 
@@ -4,9 +4,10 @@ from io import StringIO
4
4
  import numpy as np
5
5
  import pandas as pd
6
6
  from wbcore.contrib.geography.models import Geography
7
- from wbportfolio.models import Register
8
7
  from xlrd import xldate_as_datetime
9
8
 
9
+ from wbportfolio.models import Register
10
+
10
11
  from .sylk import SYLK
11
12
 
12
13
 
@@ -3,6 +3,7 @@ import re
3
3
  from io import BytesIO
4
4
 
5
5
  import pandas as pd
6
+
6
7
  from wbportfolio.models import Product, Trade
7
8
 
8
9
 
@@ -5,6 +5,7 @@ from io import BytesIO
5
5
 
6
6
  import numpy as np
7
7
  import pandas as pd
8
+
8
9
  from wbportfolio.import_export.utils import extract_exchange_ticker
9
10
 
10
11
  logger = logging.getLogger("importers.parsers.jp_morgan.strategy")
@@ -44,24 +45,22 @@ def parse(import_source):
44
45
  df_positions.columns[df_positions.columns.str.contains("Currency")][0]: "currency__key",
45
46
  df_positions.columns[df_positions.columns.str.contains("Weight")][0]: "weighting",
46
47
  df_positions.columns[df_positions.columns.str.contains("Level")][0]: "initial_price",
47
- df_positions.columns[df_positions.columns.str.contains("Ticker")][
48
- 0
49
- ]: "underlying_instrument__ticker",
50
- df_positions.columns[df_positions.columns.str.contains("ISIN")][0]: "underlying_instrument__isin",
51
- df_positions.columns[df_positions.columns.str.contains("Name")][0]: "underlying_instrument__name",
48
+ df_positions.columns[df_positions.columns.str.contains("Ticker")][0]: "underlying_quote__ticker",
49
+ df_positions.columns[df_positions.columns.str.contains("ISIN")][0]: "underlying_quote__isin",
50
+ df_positions.columns[df_positions.columns.str.contains("Name")][0]: "underlying_quote__name",
52
51
  }
53
52
  )
54
53
  for position in df_positions.to_dict("records"):
55
- ticker, exchange = extract_exchange_ticker(position["underlying_instrument__ticker"])
54
+ ticker, exchange = extract_exchange_ticker(position["underlying_quote__ticker"])
56
55
  if exchange:
57
56
  exchange = {"bbg_exchange_codes": exchange}
58
57
  data.append(
59
58
  {
60
- "underlying_instrument": {
59
+ "underlying_quote": {
61
60
  "instrument_type": "equity",
62
61
  "ticker": ticker,
63
- "isin": position["underlying_instrument__isin"],
64
- "name": position["underlying_instrument__name"],
62
+ "isin": position["underlying_quote__isin"],
63
+ "name": position["underlying_quote__name"],
65
64
  "currency__key": position["currency__key"],
66
65
  "exchange": exchange,
67
66
  },
@@ -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.import_export.utils import get_file_extension
6
7
  from wbportfolio.models import Product
7
8
 
@@ -4,6 +4,7 @@ import datetime
4
4
 
5
5
  import pandas as pd
6
6
  from wbcore.contrib.currency.models import Currency
7
+
7
8
  from wbportfolio.import_export.utils import convert_string_to_number
8
9
  from wbportfolio.models import ProductGroup
9
10
 
@@ -36,7 +37,7 @@ def parse(import_source):
36
37
  ticker = "CASH"
37
38
  title = currency.title
38
39
  initial_price = 1
39
- underlying_instrument = {
40
+ underlying_quote = {
40
41
  "instrument_type": "cash",
41
42
  "ticker": ticker,
42
43
  "name": title,
@@ -50,7 +51,7 @@ def parse(import_source):
50
51
  initial_price = basket["Wertpapierkurs"]
51
52
 
52
53
  exchange = f'X{basket["Bloomberg Code"]}' if basket["Bloomberg Code"] else None
53
- underlying_instrument = {
54
+ underlying_quote = {
54
55
  "instrument_type": instrument_type,
55
56
  "isin": basket["ISIN"],
56
57
  "exchange": {"mic_code": exchange},
@@ -62,8 +63,8 @@ def parse(import_source):
62
63
 
63
64
  data.append(
64
65
  {
65
- "underlying_instrument": underlying_instrument,
66
- "exchange": underlying_instrument.get("exchange", None),
66
+ "underlying_quote": underlying_quote,
67
+ "exchange": underlying_quote.get("exchange", None),
67
68
  "portfolio": {
68
69
  "instrument_type": "product_group",
69
70
  "id": product_group.id,
@@ -3,16 +3,17 @@ import json
3
3
  import numpy as np
4
4
  import pandas as pd
5
5
  from wbcore.contrib.currency.models import CurrencyFXRates
6
+
6
7
  from wbportfolio.import_export.utils import extract_exchange_ticker
7
8
 
8
9
  BASE_MAPPING = {
9
- "instrument": "underlying_instrument__name",
10
- "ric": "underlying_instrument__refinitiv_identifier_code",
11
- "bbTicker": "underlying_instrument__ticker",
12
- "isin": "underlying_instrument__isin",
13
- "sedol": "underlying_instrument__sedol",
14
- "valoren": "underlying_instrument__valoren",
15
- "assetClass": "underlying_instrument__instrument_type",
10
+ "instrument": "underlying_quote__name",
11
+ "ric": "underlying_quote__refinitiv_identifier_code",
12
+ "bbTicker": "underlying_quote__ticker",
13
+ "isin": "underlying_quote__isin",
14
+ "sedol": "underlying_quote__sedol",
15
+ "valoren": "underlying_quote__valoren",
16
+ "assetClass": "underlying_quote__instrument_type",
16
17
  "percentageWeight": "weighting",
17
18
  "shares": "initial_shares",
18
19
  "localClose": "initial_price",
@@ -77,8 +78,8 @@ def parse(import_source):
77
78
  df["date"] = val_date
78
79
  df["portfolio__instrument_type"] = "product"
79
80
  df["portfolio__isin"] = amc["isin"]
80
- df["underlying_instrument__currency__key"] = df["currency__key"]
81
- df["underlying_instrument__instrument_type"] = df.underlying_instrument__instrument_type.apply(
81
+ df["underlying_quote__currency__key"] = df["currency__key"]
82
+ df["underlying_quote__instrument_type"] = df.underlying_quote__instrument_type.apply(
82
83
  lambda x: INSTRUMENT_TYPE_MAP[x]
83
84
  )
84
85
  if asset_class == "CASH":
@@ -93,14 +94,14 @@ def parse(import_source):
93
94
  .astype(float)
94
95
  )
95
96
  df["is_estimated"] = False
96
- if "underlying_instrument__ticker" in df.columns:
97
- df["underlying_instrument__exchange"] = df["underlying_instrument__ticker"].apply(
97
+ if "underlying_quote__ticker" in df.columns:
98
+ df["underlying_quote__exchange"] = df["underlying_quote__ticker"].apply(
98
99
  lambda x: {"bbg_exchange_codes": extract_exchange_ticker(x)[1]}
99
100
  )
100
- df["underlying_instrument__ticker"] = df["underlying_instrument__ticker"].apply(
101
+ df["underlying_quote__ticker"] = df["underlying_quote__ticker"].apply(
101
102
  lambda x: extract_exchange_ticker(x)[0]
102
103
  )
103
- if "underlying_instrument__exchange" in df.columns:
104
- df["exchange"] = df["underlying_instrument__exchange"]
104
+ if "underlying_quote__exchange" in df.columns:
105
+ df["exchange"] = df["underlying_quote__exchange"]
105
106
  data.extend(df.to_dict("records"))
106
107
  return {"data": data}
@@ -1,6 +1,7 @@
1
1
  import json
2
2
 
3
3
  import pandas as pd
4
+
4
5
  from wbportfolio.models import Fees, Product
5
6
 
6
7
  BASE_MAPPING = {"managementFee": "total_value", "performanceFee": "total_value", "date": "transaction_date"}
@@ -4,6 +4,7 @@ from typing import Dict
4
4
  import numpy as np
5
5
  import pandas as pd
6
6
  from wbcore.contrib.io.models import ImportSource
7
+
7
8
  from wbportfolio.models import Product, Trade
8
9
 
9
10
 
@@ -2,6 +2,7 @@ import datetime
2
2
  import re
3
3
 
4
4
  import xlrd
5
+
5
6
  from wbportfolio.models import Product
6
7
 
7
8
 
@@ -53,7 +54,7 @@ def parse(import_source):
53
54
  exchange_data = {"bbg_exchange_codes": exchange}
54
55
  data.append(
55
56
  {
56
- "underlying_instrument": {
57
+ "underlying_quote": {
57
58
  "instrument_type": "equity",
58
59
  "ticker": ticker,
59
60
  "exchange": exchange_data,
@@ -77,7 +78,7 @@ def parse(import_source):
77
78
  if "Currency" == row[1].value:
78
79
  data.append(
79
80
  {
80
- "underlying_instrument": {
81
+ "underlying_quote": {
81
82
  "instrument_type": "cash",
82
83
  "currency__key": cash_sheet.cell_value(row_index + 1, 1),
83
84
  },
@@ -3,6 +3,7 @@ from typing import Dict
3
3
 
4
4
  import pandas as pd
5
5
  from wbcore.contrib.io.models import ImportSource
6
+
6
7
  from wbportfolio.models import Product, Trade
7
8
 
8
9
 
@@ -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.import_export.utils import get_file_extension
8
9
  from wbportfolio.models import Product
9
10
 
@@ -10,14 +10,14 @@ FIELD_MAP = {
10
10
  "Quantity": "initial_shares",
11
11
  "TradingCurrency": "currency__key",
12
12
  "FxRate": "initial_currency_fx_rate",
13
- "ISIN": "underlying_instrument__isin",
14
- "InstrumentName": "underlying_instrument__name",
13
+ "ISIN": "underlying_quote__isin",
14
+ "InstrumentName": "underlying_quote__name",
15
15
  "BuCurrency": "portfolio__currency__key",
16
- "Ticker": "underlying_instrument__ticker",
16
+ "Ticker": "underlying_quote__ticker",
17
17
  # "TradingPlace": "exchange",
18
18
  "Booking_comment": "comment",
19
- "AssetGroup": "underlying_instrument__instrument_type",
20
- "InstrumentIdentifier": "underlying_instrument__identifier",
19
+ "AssetGroup": "underlying_quote__instrument_type",
20
+ "InstrumentIdentifier": "underlying_quote__identifier",
21
21
  "#ClientName": "portfolio__identifier",
22
22
  }
23
23
 
@@ -46,25 +46,25 @@ def parse(import_source):
46
46
  df = df.rename(columns=FIELD_MAP).replace([np.inf, -np.inf, np.nan], None)
47
47
  df = df.drop(columns=df.columns.difference(FIELD_MAP.values()))
48
48
  if import_source.source.import_parameters.get("import_perf_fees_as_cash", False):
49
- fees_idx = df["underlying_instrument__isin"] == perf_fee_isin
50
- df.loc[fees_idx, "underlying_instrument__isin"] = None
51
- df.loc[fees_idx, "underlying_instrument__instrument_type"] = "cash_equivalent"
49
+ fees_idx = df["underlying_quote__isin"] == perf_fee_isin
50
+ df.loc[fees_idx, "underlying_quote__isin"] = None
51
+ df.loc[fees_idx, "underlying_quote__instrument_type"] = "cash_equivalent"
52
52
  df.loc[fees_idx, "initial_shares"] = df.loc[fees_idx, "initial_price"] # inverse price and share
53
53
  else:
54
- df = df.loc[df["underlying_instrument__isin"] != perf_fee_isin, :]
54
+ df = df.loc[df["underlying_quote__isin"] != perf_fee_isin, :]
55
55
 
56
- df["underlying_instrument__instrument_type"] = df["underlying_instrument__instrument_type"].apply(
56
+ df["underlying_quote__instrument_type"] = df["underlying_quote__instrument_type"].apply(
57
57
  lambda x: ASSET_GROUP_MAP[x] if x else None
58
58
  )
59
59
  # we remove instrument without isin or not of type cash because we don't support these (e.g, Dividend)
60
60
  df = df[
61
- ~df["underlying_instrument__isin"].isnull()
62
- | df["underlying_instrument__instrument_type"].isin(["cash", "cash_equivalent"])
61
+ ~df["underlying_quote__isin"].isnull()
62
+ | df["underlying_quote__instrument_type"].isin(["cash", "cash_equivalent"])
63
63
  ]
64
64
 
65
65
  # we group by instrument identifier to be sure we don't introduce duplicated position
66
66
  df = (
67
- df.groupby("underlying_instrument__identifier", dropna=False)
67
+ df.groupby("underlying_quote__identifier", dropna=False)
68
68
  .agg(
69
69
  {
70
70
  "initial_currency_fx_rate": "first",
@@ -73,21 +73,21 @@ def parse(import_source):
73
73
  "date": "first",
74
74
  "asset_valuation_date": "first",
75
75
  "currency__key": "first",
76
- "underlying_instrument__isin": "first",
77
- "underlying_instrument__name": "first",
76
+ "underlying_quote__isin": "first",
77
+ "underlying_quote__name": "first",
78
78
  "portfolio__currency__key": "first",
79
- "underlying_instrument__ticker": "first",
80
- "underlying_instrument__instrument_type": "first",
79
+ "underlying_quote__ticker": "first",
80
+ "underlying_quote__instrument_type": "first",
81
81
  "portfolio__identifier": "first",
82
82
  }
83
83
  )
84
84
  .reset_index(drop=True)
85
85
  )
86
- df.loc[df["underlying_instrument__instrument_type"].isin(["cash", "cash_equivalent"]), "initial_price"] = 1.0
86
+ df.loc[df["underlying_quote__instrument_type"].isin(["cash", "cash_equivalent"]), "initial_price"] = 1.0
87
87
  df["date"] = pd.to_datetime(df["date"], dayfirst=True).dt.strftime("%Y-%m-%d")
88
88
  df["asset_valuation_date"] = pd.to_datetime(df["asset_valuation_date"], dayfirst=True).dt.strftime("%Y-%m-%d")
89
89
  df["is_estimated"] = False
90
- df["underlying_instrument__currency__key"] = df["currency__key"]
90
+ df["underlying_quote__currency__key"] = df["currency__key"]
91
91
  df["weighting"] = df.initial_currency_fx_rate * df.initial_price * df.initial_shares
92
92
  df["weighting"] = df.weighting / df.weighting.sum()
93
93
  df["portfolio__currency__key"] = (
@@ -3,6 +3,7 @@ from functools import reduce
3
3
 
4
4
  import numpy as np
5
5
  import pandas as pd
6
+
6
7
  from wbportfolio.models import Trade
7
8
 
8
9
  FIELD_MAP = {
@@ -3,6 +3,7 @@ from io import BytesIO
3
3
 
4
4
  import pandas as pd
5
5
  from wbfdm.models import Instrument
6
+
6
7
  from wbportfolio.models import Trade
7
8
 
8
9
  FIELD_MAP = {
@@ -2,6 +2,7 @@ import re
2
2
  from datetime import datetime
3
3
 
4
4
  import pandas as pd
5
+
5
6
  from wbportfolio.models import FeeProductPercentage, Fees
6
7
 
7
8
  from .utils import get_portfolio_id, get_product
@@ -1,4 +1,5 @@
1
1
  import pandas as pd
2
+
2
3
  from wbportfolio.models import Fees
3
4
 
4
5
  from .utils import get_perf_fee_isin, get_portfolio_id, get_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_portfolio_id
@@ -0,0 +1,20 @@
1
+ import json
2
+ from contextlib import suppress
3
+ from datetime import datetime
4
+
5
+
6
+ def parse(import_source):
7
+ data = []
8
+ with suppress(KeyError):
9
+ series_data = json.loads(import_source.file.read())["payload"]["series"]
10
+ for series in series_data:
11
+ isin = series["item"]["priceIdentifier"]
12
+ for point in series["points"]:
13
+ data.append(
14
+ {
15
+ "instrument": {"isin": isin},
16
+ "date": datetime.fromtimestamp(int(point["timestamp"]) / 1000).strftime("%Y-%m-%d"),
17
+ "net_value": point["close"],
18
+ }
19
+ )
20
+ return {"data": data}
@@ -3,6 +3,7 @@ from import_export.widgets import DecimalWidget, ForeignKeyWidget
3
3
  from wbcore.contrib.currency.models import Currency
4
4
  from wbcore.contrib.io.resources import ViewResource
5
5
  from wbfdm.models import Exchange
6
+
6
7
  from wbportfolio.models import AssetPosition
7
8
 
8
9
 
@@ -52,9 +53,9 @@ class AssetPositionResource(ViewResource):
52
53
  )
53
54
  export_order = (
54
55
  "date",
55
- "underlying_instrument_name",
56
- "underlying_instrument_ticker",
57
- "underlying_instrument_isin",
56
+ "underlying_quote_name",
57
+ "underlying_quote_ticker",
58
+ "underlying_quote_isin",
58
59
  "exchange",
59
60
  "price",
60
61
  "shares",
@@ -4,6 +4,7 @@ from import_export import fields
4
4
  from import_export.widgets import ForeignKeyWidget
5
5
  from wbcore.contrib.io.resources import FilterModelResource
6
6
  from wbfdm.models import Instrument
7
+
7
8
  from wbportfolio.models import Trade
8
9
 
9
10
  fake = Faker()
@@ -6,6 +6,7 @@ from django.db.models import Exists, OuterRef, QuerySet
6
6
  from wbfdm.contrib.metric.backends.base import AbstractBackend, Metric
7
7
  from wbfdm.contrib.metric.exceptions import MetricInvalidParameterException
8
8
  from wbfdm.models import InstrumentType
9
+
9
10
  from wbportfolio.models import AssetPosition, InstrumentPortfolioThroughModel, Portfolio
10
11
 
11
12
 
@@ -9,6 +9,7 @@ from wbfdm.contrib.metric.backends.base import Metric
9
9
  from wbfdm.contrib.metric.decorators import register
10
10
  from wbfdm.enums import Financial, MarketData
11
11
  from wbfdm.models import Instrument
12
+
12
13
  from wbportfolio.models import Portfolio
13
14
 
14
15
  from .base import PortfolioMetricBaseBackend
@@ -5,6 +5,7 @@ from wbfdm.analysis.esg.enums import ESGAggregation
5
5
  from wbfdm.analysis.esg.esg_analysis import DataLoader, get_esg_df
6
6
  from wbfdm.contrib.metric.decorators import register
7
7
  from wbfdm.contrib.metric.dto import Metric, MetricField, MetricKey
8
+
8
9
  from wbportfolio.models import Portfolio
9
10
 
10
11
  from .base import PortfolioMetricBaseBackend
@@ -7,6 +7,7 @@ from django.db.models import Sum
7
7
  from faker import Faker
8
8
  from wbfdm.dataloaders.proxies import InstrumentDataloaderProxy
9
9
  from wbfdm.enums import Financial
10
+
10
11
  from wbportfolio.factories import AssetPositionFactory, PortfolioFactory
11
12
  from wbportfolio.models import AssetPosition
12
13