wbportfolio 1.49.2__py2.py3-none-any.whl → 1.49.3__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/rebalancing/models/market_capitalization_weighted.py +20 -13
- {wbportfolio-1.49.2.dist-info → wbportfolio-1.49.3.dist-info}/METADATA +1 -1
- {wbportfolio-1.49.2.dist-info → wbportfolio-1.49.3.dist-info}/RECORD +5 -5
- {wbportfolio-1.49.2.dist-info → wbportfolio-1.49.3.dist-info}/WHEEL +0 -0
- {wbportfolio-1.49.2.dist-info → wbportfolio-1.49.3.dist-info}/licenses/LICENSE +0 -0
|
@@ -3,6 +3,7 @@ from decimal import Decimal
|
|
|
3
3
|
import numpy as np
|
|
4
4
|
import pandas as pd
|
|
5
5
|
from django.db.models import QuerySet
|
|
6
|
+
from pandas._libs.tslibs.offsets import BDay
|
|
6
7
|
from wbfdm.enums import MarketData
|
|
7
8
|
from wbfdm.models import (
|
|
8
9
|
Classification,
|
|
@@ -20,13 +21,15 @@ from wbportfolio.rebalancing.decorators import register
|
|
|
20
21
|
class MarketCapitalizationRebalancing(AbstractRebalancingModel):
|
|
21
22
|
TARGET_CURRENCY: str = "USD"
|
|
22
23
|
|
|
23
|
-
def __init__(self, *args, **kwargs):
|
|
24
|
+
def __init__(self, *args, bypass_exchange_check: bool = False, ffill_market_cap_limit: int = 5, **kwargs):
|
|
24
25
|
super().__init__(*args, **kwargs)
|
|
26
|
+
self.bypass_exchange_check = bypass_exchange_check
|
|
25
27
|
instruments = self._get_instruments(**kwargs)
|
|
26
28
|
self.market_cap_df = pd.DataFrame(
|
|
27
29
|
instruments.dl.market_data(
|
|
28
30
|
values=[MarketData.MARKET_CAPITALIZATION],
|
|
29
|
-
|
|
31
|
+
from_date=self.trade_date - BDay(ffill_market_cap_limit),
|
|
32
|
+
to_date=self.trade_date,
|
|
30
33
|
target_currency=self.TARGET_CURRENCY,
|
|
31
34
|
)
|
|
32
35
|
)
|
|
@@ -38,11 +41,11 @@ class MarketCapitalizationRebalancing(AbstractRebalancingModel):
|
|
|
38
41
|
instrument_ids = list(instruments.values_list("id", flat=True))
|
|
39
42
|
try:
|
|
40
43
|
self.market_cap_df = (
|
|
41
|
-
self.market_cap_df
|
|
42
|
-
.
|
|
43
|
-
.
|
|
44
|
+
self.market_cap_df.sort_values(by="valuation_date")
|
|
45
|
+
.groupby("instrument_id")
|
|
46
|
+
.last()["market_capitalization"]
|
|
44
47
|
)
|
|
45
|
-
self.market_cap_df = self.market_cap_df
|
|
48
|
+
self.market_cap_df = self.market_cap_df.reindex(instrument_ids)
|
|
46
49
|
except (IndexError, KeyError):
|
|
47
50
|
self.market_cap_df = pd.Series(dtype="float64", index=instrument_ids)
|
|
48
51
|
|
|
@@ -92,13 +95,17 @@ class MarketCapitalizationRebalancing(AbstractRebalancingModel):
|
|
|
92
95
|
) # if we are missing any market cap for not-delisted instrument, we consider the rebalancing not valid
|
|
93
96
|
df = df.groupby("exchange", dropna=False)["market_capitalization"].any()
|
|
94
97
|
missing_exchanges = Exchange.objects.filter(id__in=df[~df].index.to_list())
|
|
95
|
-
if
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
98
|
+
# if bypass exchange check is true, we do not care whether an exchange is closed we just care if there are at least one exchange open
|
|
99
|
+
if self.bypass_exchange_check:
|
|
100
|
+
return df.any()
|
|
101
|
+
else:
|
|
102
|
+
if missing_exchanges.exists():
|
|
103
|
+
setattr(
|
|
104
|
+
self,
|
|
105
|
+
"_validation_errors",
|
|
106
|
+
f"Couldn't find any market capitalization for exchanges {', '.join([str(e) for e in missing_exchanges])}",
|
|
107
|
+
)
|
|
108
|
+
return df.all()
|
|
102
109
|
return False
|
|
103
110
|
|
|
104
111
|
def get_target_portfolio(self) -> Portfolio:
|
|
@@ -292,7 +292,7 @@ wbportfolio/rebalancing/decorators.py,sha256=JhQ2vkcIuGBTGvNmpkQerdw2-vLq-RAb0KA
|
|
|
292
292
|
wbportfolio/rebalancing/models/__init__.py,sha256=AQjG7Tu5vlmhqncVoYOjpBKU2UIvgo9FuP2_jD2w-UI,232
|
|
293
293
|
wbportfolio/rebalancing/models/composite.py,sha256=uyF1n3NAFprnAZ3Gl5pNJl0GajelqJspC2NufZ7Tf0s,1636
|
|
294
294
|
wbportfolio/rebalancing/models/equally_weighted.py,sha256=U29MOHJMQMIg7Y7W_8t5K3nXjaznzt4ArIxQSiv0Xok,863
|
|
295
|
-
wbportfolio/rebalancing/models/market_capitalization_weighted.py,sha256=
|
|
295
|
+
wbportfolio/rebalancing/models/market_capitalization_weighted.py,sha256=6ZsR8iJg6l89CsxHqoxJSXlTaj8Pmb8_bFPrXhnxaRs,5295
|
|
296
296
|
wbportfolio/rebalancing/models/model_portfolio.py,sha256=XQdvs03-0M9YUnL4DidwZC4E6k-ANCNcZ--T_aaOXTQ,1233
|
|
297
297
|
wbportfolio/reports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
298
298
|
wbportfolio/reports/monthly_position_report.py,sha256=e7BzjDd6eseUOwLwQJXKvWErQ58YnCsznHU2VtR6izM,2981
|
|
@@ -521,7 +521,7 @@ wbportfolio/viewsets/transactions/rebalancing.py,sha256=6rIrdK0rtKL1afJ-tYfAGdQV
|
|
|
521
521
|
wbportfolio/viewsets/transactions/trade_proposals.py,sha256=iQpC_Thbj56SmM05vPRsF1JZguGBDaTUH3I-_iCHCV0,5958
|
|
522
522
|
wbportfolio/viewsets/transactions/trades.py,sha256=xeEzx7GP34aBNPlDmiUmT86labsbb8_f1U2RCN1Jatg,21494
|
|
523
523
|
wbportfolio/viewsets/transactions/transactions.py,sha256=ixDp-nsNA8t_A06rBCT19hOMJHy0iRmdz1XKdV1OwAs,4450
|
|
524
|
-
wbportfolio-1.49.
|
|
525
|
-
wbportfolio-1.49.
|
|
526
|
-
wbportfolio-1.49.
|
|
527
|
-
wbportfolio-1.49.
|
|
524
|
+
wbportfolio-1.49.3.dist-info/METADATA,sha256=juDIyj3pwmZDS4xegw-suJ-JTKaEKhCfpNKFG6ubqqc,734
|
|
525
|
+
wbportfolio-1.49.3.dist-info/WHEEL,sha256=tkmg4JIqwd9H8mL30xA7crRmoStyCtGp0VWshokd1Jc,105
|
|
526
|
+
wbportfolio-1.49.3.dist-info/licenses/LICENSE,sha256=jvfVH0SY8_YMHlsJHKe_OajiscQDz4lpTlqT6x24sVw,172
|
|
527
|
+
wbportfolio-1.49.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|