wbfdm 2.2.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 wbfdm might be problematic. Click here for more details.
- wbfdm/__init__.py +2 -0
- wbfdm/admin/__init__.py +42 -0
- wbfdm/admin/classifications.py +39 -0
- wbfdm/admin/esg.py +23 -0
- wbfdm/admin/exchanges.py +53 -0
- wbfdm/admin/instrument_lists.py +23 -0
- wbfdm/admin/instrument_prices.py +62 -0
- wbfdm/admin/instrument_requests.py +33 -0
- wbfdm/admin/instruments.py +117 -0
- wbfdm/admin/instruments_relationships.py +25 -0
- wbfdm/admin/options.py +101 -0
- wbfdm/analysis/__init__.py +2 -0
- wbfdm/analysis/esg/__init__.py +0 -0
- wbfdm/analysis/esg/enums.py +82 -0
- wbfdm/analysis/esg/esg_analysis.py +217 -0
- wbfdm/analysis/esg/utils.py +13 -0
- wbfdm/analysis/financial_analysis/__init__.py +1 -0
- wbfdm/analysis/financial_analysis/financial_metric_analysis.py +88 -0
- wbfdm/analysis/financial_analysis/financial_ratio_analysis.py +125 -0
- wbfdm/analysis/financial_analysis/financial_statistics_analysis.py +271 -0
- wbfdm/analysis/financial_analysis/statement_with_estimates.py +558 -0
- wbfdm/analysis/financial_analysis/utils.py +316 -0
- wbfdm/analysis/technical_analysis/__init__.py +1 -0
- wbfdm/analysis/technical_analysis/technical_analysis.py +138 -0
- wbfdm/analysis/technical_analysis/traces.py +165 -0
- wbfdm/analysis/utils.py +32 -0
- wbfdm/apps.py +14 -0
- wbfdm/contrib/__init__.py +0 -0
- wbfdm/contrib/dsws/__init__.py +0 -0
- wbfdm/contrib/dsws/client.py +285 -0
- wbfdm/contrib/internal/__init__.py +0 -0
- wbfdm/contrib/internal/dataloaders/__init__.py +0 -0
- wbfdm/contrib/internal/dataloaders/market_data.py +87 -0
- wbfdm/contrib/metric/__init__.py +0 -0
- wbfdm/contrib/metric/admin/__init__.py +2 -0
- wbfdm/contrib/metric/admin/instruments.py +12 -0
- wbfdm/contrib/metric/admin/metrics.py +43 -0
- wbfdm/contrib/metric/apps.py +10 -0
- wbfdm/contrib/metric/backends/__init__.py +2 -0
- wbfdm/contrib/metric/backends/base.py +159 -0
- wbfdm/contrib/metric/backends/performances.py +265 -0
- wbfdm/contrib/metric/backends/statistics.py +182 -0
- wbfdm/contrib/metric/decorators.py +14 -0
- wbfdm/contrib/metric/dispatch.py +23 -0
- wbfdm/contrib/metric/dto.py +88 -0
- wbfdm/contrib/metric/exceptions.py +6 -0
- wbfdm/contrib/metric/factories.py +33 -0
- wbfdm/contrib/metric/filters.py +28 -0
- wbfdm/contrib/metric/migrations/0001_initial.py +88 -0
- wbfdm/contrib/metric/migrations/0002_remove_instrumentmetric_unique_instrument_metric_and_more.py +26 -0
- wbfdm/contrib/metric/migrations/__init__.py +0 -0
- wbfdm/contrib/metric/models.py +180 -0
- wbfdm/contrib/metric/orchestrators.py +94 -0
- wbfdm/contrib/metric/registry.py +80 -0
- wbfdm/contrib/metric/serializers.py +44 -0
- wbfdm/contrib/metric/tasks.py +27 -0
- wbfdm/contrib/metric/tests/__init__.py +0 -0
- wbfdm/contrib/metric/tests/backends/__init__.py +0 -0
- wbfdm/contrib/metric/tests/backends/test_performances.py +152 -0
- wbfdm/contrib/metric/tests/backends/test_statistics.py +48 -0
- wbfdm/contrib/metric/tests/conftest.py +92 -0
- wbfdm/contrib/metric/tests/test_dto.py +73 -0
- wbfdm/contrib/metric/tests/test_models.py +72 -0
- wbfdm/contrib/metric/tests/test_tasks.py +24 -0
- wbfdm/contrib/metric/tests/test_viewsets.py +79 -0
- wbfdm/contrib/metric/urls.py +19 -0
- wbfdm/contrib/metric/viewsets/__init__.py +1 -0
- wbfdm/contrib/metric/viewsets/configs/__init__.py +1 -0
- wbfdm/contrib/metric/viewsets/configs/display.py +92 -0
- wbfdm/contrib/metric/viewsets/configs/menus.py +11 -0
- wbfdm/contrib/metric/viewsets/configs/utils.py +137 -0
- wbfdm/contrib/metric/viewsets/mixins.py +245 -0
- wbfdm/contrib/metric/viewsets/viewsets.py +40 -0
- wbfdm/contrib/msci/__init__.py +0 -0
- wbfdm/contrib/msci/client.py +92 -0
- wbfdm/contrib/msci/dataloaders/__init__.py +0 -0
- wbfdm/contrib/msci/dataloaders/esg.py +87 -0
- wbfdm/contrib/msci/dataloaders/esg_controversies.py +81 -0
- wbfdm/contrib/msci/sync.py +58 -0
- wbfdm/contrib/msci/tests/__init__.py +0 -0
- wbfdm/contrib/msci/tests/conftest.py +1 -0
- wbfdm/contrib/msci/tests/test_client.py +70 -0
- wbfdm/contrib/qa/__init__.py +0 -0
- wbfdm/contrib/qa/apps.py +22 -0
- wbfdm/contrib/qa/database_routers.py +25 -0
- wbfdm/contrib/qa/dataloaders/__init__.py +0 -0
- wbfdm/contrib/qa/dataloaders/adjustments.py +56 -0
- wbfdm/contrib/qa/dataloaders/corporate_actions.py +59 -0
- wbfdm/contrib/qa/dataloaders/financials.py +83 -0
- wbfdm/contrib/qa/dataloaders/market_data.py +117 -0
- wbfdm/contrib/qa/dataloaders/officers.py +59 -0
- wbfdm/contrib/qa/dataloaders/reporting_dates.py +67 -0
- wbfdm/contrib/qa/dataloaders/statements.py +267 -0
- wbfdm/contrib/qa/tasks.py +0 -0
- wbfdm/dataloaders/__init__.py +0 -0
- wbfdm/dataloaders/cache.py +129 -0
- wbfdm/dataloaders/protocols.py +112 -0
- wbfdm/dataloaders/proxies.py +201 -0
- wbfdm/dataloaders/types.py +209 -0
- wbfdm/dynamic_preferences_registry.py +45 -0
- wbfdm/enums.py +657 -0
- wbfdm/factories/__init__.py +13 -0
- wbfdm/factories/classifications.py +56 -0
- wbfdm/factories/controversies.py +27 -0
- wbfdm/factories/exchanges.py +21 -0
- wbfdm/factories/instrument_list.py +22 -0
- wbfdm/factories/instrument_prices.py +79 -0
- wbfdm/factories/instruments.py +63 -0
- wbfdm/factories/instruments_relationships.py +31 -0
- wbfdm/factories/options.py +66 -0
- wbfdm/figures/__init__.py +1 -0
- wbfdm/figures/financials/__init__.py +1 -0
- wbfdm/figures/financials/financial_analysis_charts.py +469 -0
- wbfdm/figures/financials/financials_charts.py +711 -0
- wbfdm/filters/__init__.py +31 -0
- wbfdm/filters/classifications.py +100 -0
- wbfdm/filters/exchanges.py +22 -0
- wbfdm/filters/financials.py +95 -0
- wbfdm/filters/financials_analysis.py +119 -0
- wbfdm/filters/instrument_prices.py +112 -0
- wbfdm/filters/instruments.py +198 -0
- wbfdm/filters/utils.py +44 -0
- wbfdm/import_export/__init__.py +0 -0
- wbfdm/import_export/backends/__init__.py +0 -0
- wbfdm/import_export/backends/cbinsights/__init__.py +2 -0
- wbfdm/import_export/backends/cbinsights/deals.py +44 -0
- wbfdm/import_export/backends/cbinsights/equities.py +41 -0
- wbfdm/import_export/backends/cbinsights/mixin.py +15 -0
- wbfdm/import_export/backends/cbinsights/utils/__init__.py +0 -0
- wbfdm/import_export/backends/cbinsights/utils/classifications.py +4150 -0
- wbfdm/import_export/backends/cbinsights/utils/client.py +217 -0
- wbfdm/import_export/backends/refinitiv/__init__.py +5 -0
- wbfdm/import_export/backends/refinitiv/daily_fundamental.py +36 -0
- wbfdm/import_export/backends/refinitiv/fiscal_period.py +63 -0
- wbfdm/import_export/backends/refinitiv/forecast.py +178 -0
- wbfdm/import_export/backends/refinitiv/fundamental.py +103 -0
- wbfdm/import_export/backends/refinitiv/geographic_segment.py +32 -0
- wbfdm/import_export/backends/refinitiv/instrument.py +55 -0
- wbfdm/import_export/backends/refinitiv/instrument_price.py +77 -0
- wbfdm/import_export/backends/refinitiv/mixin.py +29 -0
- wbfdm/import_export/backends/refinitiv/utils/__init__.py +1 -0
- wbfdm/import_export/backends/refinitiv/utils/controller.py +182 -0
- wbfdm/import_export/handlers/__init__.py +0 -0
- wbfdm/import_export/handlers/instrument.py +253 -0
- wbfdm/import_export/handlers/instrument_list.py +101 -0
- wbfdm/import_export/handlers/instrument_price.py +71 -0
- wbfdm/import_export/handlers/option.py +54 -0
- wbfdm/import_export/handlers/private_equities.py +49 -0
- wbfdm/import_export/parsers/__init__.py +0 -0
- wbfdm/import_export/parsers/cbinsights/__init__.py +0 -0
- wbfdm/import_export/parsers/cbinsights/deals.py +39 -0
- wbfdm/import_export/parsers/cbinsights/equities.py +56 -0
- wbfdm/import_export/parsers/cbinsights/fundamentals.py +45 -0
- wbfdm/import_export/parsers/refinitiv/__init__.py +0 -0
- wbfdm/import_export/parsers/refinitiv/daily_fundamental.py +7 -0
- wbfdm/import_export/parsers/refinitiv/forecast.py +7 -0
- wbfdm/import_export/parsers/refinitiv/fundamental.py +9 -0
- wbfdm/import_export/parsers/refinitiv/geographic_segment.py +7 -0
- wbfdm/import_export/parsers/refinitiv/instrument.py +75 -0
- wbfdm/import_export/parsers/refinitiv/instrument_price.py +26 -0
- wbfdm/import_export/parsers/refinitiv/utils.py +96 -0
- wbfdm/import_export/resources/__init__.py +0 -0
- wbfdm/import_export/resources/classification.py +23 -0
- wbfdm/import_export/resources/instrument_prices.py +33 -0
- wbfdm/import_export/resources/instruments.py +176 -0
- wbfdm/jinja2.py +7 -0
- wbfdm/management/__init__.py +30 -0
- wbfdm/menu.py +11 -0
- wbfdm/migrations/0001_initial.py +71 -0
- wbfdm/migrations/0002_rename_statements_instrumentlookup_financials_and_more.py +144 -0
- wbfdm/migrations/0003_instrument_estimate_backend_and_more.py +34 -0
- wbfdm/migrations/0004_rename_financials_instrumentlookup_statements_and_more.py +86 -0
- wbfdm/migrations/0005_instrument_corporate_action_backend.py +29 -0
- wbfdm/migrations/0006_instrument_officer_backend.py +29 -0
- wbfdm/migrations/0007_instrument_country_instrument_currency_and_more.py +117 -0
- wbfdm/migrations/0008_controversy.py +75 -0
- wbfdm/migrations/0009_alter_controversy_flag_alter_controversy_initiated_and_more.py +85 -0
- wbfdm/migrations/0010_classification_classificationgroup_deal_exchange_and_more.py +1299 -0
- wbfdm/migrations/0011_delete_instrumentlookup_instrument_corporate_actions_and_more.py +169 -0
- wbfdm/migrations/0012_instrumentprice_created_instrumentprice_modified.py +564 -0
- wbfdm/migrations/0013_instrument_is_investable_universe_and_more.py +199 -0
- wbfdm/migrations/0014_alter_controversy_instrument.py +22 -0
- wbfdm/migrations/0015_instrument_instrument_investible_index.py +16 -0
- wbfdm/migrations/0016_instrumenttype_name_repr.py +18 -0
- wbfdm/migrations/0017_instrument_instrument_security_index.py +16 -0
- wbfdm/migrations/0018_instrument_instrument_level_index.py +20 -0
- wbfdm/migrations/0019_alter_controversy_source.py +17 -0
- wbfdm/migrations/0020_optionaggregate_option_and_more.py +249 -0
- wbfdm/migrations/0021_delete_instrumentdailystatistics.py +15 -0
- wbfdm/migrations/0022_instrument_cusip_option_open_interest_20d_and_more.py +91 -0
- wbfdm/migrations/0023_instrument_unique_ric_instrument_unique_rmc_and_more.py +53 -0
- wbfdm/migrations/0024_option_open_interest_10d_option_volume_10d_and_more.py +36 -0
- wbfdm/migrations/0025_instrument_is_primary_and_more.py +29 -0
- wbfdm/migrations/0026_instrument_is_cash_equivalent.py +30 -0
- wbfdm/migrations/0027_remove_instrument_unique_ric_and_more.py +100 -0
- wbfdm/migrations/__init__.py +0 -0
- wbfdm/models/__init__.py +4 -0
- wbfdm/models/esg/__init__.py +1 -0
- wbfdm/models/esg/controversies.py +81 -0
- wbfdm/models/exchanges/__init__.py +1 -0
- wbfdm/models/exchanges/exchanges.py +223 -0
- wbfdm/models/fields.py +117 -0
- wbfdm/models/fk_fields.py +403 -0
- wbfdm/models/indicators.py +0 -0
- wbfdm/models/instruments/__init__.py +19 -0
- wbfdm/models/instruments/classifications.py +265 -0
- wbfdm/models/instruments/instrument_lists.py +120 -0
- wbfdm/models/instruments/instrument_prices.py +540 -0
- wbfdm/models/instruments/instrument_relationships.py +251 -0
- wbfdm/models/instruments/instrument_requests.py +196 -0
- wbfdm/models/instruments/instruments.py +991 -0
- wbfdm/models/instruments/llm/__init__.py +1 -0
- wbfdm/models/instruments/llm/create_instrument_news_relationships.py +78 -0
- wbfdm/models/instruments/mixin/__init__.py +0 -0
- wbfdm/models/instruments/mixin/financials_computed.py +804 -0
- wbfdm/models/instruments/mixin/financials_serializer_fields.py +1407 -0
- wbfdm/models/instruments/mixin/instruments.py +294 -0
- wbfdm/models/instruments/options.py +225 -0
- wbfdm/models/instruments/private_equities.py +59 -0
- wbfdm/models/instruments/querysets.py +73 -0
- wbfdm/models/instruments/utils.py +41 -0
- wbfdm/preferences.py +21 -0
- wbfdm/serializers/__init__.py +4 -0
- wbfdm/serializers/esg.py +36 -0
- wbfdm/serializers/exchanges.py +39 -0
- wbfdm/serializers/instruments/__init__.py +37 -0
- wbfdm/serializers/instruments/classifications.py +139 -0
- wbfdm/serializers/instruments/instrument_lists.py +61 -0
- wbfdm/serializers/instruments/instrument_prices.py +73 -0
- wbfdm/serializers/instruments/instrument_relationships.py +170 -0
- wbfdm/serializers/instruments/instrument_requests.py +61 -0
- wbfdm/serializers/instruments/instruments.py +274 -0
- wbfdm/serializers/instruments/mixins.py +104 -0
- wbfdm/serializers/officers.py +20 -0
- wbfdm/signals.py +7 -0
- wbfdm/sync/__init__.py +0 -0
- wbfdm/sync/abstract.py +31 -0
- wbfdm/sync/runner.py +22 -0
- wbfdm/tasks.py +69 -0
- wbfdm/tests/__init__.py +0 -0
- wbfdm/tests/analysis/__init__.py +0 -0
- wbfdm/tests/analysis/financial_analysis/__init__.py +0 -0
- wbfdm/tests/analysis/financial_analysis/test_statement_with_estimates.py +392 -0
- wbfdm/tests/analysis/financial_analysis/test_utils.py +322 -0
- wbfdm/tests/analysis/test_esg.py +159 -0
- wbfdm/tests/conftest.py +92 -0
- wbfdm/tests/dataloaders/__init__.py +0 -0
- wbfdm/tests/dataloaders/test_cache.py +73 -0
- wbfdm/tests/models/__init__.py +0 -0
- wbfdm/tests/models/test_classifications.py +99 -0
- wbfdm/tests/models/test_exchanges.py +7 -0
- wbfdm/tests/models/test_instrument_list.py +117 -0
- wbfdm/tests/models/test_instrument_prices.py +306 -0
- wbfdm/tests/models/test_instruments.py +202 -0
- wbfdm/tests/models/test_merge.py +99 -0
- wbfdm/tests/models/test_options.py +69 -0
- wbfdm/tests/test_tasks.py +6 -0
- wbfdm/tests/tests.py +10 -0
- wbfdm/urls.py +222 -0
- wbfdm/utils.py +54 -0
- wbfdm/viewsets/__init__.py +10 -0
- wbfdm/viewsets/configs/__init__.py +5 -0
- wbfdm/viewsets/configs/buttons/__init__.py +8 -0
- wbfdm/viewsets/configs/buttons/classifications.py +23 -0
- wbfdm/viewsets/configs/buttons/exchanges.py +9 -0
- wbfdm/viewsets/configs/buttons/instrument_prices.py +49 -0
- wbfdm/viewsets/configs/buttons/instruments.py +283 -0
- wbfdm/viewsets/configs/display/__init__.py +22 -0
- wbfdm/viewsets/configs/display/classifications.py +138 -0
- wbfdm/viewsets/configs/display/esg.py +75 -0
- wbfdm/viewsets/configs/display/exchanges.py +42 -0
- wbfdm/viewsets/configs/display/instrument_lists.py +137 -0
- wbfdm/viewsets/configs/display/instrument_prices.py +199 -0
- wbfdm/viewsets/configs/display/instrument_requests.py +116 -0
- wbfdm/viewsets/configs/display/instruments.py +618 -0
- wbfdm/viewsets/configs/display/instruments_relationships.py +65 -0
- wbfdm/viewsets/configs/display/monthly_performances.py +72 -0
- wbfdm/viewsets/configs/display/officers.py +16 -0
- wbfdm/viewsets/configs/display/prices.py +21 -0
- wbfdm/viewsets/configs/display/statement_with_estimates.py +101 -0
- wbfdm/viewsets/configs/display/statements.py +48 -0
- wbfdm/viewsets/configs/endpoints/__init__.py +41 -0
- wbfdm/viewsets/configs/endpoints/classifications.py +87 -0
- wbfdm/viewsets/configs/endpoints/esg.py +20 -0
- wbfdm/viewsets/configs/endpoints/exchanges.py +6 -0
- wbfdm/viewsets/configs/endpoints/financials_analysis.py +65 -0
- wbfdm/viewsets/configs/endpoints/instrument_lists.py +38 -0
- wbfdm/viewsets/configs/endpoints/instrument_prices.py +51 -0
- wbfdm/viewsets/configs/endpoints/instrument_requests.py +20 -0
- wbfdm/viewsets/configs/endpoints/instruments.py +13 -0
- wbfdm/viewsets/configs/endpoints/instruments_relationships.py +31 -0
- wbfdm/viewsets/configs/endpoints/statements.py +6 -0
- wbfdm/viewsets/configs/menus/__init__.py +9 -0
- wbfdm/viewsets/configs/menus/classifications.py +19 -0
- wbfdm/viewsets/configs/menus/exchanges.py +10 -0
- wbfdm/viewsets/configs/menus/instrument_lists.py +10 -0
- wbfdm/viewsets/configs/menus/instruments.py +20 -0
- wbfdm/viewsets/configs/menus/instruments_relationships.py +33 -0
- wbfdm/viewsets/configs/titles/__init__.py +42 -0
- wbfdm/viewsets/configs/titles/classifications.py +79 -0
- wbfdm/viewsets/configs/titles/esg.py +11 -0
- wbfdm/viewsets/configs/titles/exchanges.py +12 -0
- wbfdm/viewsets/configs/titles/financial_ratio_analysis.py +6 -0
- wbfdm/viewsets/configs/titles/financials_analysis.py +50 -0
- wbfdm/viewsets/configs/titles/instrument_prices.py +50 -0
- wbfdm/viewsets/configs/titles/instrument_requests.py +16 -0
- wbfdm/viewsets/configs/titles/instruments.py +31 -0
- wbfdm/viewsets/configs/titles/instruments_relationships.py +21 -0
- wbfdm/viewsets/configs/titles/market_data.py +13 -0
- wbfdm/viewsets/configs/titles/prices.py +15 -0
- wbfdm/viewsets/configs/titles/statement_with_estimates.py +10 -0
- wbfdm/viewsets/esg.py +72 -0
- wbfdm/viewsets/exchanges.py +63 -0
- wbfdm/viewsets/financial_analysis/__init__.py +3 -0
- wbfdm/viewsets/financial_analysis/financial_metric_analysis.py +85 -0
- wbfdm/viewsets/financial_analysis/financial_ratio_analysis.py +85 -0
- wbfdm/viewsets/financial_analysis/statement_with_estimates.py +145 -0
- wbfdm/viewsets/instruments/__init__.py +80 -0
- wbfdm/viewsets/instruments/classifications.py +279 -0
- wbfdm/viewsets/instruments/financials_analysis.py +614 -0
- wbfdm/viewsets/instruments/instrument_lists.py +77 -0
- wbfdm/viewsets/instruments/instrument_prices.py +542 -0
- wbfdm/viewsets/instruments/instrument_requests.py +51 -0
- wbfdm/viewsets/instruments/instruments.py +106 -0
- wbfdm/viewsets/instruments/instruments_relationships.py +235 -0
- wbfdm/viewsets/instruments/utils.py +27 -0
- wbfdm/viewsets/market_data.py +172 -0
- wbfdm/viewsets/mixins.py +9 -0
- wbfdm/viewsets/officers.py +27 -0
- wbfdm/viewsets/prices.py +62 -0
- wbfdm/viewsets/statements/__init__.py +1 -0
- wbfdm/viewsets/statements/statements.py +100 -0
- wbfdm/viewsets/technical_analysis/__init__.py +1 -0
- wbfdm/viewsets/technical_analysis/monthly_performances.py +93 -0
- wbfdm-2.2.1.dist-info/METADATA +15 -0
- wbfdm-2.2.1.dist-info/RECORD +337 -0
- wbfdm-2.2.1.dist-info/WHEEL +5 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
from datetime import date
|
|
2
|
+
from typing import Iterator
|
|
3
|
+
|
|
4
|
+
from wbcore.contrib.dataloader.dataloaders import DataloaderProxy
|
|
5
|
+
from wbfdm.dataloaders.protocols import (
|
|
6
|
+
AdjustmentsProtocol,
|
|
7
|
+
CorporateActionsProtocol,
|
|
8
|
+
ESGControversyProtocol,
|
|
9
|
+
ESGProtocol,
|
|
10
|
+
FinancialsProtocol,
|
|
11
|
+
MarketDataProtocol,
|
|
12
|
+
OfficersProtocol,
|
|
13
|
+
ReportDateProtocol,
|
|
14
|
+
StatementsProtocol,
|
|
15
|
+
)
|
|
16
|
+
from wbfdm.dataloaders.types import (
|
|
17
|
+
AdjustmentDataDict,
|
|
18
|
+
CorporateActionDataDict,
|
|
19
|
+
ESGControversyDataDict,
|
|
20
|
+
ESGDataDict,
|
|
21
|
+
FinancialDataDict,
|
|
22
|
+
MarketDataDict,
|
|
23
|
+
OfficerDataDict,
|
|
24
|
+
ReportDateDataDict,
|
|
25
|
+
StatementDataDict,
|
|
26
|
+
)
|
|
27
|
+
from wbfdm.enums import (
|
|
28
|
+
ESG,
|
|
29
|
+
CalendarType,
|
|
30
|
+
DataType,
|
|
31
|
+
EstimateType,
|
|
32
|
+
Financial,
|
|
33
|
+
Frequency,
|
|
34
|
+
MarketData,
|
|
35
|
+
PeriodType,
|
|
36
|
+
SeriesType,
|
|
37
|
+
StatementType,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
from .cache import Cache
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _market_data_row_parser(row):
|
|
44
|
+
if row.get("close") is None and (bid := row.get("bid")) is not None and (ask := row.get("ask")) is not None:
|
|
45
|
+
price = (bid + ask) / 2
|
|
46
|
+
row["close"] = price
|
|
47
|
+
row["open"] = price
|
|
48
|
+
row["low"] = price
|
|
49
|
+
row["high"] = price
|
|
50
|
+
return row
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class InstrumentDataloaderProxy(
|
|
54
|
+
DataloaderProxy[
|
|
55
|
+
AdjustmentsProtocol
|
|
56
|
+
| MarketDataProtocol
|
|
57
|
+
| CorporateActionsProtocol
|
|
58
|
+
| OfficersProtocol
|
|
59
|
+
| StatementsProtocol
|
|
60
|
+
| FinancialsProtocol
|
|
61
|
+
| ReportDateProtocol
|
|
62
|
+
| ESGControversyProtocol
|
|
63
|
+
| ESGProtocol
|
|
64
|
+
]
|
|
65
|
+
):
|
|
66
|
+
def reporting_dates(self, only_next: bool = True) -> Iterator[ReportDateDataDict]:
|
|
67
|
+
for dl in self.iterate_dataloaders("reporting_dates"):
|
|
68
|
+
yield from dl.reporting_dates(only_next=only_next)
|
|
69
|
+
|
|
70
|
+
def adjustments(self, from_date: date, to_date: date) -> Iterator[AdjustmentDataDict]:
|
|
71
|
+
for dl in self.iterate_dataloaders("adjustments"):
|
|
72
|
+
yield from dl.adjustments(from_date=from_date, to_date=to_date)
|
|
73
|
+
|
|
74
|
+
def market_data(
|
|
75
|
+
self,
|
|
76
|
+
values: list[MarketData] | None = None,
|
|
77
|
+
from_date: date | None = None,
|
|
78
|
+
to_date: date | None = None,
|
|
79
|
+
exact_date: date | None = None,
|
|
80
|
+
frequency: Frequency = Frequency.DAILY,
|
|
81
|
+
target_currency: str | None = None,
|
|
82
|
+
) -> Iterator[MarketDataDict]:
|
|
83
|
+
if not values:
|
|
84
|
+
values = list(MarketData)
|
|
85
|
+
for dl in self.iterate_dataloaders("market_data"):
|
|
86
|
+
yield from map(
|
|
87
|
+
lambda row: _market_data_row_parser(row),
|
|
88
|
+
dl.market_data(
|
|
89
|
+
values=values,
|
|
90
|
+
from_date=from_date,
|
|
91
|
+
to_date=to_date,
|
|
92
|
+
exact_date=exact_date,
|
|
93
|
+
frequency=frequency,
|
|
94
|
+
target_currency=target_currency,
|
|
95
|
+
),
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
def corporate_actions(
|
|
99
|
+
self, from_date: date | None = None, to_date: date | None = None
|
|
100
|
+
) -> Iterator[CorporateActionDataDict]:
|
|
101
|
+
for dl in self.iterate_dataloaders("corporate_actions"):
|
|
102
|
+
yield from dl.corporate_actions(from_date=from_date, to_date=to_date)
|
|
103
|
+
|
|
104
|
+
def officers(self) -> Iterator[OfficerDataDict]:
|
|
105
|
+
for dl in self.iterate_dataloaders("officers"):
|
|
106
|
+
yield from dl.officers()
|
|
107
|
+
|
|
108
|
+
def statements(
|
|
109
|
+
self,
|
|
110
|
+
statement_type: StatementType | None = None,
|
|
111
|
+
from_date: date | None = None,
|
|
112
|
+
to_date: date | None = None,
|
|
113
|
+
from_year: int | None = None,
|
|
114
|
+
to_year: int | None = None,
|
|
115
|
+
period_type: PeriodType = PeriodType.ALL,
|
|
116
|
+
data_type: DataType = DataType.STANDARDIZED,
|
|
117
|
+
financials: list[Financial] | None = None,
|
|
118
|
+
target_currency: str | None = None,
|
|
119
|
+
) -> Iterator[StatementDataDict]:
|
|
120
|
+
for dl in self.iterate_dataloaders("statements"):
|
|
121
|
+
yield from dl.statements(
|
|
122
|
+
statement_type=statement_type,
|
|
123
|
+
from_date=from_date,
|
|
124
|
+
to_date=to_date,
|
|
125
|
+
from_year=from_year,
|
|
126
|
+
to_year=to_year,
|
|
127
|
+
period_type=period_type,
|
|
128
|
+
data_type=data_type,
|
|
129
|
+
financials=financials,
|
|
130
|
+
target_currency=target_currency,
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
def financials(
|
|
134
|
+
self,
|
|
135
|
+
values: list[Financial],
|
|
136
|
+
from_date: date | None = None,
|
|
137
|
+
to_date: date | None = None,
|
|
138
|
+
from_year: int | None = None,
|
|
139
|
+
to_year: int | None = None,
|
|
140
|
+
from_index: int | None = None,
|
|
141
|
+
to_index: int | None = None,
|
|
142
|
+
from_valid: date | None = None,
|
|
143
|
+
to_valid: date | None = None,
|
|
144
|
+
period_type: PeriodType = PeriodType.ANNUAL,
|
|
145
|
+
calendar_type: CalendarType = CalendarType.FISCAL,
|
|
146
|
+
series_type: SeriesType = SeriesType.COMPLETE,
|
|
147
|
+
data_type: DataType = DataType.STANDARDIZED,
|
|
148
|
+
estimate_type: EstimateType = EstimateType.VALID,
|
|
149
|
+
target_currency: str | None = None,
|
|
150
|
+
) -> Iterator[FinancialDataDict]:
|
|
151
|
+
for dl in self.iterate_dataloaders("financials"):
|
|
152
|
+
yield from dl.financials(
|
|
153
|
+
values=values,
|
|
154
|
+
from_date=from_date,
|
|
155
|
+
to_date=to_date,
|
|
156
|
+
from_year=from_year,
|
|
157
|
+
to_year=to_year,
|
|
158
|
+
from_index=from_index,
|
|
159
|
+
to_index=to_index,
|
|
160
|
+
from_valid=from_valid,
|
|
161
|
+
to_valid=to_valid,
|
|
162
|
+
period_type=period_type,
|
|
163
|
+
calendar_type=calendar_type,
|
|
164
|
+
series_type=series_type,
|
|
165
|
+
data_type=data_type,
|
|
166
|
+
estimate_type=estimate_type,
|
|
167
|
+
target_currency=target_currency,
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
def esg_controversies(self) -> Iterator[ESGControversyDataDict]:
|
|
171
|
+
for dl in self.iterate_dataloaders("esg_controversies"):
|
|
172
|
+
yield from dl.esg_controversies()
|
|
173
|
+
|
|
174
|
+
def esg(
|
|
175
|
+
self,
|
|
176
|
+
values: list[ESG],
|
|
177
|
+
) -> Iterator[ESGDataDict]:
|
|
178
|
+
for dl in self.iterate_dataloaders("esg"):
|
|
179
|
+
if (
|
|
180
|
+
(cache_identifier_key := getattr(dl, "CACHE_IDENTIFIER_KEY", None))
|
|
181
|
+
and (cache_symbol_key := getattr(dl, "CACHE_SYMBOL_KEY", None))
|
|
182
|
+
and (cache_value_key := getattr(dl, "CACHE_VALUE_KEY", None))
|
|
183
|
+
):
|
|
184
|
+
cache = Cache(
|
|
185
|
+
identifier_key=cache_identifier_key,
|
|
186
|
+
symbol_key=cache_symbol_key,
|
|
187
|
+
value_key=cache_value_key,
|
|
188
|
+
timeout=getattr(dl, "CACHE_TIMEOUT", 10 * 24 * 3600), # default to 10days
|
|
189
|
+
)
|
|
190
|
+
cache.initialize(dl.entity_ids, [v.value for v in values])
|
|
191
|
+
|
|
192
|
+
yield from cache.fetch_from_cache()
|
|
193
|
+
if len(cache.missing_symbols) > 0 and len(cache.missing_ids) > 0:
|
|
194
|
+
dl.entities = dl.entities.filter(id__in=cache.missing_ids)
|
|
195
|
+
yield from map(
|
|
196
|
+
lambda row: cache.write(row),
|
|
197
|
+
dl.esg(values=[v for v in values if v.value in cache.missing_symbols]),
|
|
198
|
+
)
|
|
199
|
+
cache.close()
|
|
200
|
+
else:
|
|
201
|
+
yield from dl.esg(values=values)
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
from datetime import date
|
|
2
|
+
from typing import Literal, TypedDict
|
|
3
|
+
|
|
4
|
+
from typing_extensions import NotRequired
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class BaseDict(TypedDict):
|
|
8
|
+
"""
|
|
9
|
+
Represents a base dictionary with common fields.
|
|
10
|
+
|
|
11
|
+
Attributes:
|
|
12
|
+
id: str | int
|
|
13
|
+
The unique identifier.
|
|
14
|
+
external_id: str | int
|
|
15
|
+
The external identifier.
|
|
16
|
+
source: str
|
|
17
|
+
The source of the data.
|
|
18
|
+
currency: str
|
|
19
|
+
The currency used.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
id: str | int
|
|
23
|
+
instrument_id: int
|
|
24
|
+
external_id: str | int
|
|
25
|
+
source: str
|
|
26
|
+
currency: NotRequired[str]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class MarketDataDict(BaseDict):
|
|
30
|
+
"""
|
|
31
|
+
Represents a dictionary for daily valuation data.
|
|
32
|
+
|
|
33
|
+
Attributes:
|
|
34
|
+
valuation_date: date
|
|
35
|
+
The date of valuation.
|
|
36
|
+
open: float | None
|
|
37
|
+
The opening value (if available).
|
|
38
|
+
close: float | None
|
|
39
|
+
The closing value (if available).
|
|
40
|
+
high: float | None
|
|
41
|
+
The highest value (if available).
|
|
42
|
+
low: float | None
|
|
43
|
+
The lowest value (if available).
|
|
44
|
+
bid: float | None
|
|
45
|
+
The bid value (if available).
|
|
46
|
+
ask: float | None
|
|
47
|
+
The ask value (if available).
|
|
48
|
+
volume: float | None
|
|
49
|
+
The volume (if available).
|
|
50
|
+
market_cap: float | None
|
|
51
|
+
The market capitalization (if available).
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
valuation_date: date
|
|
55
|
+
|
|
56
|
+
open: NotRequired[float]
|
|
57
|
+
close: NotRequired[float]
|
|
58
|
+
high: NotRequired[float]
|
|
59
|
+
low: NotRequired[float]
|
|
60
|
+
bid: NotRequired[float]
|
|
61
|
+
ask: NotRequired[float]
|
|
62
|
+
volume: NotRequired[float]
|
|
63
|
+
market_cap: NotRequired[float]
|
|
64
|
+
calculated: NotRequired[bool]
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class CorporateActionDataDict(BaseDict):
|
|
68
|
+
old_shares: float
|
|
69
|
+
new_shares: float
|
|
70
|
+
|
|
71
|
+
action_code: str
|
|
72
|
+
event_code: str
|
|
73
|
+
valuation_date: date
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class AdjustmentDataDict(BaseDict):
|
|
77
|
+
adjustment_factor: float
|
|
78
|
+
cumulative_adjustment_factor: float
|
|
79
|
+
|
|
80
|
+
adjustment_date: date
|
|
81
|
+
adjustment_end_date: date
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class FinancialDataDict(BaseDict):
|
|
85
|
+
"""
|
|
86
|
+
Represents a dictionary for financial data.
|
|
87
|
+
|
|
88
|
+
Attributes:
|
|
89
|
+
period_end_date: date
|
|
90
|
+
The period end date / The reporting date
|
|
91
|
+
valid_until: date | None
|
|
92
|
+
The validity date (if available).
|
|
93
|
+
fiscal_year: int
|
|
94
|
+
The fiscal year.
|
|
95
|
+
interim: int
|
|
96
|
+
The interim period. 0 means yearly data.
|
|
97
|
+
estimate: bool
|
|
98
|
+
Indicates if the data is an estimate or actual data
|
|
99
|
+
reported: bool
|
|
100
|
+
Indicates if the data is reported or standardized
|
|
101
|
+
value: str | float | int
|
|
102
|
+
The value.
|
|
103
|
+
financial: str
|
|
104
|
+
The type of financial data.
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
valid_until: NotRequired[date]
|
|
108
|
+
year: int
|
|
109
|
+
interim: int
|
|
110
|
+
estimate: NotRequired[bool]
|
|
111
|
+
# reported: bool
|
|
112
|
+
|
|
113
|
+
value: str | float | int
|
|
114
|
+
financial: str
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
class StatementDataDict(BaseDict):
|
|
118
|
+
"""
|
|
119
|
+
Represents a dictionary for statement data
|
|
120
|
+
|
|
121
|
+
Attributes:
|
|
122
|
+
external_code: str
|
|
123
|
+
The code that is used by the data vendor to identify this type of financial
|
|
124
|
+
external_ordering: int
|
|
125
|
+
The ordering that is supplied by the data vendor to sort this financial
|
|
126
|
+
external_description: str
|
|
127
|
+
The description supplied by the data vendor to describe this financial
|
|
128
|
+
period_end_date: date
|
|
129
|
+
The period end date / The reporting date
|
|
130
|
+
year: int
|
|
131
|
+
The financial year of the statement.
|
|
132
|
+
interim: int
|
|
133
|
+
The interim period. 0 means yearly data.
|
|
134
|
+
reported: bool
|
|
135
|
+
Indicates if the data is reported or standardized.
|
|
136
|
+
value: float | int
|
|
137
|
+
The value of the datapoint of the statement.
|
|
138
|
+
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
external_code: str
|
|
142
|
+
external_ordering: int
|
|
143
|
+
external_description: str
|
|
144
|
+
|
|
145
|
+
period_end_date: date
|
|
146
|
+
year: int
|
|
147
|
+
interim: int
|
|
148
|
+
value: float | int
|
|
149
|
+
reported: bool
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
class ReportDateDataDict(TypedDict):
|
|
153
|
+
instrument_id: int
|
|
154
|
+
external_id: int
|
|
155
|
+
source: str
|
|
156
|
+
period_end_date: date
|
|
157
|
+
is_interim: bool
|
|
158
|
+
start_date: date
|
|
159
|
+
end_date: date
|
|
160
|
+
market_phase: Literal["before_market"] | Literal["after_market"] | None
|
|
161
|
+
status: Literal["confirmed"] | Literal["tentative"]
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
class OfficerDataDict(TypedDict):
|
|
165
|
+
"""
|
|
166
|
+
Represents a dictionary for officers
|
|
167
|
+
|
|
168
|
+
Attributes:
|
|
169
|
+
instrument_id: int
|
|
170
|
+
An identifier to uniquely identify the instrument linked to an officer
|
|
171
|
+
position: str
|
|
172
|
+
The title of the position
|
|
173
|
+
name: str
|
|
174
|
+
The name of the officer
|
|
175
|
+
age: int
|
|
176
|
+
The current age of the officer
|
|
177
|
+
sex: "M" | "F"
|
|
178
|
+
Indicates the sex of the officer
|
|
179
|
+
start: date
|
|
180
|
+
The date when the officer started the position
|
|
181
|
+
"""
|
|
182
|
+
|
|
183
|
+
instrument_id: int
|
|
184
|
+
position: str
|
|
185
|
+
name: str
|
|
186
|
+
age: int
|
|
187
|
+
sex: Literal["M"] | Literal["F"]
|
|
188
|
+
start: date
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
class ESGDataDict(TypedDict):
|
|
192
|
+
instrument_id: int
|
|
193
|
+
factor_code: str
|
|
194
|
+
value: str | float | int | None
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
class ESGControversyDataDict(TypedDict):
|
|
198
|
+
id: str | int
|
|
199
|
+
instrument_id: str
|
|
200
|
+
headline: str
|
|
201
|
+
narrative: str
|
|
202
|
+
source: str
|
|
203
|
+
response: str
|
|
204
|
+
status: str | None # TODO: Move to enum?
|
|
205
|
+
type: str | None # TODO: Move to enum?
|
|
206
|
+
assessment: str | None # TODO: Move to enum?
|
|
207
|
+
review: date | None
|
|
208
|
+
initiated: date | None
|
|
209
|
+
flag: str | None # TODO: Move to enum?
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from datetime import date
|
|
2
|
+
|
|
3
|
+
from dynamic_preferences.preferences import Section
|
|
4
|
+
from dynamic_preferences.registries import global_preferences_registry
|
|
5
|
+
from dynamic_preferences.types import DatePreference, IntPreference, StringPreference
|
|
6
|
+
|
|
7
|
+
fdm = Section("wbfdm")
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@global_preferences_registry.register
|
|
11
|
+
class DefaultClassificationGroup(IntPreference):
|
|
12
|
+
section = fdm
|
|
13
|
+
name = "default_classification_group"
|
|
14
|
+
default = 0
|
|
15
|
+
|
|
16
|
+
verbose_name = "Default Classification Group"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@global_preferences_registry.register
|
|
20
|
+
class DefaultStartDateHistoricalImport(DatePreference):
|
|
21
|
+
section = fdm
|
|
22
|
+
name = "default_start_date_historical_import"
|
|
23
|
+
default = date(2015, 1, 1)
|
|
24
|
+
|
|
25
|
+
verbose_name = "Default Start Date"
|
|
26
|
+
help_text = "Default start date in historical import"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@global_preferences_registry.register
|
|
30
|
+
class NonTickerWords(StringPreference):
|
|
31
|
+
section = fdm
|
|
32
|
+
name = "non_ticker_words"
|
|
33
|
+
default = ""
|
|
34
|
+
|
|
35
|
+
verbose_name = "Non Ticker Words"
|
|
36
|
+
help_text = "Comma Separated list of non-ticker words"
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class FinancialSummarySectionName(StringPreference):
|
|
40
|
+
section = fdm
|
|
41
|
+
name = "financial_summary_section_name"
|
|
42
|
+
default = "Financial Summary"
|
|
43
|
+
|
|
44
|
+
verbose_name = "Financial Summary Section Name"
|
|
45
|
+
help_text = "This name set the tab section name shown from the instance view"
|