wbportfolio 1.54.20__py2.py3-none-any.whl → 1.54.21__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/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 +258 -0
- wbportfolio/models/orders/order_proposals.py +39 -33
- wbportfolio/models/orders/orders.py +18 -21
- wbportfolio/models/portfolio.py +108 -232
- 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/orders/configs/displays/order_proposals.py +6 -5
- wbportfolio/viewsets/orders/orders.py +1 -1
- {wbportfolio-1.54.20.dist-info → wbportfolio-1.54.21.dist-info}/METADATA +1 -1
- {wbportfolio-1.54.20.dist-info → wbportfolio-1.54.21.dist-info}/RECORD +16 -13
- {wbportfolio-1.54.20.dist-info → wbportfolio-1.54.21.dist-info}/WHEEL +0 -0
- {wbportfolio-1.54.20.dist-info → wbportfolio-1.54.21.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,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),
|
|
@@ -262,14 +262,17 @@ wbportfolio/migrations/0080_alter_trade_drift_factor_alter_trade_weighting.py,sh
|
|
|
262
262
|
wbportfolio/migrations/0081_alter_trade_drift_factor.py,sha256=rF3HA1MQJ0hltr0dExJAx47w8XxUCWRbDUyxQLoQB2I,656
|
|
263
263
|
wbportfolio/migrations/0082_remove_tradeproposal_creator_and_more.py,sha256=DZBKD0LG1aXQ2bR7UwYwdVobiCCtKDBMLHDZRmFQRKQ,4108
|
|
264
264
|
wbportfolio/migrations/0083_order_alter_trade_options_and_more.py,sha256=oFYG2cVf2CFKFJX84eUSmGJdK1BHY_QcVm_hmAIbVNg,9952
|
|
265
|
+
wbportfolio/migrations/0084_orderproposal_min_order_value.py,sha256=bJPpPX7PQmlWAIyLzZ6ca6K0paGTRbzS8AkyOHDoGMc,925
|
|
266
|
+
wbportfolio/migrations/0085_order_desired_target_weight.py,sha256=L8p5t4PqjWIwqwiqt-ofdfGkBhm-7dtbg52cIkxNnDs,803
|
|
265
267
|
wbportfolio/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
266
268
|
wbportfolio/models/__init__.py,sha256=qU4e7HKyh8NL_0Mg92PcbHTewCv7Ya2gei1DMGe1LWE,980
|
|
267
269
|
wbportfolio/models/adjustments.py,sha256=osXWkJZOiansPWYPyHtl7Z121zDWi7u1YMtrBQtbHVo,10272
|
|
268
|
-
wbportfolio/models/asset.py,sha256=
|
|
270
|
+
wbportfolio/models/asset.py,sha256=PwL16w2Rw_rJL73e0vCWMlRqsCxKW4zA9bf1EgTzD60,39574
|
|
271
|
+
wbportfolio/models/builder.py,sha256=n4__dW8L3hiM8U2_xhUPmR3Gt67pDI0vv5fejzoqah8,11536
|
|
269
272
|
wbportfolio/models/custodians.py,sha256=owTiS2Vm5CRKzh9M_P9GOVg-s-ndQ9UvRmw3yZP7cw0,3815
|
|
270
273
|
wbportfolio/models/exceptions.py,sha256=3ix0tWUO-O6jpz8f07XIwycw2x3JFRoWzjwil8FVA2Q,52
|
|
271
274
|
wbportfolio/models/indexes.py,sha256=gvW4K9U9Bj8BmVCqFYdWiXvDWhjHINRON8XhNsZUiQY,639
|
|
272
|
-
wbportfolio/models/portfolio.py,sha256=
|
|
275
|
+
wbportfolio/models/portfolio.py,sha256=XIRR2r0yDgE1zdZ5WZUeaas0ZdRGOm0Ps6bvkgg7fQc,53046
|
|
273
276
|
wbportfolio/models/portfolio_cash_flow.py,sha256=uElG7IJUBY8qvtrXftOoskX6EA-dKgEG1JJdvHeWV7g,7336
|
|
274
277
|
wbportfolio/models/portfolio_cash_targets.py,sha256=WmgG-etPisZsh2yaFQpz7EkpvAudKBEzqPsO715w52U,1498
|
|
275
278
|
wbportfolio/models/portfolio_relationship.py,sha256=ZGECiPZiLdlk4uSamOrEfuzO0hduK6OMKJLUSnh5_kc,5190
|
|
@@ -289,8 +292,8 @@ wbportfolio/models/mixins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
|
|
|
289
292
|
wbportfolio/models/mixins/instruments.py,sha256=SgBreTpa_X3uyCWo7t8B0VaTtl49IjmBMe4Pab6TjAM,6796
|
|
290
293
|
wbportfolio/models/mixins/liquidity_stress_test.py,sha256=iQVzT3QM7VtHnqfj9gT6KUIe4wC4MJXery-AXJHUYns,58820
|
|
291
294
|
wbportfolio/models/orders/__init__.py,sha256=EH9UacGR3npBMje5FGTeLOh1xqFBh9kc24WbGmBIA3g,69
|
|
292
|
-
wbportfolio/models/orders/order_proposals.py,sha256=
|
|
293
|
-
wbportfolio/models/orders/orders.py,sha256=
|
|
295
|
+
wbportfolio/models/orders/order_proposals.py,sha256=nKzeHPcSQav4KkaUXUBWJVxd8ku3GmG5KQKyQ3cvIUM,40467
|
|
296
|
+
wbportfolio/models/orders/orders.py,sha256=8vYyAV1S2ATVD3Ve_Cjtms_mj564yu5pvfK6wtqQx3A,9664
|
|
294
297
|
wbportfolio/models/reconciliations/__init__.py,sha256=MXH5fZIPGDRBgJkO6wVu_NLRs8fkP1im7G6d-h36lQY,127
|
|
295
298
|
wbportfolio/models/reconciliations/account_reconciliation_lines.py,sha256=QP6M7hMcyFbuXBa55Y-azui6Dl_WgbzMntEqWzQkbfM,7394
|
|
296
299
|
wbportfolio/models/reconciliations/account_reconciliations.py,sha256=rofSxetFfEJov6mPyoTvGxELA16HILyJZtQvm_kwYU0,4405
|
|
@@ -361,7 +364,7 @@ wbportfolio/serializers/registers.py,sha256=zhdKH_mHEBE0VOhm6xpY54bTMtcSaY5BskEa
|
|
|
361
364
|
wbportfolio/serializers/roles.py,sha256=T-9NqTldpvaEMFy-Bib5MB6MeboygEOqcMP61mzzD3Q,2146
|
|
362
365
|
wbportfolio/serializers/signals.py,sha256=hD6R4oFtwhvnsJPteytPKy2JwEelmxrapdfoLSnluaE,7053
|
|
363
366
|
wbportfolio/serializers/orders/__init__.py,sha256=PKJRksA1pWsh8nVfGASoB0m3LyUzVRnq1m9VPp90J7k,271
|
|
364
|
-
wbportfolio/serializers/orders/order_proposals.py,sha256=
|
|
367
|
+
wbportfolio/serializers/orders/order_proposals.py,sha256=MmL8noS2qqyKKXiYLLPRS4_Cz1RhlfdFwkCKZiqRyxQ,4461
|
|
365
368
|
wbportfolio/serializers/orders/orders.py,sha256=pAKjJLRANOo1iMlcv18twuQ0aAVDVKYt-pPx6avnWRQ,7464
|
|
366
369
|
wbportfolio/serializers/transactions/__init__.py,sha256=-7Pan4n7YI3iDvGXff6okzk4ycEURRxp5n_SHCY_g_I,493
|
|
367
370
|
wbportfolio/serializers/transactions/claim.py,sha256=kC4E2RZRrpd9i8tGfoiV-gpWDk3ikR5F1Wf0v_IGIvw,11599
|
|
@@ -397,14 +400,14 @@ wbportfolio/tests/models/test_merge.py,sha256=sdsjiZsmR6vsUKwTa5kkvL6QTeAZqtd_EP
|
|
|
397
400
|
wbportfolio/tests/models/test_portfolio_cash_flow.py,sha256=X8dsXexsb1b0lBiuGzu40ps_Az_1UmmKT0eo1vbXH94,5792
|
|
398
401
|
wbportfolio/tests/models/test_portfolio_cash_targets.py,sha256=q8QWAwt-kKRkLC0E05GyRhF_TTQXIi8bdHjXVU0fCV0,965
|
|
399
402
|
wbportfolio/tests/models/test_portfolio_swing_pricings.py,sha256=kr2AOcQkyg2pX3ULjU-o9ye-NVpjMrrfoe-DVbYCbjs,1656
|
|
400
|
-
wbportfolio/tests/models/test_portfolios.py,sha256=
|
|
403
|
+
wbportfolio/tests/models/test_portfolios.py,sha256=VdfkblwSow1w-HLFto8wssuBTjSqaCBpE1_Tf6wb0R0,51878
|
|
401
404
|
wbportfolio/tests/models/test_product_groups.py,sha256=AcdxhurV-n_bBuUsfD1GqVtwLFcs7VI2CRrwzsIUWbU,3337
|
|
402
405
|
wbportfolio/tests/models/test_products.py,sha256=IcBzw9hrGiWFMRwPBTMukCMWrhqnjOVA2hhb90xYOW8,9580
|
|
403
406
|
wbportfolio/tests/models/test_roles.py,sha256=4Cn7WyrA2ztJNeWLk5cy9kYo5XLWMbFSvo1O-9JYxeA,3323
|
|
404
407
|
wbportfolio/tests/models/test_splits.py,sha256=ytKcHsI_90kj1L4s8It-KEcc24rkDcElxwQ8q0QxEvk,9689
|
|
405
408
|
wbportfolio/tests/models/utils.py,sha256=ORNJq6NMo1Za22jGZXfTfKeNEnTRlfEt_8SJ6xLaQWg,325
|
|
406
409
|
wbportfolio/tests/models/orders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
407
|
-
wbportfolio/tests/models/orders/test_order_proposals.py,sha256=
|
|
410
|
+
wbportfolio/tests/models/orders/test_order_proposals.py,sha256=T0vo7D65E0Cyqhwq3QK_Fd6RlCzCJRZSbA0PSZft0k4,31316
|
|
408
411
|
wbportfolio/tests/models/transactions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
409
412
|
wbportfolio/tests/models/transactions/test_claim.py,sha256=NG3BKB-FVcIDgHSJHCjImxgMM3ISVUMl24xUPmEcPec,5570
|
|
410
413
|
wbportfolio/tests/models/transactions/test_fees.py,sha256=tAp18x2wCNQr11LUnLtHNbBDbbX0v1DZnmW7i-cEi5Q,2423
|
|
@@ -533,13 +536,13 @@ wbportfolio/viewsets/configs/titles/roles.py,sha256=9LoJa3jgenXJ5UWRlIErTzdbjpSW
|
|
|
533
536
|
wbportfolio/viewsets/configs/titles/trades.py,sha256=29XCLxvY0Xe3a2tjCno3tN2rRXCr9RWpbWnzurJfnYI,1986
|
|
534
537
|
wbportfolio/viewsets/orders/__init__.py,sha256=N8v9jdEXryOzrLlc7ML3iBCO2lmNXph9_TWoQ7PTvi4,195
|
|
535
538
|
wbportfolio/viewsets/orders/order_proposals.py,sha256=mw385zzU52nCq8p6xgionh43xLmOn5aX-2BPlCHnqlE,6214
|
|
536
|
-
wbportfolio/viewsets/orders/orders.py,sha256=
|
|
539
|
+
wbportfolio/viewsets/orders/orders.py,sha256=u3tRqio-oCnmqhC5jmn_EDKoNrF1xXMgOu2c2BfqNS8,10851
|
|
537
540
|
wbportfolio/viewsets/orders/configs/__init__.py,sha256=5MU57JXiKi32_PicHtiNr7YHmMN020FrlF5NFJf_Wds,94
|
|
538
541
|
wbportfolio/viewsets/orders/configs/buttons/__init__.py,sha256=EHzNmAfa0UQFITEF-wxj_s4wn3Y5DE3DCbEUmmvCTIs,106
|
|
539
542
|
wbportfolio/viewsets/orders/configs/buttons/order_proposals.py,sha256=Q_7LrsuLzjSXCIoscFQXMMHl8cuCporDNM5k735W7d8,3584
|
|
540
543
|
wbportfolio/viewsets/orders/configs/buttons/orders.py,sha256=GDO4Y33wkjhDxzpf7B1d_rKzAixegLv5rHam1DV3WkM,290
|
|
541
544
|
wbportfolio/viewsets/orders/configs/displays/__init__.py,sha256=__YJBbz_ZnKpE8WMMDR2PC9Nng-EVlRpGTEQucdrhRA,108
|
|
542
|
-
wbportfolio/viewsets/orders/configs/displays/order_proposals.py,sha256=
|
|
545
|
+
wbportfolio/viewsets/orders/configs/displays/order_proposals.py,sha256=Iy195FwD2KGxxNWYspAj7CKQ0assL_wtQx0hN7KMz9o,4985
|
|
543
546
|
wbportfolio/viewsets/orders/configs/displays/orders.py,sha256=8YW5Sncmowl5eLbnuUkD5xQXnP4P3vM6aBXNvolFG1s,7007
|
|
544
547
|
wbportfolio/viewsets/orders/configs/endpoints/__init__.py,sha256=IB8GEadiEtBDclhkgpcJGXWfCF6qRK_42hxJ4pcdZDU,148
|
|
545
548
|
wbportfolio/viewsets/orders/configs/endpoints/order_proposals.py,sha256=fY3y2YWR9nY-KE8k078NszDsnwOgqOIjHUgLvQjDivU,822
|
|
@@ -551,7 +554,7 @@ wbportfolio/viewsets/transactions/claim.py,sha256=Pb1WftoO-w-ZSTbLRhmQubhy7hgd68
|
|
|
551
554
|
wbportfolio/viewsets/transactions/fees.py,sha256=WT2bWWfgozz4_rpyTKX7dgBBTXD-gu0nlsd2Nk2Zh1Q,7028
|
|
552
555
|
wbportfolio/viewsets/transactions/mixins.py,sha256=WipvJoi5hylkpD0y9VATe30WAcwIHUIroVkK10FYw7k,636
|
|
553
556
|
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.
|
|
557
|
+
wbportfolio-1.54.21.dist-info/METADATA,sha256=5NHNRB4-w5pyBzzP936g_zkFz86kNs3OXQBj7qBTNa8,703
|
|
558
|
+
wbportfolio-1.54.21.dist-info/WHEEL,sha256=tkmg4JIqwd9H8mL30xA7crRmoStyCtGp0VWshokd1Jc,105
|
|
559
|
+
wbportfolio-1.54.21.dist-info/licenses/LICENSE,sha256=jvfVH0SY8_YMHlsJHKe_OajiscQDz4lpTlqT6x24sVw,172
|
|
560
|
+
wbportfolio-1.54.21.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|