wbportfolio 1.43.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/__init__.py +1 -0
- wbportfolio/admin/__init__.py +12 -0
- wbportfolio/admin/asset.py +47 -0
- wbportfolio/admin/custodians.py +9 -0
- wbportfolio/admin/portfolio.py +127 -0
- wbportfolio/admin/portfolio_relationships.py +22 -0
- wbportfolio/admin/product_groups.py +42 -0
- wbportfolio/admin/products.py +80 -0
- wbportfolio/admin/reconciliations.py +14 -0
- wbportfolio/admin/registers.py +17 -0
- wbportfolio/admin/roles.py +19 -0
- wbportfolio/admin/synchronization/__init__.py +2 -0
- wbportfolio/admin/synchronization/admin.py +114 -0
- wbportfolio/admin/synchronization/portfolio_synchronization.py +18 -0
- wbportfolio/admin/synchronization/price_computation.py +21 -0
- wbportfolio/admin/transactions/__init__.py +5 -0
- wbportfolio/admin/transactions/claim.py +16 -0
- wbportfolio/admin/transactions/dividends.py +14 -0
- wbportfolio/admin/transactions/fees.py +35 -0
- wbportfolio/admin/transactions/trades.py +49 -0
- wbportfolio/admin/transactions/transactions.py +37 -0
- wbportfolio/analysis/__init__.py +0 -0
- wbportfolio/analysis/claims.py +235 -0
- wbportfolio/apps.py +5 -0
- wbportfolio/contrib/__init__.py +0 -0
- wbportfolio/contrib/company_portfolio/__init__.py +0 -0
- wbportfolio/contrib/company_portfolio/admin.py +28 -0
- wbportfolio/contrib/company_portfolio/apps.py +29 -0
- wbportfolio/contrib/company_portfolio/configs/__init__.py +3 -0
- wbportfolio/contrib/company_portfolio/configs/display.py +182 -0
- wbportfolio/contrib/company_portfolio/configs/endpoints.py +34 -0
- wbportfolio/contrib/company_portfolio/configs/previews.py +37 -0
- wbportfolio/contrib/company_portfolio/constants.py +1 -0
- wbportfolio/contrib/company_portfolio/dynamic_preferences_registry.py +87 -0
- wbportfolio/contrib/company_portfolio/factories.py +32 -0
- wbportfolio/contrib/company_portfolio/filters.py +127 -0
- wbportfolio/contrib/company_portfolio/management.py +19 -0
- wbportfolio/contrib/company_portfolio/migrations/0001_initial.py +214 -0
- wbportfolio/contrib/company_portfolio/migrations/__init__.py +0 -0
- wbportfolio/contrib/company_portfolio/models.py +334 -0
- wbportfolio/contrib/company_portfolio/scripts.py +76 -0
- wbportfolio/contrib/company_portfolio/serializers.py +303 -0
- wbportfolio/contrib/company_portfolio/tasks.py +19 -0
- wbportfolio/contrib/company_portfolio/tests/__init__.py +0 -0
- wbportfolio/contrib/company_portfolio/tests/conftest.py +161 -0
- wbportfolio/contrib/company_portfolio/tests/test_models.py +161 -0
- wbportfolio/contrib/company_portfolio/urls.py +29 -0
- wbportfolio/contrib/company_portfolio/viewsets.py +195 -0
- wbportfolio/defaults/__init__.py +0 -0
- wbportfolio/defaults/fees/__init__.py +0 -0
- wbportfolio/defaults/fees/default.py +92 -0
- wbportfolio/defaults/portfolio/__init__.py +0 -0
- wbportfolio/defaults/portfolio/default_rebalancing.py +45 -0
- wbportfolio/dynamic_preferences_registry.py +58 -0
- wbportfolio/factories/__init__.py +35 -0
- wbportfolio/factories/adjustments.py +17 -0
- wbportfolio/factories/assets.py +75 -0
- wbportfolio/factories/claim.py +39 -0
- wbportfolio/factories/custodians.py +11 -0
- wbportfolio/factories/dividends.py +14 -0
- wbportfolio/factories/fees.py +15 -0
- wbportfolio/factories/indexes.py +17 -0
- wbportfolio/factories/portfolio_cash_flow.py +20 -0
- wbportfolio/factories/portfolio_cash_targets.py +15 -0
- wbportfolio/factories/portfolio_swing_pricings.py +15 -0
- wbportfolio/factories/portfolios.py +59 -0
- wbportfolio/factories/product_groups.py +28 -0
- wbportfolio/factories/products.py +56 -0
- wbportfolio/factories/pytest_utils.py +121 -0
- wbportfolio/factories/reconciliations.py +23 -0
- wbportfolio/factories/roles.py +20 -0
- wbportfolio/factories/synchronization.py +40 -0
- wbportfolio/factories/trades.py +35 -0
- wbportfolio/factories/transactions.py +21 -0
- wbportfolio/fdm/__init__.py +0 -0
- wbportfolio/fdm/tasks.py +12 -0
- wbportfolio/filters/__init__.py +32 -0
- wbportfolio/filters/assets.py +485 -0
- wbportfolio/filters/assets_and_net_new_money_progression.py +42 -0
- wbportfolio/filters/custodians.py +10 -0
- wbportfolio/filters/esg.py +22 -0
- wbportfolio/filters/performances.py +171 -0
- wbportfolio/filters/portfolios.py +24 -0
- wbportfolio/filters/positions.py +178 -0
- wbportfolio/filters/products.py +153 -0
- wbportfolio/filters/roles.py +26 -0
- wbportfolio/filters/signals.py +92 -0
- wbportfolio/filters/transactions/__init__.py +20 -0
- wbportfolio/filters/transactions/claim.py +394 -0
- wbportfolio/filters/transactions/fees.py +66 -0
- wbportfolio/filters/transactions/trades.py +248 -0
- wbportfolio/filters/transactions/transactions.py +98 -0
- wbportfolio/fixtures/product_factsheets.yaml +1 -0
- wbportfolio/fixtures/wbportfolio.yaml.gz +0 -0
- wbportfolio/fixtures/wbrisk_management.yaml.gz +0 -0
- wbportfolio/import_export/__init__.py +0 -0
- wbportfolio/import_export/backends/__init__.py +2 -0
- wbportfolio/import_export/backends/refinitiv/adjustment.py +40 -0
- wbportfolio/import_export/backends/ubs/__init__.py +3 -0
- wbportfolio/import_export/backends/ubs/asset_position.py +45 -0
- wbportfolio/import_export/backends/ubs/fees.py +63 -0
- wbportfolio/import_export/backends/ubs/instrument_price.py +44 -0
- wbportfolio/import_export/backends/ubs/mixin.py +15 -0
- wbportfolio/import_export/backends/utils.py +58 -0
- wbportfolio/import_export/backends/wbfdm/__init__.py +2 -0
- wbportfolio/import_export/backends/wbfdm/adjustment.py +50 -0
- wbportfolio/import_export/backends/wbfdm/dividend.py +16 -0
- wbportfolio/import_export/backends/wbfdm/mixin.py +15 -0
- wbportfolio/import_export/handlers/__init__.py +0 -0
- wbportfolio/import_export/handlers/adjustment.py +39 -0
- wbportfolio/import_export/handlers/asset_position.py +167 -0
- wbportfolio/import_export/handlers/dividend.py +80 -0
- wbportfolio/import_export/handlers/fees.py +58 -0
- wbportfolio/import_export/handlers/portfolio_cash_flow.py +57 -0
- wbportfolio/import_export/handlers/register.py +43 -0
- wbportfolio/import_export/handlers/trade.py +191 -0
- wbportfolio/import_export/parsers/__init__.py +0 -0
- wbportfolio/import_export/parsers/default_mapping.py +30 -0
- wbportfolio/import_export/parsers/jpmorgan/__init__.py +0 -0
- wbportfolio/import_export/parsers/jpmorgan/customer_trade.py +63 -0
- wbportfolio/import_export/parsers/jpmorgan/fees.py +64 -0
- wbportfolio/import_export/parsers/jpmorgan/strategy.py +116 -0
- wbportfolio/import_export/parsers/jpmorgan/valuation.py +41 -0
- wbportfolio/import_export/parsers/leonteq/__init__.py +0 -0
- wbportfolio/import_export/parsers/leonteq/customer_trade.py +47 -0
- wbportfolio/import_export/parsers/leonteq/equity.py +81 -0
- wbportfolio/import_export/parsers/leonteq/fees.py +70 -0
- wbportfolio/import_export/parsers/leonteq/trade.py +94 -0
- wbportfolio/import_export/parsers/leonteq/valuation.py +39 -0
- wbportfolio/import_export/parsers/natixis/__init__.py +0 -0
- wbportfolio/import_export/parsers/natixis/customer_trade.py +62 -0
- wbportfolio/import_export/parsers/natixis/d1_customer_trade.py +66 -0
- wbportfolio/import_export/parsers/natixis/d1_equity.py +80 -0
- wbportfolio/import_export/parsers/natixis/d1_fees.py +58 -0
- wbportfolio/import_export/parsers/natixis/d1_trade.py +70 -0
- wbportfolio/import_export/parsers/natixis/d1_valuation.py +41 -0
- wbportfolio/import_export/parsers/natixis/dividend.py +53 -0
- wbportfolio/import_export/parsers/natixis/equity.py +60 -0
- wbportfolio/import_export/parsers/natixis/fees.py +53 -0
- wbportfolio/import_export/parsers/natixis/trade.py +63 -0
- wbportfolio/import_export/parsers/natixis/utils.py +76 -0
- wbportfolio/import_export/parsers/natixis/valuation.py +46 -0
- wbportfolio/import_export/parsers/refinitiv/__init__.py +0 -0
- wbportfolio/import_export/parsers/refinitiv/adjustment.py +24 -0
- wbportfolio/import_export/parsers/sg_lux/__init__.py +0 -0
- wbportfolio/import_export/parsers/sg_lux/custodian_positions.py +70 -0
- wbportfolio/import_export/parsers/sg_lux/customer_trade.py +75 -0
- wbportfolio/import_export/parsers/sg_lux/customer_trade_pending_slk.py +140 -0
- wbportfolio/import_export/parsers/sg_lux/customer_trade_slk.py +80 -0
- wbportfolio/import_export/parsers/sg_lux/customer_trade_without_pw.py +57 -0
- wbportfolio/import_export/parsers/sg_lux/equity.py +161 -0
- wbportfolio/import_export/parsers/sg_lux/fees.py +56 -0
- wbportfolio/import_export/parsers/sg_lux/perf_fees.py +51 -0
- wbportfolio/import_export/parsers/sg_lux/portfolio_cash_flow.py +29 -0
- wbportfolio/import_export/parsers/sg_lux/portfolio_future_cash_flow.py +36 -0
- wbportfolio/import_export/parsers/sg_lux/registers.py +210 -0
- wbportfolio/import_export/parsers/sg_lux/sylk.py +248 -0
- wbportfolio/import_export/parsers/sg_lux/utils.py +36 -0
- wbportfolio/import_export/parsers/sg_lux/valuation.py +53 -0
- wbportfolio/import_export/parsers/societe_generale/__init__.py +0 -0
- wbportfolio/import_export/parsers/societe_generale/customer_trade.py +54 -0
- wbportfolio/import_export/parsers/societe_generale/strategy.py +94 -0
- wbportfolio/import_export/parsers/societe_generale/valuation.py +37 -0
- wbportfolio/import_export/parsers/tellco/__init__.py +0 -0
- wbportfolio/import_export/parsers/tellco/customer_trade.py +64 -0
- wbportfolio/import_export/parsers/tellco/equity.py +86 -0
- wbportfolio/import_export/parsers/tellco/valuation.py +52 -0
- wbportfolio/import_export/parsers/ubs/__init__.py +0 -0
- wbportfolio/import_export/parsers/ubs/api/__init__.py +0 -0
- wbportfolio/import_export/parsers/ubs/api/asset_position.py +106 -0
- wbportfolio/import_export/parsers/ubs/api/fees.py +31 -0
- wbportfolio/import_export/parsers/ubs/api/instrument_price.py +20 -0
- wbportfolio/import_export/parsers/ubs/api/utils.py +0 -0
- wbportfolio/import_export/parsers/ubs/customer_trade.py +60 -0
- wbportfolio/import_export/parsers/ubs/equity.py +97 -0
- wbportfolio/import_export/parsers/ubs/historical_customer_trade.py +67 -0
- wbportfolio/import_export/parsers/ubs/valuation.py +52 -0
- wbportfolio/import_export/parsers/vontobel/__init__.py +0 -0
- wbportfolio/import_export/parsers/vontobel/asset_position.py +97 -0
- wbportfolio/import_export/parsers/vontobel/customer_trade.py +54 -0
- wbportfolio/import_export/parsers/vontobel/historical_customer_trade.py +40 -0
- wbportfolio/import_export/parsers/vontobel/instrument.py +34 -0
- wbportfolio/import_export/parsers/vontobel/management_fees.py +86 -0
- wbportfolio/import_export/parsers/vontobel/performance_fees.py +35 -0
- wbportfolio/import_export/parsers/vontobel/trade.py +38 -0
- wbportfolio/import_export/parsers/vontobel/utils.py +17 -0
- wbportfolio/import_export/parsers/vontobel/valuation.py +29 -0
- wbportfolio/import_export/resources/__init__.py +0 -0
- wbportfolio/import_export/resources/assets.py +68 -0
- wbportfolio/import_export/resources/trades.py +41 -0
- wbportfolio/import_export/utils.py +42 -0
- wbportfolio/jinja2/wbportfolio/sql/aum_nnm.sql +119 -0
- wbportfolio/kpi_handlers/nnm.py +163 -0
- wbportfolio/metric/__init__.py +0 -0
- wbportfolio/metric/backends/__init__.py +2 -0
- wbportfolio/metric/backends/base.py +86 -0
- wbportfolio/metric/backends/constants.py +222 -0
- wbportfolio/metric/backends/portfolio_base.py +255 -0
- wbportfolio/metric/backends/portfolio_esg.py +66 -0
- wbportfolio/metric/tests/__init__.py +0 -0
- wbportfolio/metric/tests/conftest.py +4 -0
- wbportfolio/metric/tests/test_portfolio_base.py +135 -0
- wbportfolio/metric/tests/test_portfolio_esg.py +69 -0
- wbportfolio/migrations/0001_initial_squashed.py +13848 -0
- wbportfolio/migrations/0002_product_default_sub_account_squashed_0039_alter_assetallocation_company_and_more.py +3836 -0
- wbportfolio/migrations/0040_instrument_financial_instrument.py +26 -0
- wbportfolio/migrations/0041_remove_listresearch_research_ptr_and_more.py +129 -0
- wbportfolio/migrations/0042_instrumentlist_instrumentlistthroughmodel_and_more.py +71 -0
- wbportfolio/migrations/0043_alter_instrumentlistthroughmodel_options_and_more.py +238 -0
- wbportfolio/migrations/0044_alter_instrumentlist_identifier.py +35 -0
- wbportfolio/migrations/0045_alter_instrument_financial_instrument.py +26 -0
- wbportfolio/migrations/0046_add_product_default_account.py +166 -0
- wbportfolio/migrations/0047_remove_product_default_sub_account.py +14 -0
- wbportfolio/migrations/0048_alter_trade_status.py +29 -0
- wbportfolio/migrations/0049_trade_claimed_shares.py +25 -0
- wbportfolio/migrations/0050_fees_fee_date_fees_wbportfolio_transac_1f7a29_idx.py +44 -0
- wbportfolio/migrations/0051_delete_macroreview.py +11 -0
- wbportfolio/migrations/0052_remove_cash_instrument_ptr_and_more.py +888 -0
- wbportfolio/migrations/0053_remove_product_group.py +132 -0
- wbportfolio/migrations/0054_portfolioinstrumentpreferredclassificationthroughmodel_and_more.py +270 -0
- wbportfolio/migrations/0055_remove_product__custom_management_rebates_and_more.py +139 -0
- wbportfolio/migrations/0056_remove_companyportfoliodata_assets_under_management_currency_and_more.py +56 -0
- wbportfolio/migrations/0057_alter_portfolio_preferred_instrument_classifications_and_more.py +36 -0
- wbportfolio/migrations/0058_pmsinstrument.py +23 -0
- wbportfolio/migrations/0059_fees_unique_fees.py +51 -0
- wbportfolio/migrations/0060_alter_portfolioportfoliothroughmodel_type.py +21 -0
- wbportfolio/migrations/0061_portfolio_bank_accounts_product_bank_account_and_more.py +175 -0
- wbportfolio/migrations/0062_alter_dailyportfoliocashflow_options.py +20 -0
- wbportfolio/migrations/0063_accountreconciliation_accountreconciliationline_and_more.py +133 -0
- wbportfolio/migrations/0064_alter_portfolio_managers_portfolio_is_tracked_and_more.py +40 -0
- wbportfolio/migrations/0065_alter_portfolio_managers_claim_as_shares_and_more.py +73 -0
- wbportfolio/migrations/0066_assetposition_initial_shares_at_custodian_and_more.py +108 -0
- wbportfolio/migrations/0067_assetposition_unique_asset_position.py +77 -0
- wbportfolio/migrations/0068_trade_internal_trade_trade_marked_as_internal_and_more.py +59 -0
- wbportfolio/migrations/0069_remove_portfolio_is_invested_and_more.py +56 -0
- wbportfolio/migrations/0070_remove_assetposition_unique_asset_position_and_more.py +82 -0
- wbportfolio/migrations/0071_alter_trade_options_alter_trade_order.py +22 -0
- wbportfolio/migrations/__init__.py +0 -0
- wbportfolio/models/__init__.py +26 -0
- wbportfolio/models/adjustments.py +246 -0
- wbportfolio/models/asset.py +869 -0
- wbportfolio/models/custodians.py +101 -0
- wbportfolio/models/indexes.py +33 -0
- wbportfolio/models/llm/wbcrm/analyze_relationship.py +58 -0
- wbportfolio/models/mixins/__init__.py +0 -0
- wbportfolio/models/mixins/instruments.py +127 -0
- wbportfolio/models/mixins/liquidity_stress_test.py +1307 -0
- wbportfolio/models/portfolio.py +1039 -0
- wbportfolio/models/portfolio_cash_flow.py +167 -0
- wbportfolio/models/portfolio_cash_targets.py +46 -0
- wbportfolio/models/portfolio_relationship.py +135 -0
- wbportfolio/models/portfolio_swing_pricings.py +51 -0
- wbportfolio/models/product_groups.py +230 -0
- wbportfolio/models/products.py +569 -0
- wbportfolio/models/reconciliations/__init__.py +2 -0
- wbportfolio/models/reconciliations/account_reconciliation_lines.py +192 -0
- wbportfolio/models/reconciliations/account_reconciliations.py +102 -0
- wbportfolio/models/reconciliations/reconciliations.py +25 -0
- wbportfolio/models/registers.py +132 -0
- wbportfolio/models/roles.py +208 -0
- wbportfolio/models/synchronization/__init__.py +3 -0
- wbportfolio/models/synchronization/portfolio_synchronization.py +292 -0
- wbportfolio/models/synchronization/price_computation.py +200 -0
- wbportfolio/models/synchronization/synchronization.py +188 -0
- wbportfolio/models/transactions/__init__.py +7 -0
- wbportfolio/models/transactions/claim.py +634 -0
- wbportfolio/models/transactions/dividends.py +31 -0
- wbportfolio/models/transactions/expiry.py +7 -0
- wbportfolio/models/transactions/fees.py +153 -0
- wbportfolio/models/transactions/trade_proposals.py +502 -0
- wbportfolio/models/transactions/trades.py +704 -0
- wbportfolio/models/transactions/transactions.py +211 -0
- wbportfolio/models/utils.py +12 -0
- wbportfolio/permissions.py +13 -0
- wbportfolio/pms/__init__.py +0 -0
- wbportfolio/pms/statistics/__init__.py +0 -0
- wbportfolio/pms/trading/__init__.py +1 -0
- wbportfolio/pms/trading/handler.py +164 -0
- wbportfolio/pms/typing.py +194 -0
- wbportfolio/preferences.py +6 -0
- wbportfolio/reports/__init__.py +0 -0
- wbportfolio/reports/monthly_position_report.py +74 -0
- wbportfolio/risk_management/__init__.py +0 -0
- wbportfolio/risk_management/backends/__init__.py +11 -0
- wbportfolio/risk_management/backends/accounts.py +166 -0
- wbportfolio/risk_management/backends/controversy_portfolio.py +63 -0
- wbportfolio/risk_management/backends/exposure_portfolio.py +203 -0
- wbportfolio/risk_management/backends/instrument_list_portfolio.py +89 -0
- wbportfolio/risk_management/backends/liquidity_risk.py +86 -0
- wbportfolio/risk_management/backends/liquidity_stress_instrument.py +86 -0
- wbportfolio/risk_management/backends/mixins.py +220 -0
- wbportfolio/risk_management/backends/product_integrity.py +111 -0
- wbportfolio/risk_management/backends/stop_loss_instrument.py +24 -0
- wbportfolio/risk_management/backends/stop_loss_portfolio.py +36 -0
- wbportfolio/risk_management/backends/ucits_portfolio.py +63 -0
- wbportfolio/risk_management/tests/__init__.py +0 -0
- wbportfolio/risk_management/tests/conftest.py +15 -0
- wbportfolio/risk_management/tests/test_accounts.py +98 -0
- wbportfolio/risk_management/tests/test_controversy_portfolio.py +33 -0
- wbportfolio/risk_management/tests/test_exposure_portfolio.py +94 -0
- wbportfolio/risk_management/tests/test_instrument_list_portfolio.py +60 -0
- wbportfolio/risk_management/tests/test_liquidity_risk.py +47 -0
- wbportfolio/risk_management/tests/test_product_integrity.py +55 -0
- wbportfolio/risk_management/tests/test_stop_loss_instrument.py +110 -0
- wbportfolio/risk_management/tests/test_stop_loss_portfolio.py +119 -0
- wbportfolio/risk_management/tests/test_ucits_portfolio.py +39 -0
- wbportfolio/serializers/__init__.py +42 -0
- wbportfolio/serializers/adjustments.py +24 -0
- wbportfolio/serializers/assets.py +166 -0
- wbportfolio/serializers/custodians.py +26 -0
- wbportfolio/serializers/portfolio_cash_flow.py +48 -0
- wbportfolio/serializers/portfolio_cash_targets.py +20 -0
- wbportfolio/serializers/portfolio_relationship.py +53 -0
- wbportfolio/serializers/portfolio_swing_pricing.py +20 -0
- wbportfolio/serializers/portfolios.py +143 -0
- wbportfolio/serializers/positions.py +76 -0
- wbportfolio/serializers/product_group.py +88 -0
- wbportfolio/serializers/products.py +331 -0
- wbportfolio/serializers/reconciliations.py +173 -0
- wbportfolio/serializers/registers.py +72 -0
- wbportfolio/serializers/roles.py +60 -0
- wbportfolio/serializers/signals.py +157 -0
- wbportfolio/serializers/synchronization.py +18 -0
- wbportfolio/serializers/transactions/__init__.py +24 -0
- wbportfolio/serializers/transactions/claim.py +310 -0
- wbportfolio/serializers/transactions/dividends.py +18 -0
- wbportfolio/serializers/transactions/expiry.py +18 -0
- wbportfolio/serializers/transactions/fees.py +32 -0
- wbportfolio/serializers/transactions/trades.py +315 -0
- wbportfolio/serializers/transactions/transactions.py +84 -0
- wbportfolio/static/wbportfolio/css/macro_review.css +17 -0
- wbportfolio/static/wbportfolio/markdown/documentation/account_holding_reconciliation.md +16 -0
- wbportfolio/static/wbportfolio/markdown/documentation/aggregate_asset_position_liquidity.md +25 -0
- wbportfolio/static/wbportfolio/markdown/documentation/company.md +78 -0
- wbportfolio/static/wbportfolio/markdown/documentation/earnings_instrument.md +14 -0
- wbportfolio/static/wbportfolio/markdown/documentation/financial_analysis_instrument_ratios.md +94 -0
- wbportfolio/static/wbportfolio/markdown/documentation/financial_statistics.md +44 -0
- wbportfolio/static/wbportfolio/markdown/documentation/person.md +70 -0
- wbportfolio/tasks.py +125 -0
- wbportfolio/templates/portfolio/email/customer_report.html +6 -0
- wbportfolio/templates/portfolio/email/customer_trade_notification.html +26 -0
- wbportfolio/templates/portfolio/email/email_base_template.html +420 -0
- wbportfolio/templates/portfolio/email/rebalancing_report.html +34 -0
- wbportfolio/templates/portfolio/macro/macro_review.html +88 -0
- wbportfolio/tests/__init__.py +0 -0
- wbportfolio/tests/conftest.py +164 -0
- wbportfolio/tests/models/__init__.py +0 -0
- wbportfolio/tests/models/test_account_reconciliation.py +191 -0
- wbportfolio/tests/models/test_assets.py +193 -0
- wbportfolio/tests/models/test_custodians.py +12 -0
- wbportfolio/tests/models/test_customer_trades.py +113 -0
- wbportfolio/tests/models/test_dividends.py +7 -0
- wbportfolio/tests/models/test_imports.py +192 -0
- wbportfolio/tests/models/test_instrument_mixins.py +48 -0
- wbportfolio/tests/models/test_merge.py +133 -0
- wbportfolio/tests/models/test_portfolio_cash_flow.py +112 -0
- wbportfolio/tests/models/test_portfolio_cash_targets.py +27 -0
- wbportfolio/tests/models/test_portfolio_swing_pricings.py +42 -0
- wbportfolio/tests/models/test_portfolios.py +676 -0
- wbportfolio/tests/models/test_product_groups.py +80 -0
- wbportfolio/tests/models/test_products.py +187 -0
- wbportfolio/tests/models/test_roles.py +82 -0
- wbportfolio/tests/models/test_splits.py +233 -0
- wbportfolio/tests/models/test_synchronization.py +617 -0
- wbportfolio/tests/models/transactions/__init__.py +0 -0
- wbportfolio/tests/models/transactions/test_claim.py +129 -0
- wbportfolio/tests/models/transactions/test_fees.py +65 -0
- wbportfolio/tests/models/transactions/test_trades.py +204 -0
- wbportfolio/tests/models/utils.py +13 -0
- wbportfolio/tests/serializers/__init__.py +0 -0
- wbportfolio/tests/serializers/test_claims.py +21 -0
- wbportfolio/tests/signals.py +151 -0
- wbportfolio/tests/tests.py +31 -0
- wbportfolio/tests/viewsets/__init__.py +0 -0
- wbportfolio/tests/viewsets/test_assets.py +67 -0
- wbportfolio/tests/viewsets/test_performances.py +72 -0
- wbportfolio/tests/viewsets/test_products.py +92 -0
- wbportfolio/tests/viewsets/transactions/__init__.py +0 -0
- wbportfolio/tests/viewsets/transactions/test_claims.py +146 -0
- wbportfolio/urls.py +247 -0
- wbportfolio/utils.py +30 -0
- wbportfolio/viewsets/__init__.py +57 -0
- wbportfolio/viewsets/adjustments.py +46 -0
- wbportfolio/viewsets/assets.py +562 -0
- wbportfolio/viewsets/assets_and_net_new_money_progression.py +117 -0
- wbportfolio/viewsets/charts/__init__.py +1 -0
- wbportfolio/viewsets/charts/assets.py +247 -0
- wbportfolio/viewsets/configs/__init__.py +6 -0
- wbportfolio/viewsets/configs/buttons/__init__.py +23 -0
- wbportfolio/viewsets/configs/buttons/adjustments.py +13 -0
- wbportfolio/viewsets/configs/buttons/assets.py +145 -0
- wbportfolio/viewsets/configs/buttons/claims.py +83 -0
- wbportfolio/viewsets/configs/buttons/custodians.py +76 -0
- wbportfolio/viewsets/configs/buttons/fees.py +14 -0
- wbportfolio/viewsets/configs/buttons/mixins.py +88 -0
- wbportfolio/viewsets/configs/buttons/portfolios.py +115 -0
- wbportfolio/viewsets/configs/buttons/products.py +41 -0
- wbportfolio/viewsets/configs/buttons/reconciliations.py +65 -0
- wbportfolio/viewsets/configs/buttons/registers.py +11 -0
- wbportfolio/viewsets/configs/buttons/signals.py +68 -0
- wbportfolio/viewsets/configs/buttons/trade_proposals.py +25 -0
- wbportfolio/viewsets/configs/buttons/trades.py +144 -0
- wbportfolio/viewsets/configs/display/__init__.py +61 -0
- wbportfolio/viewsets/configs/display/adjustments.py +81 -0
- wbportfolio/viewsets/configs/display/assets.py +265 -0
- wbportfolio/viewsets/configs/display/claim.py +299 -0
- wbportfolio/viewsets/configs/display/custodians.py +24 -0
- wbportfolio/viewsets/configs/display/esg.py +88 -0
- wbportfolio/viewsets/configs/display/fees.py +133 -0
- wbportfolio/viewsets/configs/display/portfolio_cash_flow.py +103 -0
- wbportfolio/viewsets/configs/display/portfolio_relationship.py +38 -0
- wbportfolio/viewsets/configs/display/portfolios.py +125 -0
- wbportfolio/viewsets/configs/display/positions.py +75 -0
- wbportfolio/viewsets/configs/display/product_groups.py +54 -0
- wbportfolio/viewsets/configs/display/product_performance.py +241 -0
- wbportfolio/viewsets/configs/display/products.py +249 -0
- wbportfolio/viewsets/configs/display/reconciliations.py +151 -0
- wbportfolio/viewsets/configs/display/registers.py +71 -0
- wbportfolio/viewsets/configs/display/roles.py +49 -0
- wbportfolio/viewsets/configs/display/trade_proposals.py +97 -0
- wbportfolio/viewsets/configs/display/trades.py +359 -0
- wbportfolio/viewsets/configs/display/transactions.py +55 -0
- wbportfolio/viewsets/configs/endpoints/__init__.py +75 -0
- wbportfolio/viewsets/configs/endpoints/adjustments.py +17 -0
- wbportfolio/viewsets/configs/endpoints/assets.py +115 -0
- wbportfolio/viewsets/configs/endpoints/claim.py +106 -0
- wbportfolio/viewsets/configs/endpoints/custodians.py +6 -0
- wbportfolio/viewsets/configs/endpoints/esg.py +14 -0
- wbportfolio/viewsets/configs/endpoints/fees.py +26 -0
- wbportfolio/viewsets/configs/endpoints/portfolio_relationship.py +23 -0
- wbportfolio/viewsets/configs/endpoints/portfolios.py +43 -0
- wbportfolio/viewsets/configs/endpoints/positions.py +18 -0
- wbportfolio/viewsets/configs/endpoints/product_groups.py +11 -0
- wbportfolio/viewsets/configs/endpoints/product_performance.py +29 -0
- wbportfolio/viewsets/configs/endpoints/products.py +37 -0
- wbportfolio/viewsets/configs/endpoints/reconciliations.py +31 -0
- wbportfolio/viewsets/configs/endpoints/roles.py +9 -0
- wbportfolio/viewsets/configs/endpoints/trade_proposals.py +17 -0
- wbportfolio/viewsets/configs/endpoints/trades.py +82 -0
- wbportfolio/viewsets/configs/endpoints/transactions.py +17 -0
- wbportfolio/viewsets/configs/menu/__init__.py +30 -0
- wbportfolio/viewsets/configs/menu/adjustments.py +8 -0
- wbportfolio/viewsets/configs/menu/assets.py +8 -0
- wbportfolio/viewsets/configs/menu/claim.py +41 -0
- wbportfolio/viewsets/configs/menu/custodians.py +11 -0
- wbportfolio/viewsets/configs/menu/fees.py +13 -0
- wbportfolio/viewsets/configs/menu/instrument_prices.py +10 -0
- wbportfolio/viewsets/configs/menu/portfolio_cash_flow.py +8 -0
- wbportfolio/viewsets/configs/menu/portfolios.py +15 -0
- wbportfolio/viewsets/configs/menu/positions.py +14 -0
- wbportfolio/viewsets/configs/menu/product_groups.py +10 -0
- wbportfolio/viewsets/configs/menu/product_performance.py +25 -0
- wbportfolio/viewsets/configs/menu/products.py +15 -0
- wbportfolio/viewsets/configs/menu/reconciliations.py +7 -0
- wbportfolio/viewsets/configs/menu/registers.py +10 -0
- wbportfolio/viewsets/configs/menu/roles.py +16 -0
- wbportfolio/viewsets/configs/menu/trades.py +18 -0
- wbportfolio/viewsets/configs/menu/transactions.py +8 -0
- wbportfolio/viewsets/configs/previews/__init__.py +1 -0
- wbportfolio/viewsets/configs/previews/portfolios.py +21 -0
- wbportfolio/viewsets/configs/titles/__init__.py +65 -0
- wbportfolio/viewsets/configs/titles/adjustments.py +19 -0
- wbportfolio/viewsets/configs/titles/assets.py +57 -0
- wbportfolio/viewsets/configs/titles/assets_and_net_new_money_progression.py +6 -0
- wbportfolio/viewsets/configs/titles/claim.py +81 -0
- wbportfolio/viewsets/configs/titles/custodians.py +12 -0
- wbportfolio/viewsets/configs/titles/esg.py +10 -0
- wbportfolio/viewsets/configs/titles/fees.py +25 -0
- wbportfolio/viewsets/configs/titles/instrument_prices.py +20 -0
- wbportfolio/viewsets/configs/titles/portfolios.py +32 -0
- wbportfolio/viewsets/configs/titles/positions.py +11 -0
- wbportfolio/viewsets/configs/titles/product_groups.py +12 -0
- wbportfolio/viewsets/configs/titles/product_performance.py +16 -0
- wbportfolio/viewsets/configs/titles/products.py +6 -0
- wbportfolio/viewsets/configs/titles/registers.py +12 -0
- wbportfolio/viewsets/configs/titles/roles.py +23 -0
- wbportfolio/viewsets/configs/titles/trades.py +51 -0
- wbportfolio/viewsets/configs/titles/transactions.py +8 -0
- wbportfolio/viewsets/custodians.py +66 -0
- wbportfolio/viewsets/esg.py +165 -0
- wbportfolio/viewsets/mixins.py +48 -0
- wbportfolio/viewsets/portfolio_cash_flow.py +31 -0
- wbportfolio/viewsets/portfolio_cash_targets.py +8 -0
- wbportfolio/viewsets/portfolio_relationship.py +46 -0
- wbportfolio/viewsets/portfolio_swing_pricing.py +8 -0
- wbportfolio/viewsets/portfolios.py +154 -0
- wbportfolio/viewsets/positions.py +292 -0
- wbportfolio/viewsets/product_groups.py +84 -0
- wbportfolio/viewsets/product_performance.py +646 -0
- wbportfolio/viewsets/products.py +529 -0
- wbportfolio/viewsets/reconciliations.py +160 -0
- wbportfolio/viewsets/registers.py +75 -0
- wbportfolio/viewsets/roles.py +44 -0
- wbportfolio/viewsets/signals.py +42 -0
- wbportfolio/viewsets/synchronization.py +25 -0
- wbportfolio/viewsets/transactions/__init__.py +40 -0
- wbportfolio/viewsets/transactions/claim.py +933 -0
- wbportfolio/viewsets/transactions/fees.py +190 -0
- wbportfolio/viewsets/transactions/mixins.py +19 -0
- wbportfolio/viewsets/transactions/trade_proposals.py +93 -0
- wbportfolio/viewsets/transactions/trades.py +395 -0
- wbportfolio/viewsets/transactions/transactions.py +123 -0
- wbportfolio-1.43.1.dist-info/METADATA +22 -0
- wbportfolio-1.43.1.dist-info/RECORD +506 -0
- wbportfolio-1.43.1.dist-info/WHEEL +5 -0
- wbportfolio-1.43.1.dist-info/licenses/LICENSE +4 -0
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
from datetime import timedelta
|
|
2
|
+
from decimal import Decimal
|
|
3
|
+
|
|
4
|
+
from rest_framework import serializers
|
|
5
|
+
from rest_framework.reverse import reverse
|
|
6
|
+
from wbcore import serializers as wb_serializers
|
|
7
|
+
from wbportfolio.models import Portfolio, PortfolioRole, Trade, TradeProposal
|
|
8
|
+
from wbportfolio.models.transactions.claim import Claim
|
|
9
|
+
from wbportfolio.serializers.custodians import CustodianRepresentationSerializer
|
|
10
|
+
from wbportfolio.serializers.portfolios import PortfolioRepresentationSerializer
|
|
11
|
+
from wbportfolio.serializers.registers import RegisterRepresentationSerializer
|
|
12
|
+
|
|
13
|
+
from .transactions import (
|
|
14
|
+
TransactionModelSerializer,
|
|
15
|
+
TransactionRepresentationSerializer,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class CopyClaimRepresentationSerializer(wb_serializers.RepresentationSerializer):
|
|
20
|
+
claimant = wb_serializers.StringRelatedField()
|
|
21
|
+
product = wb_serializers.StringRelatedField()
|
|
22
|
+
account = wb_serializers.StringRelatedField()
|
|
23
|
+
_detail = wb_serializers.HyperlinkField(reverse_name="wbportfolio:claim-detail")
|
|
24
|
+
|
|
25
|
+
class Meta:
|
|
26
|
+
model = Claim
|
|
27
|
+
fields = (
|
|
28
|
+
"id",
|
|
29
|
+
"shares",
|
|
30
|
+
"claimant",
|
|
31
|
+
"bank",
|
|
32
|
+
"product",
|
|
33
|
+
"account",
|
|
34
|
+
"_detail",
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class TradeProposalRepresentationSerializer(wb_serializers.RepresentationSerializer):
|
|
39
|
+
_detail = wb_serializers.HyperlinkField(reverse_name="wbportfolio:tradeproposal-detail")
|
|
40
|
+
|
|
41
|
+
class Meta:
|
|
42
|
+
model = TradeProposal
|
|
43
|
+
fields = ("id", "trade_date", "status", "_detail")
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class TradeRepresentationSerializer(TransactionRepresentationSerializer):
|
|
47
|
+
_detail = wb_serializers.HyperlinkField(reverse_name="wbportfolio:trade-detail")
|
|
48
|
+
|
|
49
|
+
diff_shares = wb_serializers.SerializerMethodField()
|
|
50
|
+
|
|
51
|
+
def get_diff_shares(self, obj):
|
|
52
|
+
return obj._diff_shares
|
|
53
|
+
|
|
54
|
+
class Meta:
|
|
55
|
+
model = Trade
|
|
56
|
+
fields = ("claimed_shares", "diff_shares", "bank", "shares") + TransactionRepresentationSerializer.Meta.fields
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class TradeClaimRepresentationSerializer(TradeRepresentationSerializer):
|
|
60
|
+
def get_filter_params(self, request):
|
|
61
|
+
claim_id = request.parser_context["view"].kwargs.get("pk", None)
|
|
62
|
+
arg = {"marked_for_deletion": False}
|
|
63
|
+
if claim_id:
|
|
64
|
+
claim = Claim.objects.get(id=claim_id)
|
|
65
|
+
arg.update(
|
|
66
|
+
{
|
|
67
|
+
"underlying_instrument": claim.product.id,
|
|
68
|
+
"transaction_date__gte": claim.date - timedelta(days=Trade.TRADE_WINDOW_INTERVAL),
|
|
69
|
+
"transaction_date__lte": claim.date + timedelta(days=Trade.TRADE_WINDOW_INTERVAL),
|
|
70
|
+
}
|
|
71
|
+
)
|
|
72
|
+
if claim.shares:
|
|
73
|
+
if claim.shares > 0:
|
|
74
|
+
arg["shares__gte"] = claim.shares
|
|
75
|
+
else:
|
|
76
|
+
arg["shares__lte"] = claim.shares
|
|
77
|
+
return arg
|
|
78
|
+
return {}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class TradeModelSerializer(TransactionModelSerializer):
|
|
82
|
+
marked_for_deletion = wb_serializers.BooleanField(required=False, read_only=True)
|
|
83
|
+
marked_as_internal = wb_serializers.BooleanField()
|
|
84
|
+
|
|
85
|
+
approved_claimed_shares = wb_serializers.DecimalField(
|
|
86
|
+
max_digits=10, decimal_places=2, required=False, read_only=True, default=Decimal(0.0)
|
|
87
|
+
)
|
|
88
|
+
pending_claimed_shares = wb_serializers.DecimalField(
|
|
89
|
+
max_digits=10, decimal_places=2, required=False, read_only=True, default=Decimal(0.0)
|
|
90
|
+
)
|
|
91
|
+
completely_claimed = wb_serializers.BooleanField(required=False, read_only=True, default=Decimal(0.0))
|
|
92
|
+
completely_claimed_if_approved = wb_serializers.BooleanField(required=False, read_only=True, default=Decimal(0.0))
|
|
93
|
+
|
|
94
|
+
# We commented it because people needs to filter with lookup equals onto these fields
|
|
95
|
+
# shares = wb_serializers.DecimalField(max_digits=16, decimal_places=2)
|
|
96
|
+
# price = wb_serializers.DecimalField(max_digits=16, decimal_places=2)
|
|
97
|
+
|
|
98
|
+
_register = RegisterRepresentationSerializer(source="register")
|
|
99
|
+
claims = wb_serializers.PrimaryKeyRelatedField(queryset=Claim.objects.all(), label="Claims", many=True)
|
|
100
|
+
_claims = CopyClaimRepresentationSerializer(source="claims", many=True)
|
|
101
|
+
_custodian = CustodianRepresentationSerializer(source="custodian")
|
|
102
|
+
_internal_trade = TradeRepresentationSerializer(
|
|
103
|
+
source="internal_trade",
|
|
104
|
+
filter_params={"only_internal_trade": True},
|
|
105
|
+
optional_get_parameters={"underlying_instrument": "underlying_instrument", "transaction_date": "pivot_date"},
|
|
106
|
+
depends_on=[{"field": "marked_as_internal", "options": {"activates_on": [True]}}],
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
@wb_serializers.register_only_instance_resource()
|
|
110
|
+
def import_source_file_url(self, instance, request, user, *args, **kwargs):
|
|
111
|
+
if PortfolioRole.is_portfolio_manager(user.profile, instance.underlying_instrument):
|
|
112
|
+
if instance.import_source:
|
|
113
|
+
return {"import_source": instance.import_source.file.url}
|
|
114
|
+
return {}
|
|
115
|
+
|
|
116
|
+
@wb_serializers.register_resource()
|
|
117
|
+
def claims_list(self, instance, request, user):
|
|
118
|
+
if instance.is_claimable:
|
|
119
|
+
return {
|
|
120
|
+
"claims": reverse(
|
|
121
|
+
"wbportfolio:trade-claim-list",
|
|
122
|
+
args=[instance.id],
|
|
123
|
+
request=request,
|
|
124
|
+
)
|
|
125
|
+
}
|
|
126
|
+
return {}
|
|
127
|
+
|
|
128
|
+
class Meta:
|
|
129
|
+
model = Trade
|
|
130
|
+
decorators = TransactionModelSerializer.Meta.decorators
|
|
131
|
+
read_only_fields = (
|
|
132
|
+
"id",
|
|
133
|
+
"shares",
|
|
134
|
+
"price",
|
|
135
|
+
"transaction_subtype",
|
|
136
|
+
"approved_claimed_shares",
|
|
137
|
+
"pending_claimed_shares",
|
|
138
|
+
"claimed_shares",
|
|
139
|
+
"completely_claimed",
|
|
140
|
+
"completely_claimed_if_approved",
|
|
141
|
+
"register",
|
|
142
|
+
"_register",
|
|
143
|
+
"pending",
|
|
144
|
+
"bank",
|
|
145
|
+
"marked_for_deletion",
|
|
146
|
+
"_claims",
|
|
147
|
+
"claims",
|
|
148
|
+
"transaction_type",
|
|
149
|
+
"transaction_url_type",
|
|
150
|
+
"transaction_underlying_type",
|
|
151
|
+
"portfolio",
|
|
152
|
+
"_portfolio",
|
|
153
|
+
"underlying_instrument",
|
|
154
|
+
"_underlying_instrument",
|
|
155
|
+
"transaction_date",
|
|
156
|
+
"book_date",
|
|
157
|
+
"value_date",
|
|
158
|
+
"currency",
|
|
159
|
+
"_currency",
|
|
160
|
+
"currency_fx_rate",
|
|
161
|
+
"total_value",
|
|
162
|
+
"total_value_fx_portfolio",
|
|
163
|
+
"total_value_gross",
|
|
164
|
+
"total_value_gross_fx_portfolio",
|
|
165
|
+
"external_id",
|
|
166
|
+
"total_value_usd",
|
|
167
|
+
"total_value_gross_usd",
|
|
168
|
+
"_additional_resources",
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
fields = (
|
|
172
|
+
"id",
|
|
173
|
+
"shares",
|
|
174
|
+
"price",
|
|
175
|
+
"transaction_subtype",
|
|
176
|
+
"approved_claimed_shares",
|
|
177
|
+
"pending_claimed_shares",
|
|
178
|
+
"claimed_shares",
|
|
179
|
+
"completely_claimed",
|
|
180
|
+
"completely_claimed_if_approved",
|
|
181
|
+
"register",
|
|
182
|
+
"_register",
|
|
183
|
+
"pending",
|
|
184
|
+
"bank",
|
|
185
|
+
"marked_for_deletion",
|
|
186
|
+
"_claims",
|
|
187
|
+
"claims",
|
|
188
|
+
"transaction_type",
|
|
189
|
+
"transaction_url_type",
|
|
190
|
+
"transaction_underlying_type",
|
|
191
|
+
"portfolio",
|
|
192
|
+
"_portfolio",
|
|
193
|
+
"underlying_instrument",
|
|
194
|
+
"_underlying_instrument",
|
|
195
|
+
"transaction_date",
|
|
196
|
+
"book_date",
|
|
197
|
+
"value_date",
|
|
198
|
+
"currency",
|
|
199
|
+
"_currency",
|
|
200
|
+
"currency_fx_rate",
|
|
201
|
+
"total_value",
|
|
202
|
+
"total_value_fx_portfolio",
|
|
203
|
+
"total_value_gross",
|
|
204
|
+
"total_value_gross_fx_portfolio",
|
|
205
|
+
"external_id",
|
|
206
|
+
"comment",
|
|
207
|
+
"total_value_usd",
|
|
208
|
+
"total_value_gross_usd",
|
|
209
|
+
"_custodian",
|
|
210
|
+
"custodian",
|
|
211
|
+
"marked_as_internal",
|
|
212
|
+
"internal_trade",
|
|
213
|
+
"_internal_trade",
|
|
214
|
+
"_additional_resources",
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
class TradeTradeProposalModelSerializer(TradeModelSerializer):
|
|
219
|
+
status = wb_serializers.ChoiceField(default=Trade.Status.DRAFT, choices=Trade.Status.choices)
|
|
220
|
+
target_weight = wb_serializers.DecimalField(max_digits=16, decimal_places=6, required=False, default=0)
|
|
221
|
+
effective_weight = wb_serializers.DecimalField(read_only=True, max_digits=16, decimal_places=6, default=0)
|
|
222
|
+
|
|
223
|
+
def validate(self, data):
|
|
224
|
+
if self.instance and "underlying_instrument" in data:
|
|
225
|
+
raise serializers.ValidationError(
|
|
226
|
+
{
|
|
227
|
+
"underlying_instrument": "You cannot modify the underlying instrument other than creating a new entry"
|
|
228
|
+
}
|
|
229
|
+
)
|
|
230
|
+
effective_weight = self.instance._effective_weight if self.instance else Decimal(0.0)
|
|
231
|
+
if (target_weight := data.pop("target_weight", None)) is not None:
|
|
232
|
+
data["weighting"] = target_weight - effective_weight
|
|
233
|
+
if data["weighting"] >= 0:
|
|
234
|
+
data["transaction_subtype"] = "BUY"
|
|
235
|
+
else:
|
|
236
|
+
data["transaction_subtype"] = "SELL"
|
|
237
|
+
return data
|
|
238
|
+
|
|
239
|
+
class Meta:
|
|
240
|
+
model = Trade
|
|
241
|
+
percent_fields = ["effective_weight", "target_weight", "weighting"]
|
|
242
|
+
read_only_fields = (
|
|
243
|
+
"transaction_subtype",
|
|
244
|
+
"shares"
|
|
245
|
+
# "underlying_instrument",
|
|
246
|
+
# "_underlying_instrument",
|
|
247
|
+
)
|
|
248
|
+
fields = (
|
|
249
|
+
"id",
|
|
250
|
+
"shares",
|
|
251
|
+
"underlying_instrument",
|
|
252
|
+
"_underlying_instrument",
|
|
253
|
+
"transaction_subtype",
|
|
254
|
+
"status",
|
|
255
|
+
# "total_value",
|
|
256
|
+
# "total_value_fx_portfolio",
|
|
257
|
+
# "total_value_gross",
|
|
258
|
+
# "total_value_gross_fx_portfolio",
|
|
259
|
+
"comment",
|
|
260
|
+
# "total_value_usd",
|
|
261
|
+
# "total_value_gross_usd",
|
|
262
|
+
"effective_weight",
|
|
263
|
+
"target_weight",
|
|
264
|
+
"weighting",
|
|
265
|
+
"trade_proposal",
|
|
266
|
+
"order",
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
class ReadOnlyTradeTradeProposalModelSerializer(TradeTradeProposalModelSerializer):
|
|
271
|
+
class Meta(TradeTradeProposalModelSerializer.Meta):
|
|
272
|
+
read_only_fields = TradeTradeProposalModelSerializer.Meta.fields
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
class TradeProposalModelSerializer(wb_serializers.ModelSerializer):
|
|
276
|
+
_model_portfolio = PortfolioRepresentationSerializer(source="model_portfolio")
|
|
277
|
+
model_portfolio = wb_serializers.PrimaryKeyRelatedField(
|
|
278
|
+
queryset=Portfolio.objects.all(),
|
|
279
|
+
default=wb_serializers.DefaultFromKwargs("portfolio_id"),
|
|
280
|
+
read_only=lambda view: not view.new_mode,
|
|
281
|
+
)
|
|
282
|
+
trade_date = wb_serializers.DateField(read_only=lambda view: not view.new_mode)
|
|
283
|
+
|
|
284
|
+
def create(self, validated_data):
|
|
285
|
+
if request := self.context.get("request"):
|
|
286
|
+
validated_data["creator"] = request.user.profile
|
|
287
|
+
return super().create(validated_data)
|
|
288
|
+
|
|
289
|
+
@wb_serializers.register_only_instance_resource()
|
|
290
|
+
def additional_resources(self, instance, request, user, **kwargs):
|
|
291
|
+
res = {}
|
|
292
|
+
if instance.status == TradeProposal.Status.APPROVED:
|
|
293
|
+
res["replay"] = reverse("wbportfolio:tradeproposal-replay", args=[instance.id], request=request)
|
|
294
|
+
if instance.model_portfolio:
|
|
295
|
+
res["reset"] = reverse("wbportfolio:tradeproposal-reset", args=[instance.id], request=request)
|
|
296
|
+
res["trades"] = reverse(
|
|
297
|
+
"wbportfolio:tradeproposal-trade-list",
|
|
298
|
+
args=[instance.id],
|
|
299
|
+
request=request,
|
|
300
|
+
)
|
|
301
|
+
return res
|
|
302
|
+
|
|
303
|
+
class Meta:
|
|
304
|
+
model = TradeProposal
|
|
305
|
+
only_fsm_transition_on_instance = True
|
|
306
|
+
fields = (
|
|
307
|
+
"id",
|
|
308
|
+
"trade_date",
|
|
309
|
+
"comment",
|
|
310
|
+
"status",
|
|
311
|
+
"portfolio",
|
|
312
|
+
"_model_portfolio",
|
|
313
|
+
"model_portfolio",
|
|
314
|
+
"_additional_resources",
|
|
315
|
+
)
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
from wbcore import serializers as wb_serializers
|
|
2
|
+
from wbcore.contrib.currency.serializers import CurrencyRepresentationSerializer
|
|
3
|
+
from wbfdm.serializers.instruments import InvestableInstrumentRepresentationSerializer
|
|
4
|
+
from wbportfolio.models import Transaction
|
|
5
|
+
from wbportfolio.serializers.portfolios import PortfolioRepresentationSerializer
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TransactionRepresentationSerializer(wb_serializers.RepresentationSerializer):
|
|
9
|
+
_detail = wb_serializers.HyperlinkField(reverse_name="wbportfolio:transaction-detail")
|
|
10
|
+
|
|
11
|
+
class Meta:
|
|
12
|
+
model = Transaction
|
|
13
|
+
fields = ("id", "transaction_date", "total_value", "_detail")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class TransactionModelSerializer(wb_serializers.ModelSerializer):
|
|
17
|
+
external_id = wb_serializers.CharField(required=False, read_only=True)
|
|
18
|
+
value_date = wb_serializers.DateField(required=False, read_only=True)
|
|
19
|
+
total_value_usd = wb_serializers.FloatField(default=0, read_only=True, label="Total Value ($)")
|
|
20
|
+
total_value_gross_usd = wb_serializers.FloatField(default=0, read_only=True, label="Total Value Gross ($)")
|
|
21
|
+
transaction_underlying_type = wb_serializers.CharField(read_only=True)
|
|
22
|
+
transaction_url_type = wb_serializers.SerializerMethodField()
|
|
23
|
+
_portfolio = PortfolioRepresentationSerializer(source="portfolio")
|
|
24
|
+
_underlying_instrument = InvestableInstrumentRepresentationSerializer(source="underlying_instrument")
|
|
25
|
+
_currency = CurrencyRepresentationSerializer(source="currency")
|
|
26
|
+
|
|
27
|
+
total_value = wb_serializers.DecimalField(max_digits=14, decimal_places=2, read_only=True)
|
|
28
|
+
total_value_fx_portfolio = wb_serializers.DecimalField(max_digits=14, decimal_places=2, read_only=True)
|
|
29
|
+
total_value_gross = wb_serializers.DecimalField(max_digits=14, decimal_places=2, read_only=True)
|
|
30
|
+
total_value_gross_fx_portfolio = wb_serializers.DecimalField(max_digits=14, decimal_places=2, read_only=True)
|
|
31
|
+
|
|
32
|
+
def get_transaction_url_type(self, obj):
|
|
33
|
+
return obj.transaction_type.lower()
|
|
34
|
+
|
|
35
|
+
# def get_transaction_underlying_type(self, obj):
|
|
36
|
+
# try:
|
|
37
|
+
# casted_transaction = obj.get_casted_transaction()
|
|
38
|
+
# return casted_transaction.Type[casted_transaction.transaction_subtype].label
|
|
39
|
+
# except Exception as e:
|
|
40
|
+
# return ""
|
|
41
|
+
class Meta:
|
|
42
|
+
model = Transaction
|
|
43
|
+
decorators = {
|
|
44
|
+
"total_value": wb_serializers.decorator(
|
|
45
|
+
decorator_type="text", position="left", value="{{_currency.symbol}}"
|
|
46
|
+
),
|
|
47
|
+
"total_value_gross": wb_serializers.decorator(
|
|
48
|
+
decorator_type="text", position="left", value="{{_currency.symbol}}"
|
|
49
|
+
),
|
|
50
|
+
"total_value_usd": wb_serializers.decorator(decorator_type="text", position="left", value="{{$}}"),
|
|
51
|
+
"total_value_gross_usd": wb_serializers.decorator(decorator_type="text", position="left", value="{{$}}"),
|
|
52
|
+
"total_value_fx_portfolio": wb_serializers.decorator(
|
|
53
|
+
position="left", value="{{_portfolio.currency_symbol}}"
|
|
54
|
+
),
|
|
55
|
+
"total_value_gross_fx_portfolio": wb_serializers.decorator(
|
|
56
|
+
position="left", value="{{_portfolio.currency_symbol}}"
|
|
57
|
+
)
|
|
58
|
+
# "total_value_fx_portfolio": wb_serializers.decorator(decorator_type="text", position="left", value="{{_portfolio.currency_symbol}}}"),
|
|
59
|
+
# "total_value_gross_fx_portfolio": wb_serializers.decorator(decorator_type="text", position="left", value="{{_portfolio.currency_symbol}}"),
|
|
60
|
+
}
|
|
61
|
+
fields = (
|
|
62
|
+
"id",
|
|
63
|
+
"transaction_type",
|
|
64
|
+
"transaction_url_type",
|
|
65
|
+
"transaction_underlying_type",
|
|
66
|
+
"portfolio",
|
|
67
|
+
"_portfolio",
|
|
68
|
+
"underlying_instrument",
|
|
69
|
+
"_underlying_instrument",
|
|
70
|
+
"transaction_date",
|
|
71
|
+
"book_date",
|
|
72
|
+
"value_date",
|
|
73
|
+
"currency",
|
|
74
|
+
"_currency",
|
|
75
|
+
"currency_fx_rate",
|
|
76
|
+
"total_value",
|
|
77
|
+
"total_value_fx_portfolio",
|
|
78
|
+
"total_value_gross",
|
|
79
|
+
"total_value_gross_fx_portfolio",
|
|
80
|
+
"external_id",
|
|
81
|
+
"comment",
|
|
82
|
+
"total_value_usd",
|
|
83
|
+
"total_value_gross_usd",
|
|
84
|
+
)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
.page-header {
|
|
2
|
+
background-color: #051f2d;
|
|
3
|
+
text-align: center;
|
|
4
|
+
font-size: 30px;
|
|
5
|
+
color: #fff;
|
|
6
|
+
border-radius: 0;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
strong {
|
|
10
|
+
color: #f25d47;
|
|
11
|
+
font-weight: 700;
|
|
12
|
+
white-space: nowrap;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.page-content {
|
|
16
|
+
padding: 0 30px;
|
|
17
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
### Welcome to the Account Holding Reconciliation. Please confirm your holdings:
|
|
2
|
+
|
|
3
|
+
* **Confirm Holdings**: Press the **'Agree'** button.
|
|
4
|
+
* **Disagree with Holdings**: Adjust your holdings and press the **'Communicate Differences'** button. (This button will appear after adjustments are made.)
|
|
5
|
+
|
|
6
|
+
### How to Adjust Your Holdings:
|
|
7
|
+
|
|
8
|
+
* Select the **shares** or **nominal value** cell in the "Your Input" column.
|
|
9
|
+
* Press **Enter**, adjust the value, and press **Enter** again.
|
|
10
|
+
* Alternatively, right-click the cell and select **'Edit'** to adjust the value.
|
|
11
|
+
|
|
12
|
+
### Additional Options:
|
|
13
|
+
|
|
14
|
+
* **View all Subscriptions/Redemptions**: Press the **'Show Subscriptions/Redemptions'** button.
|
|
15
|
+
* **Add a Subscription/Redemption**: Press the **'Add Subscription/Redemption'** button.
|
|
16
|
+
* **Single Product Actions**: Right-click any row below to display all Subscriptions/Redemptions or add a new Subscription/Redemption for a specific product.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Aggregate AssetPosition Liquidity Table View
|
|
2
|
+
|
|
3
|
+
The purpose of this view is to observe how fast an aggregated asset position
|
|
4
|
+
can be sold across all portfolios. We have two columns for two different dates.
|
|
5
|
+
One column shows the velocity and the other one shows the relative percent of
|
|
6
|
+
the total AuM (Asset under Management), "Days to Liquidate" and "Percent AUM"
|
|
7
|
+
respectively.
|
|
8
|
+
|
|
9
|
+
Some good things to know:
|
|
10
|
+
|
|
11
|
+
- We use the mean volume for the last 50 days.
|
|
12
|
+
|
|
13
|
+
- One third of the average volume for an asset position is
|
|
14
|
+
used to estimate the velocity. This number is subjective and attempts
|
|
15
|
+
to represent the number of trades that can be made.
|
|
16
|
+
|
|
17
|
+
- If we have a value for more than 3 days to sell an asset position,
|
|
18
|
+
the latter will be displayed in yellow. If this value is greater than 5,
|
|
19
|
+
it will be in red.
|
|
20
|
+
|
|
21
|
+
- We can use a filter that only displays asset positions that have a date
|
|
22
|
+
to liquidate greater than a given value for the Historic Date.
|
|
23
|
+
|
|
24
|
+
- The "Compared Date" is used to compare the asset position with the Historic Date.
|
|
25
|
+
Therefore, the values are not sorted for the last two columns.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Companies
|
|
2
|
+
A list of every company saved in the database.
|
|
3
|
+
|
|
4
|
+
## Columns:
|
|
5
|
+
Each column title has three lines on the right if you hover over it. Click on them to show options for that column. The second tab of the options menu will allow you to filter the column, the third to completely hide entire columns. Click on anywhere else on the column to order it, cycling between ascending, descending and no ordering. Hold shift while clicking to order multiple columns with individual weights.
|
|
6
|
+
|
|
7
|
+
### Name:
|
|
8
|
+
The name of the company.
|
|
9
|
+
|
|
10
|
+
### City:
|
|
11
|
+
The city of the company's primary address. Hover over the name to display the full address.
|
|
12
|
+
|
|
13
|
+
### Type:
|
|
14
|
+
The company's type. Company types can be added, edited and deleted by managers under CRM > Administration > Company Types.
|
|
15
|
+
|
|
16
|
+
### Tier:
|
|
17
|
+
The company's tier. Tiers range from 1 to 5 and are automatically computed like this:
|
|
18
|
+
_Company is of status client or TPM:_
|
|
19
|
+
| Invested AUM / AUM | Tier |
|
|
20
|
+
| -------- | --------|
|
|
21
|
+
| > 0.1 | Tier 1 |
|
|
22
|
+
| 0.05 - 0.1 | Tier 2 |
|
|
23
|
+
| 0.02 - 0.05 | Tier 3 |
|
|
24
|
+
| 0.01 - 0.02 | Tier 4 |
|
|
25
|
+
| default | Tier 5 |
|
|
26
|
+
|
|
27
|
+
_Company is *not* of status client or TPM:_
|
|
28
|
+
| AUM | Tier |
|
|
29
|
+
| -------- | --------|
|
|
30
|
+
| > 10,000,000,000 $ | Tier 1 |
|
|
31
|
+
| 5,000,000,000 \$ - 10,000,000,000 $ | Tier 2 |
|
|
32
|
+
| 1,000,000,000 \$ - 5,000,000,000 $ | Tier 3 |
|
|
33
|
+
| 500,000,000 \$ - 1,000,000,000 $ | Tier 4 |
|
|
34
|
+
| default | Tier 5 |
|
|
35
|
+
|
|
36
|
+
### Status:
|
|
37
|
+
The company's status. Company statuses can be added, edited and deleted by managers under CRM > Administration > Customer Status.
|
|
38
|
+
|
|
39
|
+
### AUM Invested:
|
|
40
|
+
The company's assets under management managed by the main company.
|
|
41
|
+
|
|
42
|
+
### AUM:
|
|
43
|
+
Total assets under management for the company.
|
|
44
|
+
|
|
45
|
+
### Potential:
|
|
46
|
+
The potential reflects how much potential a company (regardless if client/propective) has. Formula: AUM * (Asset Allocation * Asset Allocation Max Investment) - Invested AUM. The field is populated automatically.
|
|
47
|
+
|
|
48
|
+
### Primary Relationship Manager:
|
|
49
|
+
The primary relationship manager of this company. Hover over the name to display further information about the person.
|
|
50
|
+
|
|
51
|
+
### Last Activity:
|
|
52
|
+
The name and end date of the company's last activity. Hover over it to display further information about the activity. Column can also be ordered by end date of the activity.
|
|
53
|
+
|
|
54
|
+
### Activity Heat:
|
|
55
|
+
A visual representation of the company's activeness. The data representation ranges from 0 to 1 which needs to be kept in mind to be able to apply a proper filter to the column.
|
|
56
|
+
|
|
57
|
+
## Filters:
|
|
58
|
+
|
|
59
|
+
### No Activity:
|
|
60
|
+
Filter companies with no activity for x amount of time.
|
|
61
|
+
|
|
62
|
+
### Companies' Employee:
|
|
63
|
+
Display employers of the selected person.
|
|
64
|
+
|
|
65
|
+
## Search Field:
|
|
66
|
+
Typing in the search field allows to filter the companies by name.
|
|
67
|
+
|
|
68
|
+
## Buttons:
|
|
69
|
+
You can right-click each row to reveal three buttons:
|
|
70
|
+
|
|
71
|
+
### Activities:
|
|
72
|
+
Displays activities for the row's company.
|
|
73
|
+
|
|
74
|
+
### Employees:
|
|
75
|
+
Displays a list of the company's employees.
|
|
76
|
+
|
|
77
|
+
### Relationship Managers:
|
|
78
|
+
Displays all relationship managers of the row's company.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Earnings Analysis
|
|
2
|
+
|
|
3
|
+
Consensus $ EPS
|
|
4
|
+
|
|
5
|
+
## Filters
|
|
6
|
+
|
|
7
|
+
A set of filters that control the analysis is available:
|
|
8
|
+
|
|
9
|
+
1. **Analysis**: EPS ($)
|
|
10
|
+
- **$ EPS [default view]**: By default shows an aggregated $ EPS (weighted).
|
|
11
|
+
|
|
12
|
+
2. **Period**: Common periods (TTM, FTM, FY+1, FY+2) are available with **FTW** set by default.
|
|
13
|
+
|
|
14
|
+
3. **Show related**: Adds lines for all specified peers if available
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Relative valuation
|
|
2
|
+
|
|
3
|
+
Classic and commonly used relative ratios PE, PEG, PS, PFCF, EV-EBITDA
|
|
4
|
+
Additional comparative metrics: growth (EPS, Sales, FCF), EV, Market Cap
|
|
5
|
+
|
|
6
|
+
## Filters
|
|
7
|
+
|
|
8
|
+
A set of filter is available:
|
|
9
|
+
1. **Output**: Chart, Table (Last Value), Table (Time-series)
|
|
10
|
+
- **Chart [default view]**: By default shows all ratios for the instrument in question in one figure with PEG on a secondary/right axis.
|
|
11
|
+
- **Table (Last Value)**: By default shows the last available value for all ratios for the instrument in question in one table.
|
|
12
|
+
- **Table (Time-series)**: Shows all available values for all ratios for the instrument in question in one table.
|
|
13
|
+
|
|
14
|
+
2. **Period**: Common periods (TTM, FTW, FY+1, FY+2) are available with **FTW** set by default.
|
|
15
|
+
|
|
16
|
+
3. **Versus related (not available in the Time-series view):**
|
|
17
|
+
- if the view "**Table (Last Value)**" is set, then all available related instruments (peers, partners, suppliers, etc.) will be shown in the same table, including Mean and Median values.
|
|
18
|
+
- if the view "**Chart**" is set, then all available related instruments (peers, partners, suppliers, etc.) will be shown in the same chart. Additionally, the user may choose which variables to show on X,Y,and Bubble Size axis. Median line may be disactivated, if desired.
|
|
19
|
+
|
|
20
|
+
4. **Draw ranges**: if the view "**Chart**" is set, then each ratio will be shown on a separate subplot with historic min-max ranges shown with dashed lines.
|
|
21
|
+
|
|
22
|
+
5. **Range type**: if the view "**Chart**" is set and "**Draw ranges**" is activated, then a user may choose the type of "min-max" range: Min-Max (entire period) or Rolling.
|
|
23
|
+
- **"Min-Max (entire period)"** looks for the min and max values for each ratio across the entire period in questions and sets it for the entire graph.
|
|
24
|
+
- **"Rolling"** looks for the min and max values for each ratio across the "Rolling Period" specified in a separate filter.
|
|
25
|
+
|
|
26
|
+
6. **Rolling period**: works with "**Range type**" filter if the view "**Chart**" is set and "**Draw ranges**" is activated.
|
|
27
|
+
|
|
28
|
+
7. **Clean data** (more "treatment"): significant and heavy data cleaning will be applied to all variables. For **each** series:
|
|
29
|
+
- All raw input data is forward and then backward filled.
|
|
30
|
+
- All empty rows are deleted and remaining blanks for all variables are filled by linear interpolation.
|
|
31
|
+
- Ratios are then normally calculated.
|
|
32
|
+
- The resulting series are cleaned for outliers (values in the top and bottom 5% are deleted).
|
|
33
|
+
- All negative (incl. EV/S) and NaN values are set to Null (deleted as "non-meaningful").
|
|
34
|
+
- All values above a certain threshold (by default 100) are deleted. **Exceptions** are:
|
|
35
|
+
- PEG above 15
|
|
36
|
+
- PS above 40
|
|
37
|
+
- The remaining series are forward and backward filled to clean missing values for smoother series.
|
|
38
|
+
- All series are smoothed (3-day simple moving average). The **PEG** series is smoothed differently (10-day simple moving average).
|
|
39
|
+
|
|
40
|
+
8. **X-Axis**: works if the view "**Chart**" is set and "**Versus related**" is activated. Controls the variable shown on the x-axis.
|
|
41
|
+
|
|
42
|
+
9. **Y-Axis**: works if the view "**Chart**" is set and "**Versus related**" is activated. Controls the variable shown on the y-axis.
|
|
43
|
+
|
|
44
|
+
10. **Z-Axis (bubble size)**: works if the view "**Chart**" is set and "**Versus related**" is activated. Controls the variable shown on the z-axis/bubble size.
|
|
45
|
+
|
|
46
|
+
11. **Median**: works if the view "**Chart**" is set and "**Versus related**" is activated. Calculates the median for **X-Axis** and **Y-Axis** variables across the entire period range.
|
|
47
|
+
|
|
48
|
+
## Formulas
|
|
49
|
+
|
|
50
|
+
#### FY+1 and FY+2
|
|
51
|
+
|
|
52
|
+
$$
|
|
53
|
+
Ratio_{t} = Price_{t} / Ratio\: Item_{t}
|
|
54
|
+
$$
|
|
55
|
+
|
|
56
|
+
$
|
|
57
|
+
where \\
|
|
58
|
+
$
|
|
59
|
+
$$
|
|
60
|
+
t = day \\
|
|
61
|
+
$$
|
|
62
|
+
$
|
|
63
|
+
Ratio\: Item =
|
|
64
|
+
$
|
|
65
|
+
$$
|
|
66
|
+
EPS = Daily\: Consensus\: Net\: Profit\: Forecast / Number\:of\:shares\\
|
|
67
|
+
or \\
|
|
68
|
+
Revenue\: per\: share = Daily\: Consensus\: Revenue\: Forecast / Number\:of\:shares\\
|
|
69
|
+
or \\
|
|
70
|
+
EBITDA\: per\: share = Daily\: Consensus\: EBITDA\; Forecast / Number\:of\:shares\\
|
|
71
|
+
or \\
|
|
72
|
+
FCF = Daily\: Consensus\: FreeCashFlow\; Forecast / Number\:of\:shares\\
|
|
73
|
+
$$
|
|
74
|
+
|
|
75
|
+
#### Trailing Twelve Month (TTM) and Next Twelve Month (NTM) *also known as Forward Twelve Months (FTM)*
|
|
76
|
+
\
|
|
77
|
+
$
|
|
78
|
+
Ratio\: Item =
|
|
79
|
+
$
|
|
80
|
+
$$
|
|
81
|
+
EPS = Daily\: EPS\: TTM\: \\
|
|
82
|
+
or \\
|
|
83
|
+
Revenue\: or\: EBITDA\: or\: FCF\: per\: share = Interpolated\: between\: consensus\: FY+2\:,\: FY+1 \\
|
|
84
|
+
Revenue\: or\: EBITDA\: or\: FCF\:per\: share =Interpolated\: between\: FY+1\:(current)\:,\: FY0\:(last)\:,\: FY-1\:(previous) \\
|
|
85
|
+
$$
|
|
86
|
+
|
|
87
|
+
#### Trailing Twelve Month (TTM) and Next Twelve Month (NTM) *also known as Forward Twelve Months (FTM)*
|
|
88
|
+
\
|
|
89
|
+
$
|
|
90
|
+
DailyPEG_{fy+1} = Price / EPS_{fy+1} / Growth_{fy+1\: vs\: fy0} \\
|
|
91
|
+
DailyPEG_{fy+2} = Price / EPS_{fy+2} / Growth_{geoavg(fy+2\: vs\: fy1,\:fy+1\: vs\: fy0)} \\
|
|
92
|
+
DailyPEG_{NTM} = Price / EPS_{NTM} / Growth_{ntm\: vs\: ttm} \\
|
|
93
|
+
DailyPEG_{TTM} = Price / EPS_{TTM} / Growth_{ttm\: vs\: ttm_{t-1}} \\
|
|
94
|
+
$
|