wbportfolio 1.54.4__py2.py3-none-any.whl → 1.54.5__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.

@@ -168,7 +168,8 @@ class AssetPositionIterator:
168
168
  # Merge duplicate positions
169
169
  if existing_position := self.positions.get(key):
170
170
  position.weighting += existing_position.weighting
171
- position.initial_shares += existing_position.initial_shares
171
+ if existing_position.initial_shares:
172
+ position.initial_shares += existing_position.initial_shares
172
173
  # ensure the position portfolio is the iterator portfolio (could be different when computing look-through for instance)
173
174
  position.portfolio = self.portfolio
174
175
  if position.initial_price is not None and position.initial_currency_fx_rate is not None:
@@ -372,6 +372,7 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
372
372
  approve_automatically: bool = True,
373
373
  silent_exception: bool = False,
374
374
  force_reset_trade: bool = False,
375
+ broadcast_changes_at_date: bool = True,
375
376
  **reset_trades_kwargs,
376
377
  ):
377
378
  if self.status == TradeProposal.Status.APPROVED:
@@ -394,7 +395,7 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
394
395
  if self.status == TradeProposal.Status.SUBMIT:
395
396
  logger.info("Approving trade proposal ...")
396
397
  if approve_automatically and self.portfolio.can_be_rebalanced:
397
- self.approve(replay=False)
398
+ self.approve(replay=False, broadcast_changes_at_date=broadcast_changes_at_date)
398
399
 
399
400
  def replay(self, force_reset_trade: bool = False, broadcast_changes_at_date: bool = True):
400
401
  last_trade_proposal = self
@@ -405,7 +406,11 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
405
406
  last_trade_proposal.portfolio.assets.filter(
406
407
  date=self.trade_date
407
408
  ).all().delete() # we delete the existing position and we reapply the trade proposal
408
- last_trade_proposal.approve_workflow(silent_exception=True, force_reset_trade=force_reset_trade)
409
+ last_trade_proposal.approve_workflow(
410
+ silent_exception=True,
411
+ force_reset_trade=force_reset_trade,
412
+ broadcast_changes_at_date=broadcast_changes_at_date,
413
+ )
409
414
  last_trade_proposal.save()
410
415
  if last_trade_proposal.status != TradeProposal.Status.APPROVED:
411
416
  break
@@ -681,6 +686,7 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
681
686
  AssetPositionIterator(self.portfolio).add(assets, is_estimated=False),
682
687
  evaluate_rebalancer=False,
683
688
  force_save=True,
689
+ **kwargs,
684
690
  )
685
691
  if replay and self.portfolio.is_manageable:
686
692
  replay_as_task.delay(self.id, user_id=by.id if by else None)
@@ -788,9 +794,9 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
788
794
  with suppress(KeyError):
789
795
  del self.__dict__["validated_trading_service"]
790
796
  trades = []
791
- self.portfolio.assets.filter(
792
- date=self.trade_date, is_estimated=False
793
- ).delete() # we delete the existing portfolio as it has been reverted
797
+ self.portfolio.assets.filter(date=self.trade_date, is_estimated=False).update(
798
+ is_estimated=True
799
+ ) # we delete the existing portfolio as it has been reverted
794
800
  for trade in self.trades.all():
795
801
  trade.status = Trade.Status.DRAFT
796
802
  trade.drift_factor = Decimal("1")
@@ -9,6 +9,11 @@ from wbportfolio.rebalancing.decorators import register
9
9
 
10
10
  @register("Equally Weighted Rebalancing")
11
11
  class EquallyWeightedRebalancing(AbstractRebalancingModel):
12
+ def __init__(self, *args, **kwargs):
13
+ super(EquallyWeightedRebalancing, self).__init__(*args, **kwargs)
14
+ if not self.effective_portfolio:
15
+ self.effective_portfolio = self.portfolio._build_dto(self.trade_date)
16
+
12
17
  def is_valid(self) -> bool:
13
18
  return (
14
19
  len(self.effective_portfolio.positions) > 0
@@ -1064,7 +1064,7 @@ class TestPortfolioModel(PortfolioTestMixin):
1064
1064
 
1065
1065
  # we approve the rebalancing trade proposal
1066
1066
  assert rebalancing_trade_proposal.status == "SUBMIT"
1067
- rebalancing_trade_proposal.approve(no_replay=True)
1067
+ rebalancing_trade_proposal.approve(replay=False)
1068
1068
  rebalancing_trade_proposal.save()
1069
1069
 
1070
1070
  # check that the rebalancing was applied and position reflect that
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wbportfolio
3
- Version: 1.54.4
3
+ Version: 1.54.5
4
4
  Author-email: Christopher Wittlinger <c.wittlinger@stainly.com>
5
5
  License-File: LICENSE
6
6
  Requires-Dist: cryptography==3.4.*
@@ -253,7 +253,7 @@ wbportfolio/migrations/0080_alter_trade_drift_factor_alter_trade_weighting.py,sh
253
253
  wbportfolio/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
254
254
  wbportfolio/models/__init__.py,sha256=HSpa5xwh_MHQaBpNrq9E0CbdEE5Iq-pDLIsPzZ-TRTg,904
255
255
  wbportfolio/models/adjustments.py,sha256=osXWkJZOiansPWYPyHtl7Z121zDWi7u1YMtrBQtbHVo,10272
256
- wbportfolio/models/asset.py,sha256=hhLv3Gyzr3-yd2bFA6wwYZ_i9XuqswzUIexdW1XKPWw,45634
256
+ wbportfolio/models/asset.py,sha256=RySxJzqQqXTuPOFKDVWC_S-5SDGir-EjrWne8fsns-I,45691
257
257
  wbportfolio/models/custodians.py,sha256=owTiS2Vm5CRKzh9M_P9GOVg-s-ndQ9UvRmw3yZP7cw0,3815
258
258
  wbportfolio/models/exceptions.py,sha256=3ix0tWUO-O6jpz8f07XIwycw2x3JFRoWzjwil8FVA2Q,52
259
259
  wbportfolio/models/indexes.py,sha256=gvW4K9U9Bj8BmVCqFYdWiXvDWhjHINRON8XhNsZUiQY,639
@@ -284,7 +284,7 @@ wbportfolio/models/transactions/claim.py,sha256=SF2FlwG6SRVmA_hT0NbXah5-fYejccWK
284
284
  wbportfolio/models/transactions/dividends.py,sha256=mmOdGWR35yndUMoCuG24Y6BdtxDhSk2gMQ-8LVguqzg,1890
285
285
  wbportfolio/models/transactions/fees.py,sha256=wJtlzbBCAq1UHvv0wqWTE2BEjCF5RMtoaSDS3kODFRo,7112
286
286
  wbportfolio/models/transactions/rebalancing.py,sha256=rwePcmTZOYgfSWnBQcBrZ3DQHRJ3w17hdO_hgrRbbhI,7696
287
- wbportfolio/models/transactions/trade_proposals.py,sha256=33RLqsknglMsESUb_d0gt0ehwyDIn3i4s7nOdyvsi5E,37832
287
+ wbportfolio/models/transactions/trade_proposals.py,sha256=FnEZZ7csJMRxGYrUQl0LIDlasEM4An_1gyJhGytn3WE,38104
288
288
  wbportfolio/models/transactions/trades.py,sha256=7btwshl10-XVOrTYF9PXNyfuHGOttA11D0hkvOLEhgs,34126
289
289
  wbportfolio/models/transactions/transactions.py,sha256=XTcUeMUfkf5XTSZaR2UAyGqCVkOhQYk03_vzHLIgf8Q,3807
290
290
  wbportfolio/pms/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -299,7 +299,7 @@ wbportfolio/rebalancing/base.py,sha256=wpeoxdkLz5osxm5mRjkOoML7YkYvwuAlqSLLtHBbW
299
299
  wbportfolio/rebalancing/decorators.py,sha256=JhQ2vkcIuGBTGvNmpkQerdw2-vLq-RAb0KAPjOrETkw,515
300
300
  wbportfolio/rebalancing/models/__init__.py,sha256=AQjG7Tu5vlmhqncVoYOjpBKU2UIvgo9FuP2_jD2w-UI,232
301
301
  wbportfolio/rebalancing/models/composite.py,sha256=XEgK3oMurrE_d_l5uN0stBKRrtvnKQzRWyXNXuBYfmc,1818
302
- wbportfolio/rebalancing/models/equally_weighted.py,sha256=nqkiCnDfazC0AZeRPMVtqRzbDHdW8P2FCMYXEvmwOMw,1062
302
+ wbportfolio/rebalancing/models/equally_weighted.py,sha256=JF6VoAcsHUUJvTBeUtIn2ojWtrn4pVH1PMTyJ2Y69qg,1301
303
303
  wbportfolio/rebalancing/models/market_capitalization_weighted.py,sha256=BJUoJRQ-qTG3cevPKm_3HMy4lVNk6wuxHGuUobPkrMY,5523
304
304
  wbportfolio/rebalancing/models/model_portfolio.py,sha256=Dk3tw9u3WG1jCP3V2-R05GS4-DmDBBtxH4h6p7pRe4g,1393
305
305
  wbportfolio/reports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -380,7 +380,7 @@ wbportfolio/tests/models/test_merge.py,sha256=sdsjiZsmR6vsUKwTa5kkvL6QTeAZqtd_EP
380
380
  wbportfolio/tests/models/test_portfolio_cash_flow.py,sha256=X8dsXexsb1b0lBiuGzu40ps_Az_1UmmKT0eo1vbXH94,5792
381
381
  wbportfolio/tests/models/test_portfolio_cash_targets.py,sha256=q8QWAwt-kKRkLC0E05GyRhF_TTQXIi8bdHjXVU0fCV0,965
382
382
  wbportfolio/tests/models/test_portfolio_swing_pricings.py,sha256=kr2AOcQkyg2pX3ULjU-o9ye-NVpjMrrfoe-DVbYCbjs,1656
383
- wbportfolio/tests/models/test_portfolios.py,sha256=sGmPrl-nY1-3797SDTRWAGF2xXZGD94QS3WeabfBmC0,53397
383
+ wbportfolio/tests/models/test_portfolios.py,sha256=h9iaSyZiEAfksCM6sFnQk2gci1UMth3dcmEabNhlwr0,53395
384
384
  wbportfolio/tests/models/test_product_groups.py,sha256=AcdxhurV-n_bBuUsfD1GqVtwLFcs7VI2CRrwzsIUWbU,3337
385
385
  wbportfolio/tests/models/test_products.py,sha256=IcBzw9hrGiWFMRwPBTMukCMWrhqnjOVA2hhb90xYOW8,9580
386
386
  wbportfolio/tests/models/test_roles.py,sha256=4Cn7WyrA2ztJNeWLk5cy9kYo5XLWMbFSvo1O-9JYxeA,3323
@@ -522,7 +522,7 @@ wbportfolio/viewsets/transactions/mixins.py,sha256=WipvJoi5hylkpD0y9VATe30WAcwIH
522
522
  wbportfolio/viewsets/transactions/rebalancing.py,sha256=6rIrdK0rtKL1afJ-tYfAGdQVTN2MH1kG_yCeVkmyK8k,1263
523
523
  wbportfolio/viewsets/transactions/trade_proposals.py,sha256=eDEIEUyMP70oEdwscnE8oR7pBStr7IjHNFMxu2JbJlY,6232
524
524
  wbportfolio/viewsets/transactions/trades.py,sha256=GHOw5jtcqoaHiRrxxxL29c9405QiPisEn4coGELKDrE,22146
525
- wbportfolio-1.54.4.dist-info/METADATA,sha256=N_ZubDWqgnEeWE58IyCdWzurZlbqE82G1vjnkT3dIok,702
526
- wbportfolio-1.54.4.dist-info/WHEEL,sha256=tkmg4JIqwd9H8mL30xA7crRmoStyCtGp0VWshokd1Jc,105
527
- wbportfolio-1.54.4.dist-info/licenses/LICENSE,sha256=jvfVH0SY8_YMHlsJHKe_OajiscQDz4lpTlqT6x24sVw,172
528
- wbportfolio-1.54.4.dist-info/RECORD,,
525
+ wbportfolio-1.54.5.dist-info/METADATA,sha256=Xk4aluvUoetd-3x6_M3IK2zuIvQsItNvg3713TNUA98,702
526
+ wbportfolio-1.54.5.dist-info/WHEEL,sha256=tkmg4JIqwd9H8mL30xA7crRmoStyCtGp0VWshokd1Jc,105
527
+ wbportfolio-1.54.5.dist-info/licenses/LICENSE,sha256=jvfVH0SY8_YMHlsJHKe_OajiscQDz4lpTlqT6x24sVw,172
528
+ wbportfolio-1.54.5.dist-info/RECORD,,