wbportfolio 1.48.0__py2.py3-none-any.whl → 1.49.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 (33) hide show
  1. wbportfolio/factories/__init__.py +1 -3
  2. wbportfolio/factories/portfolios.py +0 -12
  3. wbportfolio/factories/product_groups.py +8 -1
  4. wbportfolio/factories/products.py +18 -0
  5. wbportfolio/factories/trades.py +5 -1
  6. wbportfolio/import_export/handlers/trade.py +8 -0
  7. wbportfolio/migrations/0075_portfolio_initial_position_date_and_more.py +28 -0
  8. wbportfolio/models/portfolio.py +8 -13
  9. wbportfolio/models/transactions/rebalancing.py +7 -1
  10. wbportfolio/models/transactions/trade_proposals.py +146 -49
  11. wbportfolio/models/transactions/trades.py +16 -11
  12. wbportfolio/pms/trading/handler.py +1 -1
  13. wbportfolio/pms/typing.py +3 -0
  14. wbportfolio/rebalancing/models/composite.py +14 -1
  15. wbportfolio/risk_management/backends/exposure_portfolio.py +30 -1
  16. wbportfolio/risk_management/tests/test_exposure_portfolio.py +47 -0
  17. wbportfolio/serializers/portfolios.py +26 -0
  18. wbportfolio/serializers/transactions/trades.py +13 -0
  19. wbportfolio/tests/models/test_portfolios.py +1 -1
  20. wbportfolio/tests/models/transactions/test_trade_proposals.py +381 -0
  21. wbportfolio/tests/models/transactions/test_trades.py +14 -0
  22. wbportfolio/tests/signals.py +1 -1
  23. wbportfolio/tests/viewsets/test_performances.py +2 -1
  24. wbportfolio/viewsets/configs/display/portfolios.py +58 -14
  25. wbportfolio/viewsets/configs/display/trades.py +23 -8
  26. wbportfolio/viewsets/configs/endpoints/trades.py +9 -0
  27. wbportfolio/viewsets/portfolios.py +22 -7
  28. wbportfolio/viewsets/transactions/trade_proposals.py +1 -1
  29. wbportfolio/viewsets/transactions/trades.py +86 -12
  30. {wbportfolio-1.48.0.dist-info → wbportfolio-1.49.0.dist-info}/METADATA +1 -1
  31. {wbportfolio-1.48.0.dist-info → wbportfolio-1.49.0.dist-info}/RECORD +33 -31
  32. {wbportfolio-1.48.0.dist-info → wbportfolio-1.49.0.dist-info}/WHEEL +0 -0
  33. {wbportfolio-1.48.0.dist-info → wbportfolio-1.49.0.dist-info}/licenses/LICENSE +0 -0
@@ -2,7 +2,7 @@ from contextlib import suppress
2
2
  from datetime import date, datetime
3
3
 
4
4
  import pandas as pd
5
- from django.db.models import Q
5
+ from django.db.models import OuterRef, Q, Subquery, Sum
6
6
  from django.http import HttpResponse
7
7
  from django.shortcuts import get_object_or_404
8
8
  from django.utils.dateparse import parse_date
@@ -80,11 +80,26 @@ class PortfolioModelViewSet(UserPortfolioRequestPermissionMixin, InternalUserPer
80
80
  return (
81
81
  super()
82
82
  .get_queryset()
83
- .select_related(
84
- "currency",
85
- )
86
- .prefetch_related(
87
- "depends_on",
83
+ .select_related("currency", "hedged_currency")
84
+ .prefetch_related("depends_on", "instruments")
85
+ .annotate(
86
+ last_asset_under_management_usd=Subquery(
87
+ AssetPosition.objects.filter(portfolio=OuterRef("pk"), date=OuterRef("last_position_date"))
88
+ .values("portfolio")
89
+ .annotate(s=Sum("total_value_fx_usd"))
90
+ .values("s")[:1]
91
+ ),
92
+ last_positions=Subquery(
93
+ AssetPosition.objects.filter(portfolio=OuterRef("pk"), date=OuterRef("last_position_date"))
94
+ .values("portfolio")
95
+ .annotate(s=Sum("shares"))
96
+ .values("s")[:1]
97
+ ),
98
+ last_trade_proposal_date=Subquery(
99
+ TradeProposal.objects.filter(portfolio=OuterRef("pk"))
100
+ .order_by("-trade_date")
101
+ .values("trade_date")[:1]
102
+ ),
88
103
  )
89
104
  )
90
105
 
@@ -210,7 +225,7 @@ class TopDownPortfolioCompositionPandasAPIView(UserPortfolioRequestPermissionMix
210
225
 
211
226
  @cached_property
212
227
  def last_rebalancing_date(self) -> date | None:
213
- if self.composition_portfolio:
228
+ if self.composition_portfolio and self.last_effective_date:
214
229
  with suppress(TradeProposal.DoesNotExist):
215
230
  return (
216
231
  self.composition_portfolio.trade_proposals.filter(trade_date__lte=self.last_effective_date)
@@ -82,7 +82,7 @@ class TradeProposalModelViewSet(CloneMixin, RiskCheckViewSetMixin, InternalUserP
82
82
  if instance and instance.status == TradeProposal.Status.SUBMIT:
83
83
  if not instance.portfolio.is_manageable:
84
84
  info(request, "This trade proposal cannot be approved the portfolio is considered unmanaged.")
85
- if not instance.has_all_check_completed_and_succeed:
85
+ if instance.has_non_successful_checks:
86
86
  warning(
87
87
  request,
88
88
  "This trade proposal cannot be approved because there is unsuccessful pre-trade checks. Please rectify accordingly and resubmit a valid trade proposal",
@@ -25,6 +25,7 @@ from wbcore.permissions.permissions import InternalUserPermissionMixin
25
25
  from wbcore.utils.strings import format_number
26
26
  from wbcore.viewsets.mixins import OrderableMixin
27
27
  from wbcrm.models import Account
28
+ from wbfdm.models import Cash
28
29
 
29
30
  from wbportfolio.filters import (
30
31
  SubscriptionRedemptionFilterSet,
@@ -391,19 +392,82 @@ class TradeTradeProposalModelViewSet(
391
392
  def get_resource_class(self):
392
393
  return TradeProposalTradeResource
393
394
 
394
- def get_aggregates(self, queryset, paginated_queryset):
395
+ def get_aggregates(self, queryset, *args, **kwargs):
396
+ agg = {}
395
397
  if queryset.exists():
396
- aggregates = queryset.aggregate(
398
+ cash_target_cash_weight, cash_target_cash_shares = self.trade_proposal.get_estimated_target_cash(
399
+ self.trade_proposal.portfolio.currency
400
+ )
401
+ extra_existing_cash_components = Cash.objects.filter(
402
+ id__in=self.trade_proposal.trades.filter(underlying_instrument__is_cash=True).values(
403
+ "underlying_instrument"
404
+ )
405
+ ).exclude(currency=self.trade_proposal.portfolio.currency)
406
+
407
+ for cash_component in extra_existing_cash_components:
408
+ extra_cash_target_cash_weight, extra_cash_target_cash_shares = (
409
+ self.trade_proposal.get_estimated_target_cash(cash_component.currency)
410
+ )
411
+ cash_target_cash_weight += extra_cash_target_cash_weight
412
+ cash_target_cash_shares += extra_cash_target_cash_shares
413
+ noncash_aggregates = queryset.filter(underlying_instrument__is_cash=False).aggregate(
397
414
  sum_target_weight=Sum(F("target_weight")),
398
415
  sum_effective_weight=Sum(F("effective_weight")),
399
- sum_weighting=Sum(F("weighting")),
416
+ sum_target_shares=Sum(F("target_shares")),
417
+ sum_effective_shares=Sum(F("effective_shares")),
400
418
  )
401
- return {
402
- "target_weight": {"Σ": format_number(aggregates["sum_target_weight"], decimal=5)},
403
- "effective_weight": {"Σ": format_number(aggregates["sum_effective_weight"], decimal=5)},
404
- "weighting": {"Σ": format_number(aggregates["sum_weighting"], decimal=5)},
419
+ cash_aggregates = queryset.filter(underlying_instrument__is_cash=True).aggregate(
420
+ sum_effective_weight=Sum(F("effective_weight")),
421
+ sum_effective_shares=Sum(F("effective_shares")),
422
+ )
423
+ # weights aggregates
424
+ cash_sum_effective_weight = cash_aggregates["sum_effective_weight"] or Decimal(0)
425
+ noncash_sum_effective_weight = noncash_aggregates["sum_effective_weight"] or Decimal(0)
426
+ noncash_sum_target_weight = noncash_aggregates["sum_target_weight"] or Decimal(0)
427
+ sum_buy_weight = queryset.filter(weighting__gte=0).aggregate(s=Sum(F("weighting")))["s"] or Decimal(0)
428
+ sum_sell_weight = queryset.filter(weighting__lt=0).aggregate(s=Sum(F("weighting")))["s"] or Decimal(0)
429
+
430
+ # shares aggregates
431
+ cash_sum_effective_shares = cash_aggregates["sum_effective_shares"] or Decimal(0)
432
+ noncash_sum_effective_shares = noncash_aggregates["sum_effective_shares"] or Decimal(0)
433
+ noncash_sum_target_shares = noncash_aggregates["sum_target_shares"] or Decimal(0)
434
+ sum_buy_shares = queryset.filter(shares__gte=0).aggregate(s=Sum(F("shares")))["s"] or Decimal(0)
435
+ sum_sell_shares = queryset.filter(shares__lt=0).aggregate(s=Sum(F("shares")))["s"] or Decimal(0)
436
+
437
+ agg = {
438
+ "effective_weight": {
439
+ "Cash": format_number(cash_sum_effective_weight, decimal=6),
440
+ "Non-Cash": format_number(noncash_sum_effective_weight, decimal=6),
441
+ "Total": format_number(noncash_sum_effective_weight + cash_sum_effective_weight, decimal=6),
442
+ },
443
+ "target_weight": {
444
+ "Cash": format_number(cash_target_cash_weight, decimal=6),
445
+ "Non-Cash": format_number(noncash_sum_target_weight, decimal=6),
446
+ "Total": format_number(cash_target_cash_weight + noncash_sum_target_weight, decimal=6),
447
+ },
448
+ "effective_shares": {
449
+ "Cash": format_number(cash_sum_effective_shares, decimal=6),
450
+ "Non-Cash": format_number(noncash_sum_effective_shares, decimal=6),
451
+ "Total": format_number(cash_sum_effective_shares + noncash_sum_effective_shares, decimal=6),
452
+ },
453
+ "target_shares": {
454
+ "Cash": format_number(cash_target_cash_shares, decimal=6),
455
+ "Non-Cash": format_number(noncash_sum_target_shares, decimal=6),
456
+ "Total": format_number(cash_target_cash_shares + noncash_sum_target_shares, decimal=6),
457
+ },
458
+ "weighting": {
459
+ "Cash Flow": format_number(cash_sum_effective_weight - cash_target_cash_weight, decimal=6),
460
+ "Buy": format_number(sum_buy_weight, decimal=6),
461
+ "Sell": format_number(sum_sell_weight, decimal=6),
462
+ },
463
+ "shares": {
464
+ "Cash Flow": format_number(cash_sum_effective_shares - cash_target_cash_shares, decimal=6),
465
+ "Buy": format_number(sum_buy_shares, decimal=6),
466
+ "Sell": format_number(sum_sell_shares, decimal=6),
467
+ },
405
468
  }
406
- return {}
469
+
470
+ return agg
407
471
 
408
472
  def get_serializer_class(self):
409
473
  if self.trade_proposal.status != TradeProposal.Status.DRAFT:
@@ -414,14 +478,24 @@ class TradeTradeProposalModelViewSet(
414
478
  if queryset is not None and queryset.exists():
415
479
  total_target_weight = queryset.aggregate(c=Sum(F("target_weight")))["c"] or Decimal(0)
416
480
  if round(total_target_weight, 3) != 1:
417
- warning(request, "The total target weight does not equals to 1")
481
+ warning(
482
+ request,
483
+ "The total target weight does not equal 1. To avoid automatic cash allocation, please adjust the trade weights to sum up to 1. Otherwise, a cash component will be added when this trade proposal is submitted.",
484
+ )
418
485
  if queryset.filter(status=Trade.Status.FAILED):
419
486
  error(
420
487
  request,
421
- "Some Trades couldn't be succesfully prepared. Please revert back to draft and correct these trades accordingly.",
488
+ "Some trades failed preparation. To resolve this, please revert the trade proposal to draft, review and correct the trades, and then resubmit.",
422
489
  )
423
490
 
424
491
  def get_queryset(self):
425
492
  if self.is_portfolio_manager:
426
- return super().get_queryset().filter(trade_proposal=self.kwargs["trade_proposal_id"]).annotate_base_info()
427
- return TradeProposal.objects.none()
493
+ qs = super().get_queryset().filter(trade_proposal=self.kwargs["trade_proposal_id"]).annotate_base_info()
494
+ else:
495
+ qs = TradeProposal.objects.none()
496
+ return qs.annotate(
497
+ underlying_instrument_isin=F("underlying_instrument__isin"),
498
+ underlying_instrument_ticker=F("underlying_instrument__ticker"),
499
+ underlying_instrument_refinitiv_identifier_code=F("underlying_instrument__refinitiv_identifier_code"),
500
+ underlying_instrument_instrument_type=F("underlying_instrument__instrument_type__short_name"),
501
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wbportfolio
3
- Version: 1.48.0
3
+ Version: 1.49.0
4
4
  Author-email: Christopher Wittlinger <c.wittlinger@stainly.com>
5
5
  License-File: LICENSE
6
6
  Requires-Dist: cryptography==3.4.*
@@ -53,7 +53,7 @@ wbportfolio/contrib/company_portfolio/tests/test_models.py,sha256=K72dFNMzf5Cpwe
53
53
  wbportfolio/defaults/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
54
  wbportfolio/defaults/fees/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
55
  wbportfolio/defaults/fees/default.py,sha256=1hf1MkY40cmChu-NvoyMTYJMOtG0w-jwbH08BJeYJRg,4207
56
- wbportfolio/factories/__init__.py,sha256=_NICzD6M4X0gGrhP8VmHRlwECoyQrdCDkn1p2KYmx-k,1309
56
+ wbportfolio/factories/__init__.py,sha256=pTezShesLaQ-1uZdGAVBgcgClgpjOCdYozpPfMKtSJU,1236
57
57
  wbportfolio/factories/adjustments.py,sha256=aOHXJLy7DW4k1hcRBZteEe2mKe_wQg7z0bVnzvXCl4A,615
58
58
  wbportfolio/factories/assets.py,sha256=1i7xDT6bpvnYQiEJpmukWadSvS1asQC-QuUJ1PCll0U,3173
59
59
  wbportfolio/factories/claim.py,sha256=LQzz8EbIveOYpMY-JOMR8ba-taoX3u53zjBwxiydtrM,1629
@@ -64,13 +64,13 @@ wbportfolio/factories/indexes.py,sha256=sInyNARyfUNbScxr_ng1HhxtJXIsK3awFf9BF1gr
64
64
  wbportfolio/factories/portfolio_cash_flow.py,sha256=e8LWkk5Gy0FU4HoCL9xPseCtLlVIkMrvAmey5swqcfc,727
65
65
  wbportfolio/factories/portfolio_cash_targets.py,sha256=CoH6xUNtIKW4k88MAhB18CRhzZ349IZxmvlPOi3dbHY,671
66
66
  wbportfolio/factories/portfolio_swing_pricings.py,sha256=UNxnSL23WDCS0QBzbS2JUTfbg4th7wS0Fy9ok9OUFeg,821
67
- wbportfolio/factories/portfolios.py,sha256=1buCuI9yqEsHFupoUil_dR-nzwtL6jueixwIbDhqJ8s,1942
68
- wbportfolio/factories/product_groups.py,sha256=Ouc0A6q89pJN7kbfHAzSvQHxO9Qpdu0y2SljRSCuGpY,1580
69
- wbportfolio/factories/products.py,sha256=ki8G6OTiBqpZV5goXjI5DViefmtxBbcNNMba0Ko1Z_8,2064
67
+ wbportfolio/factories/portfolios.py,sha256=3_wzz-q7Tc3CtVOQNM8eA4UZljds2IizTzGWE9ue1AQ,1524
68
+ wbportfolio/factories/product_groups.py,sha256=JMtG301j5XehB3qmNSbXt6af56Y9uvG3fgbCMf9FCSc,1987
69
+ wbportfolio/factories/products.py,sha256=N0V6sM_98sC6l8qN78wgfmtpYq7O2c5rW5hT5ZM5gsA,2880
70
70
  wbportfolio/factories/rebalancing.py,sha256=5wlB5cT65oBFcMQDLyMn50JOJMD7GQvzpr9Pe0cqJLE,721
71
71
  wbportfolio/factories/reconciliations.py,sha256=Ne3rBZ_yvjlAtWW7qDLprHrLhNCtLL_RXU3yDHc3s3c,916
72
72
  wbportfolio/factories/roles.py,sha256=tot54YX70sNqZrAg5zGJTHd7_PFjZed_mny4lGlnwEA,857
73
- wbportfolio/factories/trades.py,sha256=D48r3Js75TPUqUaYQrr9bVNlkcG7HZvDw_wZ8hastkc,1246
73
+ wbportfolio/factories/trades.py,sha256=-14d_ABN9FEoXb4wm9-YjYHfP2cCEANNM45cMRZtQt8,1373
74
74
  wbportfolio/factories/transactions.py,sha256=jZqTNRpW344DSYjV5tAqU5y30Kc7GRGbZ3BN9hacKpQ,995
75
75
  wbportfolio/fdm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
76
76
  wbportfolio/fdm/tasks.py,sha256=59hXt3TOJaM8KpUaKdBNAGsO7NFMHaAlNA0T3FTUau0,533
@@ -115,7 +115,7 @@ wbportfolio/import_export/handlers/dividend.py,sha256=tftdVdAzNpKSSvouOtvJfzWL36
115
115
  wbportfolio/import_export/handlers/fees.py,sha256=XYH752IkNGYhhhwatp8nYa1zG1-YZFDkYW15dyQgOIg,2824
116
116
  wbportfolio/import_export/handlers/portfolio_cash_flow.py,sha256=2ODaquuC83RfmNwmQ-8TdhiASObfIems_B1g0yqaYTs,2733
117
117
  wbportfolio/import_export/handlers/register.py,sha256=sYyXkE8b1DPZ5monxylZn0kjxLVdNYYZR-p61dwEoDM,2271
118
- wbportfolio/import_export/handlers/trade.py,sha256=DArRPXWjH2YhqPGtbZw7Nyt3JjQNEltx1RyQ3-4FzKs,10829
118
+ wbportfolio/import_export/handlers/trade.py,sha256=KMYnaEUGWyrft0l7OuPKHcy6WKdIr8I_wefoA8pzgjY,11297
119
119
  wbportfolio/import_export/parsers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
120
120
  wbportfolio/import_export/parsers/default_mapping.py,sha256=KrO-X5CvQCeQoBYzFDxavoQGriyUSeI2QDx5ar_zo7A,1405
121
121
  wbportfolio/import_export/parsers/jpmorgan/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -240,6 +240,7 @@ wbportfolio/migrations/0071_alter_trade_options_alter_trade_order.py,sha256=QjAy
240
240
  wbportfolio/migrations/0072_trade_diff_shares.py,sha256=aTKa1SbIiwmlXaFtBg-ENrSxfM_cf3RPNQBQlk2VEZ0,635
241
241
  wbportfolio/migrations/0073_remove_product_price_computation_and_more.py,sha256=J4puisDFwnbnfv2VLWaiCQ7ost6PCOkin9qKVQoLIWM,18725
242
242
  wbportfolio/migrations/0074_alter_rebalancer_frequency_and_more.py,sha256=o01rBj-ADgwCRtAai3e5z27alPGEzaiNxUqCwWm6peY,918
243
+ wbportfolio/migrations/0075_portfolio_initial_position_date_and_more.py,sha256=rXRpsraVlmueAlO2UpBZV4qMf7dtPuptrhfLblZcJDo,1099
243
244
  wbportfolio/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
244
245
  wbportfolio/models/__init__.py,sha256=IIS_PNRxyX2Dcvyk1bcQOUzFt0B9SPC0WlM88CXqj04,881
245
246
  wbportfolio/models/adjustments.py,sha256=osXWkJZOiansPWYPyHtl7Z121zDWi7u1YMtrBQtbHVo,10272
@@ -247,7 +248,7 @@ wbportfolio/models/asset.py,sha256=yf4vBPfN1eZlWXG9SowQwr5-goG8rO1yYDitHDLZCBs,3
247
248
  wbportfolio/models/custodians.py,sha256=owTiS2Vm5CRKzh9M_P9GOVg-s-ndQ9UvRmw3yZP7cw0,3815
248
249
  wbportfolio/models/exceptions.py,sha256=3ix0tWUO-O6jpz8f07XIwycw2x3JFRoWzjwil8FVA2Q,52
249
250
  wbportfolio/models/indexes.py,sha256=iLYF2gzNzX4GLj_Nh3fybUcAQ1TslnT0wgQ6mN164QI,728
250
- wbportfolio/models/portfolio.py,sha256=aBlx37tX8msuZx3OL5QqyeuBqX3marOWTQTqfFH_Fk8,58954
251
+ wbportfolio/models/portfolio.py,sha256=dCLrGVIKqpIdQi78CF58S0GD7sSuzuHjpavKBZgTCm4,58775
251
252
  wbportfolio/models/portfolio_cash_flow.py,sha256=2blPiXSw7dbhUVd-7LcxDBb4v0SheNOdvRK3MFYiChA,7273
252
253
  wbportfolio/models/portfolio_cash_targets.py,sha256=WmgG-etPisZsh2yaFQpz7EkpvAudKBEzqPsO715w52U,1498
253
254
  wbportfolio/models/portfolio_relationship.py,sha256=mMb18UMRWg9kx_9uIPkMktwORuXXLjKdgRPQQvB6fVE,5486
@@ -273,22 +274,22 @@ wbportfolio/models/transactions/claim.py,sha256=agdpGqxpO0FSzYDWV-Gv1tQY46k0LN9C
273
274
  wbportfolio/models/transactions/dividends.py,sha256=naL5xeDQfUBf5KyGt7y-tTcHL22nzZumT8DV6AaG8Bg,1064
274
275
  wbportfolio/models/transactions/expiry.py,sha256=vnNHdcC1hf2HP4rAbmoGgOfagBYKNFytqOwzOI0MlVI,144
275
276
  wbportfolio/models/transactions/fees.py,sha256=ffvqo8I4A0l5rLi00jJ6sGot0jmnkoxaNsbDzdPLwCg,5712
276
- wbportfolio/models/transactions/rebalancing.py,sha256=3p5r6m68_7AD783hYAlDZCnUz1TOLVa9mvF5zConTMo,7036
277
- wbportfolio/models/transactions/trade_proposals.py,sha256=vLwDdHNUEJdDvqSw6s7jcabp3ldZd-NPWCxF0qzNoGQ,21531
278
- wbportfolio/models/transactions/trades.py,sha256=C-goHy_f9NJcZko39k3oPm7cGjznruhWyD_Hr1xoBKo,27941
277
+ wbportfolio/models/transactions/rebalancing.py,sha256=nrBi6x6PssCtkLtOpV-2OoAHDUKnnYyrM6xH1PmnjSo,7240
278
+ wbportfolio/models/transactions/trade_proposals.py,sha256=iZb0LHqWSqbWf3Rmyhb5igGGKoT3JN52O2Db8j3J_1g,26727
279
+ wbportfolio/models/transactions/trades.py,sha256=zoqWsDpbUKbvdW60ytNg27kRFlH1N0rUz6mf0o6DdR4,28337
279
280
  wbportfolio/models/transactions/transactions.py,sha256=4THsE4xqdigZAwWKYfTNRLPJlkmAmsgE70Ribp9Lnrk,7127
280
281
  wbportfolio/pms/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
281
- wbportfolio/pms/typing.py,sha256=WKP5tYyYt7DbMo25VM99V4IAM9oDSIPZyR3yXCzeZEA,5920
282
+ wbportfolio/pms/typing.py,sha256=b2pBWYt1E8ok-Kqm0lEFIakSnWJ6Ib57z-VX3C3gkQc,6081
282
283
  wbportfolio/pms/analytics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
283
284
  wbportfolio/pms/analytics/portfolio.py,sha256=vE0KA6Z037bUdmBTkYuBqXElt80nuYObNzY_kWvxEZY,1360
284
285
  wbportfolio/pms/statistics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
285
286
  wbportfolio/pms/trading/__init__.py,sha256=R_yLKc54sCak8A1cW0O1Aszrcv5KV8mC_3h17Hr20e4,36
286
- wbportfolio/pms/trading/handler.py,sha256=9RDRQFcnk55t69KSFYZxZDFOvd942-J4St-zJ7e8zlY,7149
287
+ wbportfolio/pms/trading/handler.py,sha256=EzvCP8NNzd0jjE3ilCupbmFBCaojKvlrbq7n_JirahU,7151
287
288
  wbportfolio/rebalancing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
288
289
  wbportfolio/rebalancing/base.py,sha256=NwTGZtBm1f35gj5Jp6iTyyFvDT1GSIztN990cKBvYzQ,637
289
290
  wbportfolio/rebalancing/decorators.py,sha256=JhQ2vkcIuGBTGvNmpkQerdw2-vLq-RAb0KAPjOrETkw,515
290
291
  wbportfolio/rebalancing/models/__init__.py,sha256=AQjG7Tu5vlmhqncVoYOjpBKU2UIvgo9FuP2_jD2w-UI,232
291
- wbportfolio/rebalancing/models/composite.py,sha256=XAjJqLRNsV-MuBKrat3THEfAWs6PXQNSO0g8k8MtBXo,1157
292
+ wbportfolio/rebalancing/models/composite.py,sha256=uyF1n3NAFprnAZ3Gl5pNJl0GajelqJspC2NufZ7Tf0s,1636
292
293
  wbportfolio/rebalancing/models/equally_weighted.py,sha256=U29MOHJMQMIg7Y7W_8t5K3nXjaznzt4ArIxQSiv0Xok,863
293
294
  wbportfolio/rebalancing/models/market_capitalization_weighted.py,sha256=LvzV7a8fNbpsRahysvKbE6oNSQccWpnnne-rlDj3uzU,4928
294
295
  wbportfolio/rebalancing/models/model_portfolio.py,sha256=XQdvs03-0M9YUnL4DidwZC4E6k-ANCNcZ--T_aaOXTQ,1233
@@ -298,7 +299,7 @@ wbportfolio/risk_management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMp
298
299
  wbportfolio/risk_management/backends/__init__.py,sha256=4N3GYcIb0XgZUQWEHxCejOCRabUtLM6ha9UdOWJKUfI,368
299
300
  wbportfolio/risk_management/backends/accounts.py,sha256=VMHwhzeFV2bzobb1RlEJadTVix1lkbbfdpo-zG3YN5c,7988
300
301
  wbportfolio/risk_management/backends/controversy_portfolio.py,sha256=ncEHyJMVomv0ehx7LoWcux1YHLV6KYYmiOkIBzJ0P1M,2852
301
- wbportfolio/risk_management/backends/exposure_portfolio.py,sha256=PaJYlv3OCG2ncpp0zLr0eGtUk0C9KtWTrp4pPVa7AqA,9290
302
+ wbportfolio/risk_management/backends/exposure_portfolio.py,sha256=8T97J0pbnGdme_Ji9ntA5FV9MCouSxDz5grMvRvpl70,10760
302
303
  wbportfolio/risk_management/backends/instrument_list_portfolio.py,sha256=Sh8PZHHKFAl4Aw8fOlu17fUSiEFYYemb-B0iltAXc10,4186
303
304
  wbportfolio/risk_management/backends/liquidity_risk.py,sha256=cRL7ZXvrC286yXCauNatuvSYikMNB-nmAt5ELmpDg0c,3688
304
305
  wbportfolio/risk_management/backends/liquidity_stress_instrument.py,sha256=oitzsaZu-HhYn9Avku3322GtDmf6QGsfyRzGPGZoM1Y,3612
@@ -311,7 +312,7 @@ wbportfolio/risk_management/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeR
311
312
  wbportfolio/risk_management/tests/conftest.py,sha256=ChVocx8SDmh13ixkRmnKe_MMudQAX0495o7nG4NDlsg,440
312
313
  wbportfolio/risk_management/tests/test_accounts.py,sha256=q9Z3hDw0Yw86VealdmUfiJBkzRcqDwfybteGxS0hAJA,3990
313
314
  wbportfolio/risk_management/tests/test_controversy_portfolio.py,sha256=TrvDQ8JEXYFMl7z6MsPAAXV5d8LILO1RYRjMtF9YVTU,1366
314
- wbportfolio/risk_management/tests/test_exposure_portfolio.py,sha256=k5lBb4ESde6hH304Oias0PyMCeO7MU_q044dLrTej1Y,3512
315
+ wbportfolio/risk_management/tests/test_exposure_portfolio.py,sha256=hKTygdBdZB-ZEIL_-J3QZBvPGtb1N5FWQBBS3rT8lrs,5536
315
316
  wbportfolio/risk_management/tests/test_instrument_list_portfolio.py,sha256=1pAsuMhxOWZHxQnVlTnRuzq8qIe6_86EYbkTnPlWRjE,2763
316
317
  wbportfolio/risk_management/tests/test_liquidity_risk.py,sha256=UtzBrW7LeY0Z0ARX9pg4CUjgdw8u5Hfrdkddro5EEZ8,1713
317
318
  wbportfolio/risk_management/tests/test_product_integrity.py,sha256=wqJ4b5DO2BrEVQF4eVX2B9AvfrRMAyC_lppGrgKc_ug,1959
@@ -326,7 +327,7 @@ wbportfolio/serializers/portfolio_cash_flow.py,sha256=vBRZnUKq4XAqcvjyk-xMsw5v4x
326
327
  wbportfolio/serializers/portfolio_cash_targets.py,sha256=_GdsFXoBda1JHJnfZbaVlNFdnXlvGuy_FEcEZH-UThY,605
327
328
  wbportfolio/serializers/portfolio_relationship.py,sha256=UR_GIF2LHw82a8mv6L8OXYvoCp5-QWtubt33Y4mqFow,1933
328
329
  wbportfolio/serializers/portfolio_swing_pricing.py,sha256=a21st7MmcugbAO_xc90QWSeXwU1ivk-y2PWlMGKySJY,655
329
- wbportfolio/serializers/portfolios.py,sha256=0MGnHXlovX6cI0im1ZFr_b2IUUKx8a3bDgs4nt3EmZM,6476
330
+ wbportfolio/serializers/portfolios.py,sha256=ZowvB0T38tuXVQI-O9pEsPdLfG1hrW6aMZ1DBVnPbuE,7679
330
331
  wbportfolio/serializers/positions.py,sha256=UK9dvE1wiILw2E209InrsUhme52vfUYDDERBeKCcn_k,2415
331
332
  wbportfolio/serializers/product_group.py,sha256=klPGmAb1MvJpyiKKMRb8uYFIMm6SCZkMFQDu5EH-mkY,3680
332
333
  wbportfolio/serializers/products.py,sha256=BDMizM77Iohe7JEUncll2ET4GtU8hicQ6c4Vm0srqd4,12374
@@ -341,7 +342,7 @@ wbportfolio/serializers/transactions/dividends.py,sha256=EULwKDumHBv4r2HsdEGZMZG
341
342
  wbportfolio/serializers/transactions/expiry.py,sha256=K3XOSbCyef-xRzOjCr4Qg_YFJ_JuuiJ9u6tDS86l0hg,477
342
343
  wbportfolio/serializers/transactions/fees.py,sha256=uPmSWuCeoV2bwVS6RmEz3a0VRBWJHIQr0WhklYc1UAI,1068
343
344
  wbportfolio/serializers/transactions/trade_proposals.py,sha256=fiGpL6za5ERLtdbud5wrciCVXHX6-3SjeF8Zaa6Zhzg,3410
344
- wbportfolio/serializers/transactions/trades.py,sha256=pONV5NSqrXUnoTEoAxovnnQqu37cZGuB33TYvIOK3rE,10009
345
+ wbportfolio/serializers/transactions/trades.py,sha256=nqldVcwcWFQaBVZE46VWo_hJ3mSPrDJ3ZaihpmvVXZE,10755
345
346
  wbportfolio/serializers/transactions/transactions.py,sha256=O137zeCndK-nxIWSRLEj7bXbBZDGa4d6qK6pJIIYK3g,4170
346
347
  wbportfolio/static/wbportfolio/css/macro_review.css,sha256=FAVVO8nModxwPXcTKpcfzVxBGPZGJVK1Xn-0dkSfGyc,233
347
348
  wbportfolio/static/wbportfolio/markdown/documentation/account_holding_reconciliation.md,sha256=MabxOvOne8s5gl6osDoow6-3ghaXLAYg9THWpvy6G5I,921
@@ -358,7 +359,7 @@ wbportfolio/templates/portfolio/email/rebalancing_report.html,sha256=Go7joPYXwF_
358
359
  wbportfolio/templates/portfolio/macro/macro_review.html,sha256=OxliFeX9pVNKeTVTaPnfNPHmM5YxVMr77PeKC-6y0jY,2273
359
360
  wbportfolio/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
360
361
  wbportfolio/tests/conftest.py,sha256=zNKZJ_ymjE0M-Q5QyVYQdStSCSdO9Gy_S_jJEBC-6JY,4380
361
- wbportfolio/tests/signals.py,sha256=5dTpWBO31sHF1NXN5CRnQQUTJuK_X4WR5iDcIS4-_c0,5918
362
+ wbportfolio/tests/signals.py,sha256=9tZczwFAcaUR5epAExCPhdRCE7duRC6WZOPe91r1TAE,5941
362
363
  wbportfolio/tests/tests.py,sha256=utTcVQI7oA7-Yo-IDM7d7BXwXNMIWpRbZNyEWqxkyL4,1033
363
364
  wbportfolio/tests/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
364
365
  wbportfolio/tests/models/test_account_reconciliation.py,sha256=7IDZh6qbG7-3czbNf5aDRaEDnMBw2Qiqk_h425dFu9w,8569
@@ -372,7 +373,7 @@ wbportfolio/tests/models/test_merge.py,sha256=sdsjiZsmR6vsUKwTa5kkvL6QTeAZqtd_EP
372
373
  wbportfolio/tests/models/test_portfolio_cash_flow.py,sha256=X8dsXexsb1b0lBiuGzu40ps_Az_1UmmKT0eo1vbXH94,5792
373
374
  wbportfolio/tests/models/test_portfolio_cash_targets.py,sha256=q8QWAwt-kKRkLC0E05GyRhF_TTQXIi8bdHjXVU0fCV0,965
374
375
  wbportfolio/tests/models/test_portfolio_swing_pricings.py,sha256=kr2AOcQkyg2pX3ULjU-o9ye-NVpjMrrfoe-DVbYCbjs,1656
375
- wbportfolio/tests/models/test_portfolios.py,sha256=idIUT2kc6Fte-bzwOS9NtOYRVnwTBijSo7deHkRon_k,52194
376
+ wbportfolio/tests/models/test_portfolios.py,sha256=DbOanYdyLEfnHqgmz0jckxnJRo4msiaaDjKWD4dQy4o,52208
376
377
  wbportfolio/tests/models/test_product_groups.py,sha256=AcdxhurV-n_bBuUsfD1GqVtwLFcs7VI2CRrwzsIUWbU,3337
377
378
  wbportfolio/tests/models/test_products.py,sha256=nBEgyUoY-4F_pfHYnAr7KXdNYvdIkSu-PWJrqp5tPHg,9482
378
379
  wbportfolio/tests/models/test_roles.py,sha256=4Cn7WyrA2ztJNeWLk5cy9kYo5XLWMbFSvo1O-9JYxeA,3323
@@ -382,7 +383,8 @@ wbportfolio/tests/models/transactions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCe
382
383
  wbportfolio/tests/models/transactions/test_claim.py,sha256=NG3BKB-FVcIDgHSJHCjImxgMM3ISVUMl24xUPmEcPec,5570
383
384
  wbportfolio/tests/models/transactions/test_fees.py,sha256=1gp_h_CCC4Z_cWHUgrZCjGAxYuT2u8FZdw0krDpESiY,2801
384
385
  wbportfolio/tests/models/transactions/test_rebalancing.py,sha256=H1UbxPm-oa00-JJXbBxNutdTKvXXJmuATTab2XsXp44,3900
385
- wbportfolio/tests/models/transactions/test_trades.py,sha256=z0CCZjB648ECDSEdwmzqCdIe7h4UWVJQ8qKR42Xu0TQ,9008
386
+ wbportfolio/tests/models/transactions/test_trade_proposals.py,sha256=sqC8uT46Znb03ZwWxIJOaFNBENKunfA5U73xjWbdj80,17053
387
+ wbportfolio/tests/models/transactions/test_trades.py,sha256=vqvOqUY_uXvBp8YOKR0Wq9ycA2oeeEBhO3dzV7sbXEU,9863
386
388
  wbportfolio/tests/pms/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
387
389
  wbportfolio/tests/pms/test_analytics.py,sha256=fAuY1zcXibttFpBh2GhKVyzdYfi1kz_b7SPa9xZQXY0,1086
388
390
  wbportfolio/tests/rebalancing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -391,7 +393,7 @@ wbportfolio/tests/serializers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5N
391
393
  wbportfolio/tests/serializers/test_claims.py,sha256=vQrg73xQXRFEgvx3KI9ivFre_wpBFzdO0p0J13PkvdY,582
392
394
  wbportfolio/tests/viewsets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
393
395
  wbportfolio/tests/viewsets/test_assets.py,sha256=-RKdU23dxXEW8f3ZQu3a15U9ljTej3FflGtDEahENsI,2568
394
- wbportfolio/tests/viewsets/test_performances.py,sha256=2_K7doqgdZJ-Lte2lLq1EJOYmTJjYw9idlY0H6M2KRI,3850
396
+ wbportfolio/tests/viewsets/test_performances.py,sha256=Cx5FqPO4K8G7F6-rqiiSDmFNYJPyv999pvR-KCO1FYY,3877
395
397
  wbportfolio/tests/viewsets/test_products.py,sha256=VsLW5iazAGch8yxH0jTgcc2fn4L7iZ2gPw7PmqQL60g,4270
396
398
  wbportfolio/tests/viewsets/transactions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
397
399
  wbportfolio/tests/viewsets/transactions/test_claims.py,sha256=QEZfMAW07dyoZ63t2umSwGOqvaTULfYfbN_F4ZoSAcw,6368
@@ -406,7 +408,7 @@ wbportfolio/viewsets/portfolio_cash_flow.py,sha256=jkBfdZRQ3KsxGMJpltRjmdrZ2qEFJ
406
408
  wbportfolio/viewsets/portfolio_cash_targets.py,sha256=CvHlrDE8qnnnfRpTYnFu-Uu15MDbF5d5gTmEKth2S24,322
407
409
  wbportfolio/viewsets/portfolio_relationship.py,sha256=RGyvxd8NfFEs8YdqEvVD3VbrISvAO5UtCTlocSIuWQw,2109
408
410
  wbportfolio/viewsets/portfolio_swing_pricing.py,sha256=-57l3WLQZRslIV67OT0ucHE5JXTtTtLvd3t7MppdVn8,357
409
- wbportfolio/viewsets/portfolios.py,sha256=ZQjlBUZYAM576V0kE8nfRdyCkOPhvt54yFz9drUZilE,13128
411
+ wbportfolio/viewsets/portfolios.py,sha256=eUty1gVN0hLKMmW0IGe_l8u6CFSTJW9ruSPlZbZnU7E,14050
410
412
  wbportfolio/viewsets/positions.py,sha256=MDf_0x9La2qE6qjaIqBtfV5VC0RfJ1chZIim45Emk10,13198
411
413
  wbportfolio/viewsets/product_groups.py,sha256=YvmuXPPy98K1J_rz6YPsx9gNK-tCS2P-wc1uRYgfyo0,2399
412
414
  wbportfolio/viewsets/product_performance.py,sha256=dRfRgifjGS1RgZSu9uJRM0SmB7eLnNUkPuqARMO4gyo,28371
@@ -441,7 +443,7 @@ wbportfolio/viewsets/configs/display/esg.py,sha256=W8uetCPN2TjHtU2kvQjKOmkq7uoaY
441
443
  wbportfolio/viewsets/configs/display/fees.py,sha256=_8HDJADh5bA5VMVPkhKObPmNNdPHWR8Oz23PEgd04F0,5834
442
444
  wbportfolio/viewsets/configs/display/portfolio_cash_flow.py,sha256=CS_UGhKZSXnX-0SZ0RXzbG1WMJm6NX3GUljwIa4RWBk,5025
443
445
  wbportfolio/viewsets/configs/display/portfolio_relationship.py,sha256=8DvsYWFCX29qj5wUf1wCtjlPwzKRd_E7JDuo_CopaJ0,1294
444
- wbportfolio/viewsets/configs/display/portfolios.py,sha256=S-cBvdpjrXT6bf7wzqVQ3w1afd_DYym39ubzEx_BSmU,8342
446
+ wbportfolio/viewsets/configs/display/portfolios.py,sha256=ke60jc2yUjEHjkyt4yruM3LXnKC63oO2RMmaj_4ljks,10716
445
447
  wbportfolio/viewsets/configs/display/positions.py,sha256=yolWLxzGPIpSQSiVhVQChURqbomPt5kSjkYrmXT1Mik,3123
446
448
  wbportfolio/viewsets/configs/display/product_groups.py,sha256=PwI-A0_ofShT2pub9-C1HqreiqpHxKMHd51JYwEzvbM,2500
447
449
  wbportfolio/viewsets/configs/display/product_performance.py,sha256=6Mme48JBn_okwClR44dBK2OK26ejvdasDvBa5DI33_0,10070
@@ -451,7 +453,7 @@ wbportfolio/viewsets/configs/display/reconciliations.py,sha256=YvMAuwmpX0HExvGsu
451
453
  wbportfolio/viewsets/configs/display/registers.py,sha256=1np75exIk5rfct6UkVN_RnfJ9ozvIkcWJgFV4_4rJns,3182
452
454
  wbportfolio/viewsets/configs/display/roles.py,sha256=SFUyCdxSlHZ3NsMrJmpVBSlg-XKGaEFteV89nyLMMAQ,1815
453
455
  wbportfolio/viewsets/configs/display/trade_proposals.py,sha256=sRLSUjKlarBhnTwg7tX_Juldor3beswJlyvZfFPvNEk,4315
454
- wbportfolio/viewsets/configs/display/trades.py,sha256=e61wLzTEDwewgctpztDa4ExvieimBe2iqycg8gHdaw4,15977
456
+ wbportfolio/viewsets/configs/display/trades.py,sha256=_J60o7s1gQ-2Jg3JvWLDWgfsobIy60kzYWdJ8ea0Fn8,16823
455
457
  wbportfolio/viewsets/configs/display/transactions.py,sha256=DOM3eV1DxBwX6Iiw3C2sJamWh6A_3ZSYC9447Jc3Wmo,2586
456
458
  wbportfolio/viewsets/configs/endpoints/__init__.py,sha256=E13AYY3CIW4CZtmqwBVMPDYA5zNyKJeRZtiXKtad68Y,2871
457
459
  wbportfolio/viewsets/configs/endpoints/adjustments.py,sha256=9CcnfNuFcxsZ8YvfUitSeyCvpLxY-jU-gIw3GG0mIp4,697
@@ -470,7 +472,7 @@ wbportfolio/viewsets/configs/endpoints/rebalancing.py,sha256=D0VqMkWUeC-4mSN-GbZ
470
472
  wbportfolio/viewsets/configs/endpoints/reconciliations.py,sha256=xriq1KSctxQa6AE9SgkupMPVa9807OyYSIYhWk9WBpM,1059
471
473
  wbportfolio/viewsets/configs/endpoints/roles.py,sha256=5Nwi2sdUYc85YL0wJ7SUtt87ZBTOVdFnEexUgVrmcX4,367
472
474
  wbportfolio/viewsets/configs/endpoints/trade_proposals.py,sha256=sno7SOHWjKvvF_YdgYx5KthntM--F3DX-9hsrY5vRTM,783
473
- wbportfolio/viewsets/configs/endpoints/trades.py,sha256=mzGz1i2b7F7Nl7Im6974UnJNaYMAyiQJ14T1ocKDmZA,3113
475
+ wbportfolio/viewsets/configs/endpoints/trades.py,sha256=5NKMSYaGWDd8OcV16HLRSlAgYYXObLikLf2w4ix2DoE,3483
474
476
  wbportfolio/viewsets/configs/endpoints/transactions.py,sha256=HQDuQ_wrnkCGTNhnx1zKsPifcDCnlpaOD2NYYiNYd54,633
475
477
  wbportfolio/viewsets/configs/menu/__init__.py,sha256=gzUpv5f8FAK1Bdhn0AhcMLJR3r9RXHRXcHg21vuvGxs,1184
476
478
  wbportfolio/viewsets/configs/menu/adjustments.py,sha256=sQ25Jp2N8nsLSUOEJTJUBE0Y7bIPHK4Y6LE0e1OzX38,316
@@ -515,10 +517,10 @@ wbportfolio/viewsets/transactions/claim.py,sha256=m_Fy4J_QZSve1VlR_sPQrVBDopgCqq
515
517
  wbportfolio/viewsets/transactions/fees.py,sha256=7VUXIogmRrXCz_D9tvDiiTae0t5j09W9zPUzxXzBGTE,7031
516
518
  wbportfolio/viewsets/transactions/mixins.py,sha256=WipvJoi5hylkpD0y9VATe30WAcwIHUIroVkK10FYw7k,636
517
519
  wbportfolio/viewsets/transactions/rebalancing.py,sha256=6rIrdK0rtKL1afJ-tYfAGdQVTN2MH1kG_yCeVkmyK8k,1263
518
- wbportfolio/viewsets/transactions/trade_proposals.py,sha256=HyffjmSq2KZpCkzvaeEc2PZY6-cJtF7bmMTFOj95at0,5835
519
- wbportfolio/viewsets/transactions/trades.py,sha256=E0QV6oPohOgeVWzNT6xfWOFvTB4KoP2DzDYnGtm3Hz0,16259
520
+ wbportfolio/viewsets/transactions/trade_proposals.py,sha256=nZsomopPfeLg1owPpOdIbhdHfCFa3-Qh-uyqoSATOjw,5821
521
+ wbportfolio/viewsets/transactions/trades.py,sha256=2w6c5ExZNmyMBGTWR3_3SEuuJ727AjKr_HgZE3sDt1Y,20950
520
522
  wbportfolio/viewsets/transactions/transactions.py,sha256=ixDp-nsNA8t_A06rBCT19hOMJHy0iRmdz1XKdV1OwAs,4450
521
- wbportfolio-1.48.0.dist-info/METADATA,sha256=jcITcoDYbFVqqHklU1vzXHkRGeJwqU3FB4kHLWZXbQ0,734
522
- wbportfolio-1.48.0.dist-info/WHEEL,sha256=tkmg4JIqwd9H8mL30xA7crRmoStyCtGp0VWshokd1Jc,105
523
- wbportfolio-1.48.0.dist-info/licenses/LICENSE,sha256=jvfVH0SY8_YMHlsJHKe_OajiscQDz4lpTlqT6x24sVw,172
524
- wbportfolio-1.48.0.dist-info/RECORD,,
523
+ wbportfolio-1.49.0.dist-info/METADATA,sha256=4ie6HSvXOoA_xHCciE716QeJG61w5Y93BDzIYvuOeVw,734
524
+ wbportfolio-1.49.0.dist-info/WHEEL,sha256=tkmg4JIqwd9H8mL30xA7crRmoStyCtGp0VWshokd1Jc,105
525
+ wbportfolio-1.49.0.dist-info/licenses/LICENSE,sha256=jvfVH0SY8_YMHlsJHKe_OajiscQDz4lpTlqT6x24sVw,172
526
+ wbportfolio-1.49.0.dist-info/RECORD,,