wbportfolio 1.54.2__tar.gz → 1.54.4__tar.gz
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-1.54.2 → wbportfolio-1.54.4}/PKG-INFO +1 -1
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/handlers/trade.py +3 -3
- wbportfolio-1.54.4/wbportfolio/migrations/0080_alter_trade_drift_factor_alter_trade_weighting.py +19 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/asset.py +19 -18
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/portfolio.py +100 -90
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/transactions/rebalancing.py +22 -12
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/transactions/trade_proposals.py +193 -77
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/transactions/trades.py +36 -19
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/pms/analytics/portfolio.py +5 -6
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/pms/trading/handler.py +16 -19
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/pms/typing.py +26 -11
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/rebalancing/base.py +12 -1
- wbportfolio-1.54.4/wbportfolio/rebalancing/models/equally_weighted.py +29 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/rebalancing/models/market_capitalization_weighted.py +18 -9
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/serializers/transactions/trade_proposals.py +2 -2
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/models/test_portfolios.py +5 -3
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/models/transactions/test_trade_proposals.py +13 -12
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/pms/test_analytics.py +4 -3
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/rebalancing/test_models.py +16 -10
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/display/trade_proposals.py +9 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/transactions/trade_proposals.py +1 -1
- wbportfolio-1.54.2/wbportfolio/rebalancing/models/equally_weighted.py +0 -32
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/.gitignore +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/LICENSE +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/pyproject.toml +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/admin/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/admin/asset.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/admin/custodians.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/admin/indexes.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/admin/portfolio.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/admin/portfolio_relationships.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/admin/product_groups.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/admin/products.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/admin/reconciliations.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/admin/registers.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/admin/roles.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/admin/transactions/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/admin/transactions/claim.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/admin/transactions/dividends.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/admin/transactions/fees.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/admin/transactions/rebalancing.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/admin/transactions/trades.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/analysis/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/analysis/claims.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/apps.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/contrib/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/contrib/company_portfolio/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/contrib/company_portfolio/admin.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/contrib/company_portfolio/apps.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/contrib/company_portfolio/configs/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/contrib/company_portfolio/configs/display.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/contrib/company_portfolio/configs/endpoints.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/contrib/company_portfolio/configs/previews.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/contrib/company_portfolio/constants.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/contrib/company_portfolio/dynamic_preferences_registry.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/contrib/company_portfolio/factories.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/contrib/company_portfolio/filters.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/contrib/company_portfolio/management.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/contrib/company_portfolio/migrations/0001_initial.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/contrib/company_portfolio/migrations/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/contrib/company_portfolio/models.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/contrib/company_portfolio/scripts.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/contrib/company_portfolio/serializers.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/contrib/company_portfolio/tasks.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/contrib/company_portfolio/tests/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/contrib/company_portfolio/tests/conftest.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/contrib/company_portfolio/tests/test_models.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/contrib/company_portfolio/urls.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/contrib/company_portfolio/viewsets.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/defaults/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/defaults/fees/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/defaults/fees/default.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/dynamic_preferences_registry.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/factories/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/factories/adjustments.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/factories/assets.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/factories/claim.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/factories/custodians.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/factories/dividends.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/factories/fees.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/factories/indexes.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/factories/portfolio_cash_flow.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/factories/portfolio_cash_targets.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/factories/portfolio_swing_pricings.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/factories/portfolios.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/factories/product_groups.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/factories/products.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/factories/rebalancing.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/factories/reconciliations.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/factories/roles.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/factories/trades.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/fdm/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/fdm/tasks.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/filters/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/filters/assets.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/filters/assets_and_net_new_money_progression.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/filters/custodians.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/filters/esg.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/filters/performances.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/filters/portfolios.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/filters/positions.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/filters/products.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/filters/roles.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/filters/signals.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/filters/transactions/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/filters/transactions/claim.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/filters/transactions/fees.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/filters/transactions/mixins.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/filters/transactions/trades.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/filters/transactions/utils.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/fixtures/product_factsheets.yaml +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/fixtures/wbportfolio.yaml.gz +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/fixtures/wbrisk_management.yaml.gz +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/backends/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/backends/refinitiv/adjustment.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/backends/ubs/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/backends/ubs/asset_position.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/backends/ubs/fees.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/backends/ubs/instrument_price.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/backends/ubs/mixin.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/backends/utils.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/backends/wbfdm/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/backends/wbfdm/adjustment.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/backends/wbfdm/dividend.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/backends/wbfdm/mixin.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/handlers/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/handlers/adjustment.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/handlers/asset_position.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/handlers/dividend.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/handlers/fees.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/handlers/portfolio_cash_flow.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/handlers/register.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/default_mapping.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/jpmorgan/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/jpmorgan/customer_trade.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/jpmorgan/fees.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/jpmorgan/strategy.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/jpmorgan/valuation.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/leonteq/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/leonteq/customer_trade.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/leonteq/equity.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/leonteq/fees.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/leonteq/trade.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/leonteq/valuation.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/natixis/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/natixis/customer_trade.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/natixis/d1_customer_trade.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/natixis/d1_equity.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/natixis/d1_fees.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/natixis/d1_trade.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/natixis/d1_valuation.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/natixis/dividend.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/natixis/equity.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/natixis/fees.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/natixis/trade.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/natixis/utils.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/natixis/valuation.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/refinitiv/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/refinitiv/adjustment.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/sg_lux/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/sg_lux/custodian_positions.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/sg_lux/customer_trade.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/sg_lux/customer_trade_pending_slk.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/sg_lux/customer_trade_slk.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/sg_lux/customer_trade_without_pw.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/sg_lux/equity.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/sg_lux/fees.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/sg_lux/perf_fees.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/sg_lux/portfolio_cash_flow.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/sg_lux/portfolio_future_cash_flow.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/sg_lux/registers.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/sg_lux/sylk.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/sg_lux/utils.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/sg_lux/valuation.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/societe_generale/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/societe_generale/customer_trade.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/societe_generale/strategy.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/societe_generale/valuation.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/tellco/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/tellco/customer_trade.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/tellco/equity.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/tellco/valuation.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/ubs/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/ubs/api/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/ubs/api/asset_position.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/ubs/api/fees.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/ubs/api/instrument_price.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/ubs/api/utils.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/ubs/customer_trade.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/ubs/equity.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/ubs/historical_customer_trade.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/ubs/valuation.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/vontobel/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/vontobel/asset_position.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/vontobel/customer_trade.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/vontobel/historical_customer_trade.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/vontobel/instrument.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/vontobel/management_fees.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/vontobel/performance_fees.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/vontobel/trade.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/vontobel/utils.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/vontobel/valuation.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/parsers/vontobel/valuation_api.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/resources/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/resources/assets.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/resources/trades.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/import_export/utils.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/jinja2/wbportfolio/sql/aum_nnm.sql +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/kpi_handlers/nnm.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/locale/de/LC_MESSAGES/django.mo +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/locale/de/LC_MESSAGES/django.po +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/locale/en/LC_MESSAGES/django.mo +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/locale/en/LC_MESSAGES/django.po +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/locale/fr/LC_MESSAGES/django.mo +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/locale/fr/LC_MESSAGES/django.po +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/metric/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/metric/backends/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/metric/backends/base.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/metric/backends/constants.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/metric/backends/portfolio_base.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/metric/backends/portfolio_esg.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/metric/tests/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/metric/tests/conftest.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/metric/tests/test_portfolio_base.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/metric/tests/test_portfolio_esg.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0001_initial_squashed.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0002_product_default_sub_account_squashed_0039_alter_assetallocation_company_and_more.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0040_instrument_financial_instrument.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0041_remove_listresearch_research_ptr_and_more.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0042_instrumentlist_instrumentlistthroughmodel_and_more.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0043_alter_instrumentlistthroughmodel_options_and_more.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0044_alter_instrumentlist_identifier.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0045_alter_instrument_financial_instrument.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0046_add_product_default_account.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0047_remove_product_default_sub_account.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0048_alter_trade_status.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0049_trade_claimed_shares.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0050_fees_fee_date_fees_wbportfolio_transac_1f7a29_idx.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0051_delete_macroreview.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0052_remove_cash_instrument_ptr_and_more.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0053_remove_product_group.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0054_portfolioinstrumentpreferredclassificationthroughmodel_and_more.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0055_remove_product__custom_management_rebates_and_more.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0056_remove_companyportfoliodata_assets_under_management_currency_and_more.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0057_alter_portfolio_preferred_instrument_classifications_and_more.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0058_pmsinstrument.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0059_fees_unique_fees.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0060_alter_portfolioportfoliothroughmodel_type.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0061_portfolio_bank_accounts_product_bank_account_and_more.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0062_alter_dailyportfoliocashflow_options.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0063_accountreconciliation_accountreconciliationline_and_more.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0064_alter_portfolio_managers_portfolio_is_tracked_and_more.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0065_alter_portfolio_managers_claim_as_shares_and_more.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0066_assetposition_initial_shares_at_custodian_and_more.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0067_assetposition_unique_asset_position.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0068_trade_internal_trade_trade_marked_as_internal_and_more.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0069_remove_portfolio_is_invested_and_more.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0070_remove_assetposition_unique_asset_position_and_more.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0071_alter_trade_options_alter_trade_order.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0072_trade_diff_shares.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0073_remove_product_price_computation_and_more.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0074_alter_rebalancer_frequency_and_more.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0075_portfolio_initial_position_date_and_more.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0076_alter_dividendtransaction_price_and_more.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0077_remove_transaction_currency_and_more.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0078_trade_drift_factor.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/0079_alter_trade_drift_factor.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/migrations/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/adjustments.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/custodians.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/exceptions.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/graphs/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/graphs/portfolio.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/graphs/utils.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/indexes.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/llm/wbcrm/analyze_relationship.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/mixins/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/mixins/instruments.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/mixins/liquidity_stress_test.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/portfolio_cash_flow.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/portfolio_cash_targets.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/portfolio_relationship.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/portfolio_swing_pricings.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/product_groups.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/products.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/reconciliations/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/reconciliations/account_reconciliation_lines.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/reconciliations/account_reconciliations.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/reconciliations/reconciliations.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/registers.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/roles.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/signals.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/transactions/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/transactions/claim.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/transactions/dividends.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/transactions/fees.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/transactions/transactions.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/models/utils.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/permissions.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/pms/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/pms/analytics/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/pms/statistics/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/pms/trading/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/preferences.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/rebalancing/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/rebalancing/decorators.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/rebalancing/models/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/rebalancing/models/composite.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/rebalancing/models/model_portfolio.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/reports/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/reports/monthly_position_report.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/risk_management/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/risk_management/backends/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/risk_management/backends/accounts.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/risk_management/backends/controversy_portfolio.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/risk_management/backends/exposure_portfolio.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/risk_management/backends/instrument_list_portfolio.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/risk_management/backends/liquidity_risk.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/risk_management/backends/liquidity_stress_instrument.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/risk_management/backends/mixins.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/risk_management/backends/product_integrity.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/risk_management/backends/stop_loss_instrument.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/risk_management/backends/stop_loss_portfolio.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/risk_management/backends/ucits_portfolio.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/risk_management/tests/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/risk_management/tests/conftest.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/risk_management/tests/test_accounts.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/risk_management/tests/test_controversy_portfolio.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/risk_management/tests/test_exposure_portfolio.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/risk_management/tests/test_instrument_list_portfolio.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/risk_management/tests/test_liquidity_risk.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/risk_management/tests/test_product_integrity.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/risk_management/tests/test_stop_loss_instrument.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/risk_management/tests/test_stop_loss_portfolio.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/risk_management/tests/test_ucits_portfolio.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/serializers/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/serializers/adjustments.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/serializers/assets.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/serializers/custodians.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/serializers/portfolio_cash_flow.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/serializers/portfolio_cash_targets.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/serializers/portfolio_relationship.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/serializers/portfolio_swing_pricing.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/serializers/portfolios.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/serializers/positions.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/serializers/product_group.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/serializers/products.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/serializers/rebalancing.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/serializers/reconciliations.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/serializers/registers.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/serializers/roles.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/serializers/signals.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/serializers/transactions/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/serializers/transactions/claim.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/serializers/transactions/dividends.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/serializers/transactions/fees.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/serializers/transactions/trades.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/static/wbportfolio/css/macro_review.css +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/static/wbportfolio/markdown/documentation/account_holding_reconciliation.md +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/static/wbportfolio/markdown/documentation/aggregate_asset_position_liquidity.md +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/static/wbportfolio/markdown/documentation/company.md +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/static/wbportfolio/markdown/documentation/earnings_instrument.md +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/static/wbportfolio/markdown/documentation/financial_analysis_instrument_ratios.md +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/static/wbportfolio/markdown/documentation/financial_statistics.md +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/static/wbportfolio/markdown/documentation/person.md +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tasks.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/templates/portfolio/email/customer_report.html +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/templates/portfolio/email/customer_trade_notification.html +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/templates/portfolio/email/email_base_template.html +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/templates/portfolio/email/rebalancing_report.html +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/templates/portfolio/macro/macro_review.html +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/conftest.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/models/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/models/test_account_reconciliation.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/models/test_assets.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/models/test_custodians.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/models/test_customer_trades.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/models/test_dividends.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/models/test_imports.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/models/test_instrument_mixins.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/models/test_merge.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/models/test_portfolio_cash_flow.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/models/test_portfolio_cash_targets.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/models/test_portfolio_swing_pricings.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/models/test_product_groups.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/models/test_products.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/models/test_roles.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/models/test_splits.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/models/transactions/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/models/transactions/test_claim.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/models/transactions/test_fees.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/models/transactions/test_rebalancing.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/models/transactions/test_trades.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/models/utils.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/pms/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/rebalancing/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/serializers/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/serializers/test_claims.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/signals.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/tests.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/viewsets/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/viewsets/test_assets.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/viewsets/test_performances.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/viewsets/test_products.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/viewsets/transactions/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/tests/viewsets/transactions/test_claims.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/urls.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/utils.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/adjustments.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/assets.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/assets_and_net_new_money_progression.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/charts/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/charts/assets.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/buttons/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/buttons/adjustments.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/buttons/assets.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/buttons/claims.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/buttons/custodians.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/buttons/fees.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/buttons/mixins.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/buttons/portfolios.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/buttons/products.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/buttons/reconciliations.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/buttons/registers.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/buttons/signals.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/buttons/trade_proposals.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/buttons/trades.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/display/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/display/adjustments.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/display/assets.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/display/claim.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/display/custodians.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/display/esg.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/display/fees.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/display/portfolio_cash_flow.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/display/portfolio_relationship.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/display/portfolios.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/display/positions.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/display/product_groups.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/display/product_performance.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/display/products.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/display/rebalancing.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/display/reconciliations.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/display/registers.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/display/roles.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/display/trades.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/endpoints/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/endpoints/adjustments.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/endpoints/assets.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/endpoints/claim.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/endpoints/custodians.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/endpoints/esg.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/endpoints/fees.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/endpoints/portfolio_relationship.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/endpoints/portfolios.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/endpoints/positions.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/endpoints/product_groups.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/endpoints/product_performance.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/endpoints/products.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/endpoints/rebalancing.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/endpoints/reconciliations.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/endpoints/roles.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/endpoints/trade_proposals.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/endpoints/trades.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/menu/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/menu/adjustments.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/menu/assets.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/menu/claim.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/menu/custodians.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/menu/fees.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/menu/instrument_prices.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/menu/portfolio_cash_flow.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/menu/portfolios.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/menu/positions.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/menu/product_groups.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/menu/product_performance.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/menu/products.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/menu/reconciliations.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/menu/registers.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/menu/roles.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/menu/trades.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/previews/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/previews/portfolios.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/titles/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/titles/adjustments.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/titles/assets.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/titles/assets_and_net_new_money_progression.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/titles/claim.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/titles/custodians.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/titles/esg.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/titles/fees.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/titles/instrument_prices.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/titles/portfolios.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/titles/positions.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/titles/product_groups.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/titles/product_performance.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/titles/products.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/titles/registers.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/titles/roles.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/configs/titles/trades.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/custodians.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/esg.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/mixins.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/portfolio_cash_flow.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/portfolio_cash_targets.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/portfolio_relationship.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/portfolio_swing_pricing.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/portfolios.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/positions.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/product_groups.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/product_performance.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/products.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/reconciliations.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/registers.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/roles.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/signals.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/transactions/__init__.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/transactions/claim.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/transactions/fees.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/transactions/mixins.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/transactions/rebalancing.py +0 -0
- {wbportfolio-1.54.2 → wbportfolio-1.54.4}/wbportfolio/viewsets/transactions/trades.py +0 -0
|
@@ -195,6 +195,8 @@ class TradeImportHandler(ImportExportHandler):
|
|
|
195
195
|
modified_objs: list[models.Model],
|
|
196
196
|
unmodified_objs: list[models.Model],
|
|
197
197
|
):
|
|
198
|
+
from wbportfolio.models.transactions.trade_proposals import replay_as_task
|
|
199
|
+
|
|
198
200
|
for instrument in set(
|
|
199
201
|
map(lambda x: x.underlying_instrument, filter(lambda t: t.is_customer_trade, created_objs + modified_objs))
|
|
200
202
|
):
|
|
@@ -203,9 +205,7 @@ class TradeImportHandler(ImportExportHandler):
|
|
|
203
205
|
|
|
204
206
|
# if the trade import relates to a trade proposal, we reset the TP after the import to ensure it contains the deleted positions (often forgotten by user)
|
|
205
207
|
for changed_trade_proposal in self.trade_proposals:
|
|
206
|
-
changed_trade_proposal.
|
|
207
|
-
target_portfolio=changed_trade_proposal._build_dto().convert_to_portfolio()
|
|
208
|
-
)
|
|
208
|
+
replay_as_task.delay(changed_trade_proposal.id)
|
|
209
209
|
|
|
210
210
|
def _post_processing_updated_object(self, _object):
|
|
211
211
|
if _object.marked_for_deletion:
|
wbportfolio-1.54.4/wbportfolio/migrations/0080_alter_trade_drift_factor_alter_trade_weighting.py
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Generated by Django 5.0.14 on 2025-07-10 09:00
|
|
2
|
+
|
|
3
|
+
from decimal import Decimal
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
dependencies = [
|
|
10
|
+
('wbportfolio', '0079_alter_trade_drift_factor'),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
migrations.AlterField(
|
|
15
|
+
model_name='assetposition',
|
|
16
|
+
name='weighting',
|
|
17
|
+
field=models.DecimalField(decimal_places=8, default=Decimal('0'), help_text='The Weight of the Asset on the price date of the Asset.', max_digits=9, verbose_name='Weight'),
|
|
18
|
+
),
|
|
19
|
+
]
|
|
@@ -112,19 +112,20 @@ class AssetPositionIterator:
|
|
|
112
112
|
return fx_rate
|
|
113
113
|
|
|
114
114
|
def _get_price(self, val_date: date, instrument: Instrument) -> float | None:
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
115
|
+
with suppress(KeyError):
|
|
116
|
+
if (_p := self._prices[val_date][instrument.id]) is not None:
|
|
117
|
+
return _p
|
|
118
|
+
return None
|
|
119
119
|
|
|
120
|
-
def _dict_to_model(self, val_date: date, instrument_id: int, weighting: float) -> "AssetPosition":
|
|
120
|
+
def _dict_to_model(self, val_date: date, instrument_id: int, weighting: float, **kwargs) -> "AssetPosition":
|
|
121
121
|
underlying_quote = self._get_instrument(instrument_id)
|
|
122
122
|
currency_fx_rate_portfolio_to_usd = self._get_fx_rate(val_date, self.portfolio.currency)
|
|
123
123
|
currency_fx_rate_instrument_to_usd = self._get_fx_rate(val_date, underlying_quote.currency)
|
|
124
124
|
price = self._get_price(val_date, underlying_quote)
|
|
125
|
-
|
|
125
|
+
|
|
126
|
+
parameters = dict(
|
|
126
127
|
underlying_quote=underlying_quote,
|
|
127
|
-
weighting=weighting,
|
|
128
|
+
weighting=round(weighting, 8),
|
|
128
129
|
date=val_date,
|
|
129
130
|
asset_valuation_date=val_date,
|
|
130
131
|
is_estimated=True,
|
|
@@ -137,15 +138,14 @@ class AssetPositionIterator:
|
|
|
137
138
|
underlying_quote_price=None,
|
|
138
139
|
underlying_instrument=None,
|
|
139
140
|
)
|
|
141
|
+
parameters.update(kwargs)
|
|
142
|
+
position = AssetPosition(**parameters)
|
|
140
143
|
position.pre_save(
|
|
141
144
|
infer_underlying_quote_price=self.infer_underlying_quote_price
|
|
142
145
|
) # inferring underlying quote price is potentially very slow for big dataset of positions, it's not very needed for model portfolio so we disable it
|
|
143
146
|
return position
|
|
144
147
|
|
|
145
|
-
def add(
|
|
146
|
-
self,
|
|
147
|
-
positions: list["AssetPosition"] | tuple[date, dict[int, float]],
|
|
148
|
-
):
|
|
148
|
+
def add(self, positions: list["AssetPosition"] | tuple[date, dict[int, float]], **kwargs):
|
|
149
149
|
"""
|
|
150
150
|
Add multiple positions efficiently with batch processing
|
|
151
151
|
|
|
@@ -157,7 +157,7 @@ class AssetPositionIterator:
|
|
|
157
157
|
positions = [(val_date, i, w) for i, w in positions[1].items()] # unflatten data to make it iterable
|
|
158
158
|
for position in positions:
|
|
159
159
|
if not isinstance(position, AssetPosition):
|
|
160
|
-
position = self._dict_to_model(*position)
|
|
160
|
+
position = self._dict_to_model(*position, **kwargs)
|
|
161
161
|
|
|
162
162
|
# Generate unique composite key
|
|
163
163
|
key = (
|
|
@@ -464,8 +464,8 @@ class AssetPosition(ImportMixin, models.Model):
|
|
|
464
464
|
# )
|
|
465
465
|
|
|
466
466
|
weighting = models.DecimalField(
|
|
467
|
-
decimal_places=
|
|
468
|
-
max_digits=
|
|
467
|
+
decimal_places=8,
|
|
468
|
+
max_digits=9,
|
|
469
469
|
default=Decimal(0),
|
|
470
470
|
verbose_name="Weight",
|
|
471
471
|
help_text="The Weight of the Asset on the price date of the Asset.",
|
|
@@ -693,15 +693,15 @@ class AssetPosition(ImportMixin, models.Model):
|
|
|
693
693
|
def get_portfolio_total_asset_value(self) -> Decimal:
|
|
694
694
|
return self.portfolio.get_total_asset_value(self.date)
|
|
695
695
|
|
|
696
|
-
def _build_dto(self,
|
|
696
|
+
def _build_dto(self, **kwargs) -> PositionDTO:
|
|
697
697
|
"""
|
|
698
698
|
Data Transfer Object
|
|
699
699
|
Returns:
|
|
700
700
|
DTO position object
|
|
701
701
|
"""
|
|
702
|
-
|
|
702
|
+
parameters = dict(
|
|
703
703
|
underlying_instrument=self.underlying_quote.id,
|
|
704
|
-
weighting=self.weighting
|
|
704
|
+
weighting=self.weighting,
|
|
705
705
|
shares=self._shares,
|
|
706
706
|
date=self.date,
|
|
707
707
|
asset_valuation_date=self.asset_valuation_date,
|
|
@@ -726,8 +726,9 @@ class AssetPosition(ImportMixin, models.Model):
|
|
|
726
726
|
price=self._price,
|
|
727
727
|
currency_fx_rate=self._currency_fx_rate,
|
|
728
728
|
portfolio_created=self.portfolio_created.id if self.portfolio_created else None,
|
|
729
|
-
**kwargs,
|
|
730
729
|
)
|
|
730
|
+
parameters.update(kwargs)
|
|
731
|
+
return PositionDTO(**parameters)
|
|
731
732
|
|
|
732
733
|
@cached_property
|
|
733
734
|
@admin.display(description="Adjusting Factor (adjustment)")
|
|
@@ -18,7 +18,6 @@ from django.db.models import (
|
|
|
18
18
|
Q,
|
|
19
19
|
QuerySet,
|
|
20
20
|
Sum,
|
|
21
|
-
Value,
|
|
22
21
|
)
|
|
23
22
|
from django.db.models.signals import post_save
|
|
24
23
|
from django.dispatch import receiver
|
|
@@ -26,12 +25,13 @@ from django.utils import timezone
|
|
|
26
25
|
from django.utils.functional import cached_property
|
|
27
26
|
from pandas._libs.tslibs.offsets import BDay
|
|
28
27
|
from skfolio.preprocessing import prices_to_returns
|
|
29
|
-
from wbcore.contrib.currency.models import Currency
|
|
28
|
+
from wbcore.contrib.currency.models import Currency
|
|
30
29
|
from wbcore.contrib.notifications.utils import create_notification_type
|
|
31
30
|
from wbcore.models import WBModel
|
|
32
31
|
from wbcore.utils.importlib import import_from_dotted_path
|
|
33
32
|
from wbcore.utils.models import ActiveObjectManager, DeleteToDisableMixin
|
|
34
33
|
from wbfdm.contrib.metric.tasks import compute_metrics_as_task
|
|
34
|
+
from wbfdm.enums import MarketData
|
|
35
35
|
from wbfdm.models import Instrument, InstrumentType
|
|
36
36
|
from wbfdm.models.instruments.instrument_prices import InstrumentPrice
|
|
37
37
|
from wbfdm.signals import investable_universe_updated
|
|
@@ -45,6 +45,7 @@ from wbportfolio.models.portfolio_relationship import (
|
|
|
45
45
|
from wbportfolio.models.products import Product
|
|
46
46
|
from wbportfolio.pms.analytics.portfolio import Portfolio as AnalyticPortfolio
|
|
47
47
|
from wbportfolio.pms.typing import Portfolio as PortfolioDTO
|
|
48
|
+
from wbportfolio.pms.typing import Position as PositionDTO
|
|
48
49
|
|
|
49
50
|
from . import ProductGroup
|
|
50
51
|
from .exceptions import InvalidAnalyticPortfolio
|
|
@@ -54,34 +55,13 @@ if TYPE_CHECKING:
|
|
|
54
55
|
from wbportfolio.models.transactions.trade_proposals import TradeProposal
|
|
55
56
|
|
|
56
57
|
|
|
57
|
-
def get_prices(instrument_ids: list[int], from_date: date, to_date: date) -> dict[date, dict[int, float]]:
|
|
58
|
-
"""
|
|
59
|
-
Utility to fetch raw prices
|
|
60
|
-
"""
|
|
61
|
-
prices = InstrumentPrice.objects.filter(instrument__in=instrument_ids, date__gte=from_date, date__lte=to_date)
|
|
62
|
-
df = (
|
|
63
|
-
pd.DataFrame(
|
|
64
|
-
prices.filter_only_valid_prices().values_list("instrument", "net_value", "date"),
|
|
65
|
-
columns=["instrument", "net_value", "date"],
|
|
66
|
-
)
|
|
67
|
-
.pivot_table(index="date", values="net_value", columns="instrument")
|
|
68
|
-
.astype(float)
|
|
69
|
-
.sort_index()
|
|
70
|
-
)
|
|
71
|
-
ts = pd.bdate_range(df.index.min(), df.index.max(), freq="B")
|
|
72
|
-
df = df.reindex(ts)
|
|
73
|
-
df = df.ffill()
|
|
74
|
-
df.index = pd.to_datetime(df.index)
|
|
75
|
-
return {ts.date(): row for ts, row in df.to_dict("index").items()}
|
|
76
|
-
|
|
77
|
-
|
|
78
58
|
def get_returns(
|
|
79
59
|
instrument_ids: list[int],
|
|
80
60
|
from_date: date,
|
|
81
61
|
to_date: date,
|
|
82
62
|
to_currency: Currency | None = None,
|
|
83
63
|
ffill_returns: bool = True,
|
|
84
|
-
) -> pd.DataFrame:
|
|
64
|
+
) -> tuple[dict[date, dict[int, float]], pd.DataFrame]:
|
|
85
65
|
"""
|
|
86
66
|
Utility methods to get instrument returns for a given date range
|
|
87
67
|
|
|
@@ -92,31 +72,40 @@ def get_returns(
|
|
|
92
72
|
Returns:
|
|
93
73
|
Return a tuple of the returns and the last prices series for conveniance
|
|
94
74
|
"""
|
|
75
|
+
# if to_currency:
|
|
76
|
+
# fx_rate = CurrencyFXRates.get_fx_rates_subquery_for_two_currencies("date", "instrument__currency", to_currency)
|
|
77
|
+
# else:
|
|
78
|
+
# fx_rate = Value(Decimal(1.0))
|
|
79
|
+
# prices = InstrumentPrice.objects.filter(
|
|
80
|
+
# instrument__in=instrument_ids, date__gte=from_date, date__lte=to_date
|
|
81
|
+
# ).annotate(fx_rate=fx_rate, price_fx_portfolio=F("net_value") * F("fx_rate"))
|
|
82
|
+
# prices_df = (
|
|
83
|
+
# pd.DataFrame(
|
|
84
|
+
# prices.filter_only_valid_prices().values_list("instrument", "price_fx_portfolio", "date"),
|
|
85
|
+
# columns=["instrument", "price_fx_portfolio", "date"],
|
|
86
|
+
# )
|
|
87
|
+
# .pivot_table(index="date", values="price_fx_portfolio", columns="instrument")
|
|
88
|
+
# .astype(float)
|
|
89
|
+
# .sort_index()
|
|
90
|
+
# )
|
|
91
|
+
kwargs = dict(from_date=from_date, to_date=to_date, values=[MarketData.CLOSE])
|
|
95
92
|
if to_currency:
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
fx_rate = Value(Decimal(1.0))
|
|
99
|
-
prices = InstrumentPrice.objects.filter(
|
|
100
|
-
instrument__in=instrument_ids, date__gte=from_date, date__lte=to_date
|
|
101
|
-
).annotate(fx_rate=fx_rate, price_fx_portfolio=F("net_value") * F("fx_rate"))
|
|
102
|
-
prices_df = (
|
|
103
|
-
pd.DataFrame(
|
|
104
|
-
prices.filter_only_valid_prices().values_list("instrument", "price_fx_portfolio", "date"),
|
|
105
|
-
columns=["instrument", "price_fx_portfolio", "date"],
|
|
106
|
-
)
|
|
107
|
-
.pivot_table(index="date", values="price_fx_portfolio", columns="instrument")
|
|
108
|
-
.astype(float)
|
|
109
|
-
.sort_index()
|
|
110
|
-
)
|
|
93
|
+
kwargs["target_currency"] = to_currency.key
|
|
94
|
+
prices_df = pd.DataFrame(Instrument.objects.filter(id__in=instrument_ids).dl.market_data(**kwargs))
|
|
111
95
|
if prices_df.empty:
|
|
112
96
|
raise InvalidAnalyticPortfolio()
|
|
97
|
+
prices_df = prices_df[["instrument_id", "close", "valuation_date"]].pivot(
|
|
98
|
+
index="valuation_date", columns="instrument_id", values="close"
|
|
99
|
+
)
|
|
113
100
|
ts = pd.bdate_range(prices_df.index.min(), prices_df.index.max(), freq="B")
|
|
114
101
|
prices_df = prices_df.reindex(ts)
|
|
115
102
|
if ffill_returns:
|
|
116
103
|
prices_df = prices_df.ffill()
|
|
117
104
|
prices_df.index = pd.to_datetime(prices_df.index)
|
|
118
105
|
returns = prices_to_returns(prices_df, drop_inceptions_nan=False, fill_nan=ffill_returns)
|
|
119
|
-
return
|
|
106
|
+
return {ts.date(): row for ts, row in prices_df.replace(np.nan, None).to_dict("index").items()}, returns.replace(
|
|
107
|
+
[np.inf, -np.inf, np.nan], 0
|
|
108
|
+
)
|
|
120
109
|
|
|
121
110
|
|
|
122
111
|
class DefaultPortfolioQueryset(QuerySet):
|
|
@@ -353,26 +342,23 @@ class Portfolio(DeleteToDisableMixin, WBModel):
|
|
|
353
342
|
instrument.delisted_date = date.today() - timedelta(days=1)
|
|
354
343
|
instrument.save()
|
|
355
344
|
|
|
356
|
-
def _build_dto(self, val_date: date, **extra_kwargs) -> PortfolioDTO:
|
|
345
|
+
def _build_dto(self, val_date: date, include_drift_factor: bool = False, **extra_kwargs) -> PortfolioDTO:
|
|
357
346
|
"returns the dto representation of this portfolio at the specified date"
|
|
358
347
|
assets = self.assets.filter(date=val_date, **extra_kwargs)
|
|
359
348
|
try:
|
|
360
349
|
drifted_weights = self.get_analytic_portfolio(val_date).get_next_weights()
|
|
361
350
|
except InvalidAnalyticPortfolio:
|
|
362
351
|
drifted_weights = {}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
]
|
|
374
|
-
),
|
|
375
|
-
)
|
|
352
|
+
positions = []
|
|
353
|
+
for asset in assets:
|
|
354
|
+
drift_factor = (
|
|
355
|
+
Decimal(drifted_weights.get(asset.underlying_quote.id, asset.weighting)) / asset.weighting
|
|
356
|
+
if asset.weighting
|
|
357
|
+
else Decimal(1.0)
|
|
358
|
+
)
|
|
359
|
+
positions.append(asset._build_dto(drift_factor=drift_factor))
|
|
360
|
+
|
|
361
|
+
return PortfolioDTO(positions)
|
|
376
362
|
|
|
377
363
|
def get_weights(self, val_date: date) -> dict[int, float]:
|
|
378
364
|
"""
|
|
@@ -410,7 +396,7 @@ class Portfolio(DeleteToDisableMixin, WBModel):
|
|
|
410
396
|
if not weights:
|
|
411
397
|
weights = self.get_weights(val_date)
|
|
412
398
|
return_date = (val_date + BDay(1)).date()
|
|
413
|
-
returns = get_returns(
|
|
399
|
+
_, returns = get_returns(
|
|
414
400
|
list(weights.keys()), (val_date - BDay(2)).date(), return_date, to_currency=self.currency, **kwargs
|
|
415
401
|
)
|
|
416
402
|
if pd.Timestamp(return_date) not in returns.index:
|
|
@@ -705,6 +691,10 @@ class Portfolio(DeleteToDisableMixin, WBModel):
|
|
|
705
691
|
if portfolio := asset.underlying_instrument.portfolio:
|
|
706
692
|
yield portfolio, asset.weighting
|
|
707
693
|
|
|
694
|
+
def get_next_rebalancing_date(self, start_date: date) -> date | None:
|
|
695
|
+
if automatic_rebalancer := getattr(self, "automatic_rebalancer", None):
|
|
696
|
+
return automatic_rebalancer.get_next_rebalancing_date(start_date)
|
|
697
|
+
|
|
708
698
|
def change_at_date(
|
|
709
699
|
self,
|
|
710
700
|
val_date: date,
|
|
@@ -756,17 +746,20 @@ class Portfolio(DeleteToDisableMixin, WBModel):
|
|
|
756
746
|
self.handle_controlling_portfolio_change_at_date(val_date)
|
|
757
747
|
|
|
758
748
|
def handle_controlling_portfolio_change_at_date(self, val_date: date):
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
rel.
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
749
|
+
if self.is_tracked:
|
|
750
|
+
for rel in PortfolioPortfolioThroughModel.objects.filter(
|
|
751
|
+
dependency_portfolio=self,
|
|
752
|
+
type=PortfolioPortfolioThroughModel.Type.PRIMARY,
|
|
753
|
+
portfolio__is_lookthrough=True,
|
|
754
|
+
):
|
|
755
|
+
rel.portfolio.compute_lookthrough(val_date)
|
|
756
|
+
for rel in PortfolioPortfolioThroughModel.objects.filter(
|
|
757
|
+
dependency_portfolio=self, type=PortfolioPortfolioThroughModel.Type.MODEL
|
|
758
|
+
):
|
|
759
|
+
rel.portfolio.evaluate_rebalancing(val_date)
|
|
760
|
+
for dependent_portfolio in self.get_child_portfolios(val_date):
|
|
761
|
+
dependent_portfolio.change_at_date(val_date)
|
|
762
|
+
dependent_portfolio.handle_controlling_portfolio_change_at_date(val_date)
|
|
770
763
|
|
|
771
764
|
def evaluate_rebalancing(self, val_date: date):
|
|
772
765
|
if hasattr(self, "automatic_rebalancer"):
|
|
@@ -802,7 +795,9 @@ class Portfolio(DeleteToDisableMixin, WBModel):
|
|
|
802
795
|
): # if price date is the latest instrument price date, we recompute the last valuation data
|
|
803
796
|
instrument.update_last_valuation_date()
|
|
804
797
|
|
|
805
|
-
def drift_weights(
|
|
798
|
+
def drift_weights(
|
|
799
|
+
self, start_date: date, end_date: date, stop_at_rebalancing: bool = False
|
|
800
|
+
) -> tuple[AssetPositionIterator, "TradeProposal"]:
|
|
806
801
|
logger.info(f"drift weights for {self} from {start_date:%Y-%m-%d} to {end_date:%Y-%m-%d}")
|
|
807
802
|
rebalancer = getattr(self, "automatic_rebalancer", None)
|
|
808
803
|
# Get initial weights
|
|
@@ -814,7 +809,8 @@ class Portfolio(DeleteToDisableMixin, WBModel):
|
|
|
814
809
|
|
|
815
810
|
# Get returns and prices data for the whole date range
|
|
816
811
|
instrument_ids = list(weights.keys())
|
|
817
|
-
|
|
812
|
+
|
|
813
|
+
prices, returns = get_returns(
|
|
818
814
|
instrument_ids,
|
|
819
815
|
(start_date - BDay(3)).date(),
|
|
820
816
|
end_date,
|
|
@@ -822,7 +818,6 @@ class Portfolio(DeleteToDisableMixin, WBModel):
|
|
|
822
818
|
ffill_returns=True,
|
|
823
819
|
)
|
|
824
820
|
# Get raw prices to speed up asset position creation
|
|
825
|
-
prices = get_prices(instrument_ids, (start_date - BDay(3)).date(), end_date)
|
|
826
821
|
# Instantiate the position iterator with the initial weights
|
|
827
822
|
positions = AssetPositionIterator(self, prices=prices)
|
|
828
823
|
last_trade_proposal = None
|
|
@@ -830,30 +825,43 @@ class Portfolio(DeleteToDisableMixin, WBModel):
|
|
|
830
825
|
to_date = to_date_ts.date()
|
|
831
826
|
to_is_active = self.is_active_at_date(to_date)
|
|
832
827
|
logger.info(f"Processing {to_date:%Y-%m-%d}")
|
|
828
|
+
|
|
829
|
+
try:
|
|
830
|
+
last_returns = returns.loc[[to_date_ts], :]
|
|
831
|
+
analytic_portfolio = AnalyticPortfolio(weights=weights, X=last_returns)
|
|
832
|
+
drifted_weights = analytic_portfolio.get_next_weights()
|
|
833
|
+
except KeyError: # if no return for that date, we break and continue
|
|
834
|
+
drifted_weights = weights
|
|
835
|
+
|
|
833
836
|
if rebalancer and rebalancer.is_valid(to_date):
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
+
effective_portfolio = PortfolioDTO(
|
|
838
|
+
positions=[
|
|
839
|
+
PositionDTO(
|
|
840
|
+
date=to_date,
|
|
841
|
+
underlying_instrument=i,
|
|
842
|
+
weighting=Decimal(w),
|
|
843
|
+
drift_factor=Decimal(drifted_weights.get(i, w) / float(w)) if w else Decimal(1.0),
|
|
844
|
+
)
|
|
845
|
+
for i, w in weights.items()
|
|
846
|
+
]
|
|
847
|
+
)
|
|
848
|
+
last_trade_proposal = rebalancer.evaluate_rebalancing(to_date, effective_portfolio=effective_portfolio)
|
|
849
|
+
if stop_at_rebalancing:
|
|
837
850
|
break
|
|
838
|
-
target_portfolio = last_trade_proposal._build_dto().convert_to_portfolio()
|
|
839
851
|
next_weights = {
|
|
840
|
-
|
|
841
|
-
for
|
|
852
|
+
trade.underlying_instrument: float(trade._target_weight)
|
|
853
|
+
for trade in last_trade_proposal.trades.all().annotate_base_info()
|
|
842
854
|
}
|
|
855
|
+
positions.add((to_date, next_weights), is_estimated=False)
|
|
843
856
|
else:
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
else:
|
|
853
|
-
positions.add(
|
|
854
|
-
(to_date, {underlying_quote_id: 0.0 for underlying_quote_id in weights.keys()})
|
|
855
|
-
) # if we have no return or portfolio is not active anymore, we return an emptied portfolio
|
|
856
|
-
break
|
|
857
|
+
next_weights = drifted_weights
|
|
858
|
+
if to_is_active:
|
|
859
|
+
positions.add((to_date, next_weights))
|
|
860
|
+
else:
|
|
861
|
+
positions.add(
|
|
862
|
+
(to_date, {underlying_quote_id: 0.0 for underlying_quote_id in weights.keys()})
|
|
863
|
+
) # if we have no return or portfolio is not active anymore, we return an emptied portfolio
|
|
864
|
+
break
|
|
857
865
|
weights = next_weights
|
|
858
866
|
return positions, last_trade_proposal
|
|
859
867
|
|
|
@@ -1023,6 +1031,7 @@ class Portfolio(DeleteToDisableMixin, WBModel):
|
|
|
1023
1031
|
delete_leftovers: bool = False,
|
|
1024
1032
|
force_save: bool = False,
|
|
1025
1033
|
compute_metrics: bool = True,
|
|
1034
|
+
broadcast_changes_at_date: bool = True,
|
|
1026
1035
|
**kwargs,
|
|
1027
1036
|
):
|
|
1028
1037
|
if positions:
|
|
@@ -1071,8 +1080,9 @@ class Portfolio(DeleteToDisableMixin, WBModel):
|
|
|
1071
1080
|
basket_id=self.id,
|
|
1072
1081
|
basket_content_type_id=ContentType.objects.get_for_model(Portfolio).id,
|
|
1073
1082
|
)
|
|
1074
|
-
|
|
1075
|
-
|
|
1083
|
+
if broadcast_changes_at_date:
|
|
1084
|
+
for update_date, changed_weights in positions.get_weights().items():
|
|
1085
|
+
self.change_at_date(update_date, changed_weights=changed_weights, **kwargs)
|
|
1076
1086
|
|
|
1077
1087
|
@classmethod
|
|
1078
1088
|
def _get_or_create_portfolio(cls, instrument_handler, portfolio_data):
|
|
@@ -43,9 +43,16 @@ class RebalancingModel(models.Model):
|
|
|
43
43
|
return import_from_dotted_path(self.class_path)
|
|
44
44
|
|
|
45
45
|
def get_target_portfolio(
|
|
46
|
-
self,
|
|
46
|
+
self,
|
|
47
|
+
portfolio: Portfolio,
|
|
48
|
+
trade_date: date,
|
|
49
|
+
last_effective_date: date,
|
|
50
|
+
effective_portfolio: PortfolioDTO | None = None,
|
|
51
|
+
**kwargs,
|
|
47
52
|
) -> PortfolioDTO:
|
|
48
|
-
model = self.model_class(
|
|
53
|
+
model = self.model_class(
|
|
54
|
+
portfolio, trade_date, last_effective_date, effective_portfolio=effective_portfolio, **kwargs
|
|
55
|
+
)
|
|
49
56
|
if not model.is_valid():
|
|
50
57
|
raise ValidationError(model.validation_errors)
|
|
51
58
|
return model.get_target_portfolio()
|
|
@@ -115,7 +122,7 @@ class Rebalancer(ComplexToStringMixin, models.Model):
|
|
|
115
122
|
break
|
|
116
123
|
return False
|
|
117
124
|
|
|
118
|
-
def evaluate_rebalancing(self, trade_date: date):
|
|
125
|
+
def evaluate_rebalancing(self, trade_date: date, effective_portfolio=None):
|
|
119
126
|
trade_proposal, _ = TradeProposal.objects.get_or_create(
|
|
120
127
|
trade_date=trade_date,
|
|
121
128
|
portfolio=self.portfolio,
|
|
@@ -126,24 +133,27 @@ class Rebalancer(ComplexToStringMixin, models.Model):
|
|
|
126
133
|
)
|
|
127
134
|
|
|
128
135
|
if trade_proposal.rebalancing_model == self.rebalancing_model:
|
|
129
|
-
trade_proposal.status = TradeProposal.Status.DRAFT
|
|
130
136
|
try:
|
|
131
137
|
logger.info(
|
|
132
138
|
f"Getting target portfolio ({self.portfolio}) for rebalancing model {self.rebalancing_model} for trade date {trade_date:%Y-%m-%d}"
|
|
133
139
|
)
|
|
134
140
|
target_portfolio = self.rebalancing_model.get_target_portfolio(
|
|
135
|
-
self.portfolio,
|
|
141
|
+
self.portfolio,
|
|
142
|
+
trade_proposal.trade_date,
|
|
143
|
+
trade_proposal.value_date,
|
|
144
|
+
effective_portfolio=effective_portfolio,
|
|
145
|
+
**self.parameters,
|
|
146
|
+
)
|
|
147
|
+
trade_proposal.approve_workflow(
|
|
148
|
+
approve_automatically=self.approve_trade_proposal_automatically,
|
|
149
|
+
target_portfolio=target_portfolio,
|
|
150
|
+
effective_portfolio=effective_portfolio,
|
|
136
151
|
)
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
if self.approve_trade_proposal_automatically and self.portfolio.can_be_rebalanced:
|
|
140
|
-
trade_proposal.approve(replay=False)
|
|
141
|
-
except ValidationError:
|
|
152
|
+
except ValidationError as e:
|
|
153
|
+
logger.warning(f"Validation error while approving the orders: {e}")
|
|
142
154
|
# If we encountered a validation error, we set the trade proposal as failed
|
|
143
155
|
trade_proposal.status = TradeProposal.Status.FAILED
|
|
144
|
-
|
|
145
156
|
trade_proposal.save()
|
|
146
|
-
|
|
147
157
|
return trade_proposal
|
|
148
158
|
|
|
149
159
|
@property
|