wbportfolio 1.44.5__py2.py3-none-any.whl → 1.45.1__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of wbportfolio might be problematic. Click here for more details.
- wbportfolio/admin/__init__.py +1 -1
- wbportfolio/admin/asset.py +2 -1
- wbportfolio/admin/custodians.py +1 -0
- wbportfolio/admin/indexes.py +15 -0
- wbportfolio/admin/portfolio.py +12 -7
- wbportfolio/admin/portfolio_relationships.py +1 -0
- wbportfolio/admin/product_groups.py +2 -0
- wbportfolio/admin/products.py +2 -1
- wbportfolio/admin/reconciliations.py +1 -0
- wbportfolio/admin/registers.py +1 -0
- wbportfolio/admin/roles.py +1 -0
- wbportfolio/admin/transactions/__init__.py +1 -0
- wbportfolio/admin/transactions/claim.py +1 -0
- wbportfolio/admin/transactions/dividends.py +1 -0
- wbportfolio/admin/transactions/fees.py +1 -0
- wbportfolio/admin/transactions/rebalancing.py +26 -0
- wbportfolio/admin/transactions/trades.py +4 -3
- wbportfolio/admin/transactions/transactions.py +1 -0
- wbportfolio/analysis/claims.py +2 -1
- wbportfolio/contrib/company_portfolio/models.py +3 -6
- wbportfolio/contrib/company_portfolio/tests/conftest.py +0 -12
- wbportfolio/contrib/company_portfolio/tests/test_models.py +1 -0
- wbportfolio/defaults/fees/default.py +1 -0
- wbportfolio/factories/__init__.py +1 -7
- wbportfolio/factories/adjustments.py +1 -0
- wbportfolio/factories/assets.py +13 -7
- wbportfolio/factories/claim.py +1 -0
- wbportfolio/factories/custodians.py +1 -0
- wbportfolio/factories/dividends.py +1 -0
- wbportfolio/factories/fees.py +1 -0
- wbportfolio/factories/indexes.py +1 -0
- wbportfolio/factories/portfolio_cash_flow.py +1 -0
- wbportfolio/factories/portfolio_cash_targets.py +1 -0
- wbportfolio/factories/portfolio_swing_pricings.py +1 -0
- wbportfolio/factories/portfolios.py +3 -0
- wbportfolio/factories/product_groups.py +1 -0
- wbportfolio/factories/products.py +1 -0
- wbportfolio/factories/rebalancing.py +23 -0
- wbportfolio/factories/reconciliations.py +1 -0
- wbportfolio/factories/roles.py +1 -0
- wbportfolio/factories/trades.py +1 -0
- wbportfolio/factories/transactions.py +1 -0
- wbportfolio/fdm/tasks.py +1 -0
- wbportfolio/filters/__init__.py +1 -1
- wbportfolio/filters/assets.py +8 -9
- wbportfolio/filters/assets_and_net_new_money_progression.py +1 -0
- wbportfolio/filters/custodians.py +1 -0
- wbportfolio/filters/esg.py +1 -0
- wbportfolio/filters/performances.py +7 -6
- wbportfolio/filters/portfolios.py +21 -1
- wbportfolio/filters/positions.py +1 -0
- wbportfolio/filters/products.py +1 -0
- wbportfolio/filters/roles.py +1 -0
- wbportfolio/filters/signals.py +1 -0
- wbportfolio/filters/transactions/claim.py +1 -0
- wbportfolio/filters/transactions/fees.py +1 -0
- wbportfolio/filters/transactions/trades.py +2 -1
- wbportfolio/filters/transactions/transactions.py +1 -0
- wbportfolio/import_export/backends/ubs/mixin.py +1 -0
- wbportfolio/import_export/backends/wbfdm/adjustment.py +1 -0
- wbportfolio/import_export/handlers/asset_position.py +11 -13
- wbportfolio/import_export/handlers/fees.py +1 -0
- wbportfolio/import_export/handlers/portfolio_cash_flow.py +1 -0
- wbportfolio/import_export/handlers/trade.py +1 -0
- wbportfolio/import_export/parsers/jpmorgan/customer_trade.py +1 -0
- wbportfolio/import_export/parsers/jpmorgan/fees.py +1 -0
- wbportfolio/import_export/parsers/jpmorgan/strategy.py +5 -4
- wbportfolio/import_export/parsers/jpmorgan/valuation.py +1 -0
- wbportfolio/import_export/parsers/leonteq/customer_trade.py +1 -0
- wbportfolio/import_export/parsers/leonteq/equity.py +13 -12
- wbportfolio/import_export/parsers/leonteq/fees.py +1 -0
- wbportfolio/import_export/parsers/leonteq/trade.py +1 -0
- wbportfolio/import_export/parsers/leonteq/valuation.py +1 -0
- wbportfolio/import_export/parsers/natixis/customer_trade.py +1 -0
- wbportfolio/import_export/parsers/natixis/d1_customer_trade.py +1 -0
- wbportfolio/import_export/parsers/natixis/d1_equity.py +3 -2
- wbportfolio/import_export/parsers/natixis/d1_fees.py +1 -0
- wbportfolio/import_export/parsers/natixis/d1_trade.py +1 -0
- wbportfolio/import_export/parsers/natixis/d1_valuation.py +1 -0
- wbportfolio/import_export/parsers/natixis/equity.py +5 -5
- wbportfolio/import_export/parsers/natixis/trade.py +1 -0
- wbportfolio/import_export/parsers/natixis/utils.py +8 -7
- wbportfolio/import_export/parsers/sg_lux/custodian_positions.py +1 -0
- wbportfolio/import_export/parsers/sg_lux/customer_trade.py +1 -0
- wbportfolio/import_export/parsers/sg_lux/customer_trade_pending_slk.py +2 -1
- wbportfolio/import_export/parsers/sg_lux/customer_trade_slk.py +2 -1
- wbportfolio/import_export/parsers/sg_lux/customer_trade_without_pw.py +1 -0
- wbportfolio/import_export/parsers/sg_lux/equity.py +7 -8
- wbportfolio/import_export/parsers/sg_lux/portfolio_cash_flow.py +1 -0
- wbportfolio/import_export/parsers/sg_lux/portfolio_future_cash_flow.py +1 -0
- wbportfolio/import_export/parsers/sg_lux/registers.py +2 -1
- wbportfolio/import_export/parsers/societe_generale/customer_trade.py +1 -0
- wbportfolio/import_export/parsers/societe_generale/strategy.py +8 -9
- wbportfolio/import_export/parsers/societe_generale/valuation.py +1 -0
- wbportfolio/import_export/parsers/tellco/equity.py +5 -4
- wbportfolio/import_export/parsers/ubs/api/asset_position.py +15 -14
- wbportfolio/import_export/parsers/ubs/api/fees.py +1 -0
- wbportfolio/import_export/parsers/ubs/customer_trade.py +1 -0
- wbportfolio/import_export/parsers/ubs/equity.py +3 -2
- wbportfolio/import_export/parsers/ubs/historical_customer_trade.py +1 -0
- wbportfolio/import_export/parsers/ubs/valuation.py +1 -0
- wbportfolio/import_export/parsers/vontobel/asset_position.py +19 -19
- wbportfolio/import_export/parsers/vontobel/customer_trade.py +1 -0
- wbportfolio/import_export/parsers/vontobel/historical_customer_trade.py +1 -0
- wbportfolio/import_export/parsers/vontobel/management_fees.py +1 -0
- wbportfolio/import_export/parsers/vontobel/performance_fees.py +1 -0
- wbportfolio/import_export/parsers/vontobel/trade.py +1 -0
- wbportfolio/import_export/parsers/vontobel/valuation_api.py +23 -0
- wbportfolio/import_export/resources/assets.py +4 -3
- wbportfolio/import_export/resources/trades.py +1 -0
- wbportfolio/metric/backends/base.py +1 -0
- wbportfolio/metric/backends/portfolio_base.py +1 -0
- wbportfolio/metric/backends/portfolio_esg.py +1 -0
- wbportfolio/metric/tests/test_portfolio_base.py +1 -0
- wbportfolio/migrations/0052_remove_cash_instrument_ptr_and_more.py +1 -131
- wbportfolio/migrations/0067_assetposition_unique_asset_position.py +1 -1
- wbportfolio/migrations/0070_remove_assetposition_unique_asset_position_and_more.py +1 -1
- wbportfolio/migrations/0073_remove_product_price_computation_and_more.py +407 -0
- wbportfolio/models/__init__.py +0 -5
- wbportfolio/models/adjustments.py +8 -2
- wbportfolio/models/asset.py +117 -98
- wbportfolio/models/graphs/portfolio.py +161 -0
- wbportfolio/models/graphs/utils.py +83 -0
- wbportfolio/models/indexes.py +2 -13
- wbportfolio/models/mixins/instruments.py +28 -8
- wbportfolio/models/portfolio.py +538 -332
- wbportfolio/models/portfolio_cash_flow.py +1 -0
- wbportfolio/models/portfolio_relationship.py +6 -2
- wbportfolio/models/product_groups.py +3 -2
- wbportfolio/models/products.py +3 -17
- wbportfolio/models/reconciliations/account_reconciliation_lines.py +1 -0
- wbportfolio/models/reconciliations/account_reconciliations.py +1 -0
- wbportfolio/models/registers.py +1 -0
- wbportfolio/models/transactions/__init__.py +1 -0
- wbportfolio/models/transactions/claim.py +8 -8
- wbportfolio/models/transactions/dividends.py +1 -0
- wbportfolio/models/transactions/fees.py +1 -0
- wbportfolio/models/transactions/rebalancing.py +153 -0
- wbportfolio/models/transactions/trade_proposals.py +153 -155
- wbportfolio/models/transactions/trades.py +48 -40
- wbportfolio/models/transactions/transactions.py +6 -12
- wbportfolio/models/utils.py +1 -0
- wbportfolio/pms/analytics/__init__.py +0 -0
- wbportfolio/pms/analytics/portfolio.py +28 -0
- wbportfolio/pms/trading/handler.py +13 -16
- wbportfolio/pms/typing.py +13 -29
- wbportfolio/rebalancing/__init__.py +0 -0
- wbportfolio/rebalancing/base.py +16 -0
- wbportfolio/rebalancing/decorators.py +17 -0
- wbportfolio/rebalancing/models/__init__.py +3 -0
- wbportfolio/rebalancing/models/composite.py +31 -0
- wbportfolio/rebalancing/models/equally_weighted.py +21 -0
- wbportfolio/rebalancing/models/model_portfolio.py +35 -0
- wbportfolio/reports/monthly_position_report.py +1 -1
- wbportfolio/risk_management/backends/accounts.py +7 -6
- wbportfolio/risk_management/backends/controversy_portfolio.py +1 -0
- wbportfolio/risk_management/backends/exposure_portfolio.py +1 -0
- wbportfolio/risk_management/backends/instrument_list_portfolio.py +1 -0
- wbportfolio/risk_management/backends/liquidity_risk.py +1 -0
- wbportfolio/risk_management/backends/liquidity_stress_instrument.py +1 -0
- wbportfolio/risk_management/backends/mixins.py +1 -0
- wbportfolio/risk_management/backends/product_integrity.py +6 -1
- wbportfolio/risk_management/backends/stop_loss_instrument.py +1 -0
- wbportfolio/risk_management/backends/stop_loss_portfolio.py +1 -0
- wbportfolio/risk_management/backends/ucits_portfolio.py +12 -5
- wbportfolio/risk_management/tests/test_accounts.py +1 -0
- wbportfolio/risk_management/tests/test_controversy_portfolio.py +1 -0
- wbportfolio/risk_management/tests/test_exposure_portfolio.py +1 -0
- wbportfolio/risk_management/tests/test_instrument_list_portfolio.py +1 -0
- wbportfolio/risk_management/tests/test_liquidity_risk.py +1 -0
- wbportfolio/risk_management/tests/test_product_integrity.py +1 -0
- wbportfolio/risk_management/tests/test_stop_loss_instrument.py +1 -0
- wbportfolio/risk_management/tests/test_stop_loss_portfolio.py +1 -0
- wbportfolio/risk_management/tests/test_ucits_portfolio.py +2 -1
- wbportfolio/serializers/__init__.py +5 -5
- wbportfolio/serializers/adjustments.py +1 -0
- wbportfolio/serializers/assets.py +18 -19
- wbportfolio/serializers/custodians.py +1 -0
- wbportfolio/serializers/portfolio_cash_flow.py +1 -0
- wbportfolio/serializers/portfolio_cash_targets.py +1 -0
- wbportfolio/serializers/portfolio_relationship.py +1 -0
- wbportfolio/serializers/portfolio_swing_pricing.py +1 -0
- wbportfolio/serializers/portfolios.py +61 -40
- wbportfolio/serializers/positions.py +1 -0
- wbportfolio/serializers/product_group.py +1 -0
- wbportfolio/serializers/products.py +4 -7
- wbportfolio/serializers/rebalancing.py +57 -0
- wbportfolio/serializers/reconciliations.py +2 -1
- wbportfolio/serializers/registers.py +1 -0
- wbportfolio/serializers/roles.py +1 -0
- wbportfolio/serializers/signals.py +10 -15
- wbportfolio/serializers/transactions/__init__.py +1 -1
- wbportfolio/serializers/transactions/claim.py +1 -0
- wbportfolio/serializers/transactions/fees.py +1 -0
- wbportfolio/serializers/transactions/trade_proposals.py +85 -0
- wbportfolio/serializers/transactions/trades.py +9 -51
- wbportfolio/serializers/transactions/transactions.py +4 -3
- wbportfolio/tasks.py +1 -78
- wbportfolio/tests/conftest.py +6 -13
- wbportfolio/tests/models/test_account_reconciliation.py +2 -0
- wbportfolio/tests/models/test_assets.py +27 -19
- wbportfolio/tests/models/test_customer_trades.py +1 -0
- wbportfolio/tests/models/test_imports.py +5 -1
- wbportfolio/tests/models/test_merge.py +5 -4
- wbportfolio/tests/models/test_portfolio_cash_flow.py +8 -6
- wbportfolio/tests/models/test_portfolios.py +619 -154
- wbportfolio/tests/models/test_product_groups.py +1 -0
- wbportfolio/tests/models/test_products.py +6 -3
- wbportfolio/tests/models/test_roles.py +1 -0
- wbportfolio/tests/models/test_splits.py +1 -0
- wbportfolio/tests/models/transactions/test_claim.py +1 -0
- wbportfolio/tests/models/transactions/test_fees.py +1 -0
- wbportfolio/tests/models/transactions/test_rebalancing.py +81 -0
- wbportfolio/tests/models/transactions/test_trades.py +1 -0
- wbportfolio/tests/models/utils.py +1 -0
- wbportfolio/tests/pms/__init__.py +0 -0
- wbportfolio/tests/pms/test_analytics.py +35 -0
- wbportfolio/tests/rebalancing/__init__.py +0 -0
- wbportfolio/tests/rebalancing/test_models.py +127 -0
- wbportfolio/tests/serializers/test_claims.py +1 -0
- wbportfolio/tests/signals.py +1 -7
- wbportfolio/tests/tests.py +2 -0
- wbportfolio/tests/viewsets/test_assets.py +1 -0
- wbportfolio/tests/viewsets/test_performances.py +1 -0
- wbportfolio/tests/viewsets/test_products.py +1 -0
- wbportfolio/tests/viewsets/transactions/test_claims.py +1 -0
- wbportfolio/urls.py +26 -12
- wbportfolio/viewsets/__init__.py +2 -5
- wbportfolio/viewsets/adjustments.py +1 -0
- wbportfolio/viewsets/assets.py +62 -51
- wbportfolio/viewsets/assets_and_net_new_money_progression.py +1 -0
- wbportfolio/viewsets/charts/assets.py +3 -1
- wbportfolio/viewsets/configs/buttons/__init__.py +1 -1
- wbportfolio/viewsets/configs/buttons/assets.py +1 -0
- wbportfolio/viewsets/configs/buttons/custodians.py +1 -0
- wbportfolio/viewsets/configs/buttons/mixins.py +1 -20
- wbportfolio/viewsets/configs/buttons/portfolios.py +90 -76
- wbportfolio/viewsets/configs/buttons/signals.py +1 -0
- wbportfolio/viewsets/configs/buttons/trades.py +1 -0
- wbportfolio/viewsets/configs/display/__init__.py +2 -1
- wbportfolio/viewsets/configs/display/adjustments.py +1 -0
- wbportfolio/viewsets/configs/display/assets.py +7 -6
- wbportfolio/viewsets/configs/display/claim.py +1 -0
- wbportfolio/viewsets/configs/display/portfolios.py +127 -79
- wbportfolio/viewsets/configs/display/product_performance.py +1 -0
- wbportfolio/viewsets/configs/display/rebalancing.py +27 -0
- wbportfolio/viewsets/configs/display/trade_proposals.py +7 -4
- wbportfolio/viewsets/configs/display/trades.py +75 -42
- wbportfolio/viewsets/configs/endpoints/__init__.py +3 -1
- wbportfolio/viewsets/configs/endpoints/assets.py +12 -0
- wbportfolio/viewsets/configs/endpoints/claim.py +1 -0
- wbportfolio/viewsets/configs/endpoints/portfolios.py +23 -7
- wbportfolio/viewsets/configs/endpoints/rebalancing.py +6 -0
- wbportfolio/viewsets/configs/endpoints/reconciliations.py +1 -0
- wbportfolio/viewsets/configs/endpoints/trade_proposals.py +1 -0
- wbportfolio/viewsets/configs/endpoints/trades.py +1 -0
- wbportfolio/viewsets/configs/menu/adjustments.py +1 -0
- wbportfolio/viewsets/configs/menu/assets.py +1 -0
- wbportfolio/viewsets/configs/menu/fees.py +1 -0
- wbportfolio/viewsets/configs/menu/portfolio_cash_flow.py +1 -0
- wbportfolio/viewsets/configs/menu/portfolios.py +4 -2
- wbportfolio/viewsets/configs/menu/positions.py +1 -0
- wbportfolio/viewsets/configs/menu/roles.py +1 -0
- wbportfolio/viewsets/configs/menu/transactions.py +1 -0
- wbportfolio/viewsets/configs/previews/portfolios.py +1 -6
- wbportfolio/viewsets/configs/titles/__init__.py +1 -1
- wbportfolio/viewsets/configs/titles/assets.py +1 -0
- wbportfolio/viewsets/configs/titles/fees.py +1 -0
- wbportfolio/viewsets/configs/titles/instrument_prices.py +1 -0
- wbportfolio/viewsets/configs/titles/portfolios.py +13 -11
- wbportfolio/viewsets/configs/titles/roles.py +1 -0
- wbportfolio/viewsets/configs/titles/trades.py +1 -0
- wbportfolio/viewsets/configs/titles/transactions.py +1 -0
- wbportfolio/viewsets/custodians.py +1 -0
- wbportfolio/viewsets/esg.py +1 -0
- wbportfolio/viewsets/mixins.py +1 -0
- wbportfolio/viewsets/portfolio_cash_flow.py +1 -0
- wbportfolio/viewsets/portfolio_cash_targets.py +1 -0
- wbportfolio/viewsets/portfolio_relationship.py +1 -0
- wbportfolio/viewsets/portfolio_swing_pricing.py +1 -0
- wbportfolio/viewsets/portfolios.py +228 -61
- wbportfolio/viewsets/positions.py +3 -2
- wbportfolio/viewsets/product_groups.py +1 -0
- wbportfolio/viewsets/product_performance.py +1 -0
- wbportfolio/viewsets/products.py +1 -0
- wbportfolio/viewsets/reconciliations.py +1 -0
- wbportfolio/viewsets/registers.py +1 -0
- wbportfolio/viewsets/roles.py +1 -0
- wbportfolio/viewsets/signals.py +1 -0
- wbportfolio/viewsets/transactions/__init__.py +1 -0
- wbportfolio/viewsets/transactions/claim.py +2 -1
- wbportfolio/viewsets/transactions/fees.py +1 -0
- wbportfolio/viewsets/transactions/mixins.py +1 -0
- wbportfolio/viewsets/transactions/rebalancing.py +31 -0
- wbportfolio/viewsets/transactions/trade_proposals.py +25 -5
- wbportfolio/viewsets/transactions/trades.py +16 -9
- wbportfolio/viewsets/transactions/transactions.py +1 -0
- {wbportfolio-1.44.5.dist-info → wbportfolio-1.45.1.dist-info}/METADATA +4 -1
- wbportfolio-1.45.1.dist-info/RECORD +521 -0
- wbportfolio/admin/synchronization/__init__.py +0 -2
- wbportfolio/admin/synchronization/admin.py +0 -114
- wbportfolio/admin/synchronization/portfolio_synchronization.py +0 -18
- wbportfolio/admin/synchronization/price_computation.py +0 -21
- wbportfolio/defaults/portfolio/default_rebalancing.py +0 -45
- wbportfolio/factories/pytest_utils.py +0 -121
- wbportfolio/factories/synchronization.py +0 -40
- wbportfolio/models/synchronization/__init__.py +0 -3
- wbportfolio/models/synchronization/portfolio_synchronization.py +0 -292
- wbportfolio/models/synchronization/price_computation.py +0 -200
- wbportfolio/models/synchronization/synchronization.py +0 -188
- wbportfolio/serializers/synchronization.py +0 -18
- wbportfolio/tests/models/test_synchronization.py +0 -617
- wbportfolio/viewsets/synchronization.py +0 -25
- wbportfolio-1.44.5.dist-info/RECORD +0 -508
- /wbportfolio/{defaults/portfolio → models/graphs}/__init__.py +0 -0
- {wbportfolio-1.44.5.dist-info → wbportfolio-1.45.1.dist-info}/WHEEL +0 -0
- {wbportfolio-1.44.5.dist-info → wbportfolio-1.45.1.dist-info}/licenses/LICENSE +0 -0
wbportfolio/admin/__init__.py
CHANGED
|
@@ -3,10 +3,10 @@ from .portfolio_relationships import PortfolioInstrumentPreferredClassificationT
|
|
|
3
3
|
from .asset import AssetPositionModelAdmin
|
|
4
4
|
from .custodians import CustodianModelAdmin
|
|
5
5
|
from .products import ProductAdmin
|
|
6
|
+
from .indexes import IndexAdmin
|
|
6
7
|
from .product_groups import ProductGroupAdmin
|
|
7
8
|
from .portfolio import PortfolioModelAdmin
|
|
8
9
|
from .registers import RegisterModelAdmin
|
|
9
10
|
from .roles import PortfolioRoleAdmin
|
|
10
|
-
from .synchronization import *
|
|
11
11
|
from .transactions import DividendAdmin, FeesAdmin, TradeAdmin, TransactionModelAdmin
|
|
12
12
|
from .reconciliations import AccountReconciliationAdmin
|
wbportfolio/admin/asset.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from django.contrib import admin
|
|
2
|
+
|
|
2
3
|
from wbportfolio.models import AssetPosition
|
|
3
4
|
|
|
4
5
|
|
|
@@ -41,7 +42,7 @@ class AssetPositionModelAdmin(admin.ModelAdmin):
|
|
|
41
42
|
raw_id_fields = [
|
|
42
43
|
"import_source",
|
|
43
44
|
"applied_adjustment",
|
|
44
|
-
"
|
|
45
|
+
"underlying_quote_price",
|
|
45
46
|
"currency_fx_rate_instrument_to_usd",
|
|
46
47
|
"currency_fx_rate_portfolio_to_usd",
|
|
47
48
|
]
|
wbportfolio/admin/custodians.py
CHANGED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from django.contrib import admin
|
|
2
|
+
from wbfdm.admin import InstrumentModelAdmin
|
|
3
|
+
|
|
4
|
+
from wbportfolio.models import Index
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@admin.register(Index)
|
|
8
|
+
class IndexAdmin(InstrumentModelAdmin):
|
|
9
|
+
fieldsets = (
|
|
10
|
+
("Instrument Information", InstrumentModelAdmin.fieldsets[0][1]),
|
|
11
|
+
(
|
|
12
|
+
"Index Information",
|
|
13
|
+
{"fields": (("net_asset_value_computation_method_path",),)},
|
|
14
|
+
),
|
|
15
|
+
)
|
wbportfolio/admin/portfolio.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from django.contrib import admin
|
|
2
|
+
|
|
2
3
|
from wbportfolio.models import (
|
|
3
4
|
DailyPortfolioCashFlow,
|
|
4
5
|
InstrumentPortfolioThroughModel,
|
|
@@ -52,22 +53,27 @@ class PortfolioModelAdmin(admin.ModelAdmin):
|
|
|
52
53
|
"Main Information",
|
|
53
54
|
{
|
|
54
55
|
"fields": (
|
|
55
|
-
("name", "
|
|
56
|
+
("name", "updated_at"),
|
|
56
57
|
("currency", "hedged_currency"),
|
|
57
|
-
(
|
|
58
|
+
(
|
|
59
|
+
"invested_timespan",
|
|
60
|
+
"is_manageable",
|
|
61
|
+
"is_active",
|
|
62
|
+
),
|
|
63
|
+
("is_tracked", "only_weighting", "is_lookthrough"),
|
|
58
64
|
)
|
|
59
65
|
},
|
|
60
66
|
),
|
|
61
67
|
)
|
|
62
|
-
readonly_fields = ["
|
|
68
|
+
readonly_fields = ["updated_at"]
|
|
63
69
|
list_display = (
|
|
70
|
+
"is_active",
|
|
64
71
|
"name",
|
|
65
72
|
"currency",
|
|
66
73
|
"hedged_currency",
|
|
67
|
-
"portfolio_synchronization",
|
|
68
74
|
"is_manageable",
|
|
69
|
-
"is_active",
|
|
70
75
|
"is_tracked",
|
|
76
|
+
"is_lookthrough",
|
|
71
77
|
)
|
|
72
78
|
inlines = [
|
|
73
79
|
PortfolioBankAccountThroughModelAdmin,
|
|
@@ -76,13 +82,12 @@ class PortfolioModelAdmin(admin.ModelAdmin):
|
|
|
76
82
|
PortfolioPortfolioThroughModelInlineAdmin,
|
|
77
83
|
]
|
|
78
84
|
raw_id_fields = [
|
|
79
|
-
"portfolio_synchronization",
|
|
80
85
|
"depends_on",
|
|
81
86
|
"preferred_instrument_classifications",
|
|
82
87
|
"currency",
|
|
83
88
|
"hedged_currency",
|
|
84
89
|
]
|
|
85
|
-
autocomplete_fields = ["currency", "hedged_currency"
|
|
90
|
+
autocomplete_fields = ["currency", "hedged_currency"]
|
|
86
91
|
|
|
87
92
|
def get_queryset(self, request):
|
|
88
93
|
return Portfolio.all_objects.all()
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from django.contrib import admin
|
|
2
2
|
from wbfdm.admin.instruments import InstrumentModelAdmin
|
|
3
|
+
|
|
3
4
|
from wbportfolio.models import ProductGroup, ProductGroupRepresentant
|
|
4
5
|
|
|
5
6
|
from .portfolio_relationships import InstrumentPortfolioThroughModelAdmin
|
|
@@ -29,6 +30,7 @@ class ProductGroupAdmin(InstrumentModelAdmin):
|
|
|
29
30
|
("type", "category", "umbrella"),
|
|
30
31
|
("management_company", "depositary", "transfer_agent", "administrator"),
|
|
31
32
|
("investment_manager", "auditor", "paying_agent"),
|
|
33
|
+
("net_asset_value_computation_method_path", "risk_scale"),
|
|
32
34
|
)
|
|
33
35
|
},
|
|
34
36
|
),
|
wbportfolio/admin/products.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from django.contrib import admin
|
|
2
2
|
from wbfdm.admin import InstrumentModelAdmin
|
|
3
|
+
|
|
3
4
|
from wbportfolio.models import FeeProductPercentage, Product
|
|
4
5
|
|
|
5
6
|
from .roles import PortfolioRoleInline
|
|
@@ -36,7 +37,7 @@ class ProductAdmin(InstrumentModelAdmin):
|
|
|
36
37
|
{
|
|
37
38
|
"fields": (
|
|
38
39
|
("share_price", "initial_high_water_mark", "bank"),
|
|
39
|
-
("termsheet", "fee_calculation"),
|
|
40
|
+
("termsheet", "fee_calculation", "net_asset_value_computation_method_path"),
|
|
40
41
|
(
|
|
41
42
|
"white_label_customers",
|
|
42
43
|
"default_account",
|
wbportfolio/admin/registers.py
CHANGED
wbportfolio/admin/roles.py
CHANGED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from django.contrib import admin
|
|
2
|
+
|
|
3
|
+
from wbportfolio.models import Rebalancer, RebalancingModel
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@admin.register(RebalancingModel)
|
|
7
|
+
class RebalancingModelAdmin(admin.ModelAdmin):
|
|
8
|
+
search_fields = ("name",)
|
|
9
|
+
list_display = (
|
|
10
|
+
"name",
|
|
11
|
+
"class_path",
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@admin.register(Rebalancer)
|
|
16
|
+
class RebalancerAdmin(admin.ModelAdmin):
|
|
17
|
+
search_fields = ("rebalancing_model__name",)
|
|
18
|
+
list_display = (
|
|
19
|
+
"computed_str",
|
|
20
|
+
"rebalancing_model",
|
|
21
|
+
"portfolio",
|
|
22
|
+
"parameters",
|
|
23
|
+
"approve_trade_proposal_automatically",
|
|
24
|
+
"activation_date",
|
|
25
|
+
"frequency",
|
|
26
|
+
)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from django.contrib import admin
|
|
2
|
+
|
|
2
3
|
from wbportfolio.admin.transactions import TransactionModelAdmin
|
|
3
4
|
from wbportfolio.models import Trade, TradeProposal
|
|
4
5
|
|
|
@@ -43,7 +44,7 @@ class TradeAdmin(TransactionModelAdmin):
|
|
|
43
44
|
|
|
44
45
|
@admin.register(TradeProposal)
|
|
45
46
|
class TradeProposalAdmin(admin.ModelAdmin):
|
|
46
|
-
search_fields = ["portfolio__name", "
|
|
47
|
+
search_fields = ["portfolio__name", "comment"]
|
|
47
48
|
|
|
48
|
-
list_display = ("portfolio", "
|
|
49
|
-
autocomplete_fields = ["portfolio", "
|
|
49
|
+
list_display = ("portfolio", "rebalancing_model", "trade_date", "status")
|
|
50
|
+
autocomplete_fields = ["portfolio", "rebalancing_model"]
|
wbportfolio/analysis/claims.py
CHANGED
|
@@ -3,7 +3,7 @@ from typing import TYPE_CHECKING
|
|
|
3
3
|
import numpy as np
|
|
4
4
|
import pandas as pd
|
|
5
5
|
from django.db import connection
|
|
6
|
-
from django.db.models import DecimalField, ExpressionWrapper, F, OuterRef, Subquery
|
|
6
|
+
from django.db.models import DateField, DecimalField, ExpressionWrapper, F, OuterRef, Subquery
|
|
7
7
|
from django.db.models.functions import Greatest
|
|
8
8
|
from django.template.loader import get_template
|
|
9
9
|
from jinjasql import JinjaSql
|
|
@@ -12,6 +12,7 @@ from wbcore.contrib.dataloader.utils import dictfetchall
|
|
|
12
12
|
from wbcrm.models import Account
|
|
13
13
|
from wbfdm.models import ClassificationGroup
|
|
14
14
|
from wbfdm.models.instruments import Classification, InstrumentPrice
|
|
15
|
+
|
|
15
16
|
from wbportfolio.models.products import Product
|
|
16
17
|
|
|
17
18
|
if TYPE_CHECKING:
|
|
@@ -11,11 +11,12 @@ from wbcore.contrib.currency.models import CurrencyFXRates
|
|
|
11
11
|
from wbcore.contrib.directory.models import Company, CustomerStatus
|
|
12
12
|
from wbcore.models import WBModel
|
|
13
13
|
from wbcore.utils.importlib import import_from_dotted_path
|
|
14
|
+
|
|
14
15
|
from wbportfolio.models import Claim, Product
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
def get_total_assets_under_management(val_date: date) -> Decimal:
|
|
18
|
-
return sum([product.
|
|
19
|
+
return sum([product.get_total_aum_usd(val_date) for product in Product.active_objects.all()])
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
def get_lost_client_customer_status():
|
|
@@ -136,11 +137,7 @@ class CompanyPortfolioData(models.Model):
|
|
|
136
137
|
self.company
|
|
137
138
|
).annotate_asset_under_management_for_date(val_date).aggregate(
|
|
138
139
|
invested_aum_usd=models.Sum("asset_under_management_usd")
|
|
139
|
-
)[
|
|
140
|
-
"invested_aum_usd"
|
|
141
|
-
] or Decimal(
|
|
142
|
-
0
|
|
143
|
-
)
|
|
140
|
+
)["invested_aum_usd"] or Decimal(0)
|
|
144
141
|
|
|
145
142
|
def _get_default_potential(self, val_date: date) -> Decimal:
|
|
146
143
|
with suppress(CurrencyFXRates.DoesNotExist):
|
|
@@ -63,13 +63,6 @@ from wbportfolio.factories import (
|
|
|
63
63
|
TradeProposalFactory,
|
|
64
64
|
WhiteLabelProductFactory,
|
|
65
65
|
)
|
|
66
|
-
from wbportfolio.factories.synchronization import (
|
|
67
|
-
CrontabScheduleFactory,
|
|
68
|
-
PeriodicTaskFactory,
|
|
69
|
-
PortfolioSynchronizationFactory,
|
|
70
|
-
PriceComputationFactory,
|
|
71
|
-
SynchronizationTaskFactory,
|
|
72
|
-
)
|
|
73
66
|
|
|
74
67
|
from ..factories import (
|
|
75
68
|
AssetAllocationFactory,
|
|
@@ -129,11 +122,6 @@ register(UserFactory)
|
|
|
129
122
|
register(SuperUserFactory, "superuser")
|
|
130
123
|
register(CustodianFactory)
|
|
131
124
|
|
|
132
|
-
register(CrontabScheduleFactory)
|
|
133
|
-
register(PeriodicTaskFactory)
|
|
134
|
-
register(SynchronizationTaskFactory)
|
|
135
|
-
register(PortfolioSynchronizationFactory)
|
|
136
|
-
register(PriceComputationFactory)
|
|
137
125
|
register(AdjustmentFactory)
|
|
138
126
|
register(IndexFactory)
|
|
139
127
|
|
|
@@ -8,6 +8,7 @@ from faker import Faker
|
|
|
8
8
|
from wbcore.contrib.currency.models import Currency
|
|
9
9
|
from wbcore.contrib.directory.factories import CompanyFactory, CustomerStatusFactory
|
|
10
10
|
from wbcore.contrib.directory.models import Company
|
|
11
|
+
|
|
11
12
|
from wbportfolio.contrib.company_portfolio.models import (
|
|
12
13
|
CompanyPortfolioData,
|
|
13
14
|
get_client_customer_status,
|
|
@@ -23,13 +23,7 @@ from .product_groups import ProductGroupFactory, ProductGroupRepresentantFactory
|
|
|
23
23
|
from .products import IndexProductFactory, ProductFactory, WhiteLabelProductFactory
|
|
24
24
|
from .reconciliations import AccountReconciliationFactory, AccountReconciliationLineFactory
|
|
25
25
|
from .roles import ManagerPortfolioRoleFactory, ProductPortfolioRoleFactory
|
|
26
|
-
from .synchronization import (
|
|
27
|
-
CrontabScheduleFactory,
|
|
28
|
-
PeriodicTaskFactory,
|
|
29
|
-
PortfolioSynchronizationFactory,
|
|
30
|
-
PriceComputationFactory,
|
|
31
|
-
SynchronizationTaskFactory,
|
|
32
|
-
)
|
|
33
26
|
from .trades import CustomerTradeFactory, TradeFactory, TradeProposalFactory
|
|
34
27
|
from .transactions import TransactionFactory
|
|
35
28
|
from .indexes import IndexFactory
|
|
29
|
+
from .rebalancing import (RebalancingModelFactory, RebalancerFactory)
|
wbportfolio/factories/assets.py
CHANGED
|
@@ -5,12 +5,14 @@ from decimal import Decimal
|
|
|
5
5
|
import factory
|
|
6
6
|
from wbcore.contrib.currency.models import CurrencyFXRates
|
|
7
7
|
from wbfdm.factories import InstrumentPriceFactory
|
|
8
|
+
|
|
8
9
|
from wbportfolio.models import AssetPosition
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
def get_weekday(o):
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
instrument = o.underlying_quote or o.underlying_instrument
|
|
14
|
+
if instrument.id and instrument.assets.exists():
|
|
15
|
+
latest_position = instrument.assets.latest("date").date
|
|
14
16
|
else:
|
|
15
17
|
latest_position = date(2020, 1, 1)
|
|
16
18
|
|
|
@@ -24,28 +26,32 @@ def get_weekday(o):
|
|
|
24
26
|
class AssetPositionFactory(factory.django.DjangoModelFactory):
|
|
25
27
|
class Meta:
|
|
26
28
|
model = AssetPosition
|
|
27
|
-
django_get_or_create = ("portfolio", "
|
|
29
|
+
django_get_or_create = ("portfolio", "underlying_quote", "date", "portfolio_created")
|
|
28
30
|
|
|
29
31
|
underlying_instrument = factory.SubFactory("wbfdm.factories.instruments.InstrumentFactory")
|
|
32
|
+
underlying_quote = factory.LazyAttribute(lambda o: o.underlying_instrument)
|
|
30
33
|
|
|
31
34
|
date = factory.LazyAttribute(lambda o: get_weekday(o))
|
|
32
35
|
asset_valuation_date = factory.LazyAttribute(lambda o: o.date)
|
|
33
36
|
|
|
34
37
|
initial_price = factory.Faker("pydecimal", min_value=100, max_value=120, right_digits=4)
|
|
35
|
-
|
|
38
|
+
underlying_quote_price = factory.LazyAttribute(
|
|
36
39
|
lambda o: InstrumentPriceFactory.create(
|
|
37
|
-
instrument=o.underlying_instrument
|
|
40
|
+
instrument=o.underlying_instrument or o.underlying_quote,
|
|
41
|
+
calculated=False,
|
|
42
|
+
date=o.date,
|
|
43
|
+
net_value=o.initial_price,
|
|
38
44
|
)
|
|
39
45
|
)
|
|
40
46
|
|
|
41
47
|
initial_shares = factory.LazyAttribute(lambda o: Decimal(random.randint(10, 10000)))
|
|
42
48
|
initial_currency_fx_rate = Decimal(1)
|
|
43
|
-
weighting = factory.
|
|
49
|
+
weighting = factory.Faker("pydecimal", min_value=0.01, max_value=1.0, right_digits=4)
|
|
44
50
|
|
|
45
51
|
portfolio = factory.SubFactory("wbportfolio.factories.portfolios.PortfolioFactory")
|
|
46
52
|
portfolio_created = None
|
|
47
53
|
|
|
48
|
-
currency = factory.LazyAttribute(lambda o: o.underlying_instrument.currency)
|
|
54
|
+
currency = factory.LazyAttribute(lambda o: (o.underlying_instrument or o.underlying_quote).currency)
|
|
49
55
|
currency_fx_rate_instrument_to_usd = factory.LazyAttribute(
|
|
50
56
|
lambda o: CurrencyFXRates.objects.get_or_create(
|
|
51
57
|
currency=o.currency, date=o.date, defaults={"value": Decimal(1.0)}
|
wbportfolio/factories/claim.py
CHANGED
wbportfolio/factories/fees.py
CHANGED
wbportfolio/factories/indexes.py
CHANGED
|
@@ -2,6 +2,7 @@ from datetime import date
|
|
|
2
2
|
|
|
3
3
|
import factory
|
|
4
4
|
from psycopg.types.range import DateRange
|
|
5
|
+
|
|
5
6
|
from wbportfolio.models import (
|
|
6
7
|
InstrumentPortfolioThroughModel,
|
|
7
8
|
Portfolio,
|
|
@@ -18,6 +19,8 @@ class PortfolioFactory(factory.django.DjangoModelFactory):
|
|
|
18
19
|
name = factory.Sequence(lambda n: f"Portfolio {n}")
|
|
19
20
|
currency = factory.SubFactory("wbcore.contrib.currency.factories.CurrencyFactory")
|
|
20
21
|
is_manageable = True
|
|
22
|
+
is_tracked = True
|
|
23
|
+
is_lookthrough = False
|
|
21
24
|
invested_timespan = DateRange(date.min, date.max)
|
|
22
25
|
|
|
23
26
|
@factory.post_generation
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import factory
|
|
2
|
+
|
|
3
|
+
from wbportfolio.models import Rebalancer, RebalancingModel
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class RebalancingModelFactory(factory.django.DjangoModelFactory):
|
|
7
|
+
class Meta:
|
|
8
|
+
model = RebalancingModel
|
|
9
|
+
|
|
10
|
+
name = factory.Faker("name")
|
|
11
|
+
class_path = "wbportfolio.rebalancing.models.equally_weighted.EquallyWeightedRebalancing"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class RebalancerFactory(factory.django.DjangoModelFactory):
|
|
15
|
+
class Meta:
|
|
16
|
+
model = Rebalancer
|
|
17
|
+
|
|
18
|
+
portfolio = factory.SubFactory("wbportfolio.factories.portfolios.PortfolioFactory")
|
|
19
|
+
rebalancing_model = factory.SubFactory(RebalancingModelFactory)
|
|
20
|
+
parameters = dict()
|
|
21
|
+
approve_trade_proposal_automatically = False
|
|
22
|
+
frequency = "RRULE:FREQ=MONTHLY;"
|
|
23
|
+
activation_date = None
|
wbportfolio/factories/roles.py
CHANGED
wbportfolio/factories/trades.py
CHANGED
wbportfolio/fdm/tasks.py
CHANGED
wbportfolio/filters/__init__.py
CHANGED
|
@@ -17,7 +17,7 @@ from .performances import (
|
|
|
17
17
|
PerformancePandasFilter,
|
|
18
18
|
ProductPerformanceNetNewMoneyFilter,
|
|
19
19
|
)
|
|
20
|
-
from .portfolios import PortfolioFilterSet
|
|
20
|
+
from .portfolios import PortfolioFilterSet, PortfolioTreeGraphChartFilterSet
|
|
21
21
|
from .positions import AggregatedAssetPositionLiquidityFilter, AssetPositionPandasFilter
|
|
22
22
|
from .roles import PortfolioRoleFilterSet
|
|
23
23
|
from .signals import *
|
wbportfolio/filters/assets.py
CHANGED
|
@@ -11,6 +11,7 @@ from wbcore.pandas.filterset import PandasFilterSetMixin
|
|
|
11
11
|
from wbcore.utils.date import current_financial_month
|
|
12
12
|
from wbfdm.models import Classification, ClassificationGroup, Instrument, InstrumentType
|
|
13
13
|
from wbfdm.preferences import get_default_classification_group
|
|
14
|
+
|
|
14
15
|
from wbportfolio.models import AssetPosition, AssetPositionGroupBy, Portfolio, Product
|
|
15
16
|
|
|
16
17
|
|
|
@@ -278,9 +279,9 @@ class AssetPositionPortfolioFilter(AssetPositionFilter):
|
|
|
278
279
|
"market_share": Max("market_share"),
|
|
279
280
|
"liquidity": Max("liquidity"),
|
|
280
281
|
"currency_symbol": Max("currency__symbol"),
|
|
281
|
-
"
|
|
282
|
-
"
|
|
283
|
-
"
|
|
282
|
+
"underlying_quote_name": Max("underlying_quote__name"),
|
|
283
|
+
"underlying_quote_ticker": Max("underlying_quote__ticker"),
|
|
284
|
+
"underlying_quote_isin": Max("underlying_quote__isin"),
|
|
284
285
|
"portfolio_currency_symbol": Max("portfolio__currency__symbol"),
|
|
285
286
|
}
|
|
286
287
|
for key in self.view._metric_serializer_fields.keys():
|
|
@@ -306,9 +307,9 @@ class AssetPositionPortfolioFilter(AssetPositionFilter):
|
|
|
306
307
|
|
|
307
308
|
|
|
308
309
|
class AssetPositionInstrumentFilter(AssetPositionFilter):
|
|
309
|
-
hide_empty_position = (
|
|
310
|
-
|
|
311
|
-
) =
|
|
310
|
+
hide_empty_position = hide_aggregated_position = instrument_type = portfolio_instrument = is_cash = (
|
|
311
|
+
classification
|
|
312
|
+
) = country = None
|
|
312
313
|
date = wb_filters.DateFilter(
|
|
313
314
|
label="Date",
|
|
314
315
|
lookup_expr="exact",
|
|
@@ -476,9 +477,7 @@ class AssetPositionUnderlyingInstrumentChartFilter(DateFilterMixin, wb_filters.F
|
|
|
476
477
|
|
|
477
478
|
|
|
478
479
|
class CompositionModelPortfolioPandasFilter(PandasFilterSetMixin, wb_filters.FilterSet):
|
|
479
|
-
date = wb_filters.DateFilter(
|
|
480
|
-
label="Date", lookup_expr="exact", field_name="date", default=get_latest_asset_position, required=True
|
|
481
|
-
)
|
|
480
|
+
date = wb_filters.DateFilter(label="Date", lookup_expr="exact", default=get_latest_asset_position, required=True)
|
|
482
481
|
|
|
483
482
|
class Meta:
|
|
484
483
|
model = AssetPosition
|