wbportfolio 1.49.0__tar.gz → 1.49.2__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.49.0 → wbportfolio-1.49.2}/PKG-INFO +1 -1
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/factories/dividends.py +1 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/handlers/dividend.py +1 -1
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/handlers/fees.py +1 -1
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/handlers/portfolio_cash_flow.py +1 -1
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/handlers/trade.py +5 -2
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/sg_lux/custodian_positions.py +1 -1
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/sg_lux/portfolio_future_cash_flow.py +1 -1
- wbportfolio-1.49.2/wbportfolio/migrations/0076_alter_dividendtransaction_price_and_more.py +126 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/portfolio.py +19 -6
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/transactions/claim.py +8 -7
- wbportfolio-1.49.2/wbportfolio/models/transactions/dividends.py +15 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/transactions/trade_proposals.py +23 -20
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/transactions/trades.py +9 -12
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/transactions/transactions.py +37 -37
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/rebalancing/models/market_capitalization_weighted.py +13 -16
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/serializers/portfolios.py +1 -1
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/models/test_portfolios.py +1 -1
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/rebalancing/test_models.py +2 -2
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/assets.py +1 -1
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/display/assets.py +0 -11
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/display/portfolios.py +2 -2
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/display/products.py +0 -13
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/display/trades.py +1 -9
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/endpoints/transactions.py +6 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/portfolios.py +17 -1
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/transactions/trade_proposals.py +6 -4
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/transactions/trades.py +21 -3
- wbportfolio-1.49.0/wbportfolio/models/transactions/dividends.py +0 -32
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/.gitignore +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/LICENSE +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/pyproject.toml +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/admin/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/admin/asset.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/admin/custodians.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/admin/indexes.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/admin/portfolio.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/admin/portfolio_relationships.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/admin/product_groups.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/admin/products.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/admin/reconciliations.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/admin/registers.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/admin/roles.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/admin/transactions/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/admin/transactions/claim.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/admin/transactions/dividends.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/admin/transactions/fees.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/admin/transactions/rebalancing.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/admin/transactions/trades.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/admin/transactions/transactions.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/analysis/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/analysis/claims.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/apps.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/contrib/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/contrib/company_portfolio/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/contrib/company_portfolio/admin.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/contrib/company_portfolio/apps.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/contrib/company_portfolio/configs/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/contrib/company_portfolio/configs/display.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/contrib/company_portfolio/configs/endpoints.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/contrib/company_portfolio/configs/previews.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/contrib/company_portfolio/constants.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/contrib/company_portfolio/dynamic_preferences_registry.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/contrib/company_portfolio/factories.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/contrib/company_portfolio/filters.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/contrib/company_portfolio/management.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/contrib/company_portfolio/migrations/0001_initial.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/contrib/company_portfolio/migrations/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/contrib/company_portfolio/models.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/contrib/company_portfolio/scripts.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/contrib/company_portfolio/serializers.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/contrib/company_portfolio/tasks.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/contrib/company_portfolio/tests/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/contrib/company_portfolio/tests/conftest.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/contrib/company_portfolio/tests/test_models.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/contrib/company_portfolio/urls.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/contrib/company_portfolio/viewsets.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/defaults/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/defaults/fees/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/defaults/fees/default.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/dynamic_preferences_registry.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/factories/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/factories/adjustments.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/factories/assets.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/factories/claim.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/factories/custodians.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/factories/fees.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/factories/indexes.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/factories/portfolio_cash_flow.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/factories/portfolio_cash_targets.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/factories/portfolio_swing_pricings.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/factories/portfolios.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/factories/product_groups.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/factories/products.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/factories/rebalancing.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/factories/reconciliations.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/factories/roles.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/factories/trades.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/factories/transactions.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/fdm/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/fdm/tasks.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/filters/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/filters/assets.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/filters/assets_and_net_new_money_progression.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/filters/custodians.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/filters/esg.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/filters/performances.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/filters/portfolios.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/filters/positions.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/filters/products.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/filters/roles.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/filters/signals.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/filters/transactions/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/filters/transactions/claim.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/filters/transactions/fees.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/filters/transactions/mixins.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/filters/transactions/trades.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/filters/transactions/transactions.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/fixtures/product_factsheets.yaml +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/fixtures/wbportfolio.yaml.gz +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/fixtures/wbrisk_management.yaml.gz +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/backends/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/backends/refinitiv/adjustment.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/backends/ubs/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/backends/ubs/asset_position.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/backends/ubs/fees.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/backends/ubs/instrument_price.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/backends/ubs/mixin.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/backends/utils.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/backends/wbfdm/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/backends/wbfdm/adjustment.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/backends/wbfdm/dividend.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/backends/wbfdm/mixin.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/handlers/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/handlers/adjustment.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/handlers/asset_position.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/handlers/register.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/default_mapping.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/jpmorgan/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/jpmorgan/customer_trade.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/jpmorgan/fees.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/jpmorgan/strategy.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/jpmorgan/valuation.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/leonteq/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/leonteq/customer_trade.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/leonteq/equity.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/leonteq/fees.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/leonteq/trade.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/leonteq/valuation.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/natixis/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/natixis/customer_trade.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/natixis/d1_customer_trade.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/natixis/d1_equity.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/natixis/d1_fees.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/natixis/d1_trade.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/natixis/d1_valuation.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/natixis/dividend.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/natixis/equity.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/natixis/fees.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/natixis/trade.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/natixis/utils.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/natixis/valuation.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/refinitiv/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/refinitiv/adjustment.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/sg_lux/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/sg_lux/customer_trade.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/sg_lux/customer_trade_pending_slk.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/sg_lux/customer_trade_slk.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/sg_lux/customer_trade_without_pw.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/sg_lux/equity.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/sg_lux/fees.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/sg_lux/perf_fees.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/sg_lux/portfolio_cash_flow.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/sg_lux/registers.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/sg_lux/sylk.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/sg_lux/utils.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/sg_lux/valuation.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/societe_generale/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/societe_generale/customer_trade.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/societe_generale/strategy.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/societe_generale/valuation.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/tellco/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/tellco/customer_trade.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/tellco/equity.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/tellco/valuation.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/ubs/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/ubs/api/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/ubs/api/asset_position.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/ubs/api/fees.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/ubs/api/instrument_price.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/ubs/api/utils.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/ubs/customer_trade.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/ubs/equity.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/ubs/historical_customer_trade.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/ubs/valuation.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/vontobel/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/vontobel/asset_position.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/vontobel/customer_trade.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/vontobel/historical_customer_trade.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/vontobel/instrument.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/vontobel/management_fees.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/vontobel/performance_fees.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/vontobel/trade.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/vontobel/utils.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/vontobel/valuation.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/parsers/vontobel/valuation_api.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/resources/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/resources/assets.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/resources/trades.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/utils.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/jinja2/wbportfolio/sql/aum_nnm.sql +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/kpi_handlers/nnm.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/metric/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/metric/backends/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/metric/backends/base.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/metric/backends/constants.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/metric/backends/portfolio_base.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/metric/backends/portfolio_esg.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/metric/tests/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/metric/tests/conftest.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/metric/tests/test_portfolio_base.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/metric/tests/test_portfolio_esg.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0001_initial_squashed.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0002_product_default_sub_account_squashed_0039_alter_assetallocation_company_and_more.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0040_instrument_financial_instrument.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0041_remove_listresearch_research_ptr_and_more.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0042_instrumentlist_instrumentlistthroughmodel_and_more.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0043_alter_instrumentlistthroughmodel_options_and_more.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0044_alter_instrumentlist_identifier.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0045_alter_instrument_financial_instrument.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0046_add_product_default_account.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0047_remove_product_default_sub_account.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0048_alter_trade_status.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0049_trade_claimed_shares.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0050_fees_fee_date_fees_wbportfolio_transac_1f7a29_idx.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0051_delete_macroreview.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0052_remove_cash_instrument_ptr_and_more.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0053_remove_product_group.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0054_portfolioinstrumentpreferredclassificationthroughmodel_and_more.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0055_remove_product__custom_management_rebates_and_more.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0056_remove_companyportfoliodata_assets_under_management_currency_and_more.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0057_alter_portfolio_preferred_instrument_classifications_and_more.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0058_pmsinstrument.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0059_fees_unique_fees.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0060_alter_portfolioportfoliothroughmodel_type.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0061_portfolio_bank_accounts_product_bank_account_and_more.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0062_alter_dailyportfoliocashflow_options.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0063_accountreconciliation_accountreconciliationline_and_more.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0064_alter_portfolio_managers_portfolio_is_tracked_and_more.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0065_alter_portfolio_managers_claim_as_shares_and_more.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0066_assetposition_initial_shares_at_custodian_and_more.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0067_assetposition_unique_asset_position.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0068_trade_internal_trade_trade_marked_as_internal_and_more.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0069_remove_portfolio_is_invested_and_more.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0070_remove_assetposition_unique_asset_position_and_more.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0071_alter_trade_options_alter_trade_order.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0072_trade_diff_shares.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0073_remove_product_price_computation_and_more.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0074_alter_rebalancer_frequency_and_more.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/0075_portfolio_initial_position_date_and_more.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/migrations/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/adjustments.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/asset.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/custodians.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/exceptions.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/graphs/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/graphs/portfolio.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/graphs/utils.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/indexes.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/llm/wbcrm/analyze_relationship.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/mixins/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/mixins/instruments.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/mixins/liquidity_stress_test.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/portfolio_cash_flow.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/portfolio_cash_targets.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/portfolio_relationship.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/portfolio_swing_pricings.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/product_groups.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/products.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/reconciliations/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/reconciliations/account_reconciliation_lines.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/reconciliations/account_reconciliations.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/reconciliations/reconciliations.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/registers.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/roles.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/transactions/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/transactions/expiry.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/transactions/fees.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/transactions/rebalancing.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/utils.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/permissions.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/pms/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/pms/analytics/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/pms/analytics/portfolio.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/pms/statistics/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/pms/trading/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/pms/trading/handler.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/pms/typing.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/preferences.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/rebalancing/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/rebalancing/base.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/rebalancing/decorators.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/rebalancing/models/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/rebalancing/models/composite.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/rebalancing/models/equally_weighted.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/rebalancing/models/model_portfolio.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/reports/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/reports/monthly_position_report.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/risk_management/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/risk_management/backends/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/risk_management/backends/accounts.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/risk_management/backends/controversy_portfolio.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/risk_management/backends/exposure_portfolio.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/risk_management/backends/instrument_list_portfolio.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/risk_management/backends/liquidity_risk.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/risk_management/backends/liquidity_stress_instrument.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/risk_management/backends/mixins.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/risk_management/backends/product_integrity.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/risk_management/backends/stop_loss_instrument.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/risk_management/backends/stop_loss_portfolio.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/risk_management/backends/ucits_portfolio.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/risk_management/tests/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/risk_management/tests/conftest.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/risk_management/tests/test_accounts.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/risk_management/tests/test_controversy_portfolio.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/risk_management/tests/test_exposure_portfolio.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/risk_management/tests/test_instrument_list_portfolio.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/risk_management/tests/test_liquidity_risk.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/risk_management/tests/test_product_integrity.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/risk_management/tests/test_stop_loss_instrument.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/risk_management/tests/test_stop_loss_portfolio.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/risk_management/tests/test_ucits_portfolio.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/serializers/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/serializers/adjustments.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/serializers/assets.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/serializers/custodians.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/serializers/portfolio_cash_flow.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/serializers/portfolio_cash_targets.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/serializers/portfolio_relationship.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/serializers/portfolio_swing_pricing.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/serializers/positions.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/serializers/product_group.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/serializers/products.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/serializers/rebalancing.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/serializers/reconciliations.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/serializers/registers.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/serializers/roles.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/serializers/signals.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/serializers/transactions/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/serializers/transactions/claim.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/serializers/transactions/dividends.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/serializers/transactions/expiry.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/serializers/transactions/fees.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/serializers/transactions/trade_proposals.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/serializers/transactions/trades.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/serializers/transactions/transactions.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/static/wbportfolio/css/macro_review.css +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/static/wbportfolio/markdown/documentation/account_holding_reconciliation.md +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/static/wbportfolio/markdown/documentation/aggregate_asset_position_liquidity.md +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/static/wbportfolio/markdown/documentation/company.md +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/static/wbportfolio/markdown/documentation/earnings_instrument.md +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/static/wbportfolio/markdown/documentation/financial_analysis_instrument_ratios.md +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/static/wbportfolio/markdown/documentation/financial_statistics.md +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/static/wbportfolio/markdown/documentation/person.md +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tasks.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/templates/portfolio/email/customer_report.html +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/templates/portfolio/email/customer_trade_notification.html +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/templates/portfolio/email/email_base_template.html +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/templates/portfolio/email/rebalancing_report.html +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/templates/portfolio/macro/macro_review.html +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/conftest.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/models/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/models/test_account_reconciliation.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/models/test_assets.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/models/test_custodians.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/models/test_customer_trades.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/models/test_dividends.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/models/test_imports.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/models/test_instrument_mixins.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/models/test_merge.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/models/test_portfolio_cash_flow.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/models/test_portfolio_cash_targets.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/models/test_portfolio_swing_pricings.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/models/test_product_groups.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/models/test_products.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/models/test_roles.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/models/test_splits.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/models/transactions/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/models/transactions/test_claim.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/models/transactions/test_fees.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/models/transactions/test_rebalancing.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/models/transactions/test_trade_proposals.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/models/transactions/test_trades.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/models/utils.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/pms/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/pms/test_analytics.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/rebalancing/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/serializers/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/serializers/test_claims.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/signals.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/tests.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/viewsets/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/viewsets/test_assets.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/viewsets/test_performances.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/viewsets/test_products.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/viewsets/transactions/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/tests/viewsets/transactions/test_claims.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/urls.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/utils.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/adjustments.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/assets_and_net_new_money_progression.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/charts/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/charts/assets.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/buttons/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/buttons/adjustments.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/buttons/assets.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/buttons/claims.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/buttons/custodians.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/buttons/fees.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/buttons/mixins.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/buttons/portfolios.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/buttons/products.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/buttons/reconciliations.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/buttons/registers.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/buttons/signals.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/buttons/trade_proposals.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/buttons/trades.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/display/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/display/adjustments.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/display/claim.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/display/custodians.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/display/esg.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/display/fees.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/display/portfolio_cash_flow.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/display/portfolio_relationship.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/display/positions.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/display/product_groups.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/display/product_performance.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/display/rebalancing.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/display/reconciliations.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/display/registers.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/display/roles.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/display/trade_proposals.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/display/transactions.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/endpoints/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/endpoints/adjustments.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/endpoints/assets.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/endpoints/claim.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/endpoints/custodians.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/endpoints/esg.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/endpoints/fees.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/endpoints/portfolio_relationship.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/endpoints/portfolios.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/endpoints/positions.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/endpoints/product_groups.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/endpoints/product_performance.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/endpoints/products.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/endpoints/rebalancing.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/endpoints/reconciliations.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/endpoints/roles.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/endpoints/trade_proposals.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/endpoints/trades.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/menu/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/menu/adjustments.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/menu/assets.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/menu/claim.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/menu/custodians.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/menu/fees.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/menu/instrument_prices.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/menu/portfolio_cash_flow.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/menu/portfolios.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/menu/positions.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/menu/product_groups.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/menu/product_performance.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/menu/products.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/menu/reconciliations.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/menu/registers.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/menu/roles.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/menu/trades.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/menu/transactions.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/previews/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/previews/portfolios.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/titles/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/titles/adjustments.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/titles/assets.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/titles/assets_and_net_new_money_progression.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/titles/claim.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/titles/custodians.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/titles/esg.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/titles/fees.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/titles/instrument_prices.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/titles/portfolios.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/titles/positions.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/titles/product_groups.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/titles/product_performance.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/titles/products.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/titles/registers.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/titles/roles.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/titles/trades.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/configs/titles/transactions.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/custodians.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/esg.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/mixins.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/portfolio_cash_flow.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/portfolio_cash_targets.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/portfolio_relationship.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/portfolio_swing_pricing.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/positions.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/product_groups.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/product_performance.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/products.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/reconciliations.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/registers.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/roles.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/signals.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/transactions/__init__.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/transactions/claim.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/transactions/fees.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/transactions/mixins.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/transactions/rebalancing.py +0 -0
- {wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/viewsets/transactions/transactions.py +0 -0
|
@@ -11,5 +11,6 @@ class DividendTransactionsFactory(TransactionFactory):
|
|
|
11
11
|
class Meta:
|
|
12
12
|
model = DividendTransaction
|
|
13
13
|
|
|
14
|
+
retrocession = 1.0
|
|
14
15
|
shares = factory.LazyAttribute(lambda o: random.randint(10, 10000))
|
|
15
16
|
price = factory.LazyAttribute(lambda o: random.randint(10, 10000))
|
|
@@ -23,7 +23,7 @@ class DividendImportHandler(ImportExportHandler):
|
|
|
23
23
|
data["value_date"] = datetime.strptime(data["value_date"], "%Y-%m-%d").date()
|
|
24
24
|
from wbportfolio.models import Portfolio
|
|
25
25
|
|
|
26
|
-
data["portfolio"] = Portfolio.
|
|
26
|
+
data["portfolio"] = Portfolio.all_objects.get(id=data["portfolio"])
|
|
27
27
|
instrument = self.instrument_handler.process_object(
|
|
28
28
|
data["underlying_instrument"], only_security=False, read_only=True
|
|
29
29
|
)[0]
|
|
@@ -26,7 +26,7 @@ class FeesImportHandler(ImportExportHandler):
|
|
|
26
26
|
|
|
27
27
|
data["linked_product"] = Product.objects.get(id=data["linked_product"])
|
|
28
28
|
if "porfolio" in data:
|
|
29
|
-
data["portfolio"] = Portfolio.
|
|
29
|
+
data["portfolio"] = Portfolio.all_objects.get(id=data["portfolio"])
|
|
30
30
|
else:
|
|
31
31
|
data["portfolio"] = data["linked_product"].primary_portfolio
|
|
32
32
|
data["underlying_instrument"] = Cash.objects.filter(currency=data["portfolio"].currency).first()
|
{wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/import_export/handlers/portfolio_cash_flow.py
RENAMED
|
@@ -19,7 +19,7 @@ class DailyPortfolioCashFlowImportHandler(ImportExportHandler):
|
|
|
19
19
|
|
|
20
20
|
def _deserialize(self, data):
|
|
21
21
|
data["value_date"] = datetime.strptime(data["value_date"], "%Y-%m-%d").date()
|
|
22
|
-
data["portfolio"] = Portfolio.
|
|
22
|
+
data["portfolio"] = Portfolio.all_objects.get(id=data["portfolio"])
|
|
23
23
|
if "cash" in data:
|
|
24
24
|
data["cash"] = Decimal(data["cash"])
|
|
25
25
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import math
|
|
1
2
|
from datetime import datetime
|
|
2
3
|
from decimal import Decimal
|
|
3
4
|
from typing import Any, Dict, Optional
|
|
@@ -71,7 +72,10 @@ class TradeImportHandler(ImportExportHandler):
|
|
|
71
72
|
|
|
72
73
|
for field in self.model._meta.get_fields():
|
|
73
74
|
if not (value := data.get(field.name, None)) is None and isinstance(field, models.DecimalField):
|
|
74
|
-
|
|
75
|
+
q = (
|
|
76
|
+
1 / (math.pow(10, 4))
|
|
77
|
+
) # we need that convertion mechanism otherwise there is floating point approximation error while casting to decimal and get_instance does not work as expected
|
|
78
|
+
data[field.name] = Decimal(value).quantize(Decimal(str(q)))
|
|
75
79
|
|
|
76
80
|
def _create_instance(self, data: Dict[str, Any], **kwargs) -> models.Model:
|
|
77
81
|
if "transaction_date" not in data: # we might get only book date and not transaction date
|
|
@@ -81,7 +85,6 @@ class TradeImportHandler(ImportExportHandler):
|
|
|
81
85
|
|
|
82
86
|
def _get_instance(self, data: Dict[str, Any], history: Optional[models.QuerySet] = None, **kwargs) -> models.Model:
|
|
83
87
|
self.import_source.log += "\nGet Trade Instance."
|
|
84
|
-
|
|
85
88
|
if transaction_date := data.get("transaction_date"):
|
|
86
89
|
dates_lookup = {"transaction_date": transaction_date}
|
|
87
90
|
elif book_date := data.get("book_date"):
|
|
@@ -29,7 +29,7 @@ def get_portfolio_id(row: pd.Series) -> int:
|
|
|
29
29
|
Raises: Portfolio.DoesNotExist: We raise an error intentionally if the portfolio does not exist to make the import fail
|
|
30
30
|
"""
|
|
31
31
|
iban = str(IBAN.generate(BANK_COUNTRY_CODE, bank_code=BANK_CODE, account_code=str(row["account_number"])))
|
|
32
|
-
return Portfolio.
|
|
32
|
+
return Portfolio.all_objects.get(bank_accounts__iban=iban).id
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
def parse(import_source: "ImportSource") -> dict:
|
|
@@ -13,7 +13,7 @@ def parse(import_source):
|
|
|
13
13
|
|
|
14
14
|
def get_portfolio_id(row) -> int | None:
|
|
15
15
|
with suppress(Portfolio.DoesNotExist):
|
|
16
|
-
return Portfolio.
|
|
16
|
+
return Portfolio.all_objects.get(instruments__children__isin__in=[row["Isin"]]).pk
|
|
17
17
|
|
|
18
18
|
df = df[~df["Isin"].isnull()]
|
|
19
19
|
df["Trade date"] = df["Trade date"].ffill()
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Generated by Django 5.0.13 on 2025-03-21 12:30
|
|
2
|
+
|
|
3
|
+
import django.db.models.expressions
|
|
4
|
+
from decimal import Decimal
|
|
5
|
+
from django.db import migrations, models
|
|
6
|
+
|
|
7
|
+
def migrate_default_values(apps, schema_editor):
|
|
8
|
+
Transaction = apps.get_model("wbportfolio", "Transaction")
|
|
9
|
+
Trade = apps.get_model("wbportfolio", "Trade")
|
|
10
|
+
Expiry = apps.get_model("wbportfolio", "Expiry")
|
|
11
|
+
DividendTransaction = apps.get_model("wbportfolio", "DividendTransaction")
|
|
12
|
+
Transaction.objects.filter(book_date__isnull=True).update(book_date=models.F("transaction_date"))
|
|
13
|
+
Transaction.objects.filter(value_date__isnull=True).update(value_date=models.F("transaction_date"))
|
|
14
|
+
Trade.objects.filter(price_gross__isnull=True).update(price_gross=models.F("price"))
|
|
15
|
+
Expiry.objects.filter(price_gross__isnull=True).update(price_gross=models.F("price"))
|
|
16
|
+
DividendTransaction.objects.filter(price_gross__isnull=True).update(price_gross=models.F("price"))
|
|
17
|
+
Transaction.objects.filter(total_value_gross__isnull=True).update(total_value_gross=models.F("total_value"))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class Migration(migrations.Migration):
|
|
21
|
+
|
|
22
|
+
dependencies = [
|
|
23
|
+
('wbportfolio', '0075_portfolio_initial_position_date_and_more'),
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
operations = [
|
|
27
|
+
migrations.RunPython(migrate_default_values),
|
|
28
|
+
migrations.AlterField(
|
|
29
|
+
model_name='transaction',
|
|
30
|
+
name='book_date',
|
|
31
|
+
field=models.DateField(help_text='The date that this transaction was booked.',
|
|
32
|
+
verbose_name='Trade Date'),
|
|
33
|
+
preserve_default=False,
|
|
34
|
+
),
|
|
35
|
+
migrations.AlterField(
|
|
36
|
+
model_name='transaction',
|
|
37
|
+
name='value_date',
|
|
38
|
+
field=models.DateField(help_text='The date that this transaction was valuated.',
|
|
39
|
+
verbose_name='Value Date'),
|
|
40
|
+
preserve_default=False,
|
|
41
|
+
),
|
|
42
|
+
migrations.AlterField(
|
|
43
|
+
model_name='dividendtransaction',
|
|
44
|
+
name='price',
|
|
45
|
+
field=models.DecimalField(decimal_places=4, default=Decimal('0.0'), help_text='The price per share.', max_digits=16, verbose_name='Price'),
|
|
46
|
+
),
|
|
47
|
+
migrations.AlterField(
|
|
48
|
+
model_name='dividendtransaction',
|
|
49
|
+
name='price_gross',
|
|
50
|
+
field=models.DecimalField(decimal_places=4, default=Decimal('0.0'), help_text='The gross price per share.', max_digits=16, verbose_name='Gross Price'),
|
|
51
|
+
preserve_default=False,
|
|
52
|
+
),
|
|
53
|
+
migrations.AlterField(
|
|
54
|
+
model_name='dividendtransaction',
|
|
55
|
+
name='shares',
|
|
56
|
+
field=models.DecimalField(decimal_places=4, default=Decimal('0.0'), help_text='The number of shares that were traded.', max_digits=15, verbose_name='Shares'),
|
|
57
|
+
),
|
|
58
|
+
migrations.AlterField(
|
|
59
|
+
model_name='expiry',
|
|
60
|
+
name='price',
|
|
61
|
+
field=models.DecimalField(decimal_places=4, default=Decimal('0.0'), help_text='The price per share.', max_digits=16, verbose_name='Price'),
|
|
62
|
+
),
|
|
63
|
+
migrations.AlterField(
|
|
64
|
+
model_name='expiry',
|
|
65
|
+
name='price_gross',
|
|
66
|
+
field=models.DecimalField(decimal_places=4, default=Decimal('0.0'), help_text='The gross price per share.', max_digits=16, verbose_name='Gross Price'),
|
|
67
|
+
preserve_default=False,
|
|
68
|
+
),
|
|
69
|
+
migrations.AlterField(
|
|
70
|
+
model_name='expiry',
|
|
71
|
+
name='shares',
|
|
72
|
+
field=models.DecimalField(decimal_places=4, default=Decimal('0.0'), help_text='The number of shares that were traded.', max_digits=15, verbose_name='Shares'),
|
|
73
|
+
),
|
|
74
|
+
migrations.AlterField(
|
|
75
|
+
model_name='trade',
|
|
76
|
+
name='price',
|
|
77
|
+
field=models.DecimalField(decimal_places=4, default=Decimal('0.0'), help_text='The price per share.', max_digits=16, verbose_name='Price'),
|
|
78
|
+
),
|
|
79
|
+
migrations.AlterField(
|
|
80
|
+
model_name='trade',
|
|
81
|
+
name='price_gross',
|
|
82
|
+
field=models.DecimalField(decimal_places=4, default=Decimal('0.0'), help_text='The gross price per share.', max_digits=16, verbose_name='Gross Price'),
|
|
83
|
+
preserve_default=False,
|
|
84
|
+
),
|
|
85
|
+
migrations.AlterField(
|
|
86
|
+
model_name='trade',
|
|
87
|
+
name='shares',
|
|
88
|
+
field=models.DecimalField(decimal_places=4, default=Decimal('0.0'), help_text='The number of shares that were traded.', max_digits=15, verbose_name='Shares'),
|
|
89
|
+
),
|
|
90
|
+
|
|
91
|
+
migrations.AlterField(
|
|
92
|
+
model_name='transaction',
|
|
93
|
+
name='total_value',
|
|
94
|
+
field=models.DecimalField(decimal_places=4, default=Decimal('0.0'), max_digits=20, verbose_name='Total Value'),
|
|
95
|
+
preserve_default=False,
|
|
96
|
+
),
|
|
97
|
+
migrations.AlterField(
|
|
98
|
+
model_name='transaction',
|
|
99
|
+
name='total_value_gross',
|
|
100
|
+
field=models.DecimalField(decimal_places=4, default=Decimal('0.0'), max_digits=20, verbose_name='Total Value Gross'),
|
|
101
|
+
preserve_default=False,
|
|
102
|
+
),
|
|
103
|
+
migrations.RemoveField(
|
|
104
|
+
model_name='transaction',
|
|
105
|
+
name='total_value_fx_portfolio',
|
|
106
|
+
),
|
|
107
|
+
migrations.RemoveField(
|
|
108
|
+
model_name='transaction',
|
|
109
|
+
name='total_value_gross_fx_portfolio',
|
|
110
|
+
),
|
|
111
|
+
migrations.AddField(
|
|
112
|
+
model_name='transaction',
|
|
113
|
+
name='total_value_fx_portfolio',
|
|
114
|
+
field=models.GeneratedField(db_persist=True, expression=django.db.models.expressions.CombinedExpression(
|
|
115
|
+
models.F('currency_fx_rate'), '*', models.F('total_value')),
|
|
116
|
+
output_field=models.DecimalField(decimal_places=4, max_digits=20)),
|
|
117
|
+
preserve_default=False,
|
|
118
|
+
),
|
|
119
|
+
migrations.AddField(
|
|
120
|
+
model_name='transaction',
|
|
121
|
+
name='total_value_gross_fx_portfolio',
|
|
122
|
+
field=models.GeneratedField(db_persist=True, expression=django.db.models.expressions.CombinedExpression(models.F('currency_fx_rate'), '*', models.F('total_value_gross')), output_field=models.DecimalField(decimal_places=4, max_digits=20)),
|
|
123
|
+
preserve_default=False,
|
|
124
|
+
),
|
|
125
|
+
|
|
126
|
+
]
|
|
@@ -411,7 +411,7 @@ class Portfolio(DeleteToDisableMixin, WBModel):
|
|
|
411
411
|
)
|
|
412
412
|
|
|
413
413
|
def __str__(self):
|
|
414
|
-
return f"{self.id:06}
|
|
414
|
+
return f"{self.id:06}: {self.name}"
|
|
415
415
|
|
|
416
416
|
class Meta:
|
|
417
417
|
verbose_name = "Portfolio"
|
|
@@ -853,7 +853,6 @@ class Portfolio(DeleteToDisableMixin, WBModel):
|
|
|
853
853
|
adjusted_weighting,
|
|
854
854
|
adjusted_currency_fx_rate,
|
|
855
855
|
adjusted_is_estimated,
|
|
856
|
-
portfolio_created=None,
|
|
857
856
|
path=None,
|
|
858
857
|
):
|
|
859
858
|
if not path:
|
|
@@ -866,7 +865,18 @@ class Portfolio(DeleteToDisableMixin, WBModel):
|
|
|
866
865
|
position.is_estimated = (adjusted_is_estimated or position.is_estimated) and not (
|
|
867
866
|
position.weighting == 1.0
|
|
868
867
|
)
|
|
869
|
-
position
|
|
868
|
+
# to get from which portfolio this position is created, we need to differantiate between:
|
|
869
|
+
# * Composition portfolio: where the portfolio created is the second encountered portfolio
|
|
870
|
+
# * Other: portfolio created is the last encountered portfolio
|
|
871
|
+
# If `path` is empty, we use None as portfolio_created
|
|
872
|
+
try:
|
|
873
|
+
if self.is_composition:
|
|
874
|
+
position.portfolio_created = path[1]
|
|
875
|
+
else:
|
|
876
|
+
position.portfolio_created = path[-1]
|
|
877
|
+
except IndexError:
|
|
878
|
+
position.portfolio_created = None
|
|
879
|
+
|
|
870
880
|
setattr(position, "path", path)
|
|
871
881
|
position.initial_shares = None
|
|
872
882
|
if portfolio_total_asset_value:
|
|
@@ -881,7 +891,6 @@ class Portfolio(DeleteToDisableMixin, WBModel):
|
|
|
881
891
|
position.weighting,
|
|
882
892
|
position.currency_fx_rate,
|
|
883
893
|
position.is_estimated,
|
|
884
|
-
portfolio_created=child_portfolio,
|
|
885
894
|
path=path.copy(),
|
|
886
895
|
)
|
|
887
896
|
elif position.weighting: # we do not yield position with weight 0 because of issue with certain multi-thematic portfolios which contain duplicates
|
|
@@ -979,7 +988,11 @@ class Portfolio(DeleteToDisableMixin, WBModel):
|
|
|
979
988
|
for position in positions:
|
|
980
989
|
position.portfolio = self
|
|
981
990
|
update_dates.add(position.date)
|
|
982
|
-
|
|
991
|
+
|
|
992
|
+
# we need to delete the existing estimated portfolio because otherwise we risk to have existing and not
|
|
993
|
+
# overlapping positions remaining (as they will not be updating by the bulk create). E.g. when someone
|
|
994
|
+
# change completely the trades of a portfolio model and drift it.
|
|
995
|
+
self.assets.filter(date__in=update_dates, is_estimated=True).delete()
|
|
983
996
|
leftover_positions_ids = list(
|
|
984
997
|
self.assets.filter(date__in=update_dates).values_list("id", flat=True)
|
|
985
998
|
) # we need to get the ids otherwise the queryset is reevaluated later
|
|
@@ -1014,7 +1027,7 @@ class Portfolio(DeleteToDisableMixin, WBModel):
|
|
|
1014
1027
|
@classmethod
|
|
1015
1028
|
def _get_or_create_portfolio(cls, instrument_handler, portfolio_data):
|
|
1016
1029
|
if isinstance(portfolio_data, int):
|
|
1017
|
-
return Portfolio.
|
|
1030
|
+
return Portfolio.all_objects.get(id=portfolio_data)
|
|
1018
1031
|
instrument = portfolio_data
|
|
1019
1032
|
if isinstance(portfolio_data, dict):
|
|
1020
1033
|
instrument = instrument_handler.process_object(instrument, only_security=False, read_only=True)[0]
|
|
@@ -14,6 +14,7 @@ from django.db.models import (
|
|
|
14
14
|
)
|
|
15
15
|
from django.db.models.functions import Greatest
|
|
16
16
|
from django.dispatch import receiver
|
|
17
|
+
from django.utils.translation import gettext_lazy as _
|
|
17
18
|
from django_fsm import FSMField, transition
|
|
18
19
|
from wbcore.contrib.ai.llm.config import add_llm_prompt
|
|
19
20
|
from wbcore.contrib.authentication.models import User
|
|
@@ -335,13 +336,13 @@ class Claim(ReferenceIDMixin, WBModel):
|
|
|
335
336
|
errors = dict()
|
|
336
337
|
|
|
337
338
|
if not self.trade:
|
|
338
|
-
errors["trade"] = ["With this status, this has to be provided."]
|
|
339
|
+
errors["trade"] = [_("With this status, this has to be provided.")]
|
|
339
340
|
|
|
340
341
|
if not self.product:
|
|
341
|
-
errors["product"] = ["With this status, this has to be provided."]
|
|
342
|
+
errors["product"] = [_("With this status, this has to be provided.")]
|
|
342
343
|
|
|
343
344
|
if not self.account:
|
|
344
|
-
errors["account"] = ["With this status, this has to be provided."]
|
|
345
|
+
errors["account"] = [_("With this status, this has to be provided.")]
|
|
345
346
|
|
|
346
347
|
# check if the specified product have a valid nav at the specified date
|
|
347
348
|
if (
|
|
@@ -350,13 +351,13 @@ class Claim(ReferenceIDMixin, WBModel):
|
|
|
350
351
|
and not product.valuations.filter(date=claim_date).exists()
|
|
351
352
|
):
|
|
352
353
|
if (prices_qs := product.valuations.filter(date__lt=claim_date)).exists():
|
|
353
|
-
errors["date"] =
|
|
354
|
+
errors["date"] = [
|
|
354
355
|
f"For product {product.name}, the latest valid valuation date before {claim_date:%Y-%m-%d} is {prices_qs.latest('date').date:%Y-%m-%d}: Please select a valid date."
|
|
355
|
-
|
|
356
|
+
]
|
|
356
357
|
else:
|
|
357
|
-
errors["date"] =
|
|
358
|
+
errors["date"] = [
|
|
358
359
|
f"There is no valuation before {claim_date:%Y-%m-%d} for product {product.name}: Please select a valid date."
|
|
359
|
-
|
|
360
|
+
]
|
|
360
361
|
return errors
|
|
361
362
|
|
|
362
363
|
@transition(
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from decimal import Decimal
|
|
2
|
+
|
|
3
|
+
from django.db import models
|
|
4
|
+
|
|
5
|
+
from wbportfolio.import_export.handlers.dividend import DividendImportHandler
|
|
6
|
+
|
|
7
|
+
from .transactions import ShareMixin, Transaction
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class DividendTransaction(Transaction, ShareMixin, models.Model):
|
|
11
|
+
import_export_handler_class = DividendImportHandler
|
|
12
|
+
retrocession = models.FloatField(default=1)
|
|
13
|
+
|
|
14
|
+
def save(self, *args, **kwargs):
|
|
15
|
+
super().save(*args, factor=Decimal(self.retrocession), **kwargs)
|
{wbportfolio-1.49.0 → wbportfolio-1.49.2}/wbportfolio/models/transactions/trade_proposals.py
RENAMED
|
@@ -8,6 +8,7 @@ from celery import shared_task
|
|
|
8
8
|
from django.core.exceptions import ValidationError
|
|
9
9
|
from django.db import models
|
|
10
10
|
from django.utils.functional import cached_property
|
|
11
|
+
from django.utils.translation import gettext_lazy as _
|
|
11
12
|
from django_fsm import FSMField, transition
|
|
12
13
|
from pandas._libs.tslibs.offsets import BDay
|
|
13
14
|
from wbcompliance.models.risk_management.mixins import RiskCheckMixin
|
|
@@ -166,7 +167,7 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
|
|
|
166
167
|
Returns:
|
|
167
168
|
The cloned trade proposal
|
|
168
169
|
"""
|
|
169
|
-
trade_date = kwargs.get("
|
|
170
|
+
trade_date = kwargs.get("clone_date", self.trade_date)
|
|
170
171
|
|
|
171
172
|
# Find the next valid trade date
|
|
172
173
|
while TradeProposal.objects.filter(portfolio=self.portfolio, trade_date=trade_date).exists():
|
|
@@ -174,7 +175,7 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
|
|
|
174
175
|
|
|
175
176
|
trade_proposal_clone = TradeProposal.objects.create(
|
|
176
177
|
trade_date=trade_date,
|
|
177
|
-
comment=kwargs.get("
|
|
178
|
+
comment=kwargs.get("clone_comment", self.comment),
|
|
178
179
|
status=TradeProposal.Status.DRAFT,
|
|
179
180
|
rebalancing_model=self.rebalancing_model,
|
|
180
181
|
portfolio=self.portfolio,
|
|
@@ -228,8 +229,6 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
|
|
|
228
229
|
"""
|
|
229
230
|
Will delete all existing trades and recreate them from the method `create_or_update_trades`
|
|
230
231
|
"""
|
|
231
|
-
if self.status != TradeProposal.Status.DRAFT:
|
|
232
|
-
raise ValueError("Cannot reset non-draft trade proposal. Revert this trade proposal first.")
|
|
233
232
|
# delete all existing trades
|
|
234
233
|
last_effective_date = self.last_effective_date
|
|
235
234
|
# Get effective and target portfolio
|
|
@@ -303,7 +302,7 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
|
|
|
303
302
|
)
|
|
304
303
|
last_trade_proposal = overriding_trade_proposal or next_trade_proposal
|
|
305
304
|
|
|
306
|
-
def get_estimated_shares(self, weight: Decimal, underlying_quote: Instrument) -> Decimal
|
|
305
|
+
def get_estimated_shares(self, weight: Decimal, underlying_quote: Instrument) -> Decimal:
|
|
307
306
|
"""
|
|
308
307
|
Estimates the number of shares for a trade based on the given weight and underlying quote.
|
|
309
308
|
|
|
@@ -332,8 +331,7 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
|
|
|
332
331
|
if price_fx_portfolio:
|
|
333
332
|
return trade_total_value_fx_portfolio / price_fx_portfolio
|
|
334
333
|
except Exception:
|
|
335
|
-
|
|
336
|
-
return None
|
|
334
|
+
raise ValueError("We couldn't estimate the number of shares")
|
|
337
335
|
|
|
338
336
|
def get_estimated_target_cash(self, currency: Currency) -> tuple[Decimal, Decimal]:
|
|
339
337
|
"""
|
|
@@ -373,7 +371,8 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
|
|
|
373
371
|
)[0]
|
|
374
372
|
|
|
375
373
|
# Estimate the target shares for the cash component
|
|
376
|
-
|
|
374
|
+
with suppress(ValueError):
|
|
375
|
+
total_target_shares = self.get_estimated_shares(target_cash_weight, cash_component)
|
|
377
376
|
|
|
378
377
|
return target_cash_weight, total_target_shares
|
|
379
378
|
|
|
@@ -428,7 +427,7 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
|
|
|
428
427
|
errors = dict()
|
|
429
428
|
errors_list = []
|
|
430
429
|
if self.trades.exists() and self.trades.exclude(status=Trade.Status.DRAFT).exists():
|
|
431
|
-
errors_list.append("All trades need to be draft before submitting")
|
|
430
|
+
errors_list.append(_("All trades need to be draft before submitting"))
|
|
432
431
|
service = self.validated_trading_service
|
|
433
432
|
try:
|
|
434
433
|
service.is_valid(ignore_error=True)
|
|
@@ -437,7 +436,7 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
|
|
|
437
436
|
# "There is no change detected in this trade proposal. Please submit at last one valid trade"
|
|
438
437
|
# )
|
|
439
438
|
if len(service.validated_trades) == 0:
|
|
440
|
-
errors_list.append("There is no valid trade on this proposal")
|
|
439
|
+
errors_list.append(_("There is no valid trade on this proposal"))
|
|
441
440
|
if service.errors:
|
|
442
441
|
errors_list.extend(service.errors)
|
|
443
442
|
if errors_list:
|
|
@@ -487,15 +486,17 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
|
|
|
487
486
|
def can_approve(self):
|
|
488
487
|
errors = dict()
|
|
489
488
|
if not self.portfolio.can_be_rebalanced:
|
|
490
|
-
errors["non_field_errors"] = "The portfolio does not allow manual rebalanced"
|
|
489
|
+
errors["non_field_errors"] = [_("The portfolio does not allow manual rebalanced")]
|
|
491
490
|
if self.trades.exclude(status=Trade.Status.SUBMIT).exists():
|
|
492
|
-
errors["non_field_errors"] =
|
|
491
|
+
errors["non_field_errors"] = [
|
|
492
|
+
_("At least one trade needs to be submitted to be able to approve this proposal")
|
|
493
|
+
]
|
|
493
494
|
if not self.portfolio.can_be_rebalanced:
|
|
494
|
-
errors["portfolio"] =
|
|
495
|
-
"The portfolio needs to be a model portfolio in order to approve this trade proposal manually"
|
|
496
|
-
|
|
495
|
+
errors["portfolio"] = [
|
|
496
|
+
[_("The portfolio needs to be a model portfolio in order to approve this trade proposal manually")]
|
|
497
|
+
]
|
|
497
498
|
if self.has_non_successful_checks:
|
|
498
|
-
errors["non_field_errors"] = "The pre trades rules did not passed successfully"
|
|
499
|
+
errors["non_field_errors"] = [_("The pre trades rules did not passed successfully")]
|
|
499
500
|
return errors
|
|
500
501
|
|
|
501
502
|
@transition(
|
|
@@ -526,7 +527,9 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
|
|
|
526
527
|
def can_deny(self):
|
|
527
528
|
errors = dict()
|
|
528
529
|
if self.trades.exclude(status=Trade.Status.SUBMIT).exists():
|
|
529
|
-
errors["non_field_errors"] =
|
|
530
|
+
errors["non_field_errors"] = [
|
|
531
|
+
_("At least one trade needs to be submitted to be able to deny this proposal")
|
|
532
|
+
]
|
|
530
533
|
return errors
|
|
531
534
|
|
|
532
535
|
@transition(
|
|
@@ -589,9 +592,9 @@ class TradeProposal(CloneMixin, RiskCheckMixin, WBModel):
|
|
|
589
592
|
def can_revert(self):
|
|
590
593
|
errors = dict()
|
|
591
594
|
if not self.portfolio.can_be_rebalanced:
|
|
592
|
-
errors["portfolio"] =
|
|
593
|
-
"The portfolio needs to be a model portfolio in order to revert this trade proposal manually"
|
|
594
|
-
|
|
595
|
+
errors["portfolio"] = [
|
|
596
|
+
_("The portfolio needs to be a model portfolio in order to revert this trade proposal manually")
|
|
597
|
+
]
|
|
595
598
|
return errors
|
|
596
599
|
|
|
597
600
|
# End FSM logics
|
|
@@ -20,6 +20,7 @@ from django.db.models.functions import Coalesce
|
|
|
20
20
|
from django.db.models.signals import post_save
|
|
21
21
|
from django.dispatch import receiver
|
|
22
22
|
from django.utils.functional import cached_property
|
|
23
|
+
from django.utils.translation import gettext_lazy as _
|
|
23
24
|
from django_fsm import GET_STATE, FSMField, transition
|
|
24
25
|
from ordered_model.models import OrderedModel, OrderedModelManager, OrderedModelQuerySet
|
|
25
26
|
from wbcore.contrib.icons import WBIcon
|
|
@@ -320,9 +321,11 @@ class Trade(ShareMixin, Transaction, OrderedModel, WBModel):
|
|
|
320
321
|
|
|
321
322
|
def can_execute(self):
|
|
322
323
|
if not self.last_underlying_quote_price:
|
|
323
|
-
return {"underlying_instrument": "Cannot execute a trade without a valid quote price"}
|
|
324
|
+
return {"underlying_instrument": [_("Cannot execute a trade without a valid quote price")]}
|
|
324
325
|
if not self.portfolio.is_manageable:
|
|
325
|
-
return {
|
|
326
|
+
return {
|
|
327
|
+
"portfolio": [_("The portfolio needs to be a model portfolio in order to execute this trade manually")]
|
|
328
|
+
}
|
|
326
329
|
|
|
327
330
|
@transition(
|
|
328
331
|
field=status,
|
|
@@ -498,22 +501,16 @@ class Trade(ShareMixin, Transaction, OrderedModel, WBModel):
|
|
|
498
501
|
self.transaction_date = self.trade_proposal.trade_date
|
|
499
502
|
self.value_date = self.trade_proposal.last_effective_date
|
|
500
503
|
if not self.portfolio.only_weighting:
|
|
501
|
-
|
|
504
|
+
with suppress(ValueError):
|
|
505
|
+
self.shares = self.trade_proposal.get_estimated_shares(self.weighting, self.underlying_instrument)
|
|
502
506
|
|
|
503
507
|
if not self.custodian and self.bank:
|
|
504
508
|
self.custodian = Custodian.get_by_mapping(self.bank)
|
|
505
509
|
if self.price is None:
|
|
506
510
|
# we try to get the price if not provided directly from the underlying instrument
|
|
507
|
-
with suppress(
|
|
508
|
-
self.price = self.underlying_instrument.
|
|
509
|
-
if self.price is not None and self.price_gross is None:
|
|
510
|
-
self.price_gross = self.price
|
|
511
|
-
|
|
512
|
-
if self.price is not None and self.shares is not None and self.total_value is None:
|
|
513
|
-
self.total_value = self.price * self.shares
|
|
511
|
+
with suppress(Exception):
|
|
512
|
+
self.price = self.underlying_instrument.get_price(self.value_date)
|
|
514
513
|
|
|
515
|
-
if self.price_gross is not None and self.shares is not None and self.total_value_gross is None:
|
|
516
|
-
self.total_value_gross = self.price_gross * self.shares
|
|
517
514
|
self.transaction_type = Transaction.Type.TRADE
|
|
518
515
|
|
|
519
516
|
if self.transaction_subtype is None or self.trade_proposal:
|
|
@@ -13,16 +13,16 @@ class ShareMixin(models.Model):
|
|
|
13
13
|
shares = models.DecimalField(
|
|
14
14
|
max_digits=15,
|
|
15
15
|
decimal_places=4,
|
|
16
|
-
|
|
17
|
-
blank=True,
|
|
16
|
+
default=Decimal("0.0"),
|
|
18
17
|
help_text="The number of shares that were traded.",
|
|
19
18
|
verbose_name="Shares",
|
|
20
19
|
)
|
|
21
20
|
price = models.DecimalField(
|
|
22
21
|
max_digits=16,
|
|
23
22
|
decimal_places=4,
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
default=Decimal(
|
|
24
|
+
"0.0"
|
|
25
|
+
), # we shouldn't default to anything but we have trade with price=None. Needs to be handled carefully
|
|
26
26
|
help_text="The price per share.",
|
|
27
27
|
verbose_name="Price",
|
|
28
28
|
)
|
|
@@ -30,12 +30,23 @@ class ShareMixin(models.Model):
|
|
|
30
30
|
price_gross = models.DecimalField(
|
|
31
31
|
max_digits=16,
|
|
32
32
|
decimal_places=4,
|
|
33
|
-
null=True,
|
|
34
|
-
blank=True,
|
|
35
33
|
help_text="The gross price per share.",
|
|
36
34
|
verbose_name="Gross Price",
|
|
37
35
|
)
|
|
38
36
|
|
|
37
|
+
def save(
|
|
38
|
+
self,
|
|
39
|
+
*args,
|
|
40
|
+
factor: Decimal = Decimal("1.0"),
|
|
41
|
+
**kwargs,
|
|
42
|
+
):
|
|
43
|
+
if self.price_gross is None:
|
|
44
|
+
self.price_gross = self.price
|
|
45
|
+
|
|
46
|
+
self.total_value = self.price * self.shares * factor
|
|
47
|
+
self.total_value_gross = self.price_gross * self.shares * factor
|
|
48
|
+
super().save(*args, **kwargs)
|
|
49
|
+
|
|
39
50
|
class Meta:
|
|
40
51
|
abstract = True
|
|
41
52
|
|
|
@@ -68,14 +79,10 @@ class Transaction(ImportMixin, models.Model):
|
|
|
68
79
|
help_text="The date that this transaction was traded.",
|
|
69
80
|
)
|
|
70
81
|
book_date = models.DateField(
|
|
71
|
-
null=True,
|
|
72
|
-
blank=True,
|
|
73
82
|
verbose_name="Trade Date",
|
|
74
83
|
help_text="The date that this transaction was booked.",
|
|
75
84
|
)
|
|
76
85
|
value_date = models.DateField(
|
|
77
|
-
null=True,
|
|
78
|
-
blank=True,
|
|
79
86
|
verbose_name="Value Date",
|
|
80
87
|
help_text="The date that this transaction was valuated.",
|
|
81
88
|
)
|
|
@@ -89,17 +96,23 @@ class Transaction(ImportMixin, models.Model):
|
|
|
89
96
|
currency_fx_rate = models.DecimalField(
|
|
90
97
|
max_digits=14, decimal_places=8, default=Decimal(1.0), verbose_name="FOREX rate"
|
|
91
98
|
)
|
|
92
|
-
total_value = models.DecimalField(
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
99
|
+
total_value = models.DecimalField(max_digits=20, decimal_places=4, verbose_name="Total Value")
|
|
100
|
+
total_value_gross = models.DecimalField(max_digits=20, decimal_places=4, verbose_name="Total Value Gross")
|
|
101
|
+
total_value_fx_portfolio = models.GeneratedField(
|
|
102
|
+
expression=models.F("currency_fx_rate") * models.F("total_value"),
|
|
103
|
+
output_field=models.DecimalField(
|
|
104
|
+
max_digits=20,
|
|
105
|
+
decimal_places=4,
|
|
106
|
+
),
|
|
107
|
+
db_persist=True,
|
|
108
|
+
)
|
|
109
|
+
total_value_gross_fx_portfolio = models.GeneratedField(
|
|
110
|
+
expression=models.F("currency_fx_rate") * models.F("total_value_gross"),
|
|
111
|
+
output_field=models.DecimalField(
|
|
112
|
+
max_digits=20,
|
|
113
|
+
decimal_places=4,
|
|
114
|
+
),
|
|
115
|
+
db_persist=True,
|
|
103
116
|
)
|
|
104
117
|
external_id = models.CharField(
|
|
105
118
|
max_length=255,
|
|
@@ -118,28 +131,15 @@ class Transaction(ImportMixin, models.Model):
|
|
|
118
131
|
|
|
119
132
|
if not getattr(self, "currency", None) and self.underlying_instrument:
|
|
120
133
|
self.currency = self.underlying_instrument.currency
|
|
121
|
-
if
|
|
134
|
+
if self.currency_fx_rate is None:
|
|
122
135
|
self.currency_fx_rate = self.underlying_instrument.currency.convert(
|
|
123
136
|
self.value_date, self.portfolio.currency, exact_lookup=True
|
|
124
137
|
)
|
|
125
138
|
if not self.transaction_type:
|
|
126
139
|
self.transaction_type = self.__class__.__name__
|
|
127
|
-
if (
|
|
128
|
-
self.total_value is not None
|
|
129
|
-
and self.currency_fx_rate is not None
|
|
130
|
-
and self.total_value_fx_portfolio is None
|
|
131
|
-
):
|
|
132
|
-
self.total_value_fx_portfolio = self.total_value * self.currency_fx_rate
|
|
133
|
-
|
|
134
|
-
if self.total_value is not None and self.total_value_gross is None and self.total_value_gross is None:
|
|
135
|
-
self.total_value_gross = self.total_value
|
|
136
140
|
|
|
137
|
-
if
|
|
138
|
-
self.
|
|
139
|
-
and self.total_value_gross is not None
|
|
140
|
-
and self.total_value_gross_fx_portfolio is None
|
|
141
|
-
):
|
|
142
|
-
self.total_value_gross_fx_portfolio = self.total_value_gross * self.currency_fx_rate
|
|
141
|
+
if self.total_value_gross is None:
|
|
142
|
+
self.total_value_gross = self.total_value
|
|
143
143
|
|
|
144
144
|
super().save(*args, **kwargs)
|
|
145
145
|
|