wbportfolio 1.44.4__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 +30 -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.4.dist-info → wbportfolio-1.45.0.dist-info}/METADATA +4 -1
- {wbportfolio-1.44.4.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.4.dist-info → wbportfolio-1.45.0.dist-info}/WHEEL +0 -0
- {wbportfolio-1.44.4.dist-info → wbportfolio-1.45.0.dist-info}/licenses/LICENSE +0 -0
wbportfolio/viewsets/assets.py
CHANGED
|
@@ -21,6 +21,7 @@ from wbcore.utils.figures import (
|
|
|
21
21
|
from wbcore.utils.strings import format_number
|
|
22
22
|
from wbfdm.contrib.metric.viewsets.mixins import InstrumentMetricMixin
|
|
23
23
|
from wbfdm.models import Instrument
|
|
24
|
+
|
|
24
25
|
from wbportfolio.filters import (
|
|
25
26
|
AssetPositionFilter,
|
|
26
27
|
AssetPositionInstrumentFilter,
|
|
@@ -45,7 +46,7 @@ from wbportfolio.models import (
|
|
|
45
46
|
Portfolio,
|
|
46
47
|
Product,
|
|
47
48
|
)
|
|
48
|
-
from wbportfolio.serializers import (
|
|
49
|
+
from wbportfolio.serializers.assets import (
|
|
49
50
|
AssetPositionAggregatedPortfolioModelSerializer,
|
|
50
51
|
AssetPositionInstrumentModelSerializer,
|
|
51
52
|
AssetPositionModelSerializer,
|
|
@@ -98,10 +99,10 @@ class AssetPositionModelViewSet(
|
|
|
98
99
|
"total_value",
|
|
99
100
|
"portfolio__name",
|
|
100
101
|
"portfolio_created__name",
|
|
101
|
-
"
|
|
102
|
-
"
|
|
103
|
-
"
|
|
104
|
-
"
|
|
102
|
+
"underlying_quote",
|
|
103
|
+
"underlying_quote_name",
|
|
104
|
+
"underlying_quote_ticker",
|
|
105
|
+
"underlying_quote_isin",
|
|
105
106
|
"price",
|
|
106
107
|
"currency__key",
|
|
107
108
|
"currency_fx_rate",
|
|
@@ -113,7 +114,7 @@ class AssetPositionModelViewSet(
|
|
|
113
114
|
"liquidity",
|
|
114
115
|
]
|
|
115
116
|
ordering = ["-weighting"]
|
|
116
|
-
search_fields = ["
|
|
117
|
+
search_fields = ["underlying_quote_ticker", "underlying_quote_name", "underlying_quote_isin"]
|
|
117
118
|
|
|
118
119
|
display_config_class = AssetPositionDisplayConfig
|
|
119
120
|
button_config_class = AssetPositionButtonConfig
|
|
@@ -142,12 +143,12 @@ class AssetPositionModelViewSet(
|
|
|
142
143
|
super()
|
|
143
144
|
.get_queryset()
|
|
144
145
|
.annotate(
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
146
|
+
underlying_quote_isin=F("underlying_quote__isin"),
|
|
147
|
+
underlying_quote_ticker=F("underlying_quote__ticker"),
|
|
148
|
+
underlying_quote_name=F("underlying_quote__name"),
|
|
148
149
|
)
|
|
149
150
|
.select_related(
|
|
150
|
-
"
|
|
151
|
+
"underlying_quote",
|
|
151
152
|
"currency",
|
|
152
153
|
"portfolio",
|
|
153
154
|
"exchange",
|
|
@@ -170,7 +171,7 @@ class AssetPositionPortfolioModelViewSet(InstrumentMetricMixin, AssetPositionMod
|
|
|
170
171
|
*PORTFOLIO_ESG_KEYS,
|
|
171
172
|
)
|
|
172
173
|
METRIC_BASKET_LABEL = "portfolio"
|
|
173
|
-
METRIC_INSTRUMENT_LABEL = "
|
|
174
|
+
METRIC_INSTRUMENT_LABEL = "underlying_quote"
|
|
174
175
|
METRIC_SHOW_BY_DEFAULT = False
|
|
175
176
|
METRIC_SHOW_FILTERS = True
|
|
176
177
|
|
|
@@ -210,7 +211,7 @@ class AssetPositionPortfolioModelViewSet(InstrumentMetricMixin, AssetPositionMod
|
|
|
210
211
|
super()
|
|
211
212
|
.get_queryset()
|
|
212
213
|
.filter(portfolio=self.portfolio)
|
|
213
|
-
.select_related("
|
|
214
|
+
.select_related("underlying_quote", "currency", "exchange", "portfolio_created")
|
|
214
215
|
)
|
|
215
216
|
return AssetPosition.objects.none()
|
|
216
217
|
|
|
@@ -238,9 +239,7 @@ class AssetPositionInstrumentModelViewSet(AssetPositionModelViewSet):
|
|
|
238
239
|
return {}
|
|
239
240
|
|
|
240
241
|
def get_queryset(self):
|
|
241
|
-
qs = (
|
|
242
|
-
super().get_queryset().filter(underlying_instrument__in=self.instrument.get_descendants(include_self=True))
|
|
243
|
-
)
|
|
242
|
+
qs = super().get_queryset().filter(underlying_quote__in=self.instrument.get_descendants(include_self=True))
|
|
244
243
|
if self.request.GET.get("filter_last_positions", "false") == "true":
|
|
245
244
|
if self.instrument.assets.exists():
|
|
246
245
|
qs = qs.filter(date=self.instrument.assets.latest("date").date)
|
|
@@ -364,10 +363,10 @@ class ContributorPortfolioChartView(UserPortfolioRequestPermissionMixin, viewset
|
|
|
364
363
|
)
|
|
365
364
|
df = Portfolio.get_contribution_df(queryset, hedged_currency=hedged_currency)
|
|
366
365
|
if not df.empty:
|
|
367
|
-
df = df[["contribution_total", "contribution_forex", "
|
|
366
|
+
df = df[["contribution_total", "contribution_forex", "underlying_instrument"]].sort_values(
|
|
368
367
|
by="contribution_total", ascending=True
|
|
369
368
|
)
|
|
370
|
-
df["instrument_id"] = df.
|
|
369
|
+
df["instrument_id"] = df.underlying_instrument.apply(lambda x: Instrument.objects.get(id=x).name_repr)
|
|
371
370
|
df_forex = df[["instrument_id", "contribution_forex"]]
|
|
372
371
|
df_forex = df_forex[df_forex.contribution_forex != 0]
|
|
373
372
|
|
|
@@ -486,7 +485,7 @@ class AssetPositionUnderlyingInstrumentChartViewSet(UserPortfolioRequestPermissi
|
|
|
486
485
|
class CompositionModelPortfolioPandasView(
|
|
487
486
|
UserPortfolioRequestPermissionMixin, InternalUserPermissionMixin, ExportPandasAPIViewSet
|
|
488
487
|
):
|
|
489
|
-
IDENTIFIER = "wbportfolio:
|
|
488
|
+
IDENTIFIER = "wbportfolio:topdowncomposition"
|
|
490
489
|
filterset_class = CompositionModelPortfolioPandasFilter
|
|
491
490
|
queryset = AssetPosition.objects.all()
|
|
492
491
|
|
|
@@ -494,22 +493,24 @@ class CompositionModelPortfolioPandasView(
|
|
|
494
493
|
title_config_class = CompositionModelPortfolioPandasTitleConfig
|
|
495
494
|
endpoint_config_class = CompositionModelPortfolioPandasEndpointConfig
|
|
496
495
|
|
|
496
|
+
@cached_property
|
|
497
|
+
def val_date(self) -> date:
|
|
498
|
+
return parse_date(self.request.GET["date"])
|
|
499
|
+
|
|
497
500
|
@cached_property
|
|
498
501
|
def dependant_portfolios(self):
|
|
499
502
|
return Portfolio.objects.filter(
|
|
500
503
|
Q(depends_on__in=[self.portfolio]) | Q(dependent_portfolios__in=[self.portfolio])
|
|
501
504
|
)
|
|
502
505
|
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
).values("id", "computed_str")
|
|
508
|
-
return {item["id"]: item["computed_str"] for item in instrument_qs}
|
|
506
|
+
def get_queryset(self):
|
|
507
|
+
if self.has_portfolio_access:
|
|
508
|
+
return super().get_queryset().filter(portfolio=self.portfolio)
|
|
509
|
+
return AssetPosition.objects.none()
|
|
509
510
|
|
|
510
511
|
def get_pandas_fields(self, request):
|
|
511
512
|
fields = [
|
|
512
|
-
pf.PKField(key="
|
|
513
|
+
pf.PKField(key="underlying_instrument", label="ID"),
|
|
513
514
|
pf.CharField(key="underlying_instrument_repr", label="Instrument"),
|
|
514
515
|
]
|
|
515
516
|
if not self.portfolio.only_weighting:
|
|
@@ -529,34 +530,44 @@ class CompositionModelPortfolioPandasView(
|
|
|
529
530
|
search_fields = ["underlying_instrument_repr"]
|
|
530
531
|
ordering_fields = ["underlying_instrument_repr", "model_portfolio"]
|
|
531
532
|
|
|
532
|
-
def get_queryset(self):
|
|
533
|
-
if self.has_portfolio_access:
|
|
534
|
-
return AssetPosition.objects.filter(portfolio__in=[*self.dependant_portfolios, self.portfolio])
|
|
535
|
-
return AssetPosition.objects.none()
|
|
536
|
-
|
|
537
533
|
def get_dataframe(self, request, queryset, **kwargs):
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
534
|
+
rows = []
|
|
535
|
+
for portfolio in [*self.dependant_portfolios, self.portfolio]:
|
|
536
|
+
rows.extend(
|
|
537
|
+
list(
|
|
538
|
+
map(
|
|
539
|
+
lambda x: {
|
|
540
|
+
"underlying_instrument": x.underlying_instrument.id,
|
|
541
|
+
"weighting": x.weighting,
|
|
542
|
+
"shares": x.shares,
|
|
543
|
+
"portfolio": portfolio.id,
|
|
544
|
+
},
|
|
545
|
+
portfolio.get_positions(self.val_date),
|
|
546
|
+
)
|
|
547
|
+
)
|
|
548
548
|
)
|
|
549
|
+
df = pd.DataFrame(rows)
|
|
550
|
+
df = df.pivot_table(
|
|
551
|
+
index="underlying_instrument",
|
|
552
|
+
columns=["portfolio"],
|
|
553
|
+
values=["weighting", "shares"],
|
|
554
|
+
aggfunc="sum",
|
|
555
|
+
fill_value=0,
|
|
556
|
+
)
|
|
557
|
+
for portfolio in self.dependant_portfolios:
|
|
558
|
+
with suppress(KeyError):
|
|
559
|
+
if portfolio.only_weighting:
|
|
560
|
+
df["difference", portfolio.id] = df["weighting"][self.portfolio.id] - df["weighting"][portfolio.id]
|
|
561
|
+
else:
|
|
562
|
+
df["difference", portfolio.id] = df["shares"][self.portfolio.id] - df["shares"][portfolio.id]
|
|
549
563
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
if portfolio.only_weighting:
|
|
553
|
-
df["difference", portfolio.id] = (
|
|
554
|
-
df["weighting"][self.portfolio.id] - df["weighting"][portfolio.id]
|
|
555
|
-
)
|
|
556
|
-
else:
|
|
557
|
-
df["difference", portfolio.id] = df["shares"][self.portfolio.id] - df["shares"][portfolio.id]
|
|
558
|
-
df.columns = ["_".join([str(item) for item in col]) for col in df.columns.to_flat_index()]
|
|
559
|
-
df = df.reset_index()
|
|
560
|
-
df["underlying_instrument_repr"] = df.underlying_instrument__parent.map(self.instrument_map)
|
|
564
|
+
df.columns = ["_".join([str(item) for item in col]) for col in df.columns.to_flat_index()]
|
|
565
|
+
df = df.reset_index()
|
|
561
566
|
|
|
562
567
|
return df
|
|
568
|
+
|
|
569
|
+
def manipulate_dataframe(self, df):
|
|
570
|
+
df["underlying_instrument_repr"] = df["underlying_instrument"].map(
|
|
571
|
+
dict(Instrument.objects.filter(id__in=df["underlying_instrument"]).values_list("id", "computed_str"))
|
|
572
|
+
)
|
|
573
|
+
return df
|
|
@@ -5,6 +5,7 @@ import pandas as pd
|
|
|
5
5
|
import plotly.graph_objects as go
|
|
6
6
|
from wbcore import viewsets
|
|
7
7
|
from wbcrm.models.accounts import Account
|
|
8
|
+
|
|
8
9
|
from wbportfolio.analysis.claims import get_assets_and_net_new_money_progression
|
|
9
10
|
from wbportfolio.filters import AssetsAndNetNewMoneyProgressionFilterSet
|
|
10
11
|
from wbportfolio.models.products import Product
|
|
@@ -15,7 +15,9 @@ from wbfdm.models import (
|
|
|
15
15
|
ClassificationGroup,
|
|
16
16
|
Instrument,
|
|
17
17
|
InstrumentClassificationThroughModel,
|
|
18
|
+
InstrumentType,
|
|
18
19
|
)
|
|
20
|
+
|
|
19
21
|
from wbportfolio.filters.assets import DistributionFilter
|
|
20
22
|
from wbportfolio.models import (
|
|
21
23
|
AssetPosition,
|
|
@@ -68,7 +70,7 @@ class AbstractDistributionMixin:
|
|
|
68
70
|
|
|
69
71
|
def _generate_classification_df(self, queryset):
|
|
70
72
|
df = pd.DataFrame(
|
|
71
|
-
queryset.filter(
|
|
73
|
+
queryset.filter(underlying_instrument__instrument_type=InstrumentType.EQUITY).values(
|
|
72
74
|
"weighting", "underlying_instrument"
|
|
73
75
|
),
|
|
74
76
|
columns=["weighting", "underlying_instrument"],
|
|
@@ -10,7 +10,7 @@ from .claims import ClaimTradeButtonConfig, ConsolidatedTradeSummaryButtonConfig
|
|
|
10
10
|
|
|
11
11
|
from .custodians import CustodianButtonConfig
|
|
12
12
|
from .fees import FeesButtonConfig
|
|
13
|
-
from .portfolios import
|
|
13
|
+
from .portfolios import PortfolioButtonConfig
|
|
14
14
|
from .products import ProductButtonConfig, ProductCustomerButtonConfig
|
|
15
15
|
from .registers import RegisterButtonConfig
|
|
16
16
|
from .trades import (
|
|
@@ -3,6 +3,7 @@ from contextlib import suppress
|
|
|
3
3
|
from rest_framework.reverse import reverse
|
|
4
4
|
from wbcore.metadata.configs import buttons as bt
|
|
5
5
|
from wbcore.metadata.configs.buttons.view_config import ButtonViewConfig
|
|
6
|
+
|
|
6
7
|
from wbportfolio.models.portfolio import Portfolio, PortfolioPortfolioThroughModel
|
|
7
8
|
|
|
8
9
|
|
|
@@ -6,6 +6,7 @@ from wbcore.metadata.configs.buttons.view_config import ButtonViewConfig
|
|
|
6
6
|
from wbcore.metadata.configs.display.instance_display.shortcuts import (
|
|
7
7
|
create_simple_display,
|
|
8
8
|
)
|
|
9
|
+
|
|
9
10
|
from wbportfolio.models import Custodian
|
|
10
11
|
from wbportfolio.serializers import CustodianRepresentationSerializer
|
|
11
12
|
|
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
from contextlib import suppress
|
|
2
2
|
|
|
3
3
|
from wbcore.contrib.icons import WBIcon
|
|
4
|
-
from wbcore.enums import RequestType
|
|
5
4
|
from wbcore.metadata.configs import buttons as bt
|
|
6
|
-
from wbcore.metadata.configs.display.instance_display.shortcuts import (
|
|
7
|
-
create_simple_display,
|
|
8
|
-
)
|
|
9
5
|
from wbfdm.models.instruments import Instrument
|
|
10
6
|
|
|
11
|
-
from .portfolios import get_portfolio_start_end_serializer_class
|
|
12
|
-
|
|
13
7
|
|
|
14
8
|
class InstrumentButtonMixin:
|
|
15
9
|
@classmethod
|
|
@@ -25,22 +19,9 @@ class InstrumentButtonMixin:
|
|
|
25
19
|
with suppress(Instrument.DoesNotExist):
|
|
26
20
|
instrument = Instrument.objects.get(id=pk)
|
|
27
21
|
asset_instrument_btn_label = "Asset Portfolio"
|
|
28
|
-
if
|
|
22
|
+
if instrument.portfolio:
|
|
29
23
|
buttons.extend(
|
|
30
24
|
[
|
|
31
|
-
bt.ActionButton(
|
|
32
|
-
method=RequestType.PATCH,
|
|
33
|
-
identifiers=("wbportfolio:portfolio",),
|
|
34
|
-
key="resynchronize",
|
|
35
|
-
label="Resynchronize/Rebalance",
|
|
36
|
-
description_fields="""
|
|
37
|
-
<p>Resynchronize portfolio from {{start}} to {{end}}</p>
|
|
38
|
-
""",
|
|
39
|
-
serializer=get_portfolio_start_end_serializer_class(portfolio),
|
|
40
|
-
action_label="resynchronize",
|
|
41
|
-
title="Resynchronize/Rebalance",
|
|
42
|
-
instance_display=create_simple_display([["start"], ["end"]]),
|
|
43
|
-
),
|
|
44
25
|
bt.WidgetButton(key="portfolio_positions", label=asset_instrument_btn_label),
|
|
45
26
|
bt.DropDownButton(
|
|
46
27
|
label="Charts",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
from contextlib import suppress
|
|
1
2
|
from datetime import date
|
|
2
3
|
|
|
3
|
-
from
|
|
4
|
-
from rest_framework.reverse import reverse
|
|
4
|
+
from pandas._libs.tslibs.offsets import BDay
|
|
5
5
|
from wbcore import serializers as wb_serializers
|
|
6
6
|
from wbcore.contrib.currency.serializers import CurrencyRepresentationSerializer
|
|
7
7
|
from wbcore.contrib.icons import WBIcon
|
|
@@ -11,14 +11,28 @@ from wbcore.metadata.configs.buttons.view_config import ButtonViewConfig
|
|
|
11
11
|
from wbcore.metadata.configs.display.instance_display.shortcuts import (
|
|
12
12
|
create_simple_display,
|
|
13
13
|
)
|
|
14
|
-
from wbportfolio.models import Portfolio, PriceComputation
|
|
15
|
-
from wbportfolio.serializers import (
|
|
16
|
-
PortfolioSynchronizationRepresentationSerializer,
|
|
17
|
-
PriceComputationRepresentationSerializer,
|
|
18
|
-
)
|
|
19
14
|
|
|
15
|
+
from wbportfolio.models import AssetPosition, Portfolio
|
|
16
|
+
from wbportfolio.serializers import RebalancerModelSerializer
|
|
17
|
+
from wbportfolio.viewsets.configs.display.rebalancing import RebalancerDisplayConfig
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class CreateModelPortfolioSerializer(wb_serializers.ModelSerializer):
|
|
21
|
+
create_index = wb_serializers.BooleanField(default=False, label="Create Underlying Index")
|
|
22
|
+
name = wb_serializers.CharField(required=True)
|
|
23
|
+
_currency = CurrencyRepresentationSerializer(source="currency")
|
|
20
24
|
|
|
21
|
-
|
|
25
|
+
class Meta:
|
|
26
|
+
model = Portfolio
|
|
27
|
+
fields = (
|
|
28
|
+
"name",
|
|
29
|
+
"currency",
|
|
30
|
+
"create_index",
|
|
31
|
+
"_currency",
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _get_portfolio_start_end_serializer_class(portfolio):
|
|
22
36
|
today = date.today()
|
|
23
37
|
|
|
24
38
|
class StartEndDateSerializer(wb_serializers.Serializer):
|
|
@@ -33,83 +47,83 @@ def get_portfolio_start_end_serializer_class(portfolio):
|
|
|
33
47
|
return StartEndDateSerializer
|
|
34
48
|
|
|
35
49
|
|
|
50
|
+
def _get_rebalance_serializer_class(portfolio):
|
|
51
|
+
try:
|
|
52
|
+
default_trade_date = (portfolio.assets.latest("date").date + BDay(1)).date()
|
|
53
|
+
except AssetPosition.DoesNotExist:
|
|
54
|
+
default_trade_date = date.today()
|
|
55
|
+
|
|
56
|
+
class RebalanceSerializer(wb_serializers.Serializer):
|
|
57
|
+
trade_date = wb_serializers.DateField(default=default_trade_date)
|
|
58
|
+
|
|
59
|
+
return RebalanceSerializer
|
|
60
|
+
|
|
61
|
+
|
|
36
62
|
class PortfolioButtonConfig(ButtonViewConfig):
|
|
37
63
|
def get_custom_instance_buttons(self):
|
|
38
|
-
|
|
39
|
-
bt.
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
64
|
+
admin_buttons = [
|
|
65
|
+
bt.ActionButton(
|
|
66
|
+
method=RequestType.POST,
|
|
67
|
+
identifiers=("wbportfolio:portfolio",),
|
|
68
|
+
key="add_automatic_rebalancer",
|
|
69
|
+
label="Attach Rebalancer",
|
|
70
|
+
serializer=RebalancerModelSerializer,
|
|
71
|
+
action_label="Attach Rebalancer",
|
|
72
|
+
title="Attach Rebalancer",
|
|
73
|
+
instance_display=RebalancerDisplayConfig(
|
|
74
|
+
self.view, self.request, self.instance
|
|
75
|
+
).get_instance_display(),
|
|
76
|
+
)
|
|
44
77
|
]
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
78
|
+
buttons = [bt.WidgetButton(key="treegraphchart", label="Visualize Tree Graph Chart")]
|
|
79
|
+
with suppress(Portfolio.DoesNotExist, KeyError):
|
|
80
|
+
portfolio = Portfolio.objects.get(id=self.view.kwargs["pk"])
|
|
81
|
+
buttons.append(
|
|
49
82
|
bt.ActionButton(
|
|
50
|
-
method=RequestType.
|
|
83
|
+
method=RequestType.POST,
|
|
51
84
|
identifiers=("wbportfolio:portfolio",),
|
|
52
|
-
key="
|
|
53
|
-
label="
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
""
|
|
57
|
-
|
|
58
|
-
action_label="resynchronize",
|
|
59
|
-
title="Resynchronize/Rebalance",
|
|
60
|
-
instance_display=create_simple_display([["start"], ["end"]]),
|
|
85
|
+
key="rebalance",
|
|
86
|
+
label="Rebalance",
|
|
87
|
+
serializer=_get_rebalance_serializer_class(portfolio),
|
|
88
|
+
action_label="Rebalance",
|
|
89
|
+
title="Rebalance",
|
|
90
|
+
instance_display=create_simple_display([["trade_date"]]),
|
|
61
91
|
)
|
|
62
92
|
)
|
|
63
93
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
94
|
+
if primary_portfolio := portfolio.primary_portfolio:
|
|
95
|
+
admin_buttons.append(
|
|
96
|
+
bt.ActionButton(
|
|
97
|
+
method=RequestType.POST,
|
|
98
|
+
identifiers=("wbportfolio:portfolio",),
|
|
99
|
+
key="recompute_lookthrough",
|
|
100
|
+
label="Recompute Look-Through Portfolio",
|
|
101
|
+
serializer=_get_portfolio_start_end_serializer_class(primary_portfolio),
|
|
102
|
+
action_label="Recompute Look-Through Portfolio",
|
|
103
|
+
title="Recompute Look-Through Portfolio",
|
|
104
|
+
instance_display=create_simple_display([["start", "end"]]),
|
|
105
|
+
)
|
|
106
|
+
)
|
|
107
|
+
buttons.append(
|
|
108
|
+
bt.DropDownButton(label="Admin", icon=WBIcon.UNFOLD.icon, buttons=tuple(admin_buttons)),
|
|
109
|
+
)
|
|
110
|
+
return set(buttons)
|
|
67
111
|
|
|
68
112
|
def get_custom_list_instance_buttons(self):
|
|
69
113
|
return self.get_custom_instance_buttons()
|
|
70
114
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
"name",
|
|
87
|
-
"currency",
|
|
88
|
-
"portfolio_synchronization",
|
|
89
|
-
"create_index",
|
|
90
|
-
"price_computation",
|
|
91
|
-
"_price_computation",
|
|
92
|
-
"_currency",
|
|
93
|
-
"_portfolio_synchronization",
|
|
94
|
-
)
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
class ModelPortfolioButtonConfig(PortfolioButtonConfig):
|
|
98
|
-
# pass
|
|
99
|
-
def get_custom_buttons(self):
|
|
100
|
-
if not self.view.kwargs.get("pk", None):
|
|
101
|
-
return {
|
|
102
|
-
bt.ActionButton(
|
|
103
|
-
method=RequestType.POST,
|
|
104
|
-
identifiers=("wbportfolio:portfolio",),
|
|
105
|
-
endpoint=reverse("wbportfolio:modelportfolio-createmodelportfolio", request=self.request),
|
|
106
|
-
label="Create New Model Portfolio",
|
|
107
|
-
serializer=CreateModelPortfolioSerializer,
|
|
108
|
-
action_label="create",
|
|
109
|
-
title="Create Model Portfolio",
|
|
110
|
-
instance_display=create_simple_display(
|
|
111
|
-
[["name", "currency", "portfolio_synchronization"], ["create_index", "price_computation", "."]]
|
|
112
|
-
),
|
|
113
|
-
)
|
|
114
|
-
}
|
|
115
|
-
return set()
|
|
115
|
+
# def get_custom_buttons(self):
|
|
116
|
+
# if not self.view.kwargs.get("pk", None):
|
|
117
|
+
# return {
|
|
118
|
+
# bt.ActionButton(
|
|
119
|
+
# method=RequestType.POST,
|
|
120
|
+
# identifiers=("wbportfolio:portfolio",),
|
|
121
|
+
# endpoint=reverse("wbportfolio:portfolio-createmodelportfolio", request=self.request),
|
|
122
|
+
# label="Create New Model Portfolio",
|
|
123
|
+
# serializer=CreateModelPortfolioSerializer,
|
|
124
|
+
# action_label="create",
|
|
125
|
+
# title="Create Model Portfolio",
|
|
126
|
+
# instance_display=create_simple_display([["name", "currency"], ["create_index", "."]]),
|
|
127
|
+
# )
|
|
128
|
+
# }
|
|
129
|
+
# return set()
|
|
@@ -11,6 +11,7 @@ from wbcore.metadata.configs.display import create_simple_display
|
|
|
11
11
|
from wbcore.signals.instance_buttons import add_instance_button
|
|
12
12
|
from wbcrm.viewsets import AccountModelViewSet
|
|
13
13
|
from wbfdm.viewsets.instruments import InstrumentModelViewSet
|
|
14
|
+
|
|
14
15
|
from wbportfolio.serializers.reconciliations import AccountReconciliationModelSerializer
|
|
15
16
|
|
|
16
17
|
from .mixins import InstrumentButtonMixin
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from .adjustments import AdjustmentDisplayConfig
|
|
2
|
+
from .rebalancing import RebalancerDisplayConfig
|
|
2
3
|
from .assets import (
|
|
3
4
|
AssetPositionDisplayConfig,
|
|
4
5
|
AssetPositionInstrumentDisplayConfig,
|
|
@@ -23,9 +24,9 @@ from .fees import (
|
|
|
23
24
|
FeesPortfolioDisplayConfig,
|
|
24
25
|
)
|
|
25
26
|
from .portfolios import (
|
|
26
|
-
ModelPortfolioDisplayConfig,
|
|
27
27
|
PortfolioDisplayConfig,
|
|
28
28
|
PortfolioPortfolioThroughModelDisplayConfig,
|
|
29
|
+
TopDownPortfolioCompositionPandasDisplayConfig
|
|
29
30
|
)
|
|
30
31
|
from .positions import (
|
|
31
32
|
AggregatedAssetPositionLiquidityDisplayConfig,
|
|
@@ -8,6 +8,7 @@ from wbcore.metadata.configs.display.instance_display.shortcuts import (
|
|
|
8
8
|
)
|
|
9
9
|
from wbcore.metadata.configs.display.instance_display.utils import repeat_field
|
|
10
10
|
from wbcore.metadata.configs.display.view_config import DisplayViewConfig
|
|
11
|
+
|
|
11
12
|
from wbportfolio.models import Adjustment
|
|
12
13
|
|
|
13
14
|
|
|
@@ -73,9 +73,9 @@ class AssetPositionPortfolioDisplayConfig(AssetPositionDisplayConfig):
|
|
|
73
73
|
open_by_default=False,
|
|
74
74
|
key=None,
|
|
75
75
|
children=[
|
|
76
|
-
dp.Field(key="
|
|
77
|
-
dp.Field(key="
|
|
78
|
-
dp.Field(key="
|
|
76
|
+
dp.Field(key="underlying_quote_name", label="Name"),
|
|
77
|
+
dp.Field(key="underlying_quote_isin", label="ISIN"),
|
|
78
|
+
dp.Field(key="underlying_quote_ticker", label="Ticker"),
|
|
79
79
|
dp.Field(key="exchange", label="Exchange", width=Unit.PIXEL(250)),
|
|
80
80
|
],
|
|
81
81
|
),
|
|
@@ -88,14 +88,15 @@ class AssetPositionPortfolioDisplayConfig(AssetPositionDisplayConfig):
|
|
|
88
88
|
dp.Field(key="price", label="Price"),
|
|
89
89
|
dp.Field(key="shares", label="Shares"),
|
|
90
90
|
dp.Field(key="currency_fx_rate", label="Currency Rate", show="open"),
|
|
91
|
-
dp.Field(key="total_value", label="Total Value", show="open"),
|
|
92
91
|
dp.Field(
|
|
93
92
|
key="total_value_fx_portfolio",
|
|
94
93
|
label="Total Value Portfolio",
|
|
95
94
|
width=Unit.PIXEL(150),
|
|
96
|
-
show="open",
|
|
97
95
|
),
|
|
98
|
-
dp.Field(key="
|
|
96
|
+
dp.Field(key="total_value", label="Total Value", show="open"),
|
|
97
|
+
dp.Field(
|
|
98
|
+
key="total_value_fx_usd", label="Total Value ($)", width=Unit.PIXEL(150), show="open"
|
|
99
|
+
),
|
|
99
100
|
],
|
|
100
101
|
),
|
|
101
102
|
dp.Field(
|
|
@@ -10,6 +10,7 @@ from wbcore.metadata.configs.display.instance_display.styles import Style
|
|
|
10
10
|
from wbcore.metadata.configs.display.instance_display.utils import repeat
|
|
11
11
|
from wbcore.metadata.configs.display.view_config import DisplayViewConfig
|
|
12
12
|
from wbcore.metadata.configs.display.windows import Window
|
|
13
|
+
|
|
13
14
|
from wbportfolio.models.transactions.claim import Claim
|
|
14
15
|
|
|
15
16
|
|