wbportfolio 1.54.20__py2.py3-none-any.whl → 1.54.22__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/constants.py +1 -0
- wbportfolio/import_export/parsers/vontobel/valuation_api.py +4 -1
- wbportfolio/migrations/0084_orderproposal_min_order_value.py +25 -0
- wbportfolio/migrations/0085_order_desired_target_weight.py +26 -0
- wbportfolio/models/asset.py +4 -141
- wbportfolio/models/builder.py +260 -0
- wbportfolio/models/orders/order_proposals.py +39 -33
- wbportfolio/models/orders/orders.py +18 -21
- wbportfolio/models/portfolio.py +118 -235
- wbportfolio/serializers/orders/order_proposals.py +1 -0
- wbportfolio/tests/models/orders/test_order_proposals.py +16 -1
- wbportfolio/tests/models/test_portfolios.py +34 -121
- wbportfolio/viewsets/charts/assets.py +2 -2
- wbportfolio/viewsets/orders/configs/displays/order_proposals.py +6 -5
- wbportfolio/viewsets/orders/orders.py +1 -1
- wbportfolio/viewsets/positions.py +3 -2
- {wbportfolio-1.54.20.dist-info → wbportfolio-1.54.22.dist-info}/METADATA +1 -1
- {wbportfolio-1.54.20.dist-info → wbportfolio-1.54.22.dist-info}/RECORD +20 -16
- {wbportfolio-1.54.20.dist-info → wbportfolio-1.54.22.dist-info}/WHEEL +0 -0
- {wbportfolio-1.54.20.dist-info → wbportfolio-1.54.22.dist-info}/licenses/LICENSE +0 -0
|
@@ -5,7 +5,6 @@ from unittest.mock import patch
|
|
|
5
5
|
|
|
6
6
|
import pandas as pd
|
|
7
7
|
import pytest
|
|
8
|
-
from django.contrib.contenttypes.models import ContentType
|
|
9
8
|
from django.db.models import F, Sum
|
|
10
9
|
from django.forms.models import model_to_dict
|
|
11
10
|
from faker import Faker
|
|
@@ -20,9 +19,8 @@ from wbportfolio.models import (
|
|
|
20
19
|
PortfolioPortfolioThroughModel,
|
|
21
20
|
Trade,
|
|
22
21
|
)
|
|
23
|
-
from wbportfolio.models.asset import AssetPositionIterator
|
|
24
22
|
|
|
25
|
-
from ...models.portfolio import
|
|
23
|
+
from ...models.portfolio import update_portfolio_after_investable_universe
|
|
26
24
|
from .utils import PortfolioTestMixin
|
|
27
25
|
|
|
28
26
|
fake = Faker()
|
|
@@ -264,7 +262,9 @@ class TestPortfolioModel(PortfolioTestMixin):
|
|
|
264
262
|
for pos in AssetPosition.objects.all():
|
|
265
263
|
assert float(pos.weighting) == pytest.approx(float(pos.total_value_fx_portfolio / total_value), rel=1e-2)
|
|
266
264
|
|
|
267
|
-
mock_estimate_net_asset_values.assert_called_once_with(
|
|
265
|
+
mock_estimate_net_asset_values.assert_called_once_with(
|
|
266
|
+
portfolio, (weekday + BDay(1)).date(), analytic_portfolio=None
|
|
267
|
+
)
|
|
268
268
|
|
|
269
269
|
@patch.object(Portfolio, "compute_lookthrough", autospec=True)
|
|
270
270
|
def test_change_at_date_with_dependent_portfolio(
|
|
@@ -285,9 +285,6 @@ class TestPortfolioModel(PortfolioTestMixin):
|
|
|
285
285
|
mock_compute_lookthrough.assert_called_once_with(
|
|
286
286
|
dependent_portfolio,
|
|
287
287
|
weekday,
|
|
288
|
-
recompute_weighting=False,
|
|
289
|
-
force_recompute_weighting=False,
|
|
290
|
-
changed_weights=None,
|
|
291
288
|
)
|
|
292
289
|
|
|
293
290
|
def test_is_active_at_date(
|
|
@@ -1005,12 +1002,10 @@ class TestPortfolioModel(PortfolioTestMixin):
|
|
|
1005
1002
|
fx_instrument = currency_fx_rates_factory.create(currency=instrument.currency, date=weekday)
|
|
1006
1003
|
instrument_id: int = instrument.id
|
|
1007
1004
|
weights = {instrument_id: random.random()}
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
)
|
|
1011
|
-
positions.add((weekday, weights))
|
|
1005
|
+
portfolio.builder.set_prices({weekday: {instrument_id: p.net_value}})
|
|
1006
|
+
portfolio.builder.add((weekday, weights), infer_underlying_quote_price=False)
|
|
1012
1007
|
|
|
1013
|
-
res = list(
|
|
1008
|
+
res = list(portfolio.builder.get_positions())
|
|
1014
1009
|
a = res[0]
|
|
1015
1010
|
assert len(res) == 1
|
|
1016
1011
|
assert a.date == weekday
|
|
@@ -1053,35 +1048,34 @@ class TestPortfolioModel(PortfolioTestMixin):
|
|
|
1053
1048
|
asset_position_factory.create(date=weekday, portfolio=portfolio, underlying_instrument=i2, weighting=0.3)
|
|
1054
1049
|
|
|
1055
1050
|
rebalancer_factory.create(portfolio=portfolio, frequency="RRULE:FREQ=DAILY;", activation_date=rebalancing_date)
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
)
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1051
|
+
portfolio.load_builder_returns(weekday, rebalancing_date)
|
|
1052
|
+
gen = portfolio.drift_weights(weekday, (rebalancing_date + BDay(1)).date(), stop_at_rebalancing=True)
|
|
1053
|
+
assert next(gen)[0] == middle_date, "Drifting weight with a non automatic rebalancer stops the iteration"
|
|
1054
|
+
try:
|
|
1055
|
+
next(gen)
|
|
1056
|
+
assert False, "the next iteration should stop and return the rebalancing"
|
|
1057
|
+
except StopIteration as e:
|
|
1058
|
+
rebalancing_order_proposal = e.value
|
|
1059
|
+
assert rebalancing_order_proposal.trade_date == rebalancing_date
|
|
1060
|
+
assert rebalancing_order_proposal.status == "SUBMIT"
|
|
1061
|
+
|
|
1062
|
+
# we expect a equally rebalancing (default) so both orders needs to be created
|
|
1063
|
+
orders = rebalancing_order_proposal.get_orders()
|
|
1064
|
+
t1 = orders.get(value_date=rebalancing_date, underlying_instrument=i1)
|
|
1065
|
+
t2 = orders.get(value_date=rebalancing_date, underlying_instrument=i2)
|
|
1066
|
+
assert t1._target_weight == Decimal("0.5")
|
|
1067
|
+
assert t2._target_weight == Decimal("0.5")
|
|
1068
|
+
|
|
1069
|
+
# we approve the rebalancing order proposal
|
|
1070
|
+
assert rebalancing_order_proposal.status == "SUBMIT"
|
|
1071
|
+
rebalancing_order_proposal.approve(replay=False)
|
|
1072
|
+
rebalancing_order_proposal.save()
|
|
1076
1073
|
|
|
1077
1074
|
# check that the rebalancing was applied and position reflect that
|
|
1078
1075
|
assert portfolio.assets.get(date=rebalancing_date, underlying_instrument=i1).weighting == Decimal("0.5")
|
|
1079
1076
|
assert portfolio.assets.get(date=rebalancing_date, underlying_instrument=i2).weighting == Decimal("0.5")
|
|
1080
1077
|
|
|
1081
|
-
|
|
1082
|
-
def test_bulk_create_positions(
|
|
1083
|
-
self, mock_compute_metrics, portfolio, weekday, asset_position_factory, instrument_factory
|
|
1084
|
-
):
|
|
1078
|
+
def test_bulk_create_positions(self, portfolio, weekday, asset_position_factory, instrument_factory):
|
|
1085
1079
|
portfolio.is_manageable = False
|
|
1086
1080
|
portfolio.save()
|
|
1087
1081
|
i1 = instrument_factory.create()
|
|
@@ -1090,21 +1084,17 @@ class TestPortfolioModel(PortfolioTestMixin):
|
|
|
1090
1084
|
a1 = asset_position_factory.build(date=weekday, portfolio=portfolio, underlying_instrument=i1)
|
|
1091
1085
|
|
|
1092
1086
|
# check initial creation
|
|
1093
|
-
portfolio.
|
|
1087
|
+
portfolio.builder.add([a1]).bulk_create_positions(compute_metrics=True)
|
|
1094
1088
|
assert AssetPosition.objects.get(portfolio=portfolio, date=weekday).weighting == a1.weighting
|
|
1095
1089
|
assert AssetPosition.objects.get(portfolio=portfolio, date=weekday).underlying_instrument == i1
|
|
1096
1090
|
|
|
1097
|
-
mock_compute_metrics.assert_called_once_with(
|
|
1098
|
-
weekday, basket_id=portfolio.id, basket_content_type_id=ContentType.objects.get_for_model(Portfolio).id
|
|
1099
|
-
)
|
|
1100
|
-
|
|
1101
1091
|
# check that if we change key value, an already exising position will be updated accordingly
|
|
1102
1092
|
a1.weighting = Decimal(0.5)
|
|
1103
|
-
portfolio.
|
|
1093
|
+
portfolio.builder.add([a1]).bulk_create_positions()
|
|
1104
1094
|
assert AssetPosition.objects.get(portfolio=portfolio, date=weekday).weighting == Decimal(0.5)
|
|
1105
1095
|
|
|
1106
1096
|
a2 = asset_position_factory.build(date=weekday, portfolio=portfolio, underlying_instrument=i2)
|
|
1107
|
-
portfolio.
|
|
1097
|
+
portfolio.builder.add([a2]).bulk_create_positions()
|
|
1108
1098
|
assert (
|
|
1109
1099
|
AssetPosition.objects.get(portfolio=portfolio, date=weekday, underlying_instrument=i1).weighting
|
|
1110
1100
|
== a1.weighting
|
|
@@ -1115,7 +1105,7 @@ class TestPortfolioModel(PortfolioTestMixin):
|
|
|
1115
1105
|
)
|
|
1116
1106
|
|
|
1117
1107
|
a3 = asset_position_factory.build(date=weekday, portfolio=portfolio, underlying_instrument=i3)
|
|
1118
|
-
portfolio.
|
|
1108
|
+
portfolio.builder.add([a3]).bulk_create_positions(delete_leftovers=True)
|
|
1119
1109
|
assert AssetPosition.objects.get(portfolio=portfolio, date=weekday).weighting == a3.weighting
|
|
1120
1110
|
assert AssetPosition.objects.get(portfolio=portfolio, date=weekday).underlying_instrument == i3
|
|
1121
1111
|
|
|
@@ -1134,83 +1124,6 @@ class TestPortfolioModel(PortfolioTestMixin):
|
|
|
1134
1124
|
res = list(Portfolio.objects.all().to_dependency_iterator(weekday))
|
|
1135
1125
|
assert res == [index_portfolio, dependency_portfolio, dependant_portfolio, undependant_portfolio]
|
|
1136
1126
|
|
|
1137
|
-
def test_get_returns(self, instrument_factory, instrument_price_factory, asset_position_factory, portfolio):
|
|
1138
|
-
v1 = date(2024, 12, 31)
|
|
1139
|
-
v2 = date(2025, 1, 1)
|
|
1140
|
-
v3 = date(2025, 1, 2)
|
|
1141
|
-
v4 = date(2025, 1, 3)
|
|
1142
|
-
|
|
1143
|
-
i1 = instrument_factory.create()
|
|
1144
|
-
i2 = instrument_factory.create()
|
|
1145
|
-
|
|
1146
|
-
i11 = instrument_price_factory.create(date=v1, instrument=i1)
|
|
1147
|
-
i12 = instrument_price_factory.create(date=v2, instrument=i1)
|
|
1148
|
-
i14 = instrument_price_factory.create(date=v4, instrument=i1)
|
|
1149
|
-
i21 = instrument_price_factory.create(date=v1, instrument=i2)
|
|
1150
|
-
i11.refresh_from_db()
|
|
1151
|
-
i12.refresh_from_db()
|
|
1152
|
-
i14.refresh_from_db()
|
|
1153
|
-
prices, returns = get_returns([i1.id, i2.id], from_date=v1, to_date=v4)
|
|
1154
|
-
|
|
1155
|
-
expected_returns = pd.DataFrame(
|
|
1156
|
-
[[i12.net_value / i11.net_value - 1, 0.0], [0.0, 0.0], [i14.net_value / i12.net_value - 1, 0.0]],
|
|
1157
|
-
index=[v2, v3, v4],
|
|
1158
|
-
columns=[i1.id, i2.id],
|
|
1159
|
-
dtype="float64",
|
|
1160
|
-
)
|
|
1161
|
-
expected_returns.index = pd.to_datetime(expected_returns.index)
|
|
1162
|
-
pd.testing.assert_frame_equal(returns, expected_returns, check_names=False, check_freq=False, atol=1e-6)
|
|
1163
|
-
assert prices[v1][i1.id] == float(i11.net_value)
|
|
1164
|
-
assert prices[v2][i1.id] == float(i12.net_value)
|
|
1165
|
-
assert prices[v3][i1.id] == float(i12.net_value)
|
|
1166
|
-
assert prices[v4][i1.id] == float(i14.net_value)
|
|
1167
|
-
# test that the returned price are ffill
|
|
1168
|
-
assert prices[v1][i2.id] == float(i21.net_value)
|
|
1169
|
-
assert prices[v2][i2.id] == float(i21.net_value)
|
|
1170
|
-
assert prices[v3][i2.id] == float(i21.net_value)
|
|
1171
|
-
assert prices[v4][i2.id] == float(i21.net_value)
|
|
1172
|
-
|
|
1173
|
-
def test_get_returns_fix_forex_on_holiday(
|
|
1174
|
-
self, instrument, instrument_price_factory, currency_fx_rates_factory, currency_factory
|
|
1175
|
-
):
|
|
1176
|
-
v1 = date(2024, 12, 31)
|
|
1177
|
-
v2 = date(2025, 1, 1)
|
|
1178
|
-
v3 = date(2025, 1, 2)
|
|
1179
|
-
|
|
1180
|
-
target_currency = currency_factory.create()
|
|
1181
|
-
fx_target1 = currency_fx_rates_factory.create(currency=target_currency, date=v1)
|
|
1182
|
-
fx_target2 = currency_fx_rates_factory.create(currency=target_currency, date=v2) # noqa
|
|
1183
|
-
fx_target3 = currency_fx_rates_factory.create(currency=target_currency, date=v3)
|
|
1184
|
-
|
|
1185
|
-
fx1 = currency_fx_rates_factory.create(currency=instrument.currency, date=v1)
|
|
1186
|
-
fx2 = currency_fx_rates_factory.create(currency=instrument.currency, date=v2) # noqa
|
|
1187
|
-
fx3 = currency_fx_rates_factory.create(currency=instrument.currency, date=v3)
|
|
1188
|
-
|
|
1189
|
-
i1 = instrument_price_factory.create(net_value=Decimal("100"), date=v1, instrument=instrument)
|
|
1190
|
-
i2 = instrument_price_factory.create(net_value=Decimal("100"), date=v2, instrument=instrument, calculated=True)
|
|
1191
|
-
i3 = instrument_price_factory.create(net_value=Decimal("200"), date=v3, instrument=instrument)
|
|
1192
|
-
|
|
1193
|
-
prices, returns = get_returns([instrument.id], from_date=v1, to_date=v3, to_currency=target_currency)
|
|
1194
|
-
returns.index = pd.to_datetime(returns.index)
|
|
1195
|
-
assert prices[v1][instrument.id] == float(i1.net_value)
|
|
1196
|
-
assert prices[v2][instrument.id] == float(i2.net_value)
|
|
1197
|
-
assert prices[v3][instrument.id] == float(i3.net_value)
|
|
1198
|
-
|
|
1199
|
-
assert returns.loc[pd.Timestamp(v2), instrument.id] == pytest.approx(
|
|
1200
|
-
float(
|
|
1201
|
-
(i2.net_value * fx_target1.value / fx1.value) / (i1.net_value * fx_target1.value / fx1.value)
|
|
1202
|
-
- Decimal("1")
|
|
1203
|
-
),
|
|
1204
|
-
abs=10e-8,
|
|
1205
|
-
) # as v2 as a calculated price, the forex won't apply to it
|
|
1206
|
-
assert returns.loc[pd.Timestamp(v3), instrument.id] == pytest.approx(
|
|
1207
|
-
float(
|
|
1208
|
-
(i3.net_value * fx_target3.value / fx3.value) / (i2.net_value * fx_target1.value / fx1.value)
|
|
1209
|
-
- Decimal("1")
|
|
1210
|
-
),
|
|
1211
|
-
abs=10e-8,
|
|
1212
|
-
)
|
|
1213
|
-
|
|
1214
1127
|
@patch.object(Portfolio, "compute_lookthrough", autospec=True)
|
|
1215
1128
|
def test_handle_controlling_portfolio_change_at_date(self, mock_compute_lookthrough, weekday, portfolio_factory):
|
|
1216
1129
|
primary_portfolio = portfolio_factory.create(only_weighting=True)
|
|
@@ -15,7 +15,6 @@ from wbfdm.models import (
|
|
|
15
15
|
ClassificationGroup,
|
|
16
16
|
Instrument,
|
|
17
17
|
InstrumentClassificationThroughModel,
|
|
18
|
-
InstrumentType,
|
|
19
18
|
)
|
|
20
19
|
|
|
21
20
|
from wbportfolio.filters.assets import DistributionFilter
|
|
@@ -26,6 +25,7 @@ from wbportfolio.models import (
|
|
|
26
25
|
PortfolioRole,
|
|
27
26
|
)
|
|
28
27
|
|
|
28
|
+
from ...constants import EQUITY_TYPE_KEYS
|
|
29
29
|
from ..configs.buttons.assets import (
|
|
30
30
|
DistributionChartButtonConfig,
|
|
31
31
|
DistributionTableButtonConfig,
|
|
@@ -70,7 +70,7 @@ class AbstractDistributionMixin:
|
|
|
70
70
|
|
|
71
71
|
def _generate_classification_df(self, queryset):
|
|
72
72
|
df = pd.DataFrame(
|
|
73
|
-
queryset.filter(
|
|
73
|
+
queryset.filter(underlying_instrument__instrument_type__key__in=EQUITY_TYPE_KEYS).values(
|
|
74
74
|
"weighting", "underlying_instrument"
|
|
75
75
|
),
|
|
76
76
|
columns=["weighting", "underlying_instrument"],
|
|
@@ -15,6 +15,7 @@ class OrderProposalDisplayConfig(DisplayViewConfig):
|
|
|
15
15
|
return dp.ListDisplay(
|
|
16
16
|
fields=[
|
|
17
17
|
dp.Field(key="trade_date", label="Order Date"),
|
|
18
|
+
dp.Field(key="rebalancing_model", label="Rebalancing Model"),
|
|
18
19
|
dp.Field(key="comment", label="Comment"),
|
|
19
20
|
],
|
|
20
21
|
legends=[
|
|
@@ -86,12 +87,12 @@ class OrderProposalDisplayConfig(DisplayViewConfig):
|
|
|
86
87
|
layouts={
|
|
87
88
|
default(): Layout(
|
|
88
89
|
grid_template_areas=[
|
|
89
|
-
["status", "status"],
|
|
90
|
-
["trade_date", "total_cash_weight"],
|
|
91
|
-
["rebalancing_model", "target_portfolio"]
|
|
90
|
+
["status", "status", "status"],
|
|
91
|
+
["trade_date", "total_cash_weight", "min_order_value"],
|
|
92
|
+
["rebalancing_model", "target_portfolio", "target_portfolio"]
|
|
92
93
|
if self.view.new_mode
|
|
93
|
-
else ["rebalancing_model", "rebalancing_model"],
|
|
94
|
-
["comment", "comment"],
|
|
94
|
+
else ["rebalancing_model", "rebalancing_model", "rebalancing_model"],
|
|
95
|
+
["comment", "comment", "comment"],
|
|
95
96
|
],
|
|
96
97
|
),
|
|
97
98
|
},
|
|
@@ -150,7 +150,7 @@ class OrderOrderProposalModelViewSet(
|
|
|
150
150
|
},
|
|
151
151
|
"weighting": {
|
|
152
152
|
"Cash Flow": format_number(
|
|
153
|
-
|
|
153
|
+
sum_sell_weight + sum_buy_weight,
|
|
154
154
|
decimal=Order.ORDER_WEIGHTING_PRECISION,
|
|
155
155
|
),
|
|
156
156
|
"Buy": format_number(sum_buy_weight, decimal=Order.ORDER_WEIGHTING_PRECISION),
|
|
@@ -10,7 +10,7 @@ from wbcore.pandas import fields as pf
|
|
|
10
10
|
from wbcore.permissions.permissions import InternalUserPermissionMixin
|
|
11
11
|
from wbcore.serializers import decorator
|
|
12
12
|
from wbcore.utils.strings import format_number
|
|
13
|
-
from wbfdm.models import Classification, ClassificationGroup, Instrument
|
|
13
|
+
from wbfdm.models import Classification, ClassificationGroup, Instrument
|
|
14
14
|
|
|
15
15
|
from wbportfolio.filters import (
|
|
16
16
|
AggregatedAssetPositionLiquidityFilter,
|
|
@@ -19,6 +19,7 @@ from wbportfolio.filters import (
|
|
|
19
19
|
from wbportfolio.filters.positions import GroupbyChoice
|
|
20
20
|
from wbportfolio.models import AssetPosition, Portfolio
|
|
21
21
|
|
|
22
|
+
from ..constants import EQUITY_TYPE_KEYS
|
|
22
23
|
from .configs import (
|
|
23
24
|
AggregatedAssetPositionLiquidityDisplayConfig,
|
|
24
25
|
AggregatedAssetPositionLiquidityEndpointConfig,
|
|
@@ -212,7 +213,7 @@ class AggregatedAssetPositionLiquidityPandasView(InternalUserPermissionMixin, Ex
|
|
|
212
213
|
|
|
213
214
|
# Take the liquidity query for the two dates.
|
|
214
215
|
qs_assets = queryset.filter(
|
|
215
|
-
|
|
216
|
+
underlying_instrument__instrument_type__key__in=EQUITY_TYPE_KEYS,
|
|
216
217
|
date__in=[historic_date, compared_date],
|
|
217
218
|
).values(
|
|
218
219
|
"date",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
wbportfolio/__init__.py,sha256=J-j-u0itpEFT6irdmWmixQqYMadNl1X91TxUmoiLHMI,22
|
|
2
2
|
wbportfolio/apps.py,sha256=tybcoLFiw5tLdGHYV68X96n6jNZqx4BYx7Ao8mPflH8,749
|
|
3
|
+
wbportfolio/constants.py,sha256=86bfJ-xAyJQGv8DDxhVP_BM7Jr_lxQMhe4SkrxpfN_c,119
|
|
3
4
|
wbportfolio/dynamic_preferences_registry.py,sha256=SV-4JWBZBYhXt5cNMglx-yRJhxpejP_jo157ghjq2q0,2294
|
|
4
5
|
wbportfolio/permissions.py,sha256=F147DXfitbw6IdMQGEFfymCJkiG5YGkWKsLdVVliPyw,320
|
|
5
6
|
wbportfolio/preferences.py,sha256=JpowIFTrnjfomogJNrYmmfv7V35bRZNNGL_zooKzEhc,465
|
|
@@ -194,7 +195,7 @@ wbportfolio/import_export/parsers/vontobel/performance_fees.py,sha256=K-E7bRs7Lx
|
|
|
194
195
|
wbportfolio/import_export/parsers/vontobel/trade.py,sha256=Xc0ttSkdLm-ZIHtXOyHxHr3FuR89T87I9hXqiTMU1Hk,1566
|
|
195
196
|
wbportfolio/import_export/parsers/vontobel/utils.py,sha256=3-g2Jep9SxvqqQff8_3FjIeiPxSJCEfXBiBHIk0TiXQ,225
|
|
196
197
|
wbportfolio/import_export/parsers/vontobel/valuation.py,sha256=iav8_xYpTJchmTa7KOPmFr1gi9xxLwq3e-VcZ9MDiRk,1220
|
|
197
|
-
wbportfolio/import_export/parsers/vontobel/valuation_api.py,sha256=
|
|
198
|
+
wbportfolio/import_export/parsers/vontobel/valuation_api.py,sha256=z9b5zKS-Dz907Mrbg7rJjFVJocSutEiS6oo2ICTjpUI,980
|
|
198
199
|
wbportfolio/import_export/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
199
200
|
wbportfolio/import_export/resources/assets.py,sha256=zjgHlQWpud41jHrKdRyqGUt1KUJQm9Z7pt0uVh4qBWQ,2234
|
|
200
201
|
wbportfolio/import_export/resources/trades.py,sha256=-HJPVYNuMRmCu4XpD00fYlRYu3N-Ys_JpyxE0HIU5bM,1723
|
|
@@ -262,14 +263,17 @@ wbportfolio/migrations/0080_alter_trade_drift_factor_alter_trade_weighting.py,sh
|
|
|
262
263
|
wbportfolio/migrations/0081_alter_trade_drift_factor.py,sha256=rF3HA1MQJ0hltr0dExJAx47w8XxUCWRbDUyxQLoQB2I,656
|
|
263
264
|
wbportfolio/migrations/0082_remove_tradeproposal_creator_and_more.py,sha256=DZBKD0LG1aXQ2bR7UwYwdVobiCCtKDBMLHDZRmFQRKQ,4108
|
|
264
265
|
wbportfolio/migrations/0083_order_alter_trade_options_and_more.py,sha256=oFYG2cVf2CFKFJX84eUSmGJdK1BHY_QcVm_hmAIbVNg,9952
|
|
266
|
+
wbportfolio/migrations/0084_orderproposal_min_order_value.py,sha256=bJPpPX7PQmlWAIyLzZ6ca6K0paGTRbzS8AkyOHDoGMc,925
|
|
267
|
+
wbportfolio/migrations/0085_order_desired_target_weight.py,sha256=L8p5t4PqjWIwqwiqt-ofdfGkBhm-7dtbg52cIkxNnDs,803
|
|
265
268
|
wbportfolio/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
266
269
|
wbportfolio/models/__init__.py,sha256=qU4e7HKyh8NL_0Mg92PcbHTewCv7Ya2gei1DMGe1LWE,980
|
|
267
270
|
wbportfolio/models/adjustments.py,sha256=osXWkJZOiansPWYPyHtl7Z121zDWi7u1YMtrBQtbHVo,10272
|
|
268
|
-
wbportfolio/models/asset.py,sha256=
|
|
271
|
+
wbportfolio/models/asset.py,sha256=PwL16w2Rw_rJL73e0vCWMlRqsCxKW4zA9bf1EgTzD60,39574
|
|
272
|
+
wbportfolio/models/builder.py,sha256=gGBlU0s5kvMxUas2lil0n98BxVjVocUDfU9oHKgkkJY,11622
|
|
269
273
|
wbportfolio/models/custodians.py,sha256=owTiS2Vm5CRKzh9M_P9GOVg-s-ndQ9UvRmw3yZP7cw0,3815
|
|
270
274
|
wbportfolio/models/exceptions.py,sha256=3ix0tWUO-O6jpz8f07XIwycw2x3JFRoWzjwil8FVA2Q,52
|
|
271
275
|
wbportfolio/models/indexes.py,sha256=gvW4K9U9Bj8BmVCqFYdWiXvDWhjHINRON8XhNsZUiQY,639
|
|
272
|
-
wbportfolio/models/portfolio.py,sha256=
|
|
276
|
+
wbportfolio/models/portfolio.py,sha256=7PRPI8sNe4Ehe39-VJ14uPyG4gXqc3uMvwqS7pCy9yg,53266
|
|
273
277
|
wbportfolio/models/portfolio_cash_flow.py,sha256=uElG7IJUBY8qvtrXftOoskX6EA-dKgEG1JJdvHeWV7g,7336
|
|
274
278
|
wbportfolio/models/portfolio_cash_targets.py,sha256=WmgG-etPisZsh2yaFQpz7EkpvAudKBEzqPsO715w52U,1498
|
|
275
279
|
wbportfolio/models/portfolio_relationship.py,sha256=ZGECiPZiLdlk4uSamOrEfuzO0hduK6OMKJLUSnh5_kc,5190
|
|
@@ -289,8 +293,8 @@ wbportfolio/models/mixins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
|
|
|
289
293
|
wbportfolio/models/mixins/instruments.py,sha256=SgBreTpa_X3uyCWo7t8B0VaTtl49IjmBMe4Pab6TjAM,6796
|
|
290
294
|
wbportfolio/models/mixins/liquidity_stress_test.py,sha256=iQVzT3QM7VtHnqfj9gT6KUIe4wC4MJXery-AXJHUYns,58820
|
|
291
295
|
wbportfolio/models/orders/__init__.py,sha256=EH9UacGR3npBMje5FGTeLOh1xqFBh9kc24WbGmBIA3g,69
|
|
292
|
-
wbportfolio/models/orders/order_proposals.py,sha256=
|
|
293
|
-
wbportfolio/models/orders/orders.py,sha256=
|
|
296
|
+
wbportfolio/models/orders/order_proposals.py,sha256=nKzeHPcSQav4KkaUXUBWJVxd8ku3GmG5KQKyQ3cvIUM,40467
|
|
297
|
+
wbportfolio/models/orders/orders.py,sha256=8vYyAV1S2ATVD3Ve_Cjtms_mj564yu5pvfK6wtqQx3A,9664
|
|
294
298
|
wbportfolio/models/reconciliations/__init__.py,sha256=MXH5fZIPGDRBgJkO6wVu_NLRs8fkP1im7G6d-h36lQY,127
|
|
295
299
|
wbportfolio/models/reconciliations/account_reconciliation_lines.py,sha256=QP6M7hMcyFbuXBa55Y-azui6Dl_WgbzMntEqWzQkbfM,7394
|
|
296
300
|
wbportfolio/models/reconciliations/account_reconciliations.py,sha256=rofSxetFfEJov6mPyoTvGxELA16HILyJZtQvm_kwYU0,4405
|
|
@@ -361,7 +365,7 @@ wbportfolio/serializers/registers.py,sha256=zhdKH_mHEBE0VOhm6xpY54bTMtcSaY5BskEa
|
|
|
361
365
|
wbportfolio/serializers/roles.py,sha256=T-9NqTldpvaEMFy-Bib5MB6MeboygEOqcMP61mzzD3Q,2146
|
|
362
366
|
wbportfolio/serializers/signals.py,sha256=hD6R4oFtwhvnsJPteytPKy2JwEelmxrapdfoLSnluaE,7053
|
|
363
367
|
wbportfolio/serializers/orders/__init__.py,sha256=PKJRksA1pWsh8nVfGASoB0m3LyUzVRnq1m9VPp90J7k,271
|
|
364
|
-
wbportfolio/serializers/orders/order_proposals.py,sha256=
|
|
368
|
+
wbportfolio/serializers/orders/order_proposals.py,sha256=MmL8noS2qqyKKXiYLLPRS4_Cz1RhlfdFwkCKZiqRyxQ,4461
|
|
365
369
|
wbportfolio/serializers/orders/orders.py,sha256=pAKjJLRANOo1iMlcv18twuQ0aAVDVKYt-pPx6avnWRQ,7464
|
|
366
370
|
wbportfolio/serializers/transactions/__init__.py,sha256=-7Pan4n7YI3iDvGXff6okzk4ycEURRxp5n_SHCY_g_I,493
|
|
367
371
|
wbportfolio/serializers/transactions/claim.py,sha256=kC4E2RZRrpd9i8tGfoiV-gpWDk3ikR5F1Wf0v_IGIvw,11599
|
|
@@ -397,14 +401,14 @@ wbportfolio/tests/models/test_merge.py,sha256=sdsjiZsmR6vsUKwTa5kkvL6QTeAZqtd_EP
|
|
|
397
401
|
wbportfolio/tests/models/test_portfolio_cash_flow.py,sha256=X8dsXexsb1b0lBiuGzu40ps_Az_1UmmKT0eo1vbXH94,5792
|
|
398
402
|
wbportfolio/tests/models/test_portfolio_cash_targets.py,sha256=q8QWAwt-kKRkLC0E05GyRhF_TTQXIi8bdHjXVU0fCV0,965
|
|
399
403
|
wbportfolio/tests/models/test_portfolio_swing_pricings.py,sha256=kr2AOcQkyg2pX3ULjU-o9ye-NVpjMrrfoe-DVbYCbjs,1656
|
|
400
|
-
wbportfolio/tests/models/test_portfolios.py,sha256=
|
|
404
|
+
wbportfolio/tests/models/test_portfolios.py,sha256=VdfkblwSow1w-HLFto8wssuBTjSqaCBpE1_Tf6wb0R0,51878
|
|
401
405
|
wbportfolio/tests/models/test_product_groups.py,sha256=AcdxhurV-n_bBuUsfD1GqVtwLFcs7VI2CRrwzsIUWbU,3337
|
|
402
406
|
wbportfolio/tests/models/test_products.py,sha256=IcBzw9hrGiWFMRwPBTMukCMWrhqnjOVA2hhb90xYOW8,9580
|
|
403
407
|
wbportfolio/tests/models/test_roles.py,sha256=4Cn7WyrA2ztJNeWLk5cy9kYo5XLWMbFSvo1O-9JYxeA,3323
|
|
404
408
|
wbportfolio/tests/models/test_splits.py,sha256=ytKcHsI_90kj1L4s8It-KEcc24rkDcElxwQ8q0QxEvk,9689
|
|
405
409
|
wbportfolio/tests/models/utils.py,sha256=ORNJq6NMo1Za22jGZXfTfKeNEnTRlfEt_8SJ6xLaQWg,325
|
|
406
410
|
wbportfolio/tests/models/orders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
407
|
-
wbportfolio/tests/models/orders/test_order_proposals.py,sha256=
|
|
411
|
+
wbportfolio/tests/models/orders/test_order_proposals.py,sha256=T0vo7D65E0Cyqhwq3QK_Fd6RlCzCJRZSbA0PSZft0k4,31316
|
|
408
412
|
wbportfolio/tests/models/transactions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
409
413
|
wbportfolio/tests/models/transactions/test_claim.py,sha256=NG3BKB-FVcIDgHSJHCjImxgMM3ISVUMl24xUPmEcPec,5570
|
|
410
414
|
wbportfolio/tests/models/transactions/test_fees.py,sha256=tAp18x2wCNQr11LUnLtHNbBDbbX0v1DZnmW7i-cEi5Q,2423
|
|
@@ -434,7 +438,7 @@ wbportfolio/viewsets/portfolio_cash_targets.py,sha256=CvHlrDE8qnnnfRpTYnFu-Uu15M
|
|
|
434
438
|
wbportfolio/viewsets/portfolio_relationship.py,sha256=RGyvxd8NfFEs8YdqEvVD3VbrISvAO5UtCTlocSIuWQw,2109
|
|
435
439
|
wbportfolio/viewsets/portfolio_swing_pricing.py,sha256=-57l3WLQZRslIV67OT0ucHE5JXTtTtLvd3t7MppdVn8,357
|
|
436
440
|
wbportfolio/viewsets/portfolios.py,sha256=6aF2Uh0EAdHdX1mMTQrFBlXZ5kmlaCPz49iDvT2CnYM,14438
|
|
437
|
-
wbportfolio/viewsets/positions.py,sha256=
|
|
441
|
+
wbportfolio/viewsets/positions.py,sha256=fYmkcYwNybeEZejMZVvel8yFdr7ob_jG8t6ar7snD58,13236
|
|
438
442
|
wbportfolio/viewsets/product_groups.py,sha256=YvmuXPPy98K1J_rz6YPsx9gNK-tCS2P-wc1uRYgfyo0,2399
|
|
439
443
|
wbportfolio/viewsets/product_performance.py,sha256=dRfRgifjGS1RgZSu9uJRM0SmB7eLnNUkPuqARMO4gyo,28371
|
|
440
444
|
wbportfolio/viewsets/products.py,sha256=V8UFtfqxzs67XaU1JZcJJms1WzeNPeXtNBrQuz4B5mk,20414
|
|
@@ -444,7 +448,7 @@ wbportfolio/viewsets/registers.py,sha256=eOuEhW2McHsOapCKue7M4eazrJnVpCBVxImpFcc
|
|
|
444
448
|
wbportfolio/viewsets/roles.py,sha256=vnzS1mlJMZS3GObrss6SfXOr3KRb-OHB1s4Msvtn7xQ,1556
|
|
445
449
|
wbportfolio/viewsets/signals.py,sha256=URxNz-7tKNBgvaFIE3FItfao3Md0dKQN_eVFwxxiErk,2125
|
|
446
450
|
wbportfolio/viewsets/charts/__init__.py,sha256=mNSpDrsqK-afRxGBfEsfgupUc20xU-JW08FpxIyudok,71
|
|
447
|
-
wbportfolio/viewsets/charts/assets.py,sha256=
|
|
451
|
+
wbportfolio/viewsets/charts/assets.py,sha256=d8y_9N3D3a41S-XUg7AV5GjLHoW44kRJOHTkzpeuemU,10573
|
|
448
452
|
wbportfolio/viewsets/configs/__init__.py,sha256=K5opfVQvgGwSyw3XwDGkv3lo5i9jBxOJXYhLqyCdfeQ,137
|
|
449
453
|
wbportfolio/viewsets/configs/buttons/__init__.py,sha256=hyvpxwh9ss8Q0xcE006qsTLuSsJeWt9saHRcU4g96tA,791
|
|
450
454
|
wbportfolio/viewsets/configs/buttons/adjustments.py,sha256=sUY_3vxqP0kuqs8i5hklfboZI6QiAOrmu30eb29Xupo,492
|
|
@@ -533,13 +537,13 @@ wbportfolio/viewsets/configs/titles/roles.py,sha256=9LoJa3jgenXJ5UWRlIErTzdbjpSW
|
|
|
533
537
|
wbportfolio/viewsets/configs/titles/trades.py,sha256=29XCLxvY0Xe3a2tjCno3tN2rRXCr9RWpbWnzurJfnYI,1986
|
|
534
538
|
wbportfolio/viewsets/orders/__init__.py,sha256=N8v9jdEXryOzrLlc7ML3iBCO2lmNXph9_TWoQ7PTvi4,195
|
|
535
539
|
wbportfolio/viewsets/orders/order_proposals.py,sha256=mw385zzU52nCq8p6xgionh43xLmOn5aX-2BPlCHnqlE,6214
|
|
536
|
-
wbportfolio/viewsets/orders/orders.py,sha256=
|
|
540
|
+
wbportfolio/viewsets/orders/orders.py,sha256=u3tRqio-oCnmqhC5jmn_EDKoNrF1xXMgOu2c2BfqNS8,10851
|
|
537
541
|
wbportfolio/viewsets/orders/configs/__init__.py,sha256=5MU57JXiKi32_PicHtiNr7YHmMN020FrlF5NFJf_Wds,94
|
|
538
542
|
wbportfolio/viewsets/orders/configs/buttons/__init__.py,sha256=EHzNmAfa0UQFITEF-wxj_s4wn3Y5DE3DCbEUmmvCTIs,106
|
|
539
543
|
wbportfolio/viewsets/orders/configs/buttons/order_proposals.py,sha256=Q_7LrsuLzjSXCIoscFQXMMHl8cuCporDNM5k735W7d8,3584
|
|
540
544
|
wbportfolio/viewsets/orders/configs/buttons/orders.py,sha256=GDO4Y33wkjhDxzpf7B1d_rKzAixegLv5rHam1DV3WkM,290
|
|
541
545
|
wbportfolio/viewsets/orders/configs/displays/__init__.py,sha256=__YJBbz_ZnKpE8WMMDR2PC9Nng-EVlRpGTEQucdrhRA,108
|
|
542
|
-
wbportfolio/viewsets/orders/configs/displays/order_proposals.py,sha256=
|
|
546
|
+
wbportfolio/viewsets/orders/configs/displays/order_proposals.py,sha256=Iy195FwD2KGxxNWYspAj7CKQ0assL_wtQx0hN7KMz9o,4985
|
|
543
547
|
wbportfolio/viewsets/orders/configs/displays/orders.py,sha256=8YW5Sncmowl5eLbnuUkD5xQXnP4P3vM6aBXNvolFG1s,7007
|
|
544
548
|
wbportfolio/viewsets/orders/configs/endpoints/__init__.py,sha256=IB8GEadiEtBDclhkgpcJGXWfCF6qRK_42hxJ4pcdZDU,148
|
|
545
549
|
wbportfolio/viewsets/orders/configs/endpoints/order_proposals.py,sha256=fY3y2YWR9nY-KE8k078NszDsnwOgqOIjHUgLvQjDivU,822
|
|
@@ -551,7 +555,7 @@ wbportfolio/viewsets/transactions/claim.py,sha256=Pb1WftoO-w-ZSTbLRhmQubhy7hgd68
|
|
|
551
555
|
wbportfolio/viewsets/transactions/fees.py,sha256=WT2bWWfgozz4_rpyTKX7dgBBTXD-gu0nlsd2Nk2Zh1Q,7028
|
|
552
556
|
wbportfolio/viewsets/transactions/mixins.py,sha256=WipvJoi5hylkpD0y9VATe30WAcwIHUIroVkK10FYw7k,636
|
|
553
557
|
wbportfolio/viewsets/transactions/trades.py,sha256=xBgOGaJ8aEg-2RxEJ4FDaBs4SGwuLasun3nhpis0WQY,12363
|
|
554
|
-
wbportfolio-1.54.
|
|
555
|
-
wbportfolio-1.54.
|
|
556
|
-
wbportfolio-1.54.
|
|
557
|
-
wbportfolio-1.54.
|
|
558
|
+
wbportfolio-1.54.22.dist-info/METADATA,sha256=dHZzJlBfD3drPh9scLSxGZPJNFdLDG_zEIqSzdyiMbo,703
|
|
559
|
+
wbportfolio-1.54.22.dist-info/WHEEL,sha256=tkmg4JIqwd9H8mL30xA7crRmoStyCtGp0VWshokd1Jc,105
|
|
560
|
+
wbportfolio-1.54.22.dist-info/licenses/LICENSE,sha256=jvfVH0SY8_YMHlsJHKe_OajiscQDz4lpTlqT6x24sVw,172
|
|
561
|
+
wbportfolio-1.54.22.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|