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.
- wbportfolio/models/asset.py +2 -1
- wbportfolio/models/transactions/trade_proposals.py +11 -5
- wbportfolio/rebalancing/models/equally_weighted.py +5 -0
- wbportfolio/tests/models/test_portfolios.py +1 -1
- {wbportfolio-1.54.4.dist-info → wbportfolio-1.54.5.dist-info}/METADATA +1 -1
- {wbportfolio-1.54.4.dist-info → wbportfolio-1.54.5.dist-info}/RECORD +8 -8
- {wbportfolio-1.54.4.dist-info → wbportfolio-1.54.5.dist-info}/WHEEL +0 -0
- {wbportfolio-1.54.4.dist-info → wbportfolio-1.54.5.dist-info}/licenses/LICENSE +0 -0
wbportfolio/models/asset.py
CHANGED
|
@@ -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
|
-
|
|
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(
|
|
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
|
-
|
|
793
|
-
)
|
|
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(
|
|
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
|
|
@@ -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=
|
|
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=
|
|
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=
|
|
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=
|
|
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.
|
|
526
|
-
wbportfolio-1.54.
|
|
527
|
-
wbportfolio-1.54.
|
|
528
|
-
wbportfolio-1.54.
|
|
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,,
|
|
File without changes
|
|
File without changes
|