wbportfolio 1.44.5__py2.py3-none-any.whl → 1.45.0__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/admin/__init__.py +1 -1
- wbportfolio/admin/asset.py +2 -1
- wbportfolio/admin/custodians.py +1 -0
- wbportfolio/admin/indexes.py +15 -0
- wbportfolio/admin/portfolio.py +12 -7
- wbportfolio/admin/portfolio_relationships.py +1 -0
- wbportfolio/admin/product_groups.py +2 -0
- wbportfolio/admin/products.py +2 -1
- wbportfolio/admin/reconciliations.py +1 -0
- wbportfolio/admin/registers.py +1 -0
- wbportfolio/admin/roles.py +1 -0
- wbportfolio/admin/transactions/__init__.py +1 -0
- wbportfolio/admin/transactions/claim.py +1 -0
- wbportfolio/admin/transactions/dividends.py +1 -0
- wbportfolio/admin/transactions/fees.py +1 -0
- wbportfolio/admin/transactions/rebalancing.py +26 -0
- wbportfolio/admin/transactions/trades.py +4 -3
- wbportfolio/admin/transactions/transactions.py +1 -0
- wbportfolio/analysis/claims.py +2 -1
- wbportfolio/contrib/company_portfolio/models.py +3 -6
- wbportfolio/contrib/company_portfolio/tests/conftest.py +0 -12
- wbportfolio/contrib/company_portfolio/tests/test_models.py +1 -0
- wbportfolio/defaults/fees/default.py +1 -0
- wbportfolio/factories/__init__.py +1 -7
- wbportfolio/factories/adjustments.py +1 -0
- wbportfolio/factories/assets.py +13 -7
- wbportfolio/factories/claim.py +1 -0
- wbportfolio/factories/custodians.py +1 -0
- wbportfolio/factories/dividends.py +1 -0
- wbportfolio/factories/fees.py +1 -0
- wbportfolio/factories/indexes.py +1 -0
- wbportfolio/factories/portfolio_cash_flow.py +1 -0
- wbportfolio/factories/portfolio_cash_targets.py +1 -0
- wbportfolio/factories/portfolio_swing_pricings.py +1 -0
- wbportfolio/factories/portfolios.py +3 -0
- wbportfolio/factories/product_groups.py +1 -0
- wbportfolio/factories/products.py +1 -0
- wbportfolio/factories/rebalancing.py +23 -0
- wbportfolio/factories/reconciliations.py +1 -0
- wbportfolio/factories/roles.py +1 -0
- wbportfolio/factories/trades.py +1 -0
- wbportfolio/factories/transactions.py +1 -0
- wbportfolio/fdm/tasks.py +1 -0
- wbportfolio/filters/__init__.py +1 -1
- wbportfolio/filters/assets.py +8 -9
- wbportfolio/filters/assets_and_net_new_money_progression.py +1 -0
- wbportfolio/filters/custodians.py +1 -0
- wbportfolio/filters/esg.py +1 -0
- wbportfolio/filters/performances.py +7 -6
- wbportfolio/filters/portfolios.py +21 -1
- wbportfolio/filters/positions.py +1 -0
- wbportfolio/filters/products.py +1 -0
- wbportfolio/filters/roles.py +1 -0
- wbportfolio/filters/signals.py +1 -0
- wbportfolio/filters/transactions/claim.py +1 -0
- wbportfolio/filters/transactions/fees.py +1 -0
- wbportfolio/filters/transactions/trades.py +2 -1
- wbportfolio/filters/transactions/transactions.py +1 -0
- wbportfolio/import_export/backends/ubs/mixin.py +1 -0
- wbportfolio/import_export/backends/wbfdm/adjustment.py +1 -0
- wbportfolio/import_export/handlers/asset_position.py +11 -13
- wbportfolio/import_export/handlers/fees.py +1 -0
- wbportfolio/import_export/handlers/portfolio_cash_flow.py +1 -0
- wbportfolio/import_export/handlers/trade.py +1 -0
- wbportfolio/import_export/parsers/jpmorgan/customer_trade.py +1 -0
- wbportfolio/import_export/parsers/jpmorgan/fees.py +1 -0
- wbportfolio/import_export/parsers/jpmorgan/strategy.py +5 -4
- wbportfolio/import_export/parsers/jpmorgan/valuation.py +1 -0
- wbportfolio/import_export/parsers/leonteq/customer_trade.py +1 -0
- wbportfolio/import_export/parsers/leonteq/equity.py +13 -12
- wbportfolio/import_export/parsers/leonteq/fees.py +1 -0
- wbportfolio/import_export/parsers/leonteq/trade.py +1 -0
- wbportfolio/import_export/parsers/leonteq/valuation.py +1 -0
- wbportfolio/import_export/parsers/natixis/customer_trade.py +1 -0
- wbportfolio/import_export/parsers/natixis/d1_customer_trade.py +1 -0
- wbportfolio/import_export/parsers/natixis/d1_equity.py +3 -2
- wbportfolio/import_export/parsers/natixis/d1_fees.py +1 -0
- wbportfolio/import_export/parsers/natixis/d1_trade.py +1 -0
- wbportfolio/import_export/parsers/natixis/d1_valuation.py +1 -0
- wbportfolio/import_export/parsers/natixis/equity.py +5 -5
- wbportfolio/import_export/parsers/natixis/trade.py +1 -0
- wbportfolio/import_export/parsers/natixis/utils.py +8 -7
- wbportfolio/import_export/parsers/sg_lux/custodian_positions.py +1 -0
- wbportfolio/import_export/parsers/sg_lux/customer_trade.py +1 -0
- wbportfolio/import_export/parsers/sg_lux/customer_trade_pending_slk.py +2 -1
- wbportfolio/import_export/parsers/sg_lux/customer_trade_slk.py +2 -1
- wbportfolio/import_export/parsers/sg_lux/customer_trade_without_pw.py +1 -0
- wbportfolio/import_export/parsers/sg_lux/equity.py +7 -8
- wbportfolio/import_export/parsers/sg_lux/portfolio_cash_flow.py +1 -0
- wbportfolio/import_export/parsers/sg_lux/portfolio_future_cash_flow.py +1 -0
- wbportfolio/import_export/parsers/sg_lux/registers.py +2 -1
- wbportfolio/import_export/parsers/societe_generale/customer_trade.py +1 -0
- wbportfolio/import_export/parsers/societe_generale/strategy.py +8 -9
- wbportfolio/import_export/parsers/societe_generale/valuation.py +1 -0
- wbportfolio/import_export/parsers/tellco/equity.py +5 -4
- wbportfolio/import_export/parsers/ubs/api/asset_position.py +15 -14
- wbportfolio/import_export/parsers/ubs/api/fees.py +1 -0
- wbportfolio/import_export/parsers/ubs/customer_trade.py +1 -0
- wbportfolio/import_export/parsers/ubs/equity.py +3 -2
- wbportfolio/import_export/parsers/ubs/historical_customer_trade.py +1 -0
- wbportfolio/import_export/parsers/ubs/valuation.py +1 -0
- wbportfolio/import_export/parsers/vontobel/asset_position.py +19 -19
- wbportfolio/import_export/parsers/vontobel/customer_trade.py +1 -0
- wbportfolio/import_export/parsers/vontobel/historical_customer_trade.py +1 -0
- wbportfolio/import_export/parsers/vontobel/management_fees.py +1 -0
- wbportfolio/import_export/parsers/vontobel/performance_fees.py +1 -0
- wbportfolio/import_export/parsers/vontobel/trade.py +1 -0
- wbportfolio/import_export/parsers/vontobel/valuation_api.py +20 -0
- wbportfolio/import_export/resources/assets.py +4 -3
- wbportfolio/import_export/resources/trades.py +1 -0
- wbportfolio/metric/backends/base.py +1 -0
- wbportfolio/metric/backends/portfolio_base.py +1 -0
- wbportfolio/metric/backends/portfolio_esg.py +1 -0
- wbportfolio/metric/tests/test_portfolio_base.py +1 -0
- wbportfolio/migrations/0052_remove_cash_instrument_ptr_and_more.py +1 -131
- wbportfolio/migrations/0067_assetposition_unique_asset_position.py +1 -1
- wbportfolio/migrations/0070_remove_assetposition_unique_asset_position_and_more.py +1 -1
- wbportfolio/migrations/0073_remove_product_price_computation_and_more.py +407 -0
- wbportfolio/models/__init__.py +0 -5
- wbportfolio/models/adjustments.py +8 -2
- wbportfolio/models/asset.py +117 -98
- wbportfolio/models/graphs/portfolio.py +144 -0
- wbportfolio/models/graphs/utils.py +83 -0
- wbportfolio/models/indexes.py +2 -13
- wbportfolio/models/mixins/instruments.py +28 -8
- wbportfolio/models/portfolio.py +538 -332
- wbportfolio/models/portfolio_cash_flow.py +1 -0
- wbportfolio/models/portfolio_relationship.py +6 -2
- wbportfolio/models/product_groups.py +3 -2
- wbportfolio/models/products.py +3 -17
- wbportfolio/models/reconciliations/account_reconciliation_lines.py +1 -0
- wbportfolio/models/reconciliations/account_reconciliations.py +1 -0
- wbportfolio/models/registers.py +1 -0
- wbportfolio/models/transactions/__init__.py +1 -0
- wbportfolio/models/transactions/claim.py +8 -8
- wbportfolio/models/transactions/dividends.py +1 -0
- wbportfolio/models/transactions/fees.py +1 -0
- wbportfolio/models/transactions/rebalancing.py +153 -0
- wbportfolio/models/transactions/trade_proposals.py +153 -155
- wbportfolio/models/transactions/trades.py +48 -40
- wbportfolio/models/transactions/transactions.py +6 -12
- wbportfolio/models/utils.py +1 -0
- wbportfolio/pms/analytics/__init__.py +0 -0
- wbportfolio/pms/analytics/portfolio.py +28 -0
- wbportfolio/pms/trading/handler.py +13 -16
- wbportfolio/pms/typing.py +13 -29
- wbportfolio/rebalancing/__init__.py +0 -0
- wbportfolio/rebalancing/base.py +16 -0
- wbportfolio/rebalancing/decorators.py +17 -0
- wbportfolio/rebalancing/models/__init__.py +3 -0
- wbportfolio/rebalancing/models/composite.py +31 -0
- wbportfolio/rebalancing/models/equally_weighted.py +21 -0
- wbportfolio/rebalancing/models/model_portfolio.py +35 -0
- wbportfolio/reports/monthly_position_report.py +1 -1
- wbportfolio/risk_management/backends/accounts.py +7 -6
- wbportfolio/risk_management/backends/controversy_portfolio.py +1 -0
- wbportfolio/risk_management/backends/exposure_portfolio.py +1 -0
- wbportfolio/risk_management/backends/instrument_list_portfolio.py +1 -0
- wbportfolio/risk_management/backends/liquidity_risk.py +1 -0
- wbportfolio/risk_management/backends/liquidity_stress_instrument.py +1 -0
- wbportfolio/risk_management/backends/mixins.py +1 -0
- wbportfolio/risk_management/backends/product_integrity.py +6 -1
- wbportfolio/risk_management/backends/stop_loss_instrument.py +1 -0
- wbportfolio/risk_management/backends/stop_loss_portfolio.py +1 -0
- wbportfolio/risk_management/backends/ucits_portfolio.py +1 -0
- wbportfolio/risk_management/tests/test_accounts.py +1 -0
- wbportfolio/risk_management/tests/test_controversy_portfolio.py +1 -0
- wbportfolio/risk_management/tests/test_exposure_portfolio.py +1 -0
- wbportfolio/risk_management/tests/test_instrument_list_portfolio.py +1 -0
- wbportfolio/risk_management/tests/test_liquidity_risk.py +1 -0
- wbportfolio/risk_management/tests/test_product_integrity.py +1 -0
- wbportfolio/risk_management/tests/test_stop_loss_instrument.py +1 -0
- wbportfolio/risk_management/tests/test_stop_loss_portfolio.py +1 -0
- wbportfolio/risk_management/tests/test_ucits_portfolio.py +1 -0
- wbportfolio/serializers/__init__.py +5 -5
- wbportfolio/serializers/adjustments.py +1 -0
- wbportfolio/serializers/assets.py +18 -19
- wbportfolio/serializers/custodians.py +1 -0
- wbportfolio/serializers/portfolio_cash_flow.py +1 -0
- wbportfolio/serializers/portfolio_cash_targets.py +1 -0
- wbportfolio/serializers/portfolio_relationship.py +1 -0
- wbportfolio/serializers/portfolio_swing_pricing.py +1 -0
- wbportfolio/serializers/portfolios.py +61 -40
- wbportfolio/serializers/positions.py +1 -0
- wbportfolio/serializers/product_group.py +1 -0
- wbportfolio/serializers/products.py +4 -7
- wbportfolio/serializers/rebalancing.py +57 -0
- wbportfolio/serializers/reconciliations.py +2 -1
- wbportfolio/serializers/registers.py +1 -0
- wbportfolio/serializers/roles.py +1 -0
- wbportfolio/serializers/signals.py +10 -15
- wbportfolio/serializers/transactions/__init__.py +1 -1
- wbportfolio/serializers/transactions/claim.py +1 -0
- wbportfolio/serializers/transactions/fees.py +1 -0
- wbportfolio/serializers/transactions/trade_proposals.py +85 -0
- wbportfolio/serializers/transactions/trades.py +9 -51
- wbportfolio/serializers/transactions/transactions.py +4 -3
- wbportfolio/tasks.py +1 -78
- wbportfolio/tests/conftest.py +6 -13
- wbportfolio/tests/models/test_account_reconciliation.py +2 -0
- wbportfolio/tests/models/test_assets.py +27 -19
- wbportfolio/tests/models/test_customer_trades.py +1 -0
- wbportfolio/tests/models/test_imports.py +5 -1
- wbportfolio/tests/models/test_merge.py +5 -4
- wbportfolio/tests/models/test_portfolio_cash_flow.py +8 -6
- wbportfolio/tests/models/test_portfolios.py +594 -154
- wbportfolio/tests/models/test_product_groups.py +1 -0
- wbportfolio/tests/models/test_products.py +6 -3
- wbportfolio/tests/models/test_roles.py +1 -0
- wbportfolio/tests/models/test_splits.py +1 -0
- wbportfolio/tests/models/transactions/test_claim.py +1 -0
- wbportfolio/tests/models/transactions/test_fees.py +1 -0
- wbportfolio/tests/models/transactions/test_rebalancing.py +81 -0
- wbportfolio/tests/models/transactions/test_trades.py +1 -0
- wbportfolio/tests/models/utils.py +1 -0
- wbportfolio/tests/pms/__init__.py +0 -0
- wbportfolio/tests/pms/test_analytics.py +35 -0
- wbportfolio/tests/rebalancing/__init__.py +0 -0
- wbportfolio/tests/rebalancing/test_models.py +127 -0
- wbportfolio/tests/serializers/test_claims.py +1 -0
- wbportfolio/tests/signals.py +1 -7
- wbportfolio/tests/tests.py +2 -0
- wbportfolio/tests/viewsets/test_assets.py +1 -0
- wbportfolio/tests/viewsets/test_performances.py +1 -0
- wbportfolio/tests/viewsets/test_products.py +1 -0
- wbportfolio/tests/viewsets/transactions/test_claims.py +1 -0
- wbportfolio/urls.py +26 -12
- wbportfolio/viewsets/__init__.py +2 -5
- wbportfolio/viewsets/adjustments.py +1 -0
- wbportfolio/viewsets/assets.py +62 -51
- wbportfolio/viewsets/assets_and_net_new_money_progression.py +1 -0
- wbportfolio/viewsets/charts/assets.py +3 -1
- wbportfolio/viewsets/configs/buttons/__init__.py +1 -1
- wbportfolio/viewsets/configs/buttons/assets.py +1 -0
- wbportfolio/viewsets/configs/buttons/custodians.py +1 -0
- wbportfolio/viewsets/configs/buttons/mixins.py +1 -20
- wbportfolio/viewsets/configs/buttons/portfolios.py +90 -76
- wbportfolio/viewsets/configs/buttons/signals.py +1 -0
- wbportfolio/viewsets/configs/buttons/trades.py +1 -0
- wbportfolio/viewsets/configs/display/__init__.py +2 -1
- wbportfolio/viewsets/configs/display/adjustments.py +1 -0
- wbportfolio/viewsets/configs/display/assets.py +7 -6
- wbportfolio/viewsets/configs/display/claim.py +1 -0
- wbportfolio/viewsets/configs/display/portfolios.py +127 -79
- wbportfolio/viewsets/configs/display/product_performance.py +1 -0
- wbportfolio/viewsets/configs/display/rebalancing.py +27 -0
- wbportfolio/viewsets/configs/display/trade_proposals.py +7 -4
- wbportfolio/viewsets/configs/display/trades.py +75 -42
- wbportfolio/viewsets/configs/endpoints/__init__.py +3 -1
- wbportfolio/viewsets/configs/endpoints/claim.py +1 -0
- wbportfolio/viewsets/configs/endpoints/portfolios.py +23 -7
- wbportfolio/viewsets/configs/endpoints/rebalancing.py +6 -0
- wbportfolio/viewsets/configs/endpoints/reconciliations.py +1 -0
- wbportfolio/viewsets/configs/endpoints/trade_proposals.py +1 -0
- wbportfolio/viewsets/configs/endpoints/trades.py +1 -0
- wbportfolio/viewsets/configs/menu/adjustments.py +1 -0
- wbportfolio/viewsets/configs/menu/assets.py +1 -0
- wbportfolio/viewsets/configs/menu/fees.py +1 -0
- wbportfolio/viewsets/configs/menu/portfolio_cash_flow.py +1 -0
- wbportfolio/viewsets/configs/menu/portfolios.py +4 -2
- wbportfolio/viewsets/configs/menu/positions.py +1 -0
- wbportfolio/viewsets/configs/menu/roles.py +1 -0
- wbportfolio/viewsets/configs/menu/transactions.py +1 -0
- wbportfolio/viewsets/configs/previews/portfolios.py +1 -6
- wbportfolio/viewsets/configs/titles/__init__.py +1 -1
- wbportfolio/viewsets/configs/titles/assets.py +1 -0
- wbportfolio/viewsets/configs/titles/fees.py +1 -0
- wbportfolio/viewsets/configs/titles/instrument_prices.py +1 -0
- wbportfolio/viewsets/configs/titles/portfolios.py +13 -11
- wbportfolio/viewsets/configs/titles/roles.py +1 -0
- wbportfolio/viewsets/configs/titles/trades.py +1 -0
- wbportfolio/viewsets/configs/titles/transactions.py +1 -0
- wbportfolio/viewsets/custodians.py +1 -0
- wbportfolio/viewsets/esg.py +1 -0
- wbportfolio/viewsets/mixins.py +1 -0
- wbportfolio/viewsets/portfolio_cash_flow.py +1 -0
- wbportfolio/viewsets/portfolio_cash_targets.py +1 -0
- wbportfolio/viewsets/portfolio_relationship.py +1 -0
- wbportfolio/viewsets/portfolio_swing_pricing.py +1 -0
- wbportfolio/viewsets/portfolios.py +228 -61
- wbportfolio/viewsets/positions.py +3 -2
- wbportfolio/viewsets/product_groups.py +1 -0
- wbportfolio/viewsets/product_performance.py +1 -0
- wbportfolio/viewsets/products.py +1 -0
- wbportfolio/viewsets/reconciliations.py +1 -0
- wbportfolio/viewsets/registers.py +1 -0
- wbportfolio/viewsets/roles.py +1 -0
- wbportfolio/viewsets/signals.py +1 -0
- wbportfolio/viewsets/transactions/__init__.py +1 -0
- wbportfolio/viewsets/transactions/claim.py +2 -1
- wbportfolio/viewsets/transactions/fees.py +1 -0
- wbportfolio/viewsets/transactions/mixins.py +1 -0
- wbportfolio/viewsets/transactions/rebalancing.py +31 -0
- wbportfolio/viewsets/transactions/trade_proposals.py +25 -5
- wbportfolio/viewsets/transactions/trades.py +16 -9
- wbportfolio/viewsets/transactions/transactions.py +1 -0
- {wbportfolio-1.44.5.dist-info → wbportfolio-1.45.0.dist-info}/METADATA +4 -1
- {wbportfolio-1.44.5.dist-info → wbportfolio-1.45.0.dist-info}/RECORD +301 -288
- wbportfolio/admin/synchronization/__init__.py +0 -2
- wbportfolio/admin/synchronization/admin.py +0 -114
- wbportfolio/admin/synchronization/portfolio_synchronization.py +0 -18
- wbportfolio/admin/synchronization/price_computation.py +0 -21
- wbportfolio/defaults/portfolio/default_rebalancing.py +0 -45
- wbportfolio/factories/pytest_utils.py +0 -121
- wbportfolio/factories/synchronization.py +0 -40
- wbportfolio/models/synchronization/__init__.py +0 -3
- wbportfolio/models/synchronization/portfolio_synchronization.py +0 -292
- wbportfolio/models/synchronization/price_computation.py +0 -200
- wbportfolio/models/synchronization/synchronization.py +0 -188
- wbportfolio/serializers/synchronization.py +0 -18
- wbportfolio/tests/models/test_synchronization.py +0 -617
- wbportfolio/viewsets/synchronization.py +0 -25
- /wbportfolio/{defaults/portfolio → models/graphs}/__init__.py +0 -0
- {wbportfolio-1.44.5.dist-info → wbportfolio-1.45.0.dist-info}/WHEEL +0 -0
- {wbportfolio-1.44.5.dist-info → wbportfolio-1.45.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from wbcore import viewsets
|
|
2
|
+
from wbcore.permissions.permissions import InternalUserPermissionMixin
|
|
3
|
+
|
|
4
|
+
from wbportfolio.models import Rebalancer, RebalancingModel
|
|
5
|
+
from wbportfolio.serializers import (
|
|
6
|
+
RebalancerModelSerializer,
|
|
7
|
+
RebalancerRepresentationSerializer,
|
|
8
|
+
RebalancingModelRepresentationSerializer,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
from ..configs.display import RebalancerDisplayConfig
|
|
12
|
+
from ..configs.endpoints import RebalancerEndpointConfig
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class RebalancingModelRepresentationViewSet(InternalUserPermissionMixin, viewsets.RepresentationViewSet):
|
|
16
|
+
IDENTIFIER = "wbportfolio:rebalancingmodel"
|
|
17
|
+
queryset = RebalancingModel.objects.all()
|
|
18
|
+
serializer_class = RebalancingModelRepresentationSerializer
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class RebalancerRepresentationViewSet(InternalUserPermissionMixin, viewsets.RepresentationViewSet):
|
|
22
|
+
IDENTIFIER = "wbportfolio:rebalancingmodel"
|
|
23
|
+
queryset = Rebalancer.objects.all()
|
|
24
|
+
serializer_class = RebalancerRepresentationSerializer
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class RebalancerModelViewSet(InternalUserPermissionMixin, viewsets.ModelViewSet):
|
|
28
|
+
queryset = Rebalancer.objects.select_related("rebalancing_model", "portfolio")
|
|
29
|
+
serializer_class = RebalancerModelSerializer
|
|
30
|
+
display_config_class = RebalancerDisplayConfig
|
|
31
|
+
endpoint_config_class = RebalancerEndpointConfig
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
+
from contextlib import suppress
|
|
2
|
+
from datetime import date
|
|
3
|
+
|
|
1
4
|
from django.shortcuts import get_object_or_404
|
|
5
|
+
from django.utils.functional import cached_property
|
|
6
|
+
from pandas._libs.tslibs.offsets import BDay
|
|
2
7
|
from rest_framework.decorators import action
|
|
3
8
|
from rest_framework.response import Response
|
|
4
9
|
from wbcompliance.viewsets.risk_management.mixins import RiskCheckViewSetMixin
|
|
@@ -9,11 +14,13 @@ from wbcore.metadata.configs.display.instance_display import (
|
|
|
9
14
|
)
|
|
10
15
|
from wbcore.permissions.permissions import InternalUserPermissionMixin
|
|
11
16
|
from wbcore.utils.views import CloneMixin
|
|
12
|
-
|
|
17
|
+
|
|
18
|
+
from wbportfolio.models import AssetPosition, TradeProposal
|
|
13
19
|
from wbportfolio.models.transactions.trade_proposals import (
|
|
14
|
-
|
|
20
|
+
replay_as_task,
|
|
15
21
|
)
|
|
16
22
|
from wbportfolio.serializers import (
|
|
23
|
+
ReadOnlyTradeProposalModelSerializer,
|
|
17
24
|
TradeProposalModelSerializer,
|
|
18
25
|
TradeProposalRepresentationSerializer,
|
|
19
26
|
)
|
|
@@ -24,6 +31,7 @@ from ..configs import (
|
|
|
24
31
|
TradeProposalEndpointConfig,
|
|
25
32
|
TradeProposalPortfolioEndpointConfig,
|
|
26
33
|
)
|
|
34
|
+
from ..mixins import UserPortfolioRequestPermissionMixin
|
|
27
35
|
|
|
28
36
|
|
|
29
37
|
class TradeProposalRepresentationViewSet(InternalUserPermissionMixin, viewsets.RepresentationViewSet):
|
|
@@ -38,12 +46,19 @@ class TradeProposalModelViewSet(CloneMixin, RiskCheckViewSetMixin, InternalUserP
|
|
|
38
46
|
search_fields = ("comment",)
|
|
39
47
|
filterset_fields = {"trade_date": ["exact", "gte", "lte"], "status": ["exact"]}
|
|
40
48
|
|
|
41
|
-
queryset = TradeProposal.objects.select_related("
|
|
49
|
+
queryset = TradeProposal.objects.select_related("rebalancing_model", "portfolio")
|
|
42
50
|
serializer_class = TradeProposalModelSerializer
|
|
43
51
|
display_config_class = TradeProposalDisplayConfig
|
|
44
52
|
button_config_class = TradeProposalButtonConfig
|
|
45
53
|
endpoint_config_class = TradeProposalEndpointConfig
|
|
46
54
|
|
|
55
|
+
def get_serializer_class(self):
|
|
56
|
+
if self.new_mode or (
|
|
57
|
+
"pk" in self.kwargs and (obj := self.get_object()) and obj.status == TradeProposal.Status.DRAFT
|
|
58
|
+
):
|
|
59
|
+
return TradeProposalModelSerializer
|
|
60
|
+
return ReadOnlyTradeProposalModelSerializer
|
|
61
|
+
|
|
47
62
|
@classmethod
|
|
48
63
|
def get_clone_instance_display(cls) -> Display:
|
|
49
64
|
return create_simple_display(
|
|
@@ -75,7 +90,7 @@ class TradeProposalModelViewSet(CloneMixin, RiskCheckViewSetMixin, InternalUserP
|
|
|
75
90
|
def replay(self, request, pk=None):
|
|
76
91
|
trade_proposal = get_object_or_404(TradeProposal, pk=pk)
|
|
77
92
|
if trade_proposal.portfolio.is_manageable:
|
|
78
|
-
|
|
93
|
+
replay_as_task.delay(trade_proposal.id)
|
|
79
94
|
return Response({"send": True})
|
|
80
95
|
|
|
81
96
|
@action(detail=True, methods=["PATCH"])
|
|
@@ -86,8 +101,13 @@ class TradeProposalModelViewSet(CloneMixin, RiskCheckViewSetMixin, InternalUserP
|
|
|
86
101
|
return Response({"send": True})
|
|
87
102
|
|
|
88
103
|
|
|
89
|
-
class TradeProposalPortfolioModelViewSet(TradeProposalModelViewSet):
|
|
104
|
+
class TradeProposalPortfolioModelViewSet(UserPortfolioRequestPermissionMixin, TradeProposalModelViewSet):
|
|
90
105
|
endpoint_config_class = TradeProposalPortfolioEndpointConfig
|
|
91
106
|
|
|
107
|
+
@cached_property
|
|
108
|
+
def default_trade_date(self) -> date | None:
|
|
109
|
+
with suppress(AssetPosition.DoesNotExist):
|
|
110
|
+
return (self.portfolio.assets.latest("date").date + BDay(1)).date()
|
|
111
|
+
|
|
92
112
|
def get_queryset(self):
|
|
93
113
|
return TradeProposal.objects.filter(portfolio=self.kwargs["portfolio_id"])
|
|
@@ -2,18 +2,18 @@ from decimal import Decimal
|
|
|
2
2
|
|
|
3
3
|
import pandas as pd
|
|
4
4
|
import plotly.graph_objects as go
|
|
5
|
-
from django.contrib.messages import warning
|
|
5
|
+
from django.contrib.messages import error, warning
|
|
6
6
|
from django.db.models import (
|
|
7
7
|
BooleanField,
|
|
8
8
|
Case,
|
|
9
|
+
DecimalField,
|
|
10
|
+
ExpressionWrapper,
|
|
9
11
|
F,
|
|
10
12
|
OuterRef,
|
|
11
13
|
Subquery,
|
|
12
14
|
Sum,
|
|
13
15
|
Value,
|
|
14
16
|
When,
|
|
15
|
-
DecimalField,
|
|
16
|
-
ExpressionWrapper,
|
|
17
17
|
)
|
|
18
18
|
from django.db.models.functions import Coalesce
|
|
19
19
|
from django.shortcuts import get_object_or_404
|
|
@@ -23,8 +23,9 @@ from wbcore import viewsets
|
|
|
23
23
|
from wbcore.contrib.currency.models import CurrencyFXRates
|
|
24
24
|
from wbcore.permissions.permissions import InternalUserPermissionMixin
|
|
25
25
|
from wbcore.utils.strings import format_number
|
|
26
|
-
from wbcrm.models import Account
|
|
27
26
|
from wbcore.viewsets.mixins import OrderableMixin
|
|
27
|
+
from wbcrm.models import Account
|
|
28
|
+
|
|
28
29
|
from wbportfolio.filters import (
|
|
29
30
|
SubscriptionRedemptionFilterSet,
|
|
30
31
|
SubscriptionRedemptionPortfolioFilterSet,
|
|
@@ -365,6 +366,7 @@ class TradeTradeProposalModelViewSet(
|
|
|
365
366
|
"trade_proposal",
|
|
366
367
|
"order",
|
|
367
368
|
)
|
|
369
|
+
ordering_fields = ("target_weight", "effective_weight", "effective_shares", "target_shares", "shares", "weighting")
|
|
368
370
|
IDENTIFIER = "wbportfolio:tradeproposal"
|
|
369
371
|
search_fields = ("underlying_instrument__name",)
|
|
370
372
|
filterset_fields = {}
|
|
@@ -376,8 +378,8 @@ class TradeTradeProposalModelViewSet(
|
|
|
376
378
|
button_config_class = TradeTradeProposalButtonConfig
|
|
377
379
|
|
|
378
380
|
@cached_property
|
|
379
|
-
def
|
|
380
|
-
return get_object_or_404(TradeProposal, pk=self.kwargs["trade_proposal_id"])
|
|
381
|
+
def trade_proposal(self):
|
|
382
|
+
return get_object_or_404(TradeProposal, pk=self.kwargs["trade_proposal_id"])
|
|
381
383
|
|
|
382
384
|
def get_resource_class(self):
|
|
383
385
|
return TradeProposalTradeResource
|
|
@@ -397,15 +399,20 @@ class TradeTradeProposalModelViewSet(
|
|
|
397
399
|
return {}
|
|
398
400
|
|
|
399
401
|
def get_serializer_class(self):
|
|
400
|
-
if self.
|
|
402
|
+
if self.trade_proposal.status != TradeProposal.Status.DRAFT:
|
|
401
403
|
return ReadOnlyTradeTradeProposalModelSerializer
|
|
402
404
|
return TradeTradeProposalModelSerializer
|
|
403
405
|
|
|
404
406
|
def add_messages(self, request, queryset=None, paginated_queryset=None, instance=None, initial=False):
|
|
405
|
-
if queryset:
|
|
406
|
-
total_target_weight =
|
|
407
|
+
if queryset is not None:
|
|
408
|
+
total_target_weight = queryset.aggregate(c=Sum(F("target_weight")))["c"] or Decimal(0)
|
|
407
409
|
if round(total_target_weight, 3) != 1:
|
|
408
410
|
warning(request, "The total target weight does not equals to 1")
|
|
411
|
+
if queryset.filter(status=Trade.Status.FAILED):
|
|
412
|
+
error(
|
|
413
|
+
request,
|
|
414
|
+
"Some Trades couldn't be succesfully prepared. Please revert back to draft and correct these trades accordingly.",
|
|
415
|
+
)
|
|
409
416
|
|
|
410
417
|
def get_queryset(self):
|
|
411
418
|
if self.is_portfolio_manager:
|
|
@@ -14,6 +14,7 @@ from wbcore import viewsets
|
|
|
14
14
|
from wbcore.contrib.currency.models import CurrencyFXRates
|
|
15
15
|
from wbcore.permissions.permissions import InternalUserPermissionMixin
|
|
16
16
|
from wbcore.utils.strings import format_number
|
|
17
|
+
|
|
17
18
|
from wbportfolio.filters import TransactionFilterSet, TransactionPortfolioFilterSet
|
|
18
19
|
from wbportfolio.models import Fees, Trade, Transaction
|
|
19
20
|
from wbportfolio.serializers import (
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: wbportfolio
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.45.0
|
|
4
4
|
Author-email: Christopher Wittlinger <c.wittlinger@stainly.com>
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Requires-Dist: cryptography==3.4.*
|
|
@@ -9,9 +9,12 @@ Requires-Dist: django-storages==1.14.*
|
|
|
9
9
|
Requires-Dist: fuzzywuzzy==0.*
|
|
10
10
|
Requires-Dist: jinjasql2==0.1.*
|
|
11
11
|
Requires-Dist: msoffcrypto-tool==4.10.*
|
|
12
|
+
Requires-Dist: networkx>=3.4.2
|
|
13
|
+
Requires-Dist: pydot>=3.0.4
|
|
12
14
|
Requires-Dist: python-levenshtein==0.*
|
|
13
15
|
Requires-Dist: reportlab==3.*
|
|
14
16
|
Requires-Dist: scipy>=1
|
|
17
|
+
Requires-Dist: skfolio==0.6.*
|
|
15
18
|
Requires-Dist: wbcompliance
|
|
16
19
|
Requires-Dist: wbcore
|
|
17
20
|
Requires-Dist: wbcrm
|