wbfdm 2.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of wbfdm might be problematic. Click here for more details.

Files changed (350) hide show
  1. wbfdm-2.2.1/.gitignore +181 -0
  2. wbfdm-2.2.1/PKG-INFO +15 -0
  3. wbfdm-2.2.1/pyproject.toml +43 -0
  4. wbfdm-2.2.1/wbfdm/__init__.py +2 -0
  5. wbfdm-2.2.1/wbfdm/admin/__init__.py +42 -0
  6. wbfdm-2.2.1/wbfdm/admin/classifications.py +39 -0
  7. wbfdm-2.2.1/wbfdm/admin/esg.py +23 -0
  8. wbfdm-2.2.1/wbfdm/admin/exchanges.py +53 -0
  9. wbfdm-2.2.1/wbfdm/admin/instrument_lists.py +23 -0
  10. wbfdm-2.2.1/wbfdm/admin/instrument_prices.py +62 -0
  11. wbfdm-2.2.1/wbfdm/admin/instrument_requests.py +33 -0
  12. wbfdm-2.2.1/wbfdm/admin/instruments.py +117 -0
  13. wbfdm-2.2.1/wbfdm/admin/instruments_relationships.py +25 -0
  14. wbfdm-2.2.1/wbfdm/admin/options.py +101 -0
  15. wbfdm-2.2.1/wbfdm/analysis/__init__.py +2 -0
  16. wbfdm-2.2.1/wbfdm/analysis/esg/__init__.py +0 -0
  17. wbfdm-2.2.1/wbfdm/analysis/esg/enums.py +82 -0
  18. wbfdm-2.2.1/wbfdm/analysis/esg/esg_analysis.py +217 -0
  19. wbfdm-2.2.1/wbfdm/analysis/esg/utils.py +13 -0
  20. wbfdm-2.2.1/wbfdm/analysis/financial_analysis/__init__.py +1 -0
  21. wbfdm-2.2.1/wbfdm/analysis/financial_analysis/financial_metric_analysis.py +88 -0
  22. wbfdm-2.2.1/wbfdm/analysis/financial_analysis/financial_ratio_analysis.py +125 -0
  23. wbfdm-2.2.1/wbfdm/analysis/financial_analysis/financial_statistics_analysis.py +271 -0
  24. wbfdm-2.2.1/wbfdm/analysis/financial_analysis/statement_with_estimates.py +558 -0
  25. wbfdm-2.2.1/wbfdm/analysis/financial_analysis/utils.py +316 -0
  26. wbfdm-2.2.1/wbfdm/analysis/technical_analysis/__init__.py +1 -0
  27. wbfdm-2.2.1/wbfdm/analysis/technical_analysis/technical_analysis.py +138 -0
  28. wbfdm-2.2.1/wbfdm/analysis/technical_analysis/traces.py +165 -0
  29. wbfdm-2.2.1/wbfdm/analysis/utils.py +32 -0
  30. wbfdm-2.2.1/wbfdm/apps.py +14 -0
  31. wbfdm-2.2.1/wbfdm/backends/dto.py +36 -0
  32. wbfdm-2.2.1/wbfdm/contrib/__init__.py +0 -0
  33. wbfdm-2.2.1/wbfdm/contrib/dsws/__init__.py +0 -0
  34. wbfdm-2.2.1/wbfdm/contrib/dsws/client.py +285 -0
  35. wbfdm-2.2.1/wbfdm/contrib/dsws/dataloaders/market_data.py +130 -0
  36. wbfdm-2.2.1/wbfdm/contrib/internal/__init__.py +0 -0
  37. wbfdm-2.2.1/wbfdm/contrib/internal/dataloaders/__init__.py +0 -0
  38. wbfdm-2.2.1/wbfdm/contrib/internal/dataloaders/market_data.py +87 -0
  39. wbfdm-2.2.1/wbfdm/contrib/metric/__init__.py +0 -0
  40. wbfdm-2.2.1/wbfdm/contrib/metric/admin/__init__.py +2 -0
  41. wbfdm-2.2.1/wbfdm/contrib/metric/admin/instruments.py +12 -0
  42. wbfdm-2.2.1/wbfdm/contrib/metric/admin/metrics.py +43 -0
  43. wbfdm-2.2.1/wbfdm/contrib/metric/apps.py +10 -0
  44. wbfdm-2.2.1/wbfdm/contrib/metric/backends/__init__.py +2 -0
  45. wbfdm-2.2.1/wbfdm/contrib/metric/backends/base.py +159 -0
  46. wbfdm-2.2.1/wbfdm/contrib/metric/backends/performances.py +265 -0
  47. wbfdm-2.2.1/wbfdm/contrib/metric/backends/statistics.py +182 -0
  48. wbfdm-2.2.1/wbfdm/contrib/metric/decorators.py +14 -0
  49. wbfdm-2.2.1/wbfdm/contrib/metric/dispatch.py +23 -0
  50. wbfdm-2.2.1/wbfdm/contrib/metric/dto.py +88 -0
  51. wbfdm-2.2.1/wbfdm/contrib/metric/exceptions.py +6 -0
  52. wbfdm-2.2.1/wbfdm/contrib/metric/factories.py +33 -0
  53. wbfdm-2.2.1/wbfdm/contrib/metric/filters.py +28 -0
  54. wbfdm-2.2.1/wbfdm/contrib/metric/migrations/0001_initial.py +88 -0
  55. wbfdm-2.2.1/wbfdm/contrib/metric/migrations/0002_remove_instrumentmetric_unique_instrument_metric_and_more.py +26 -0
  56. wbfdm-2.2.1/wbfdm/contrib/metric/migrations/__init__.py +0 -0
  57. wbfdm-2.2.1/wbfdm/contrib/metric/models.py +180 -0
  58. wbfdm-2.2.1/wbfdm/contrib/metric/orchestrators.py +94 -0
  59. wbfdm-2.2.1/wbfdm/contrib/metric/registry.py +80 -0
  60. wbfdm-2.2.1/wbfdm/contrib/metric/serializers.py +44 -0
  61. wbfdm-2.2.1/wbfdm/contrib/metric/tasks.py +27 -0
  62. wbfdm-2.2.1/wbfdm/contrib/metric/tests/__init__.py +0 -0
  63. wbfdm-2.2.1/wbfdm/contrib/metric/tests/backends/__init__.py +0 -0
  64. wbfdm-2.2.1/wbfdm/contrib/metric/tests/backends/test_performances.py +152 -0
  65. wbfdm-2.2.1/wbfdm/contrib/metric/tests/backends/test_statistics.py +48 -0
  66. wbfdm-2.2.1/wbfdm/contrib/metric/tests/conftest.py +92 -0
  67. wbfdm-2.2.1/wbfdm/contrib/metric/tests/test_dto.py +73 -0
  68. wbfdm-2.2.1/wbfdm/contrib/metric/tests/test_models.py +72 -0
  69. wbfdm-2.2.1/wbfdm/contrib/metric/tests/test_tasks.py +24 -0
  70. wbfdm-2.2.1/wbfdm/contrib/metric/tests/test_viewsets.py +79 -0
  71. wbfdm-2.2.1/wbfdm/contrib/metric/urls.py +19 -0
  72. wbfdm-2.2.1/wbfdm/contrib/metric/viewsets/__init__.py +1 -0
  73. wbfdm-2.2.1/wbfdm/contrib/metric/viewsets/configs/__init__.py +1 -0
  74. wbfdm-2.2.1/wbfdm/contrib/metric/viewsets/configs/display.py +92 -0
  75. wbfdm-2.2.1/wbfdm/contrib/metric/viewsets/configs/menus.py +11 -0
  76. wbfdm-2.2.1/wbfdm/contrib/metric/viewsets/configs/utils.py +137 -0
  77. wbfdm-2.2.1/wbfdm/contrib/metric/viewsets/mixins.py +245 -0
  78. wbfdm-2.2.1/wbfdm/contrib/metric/viewsets/viewsets.py +40 -0
  79. wbfdm-2.2.1/wbfdm/contrib/msci/__init__.py +0 -0
  80. wbfdm-2.2.1/wbfdm/contrib/msci/client.py +92 -0
  81. wbfdm-2.2.1/wbfdm/contrib/msci/dataloaders/__init__.py +0 -0
  82. wbfdm-2.2.1/wbfdm/contrib/msci/dataloaders/esg.py +87 -0
  83. wbfdm-2.2.1/wbfdm/contrib/msci/dataloaders/esg_controversies.py +81 -0
  84. wbfdm-2.2.1/wbfdm/contrib/msci/sync.py +58 -0
  85. wbfdm-2.2.1/wbfdm/contrib/msci/tests/__init__.py +0 -0
  86. wbfdm-2.2.1/wbfdm/contrib/msci/tests/conftest.py +1 -0
  87. wbfdm-2.2.1/wbfdm/contrib/msci/tests/test_client.py +70 -0
  88. wbfdm-2.2.1/wbfdm/contrib/qa/__init__.py +0 -0
  89. wbfdm-2.2.1/wbfdm/contrib/qa/apps.py +22 -0
  90. wbfdm-2.2.1/wbfdm/contrib/qa/database_routers.py +25 -0
  91. wbfdm-2.2.1/wbfdm/contrib/qa/dataloaders/__init__.py +0 -0
  92. wbfdm-2.2.1/wbfdm/contrib/qa/dataloaders/adjustments.py +56 -0
  93. wbfdm-2.2.1/wbfdm/contrib/qa/dataloaders/corporate_actions.py +59 -0
  94. wbfdm-2.2.1/wbfdm/contrib/qa/dataloaders/financials.py +83 -0
  95. wbfdm-2.2.1/wbfdm/contrib/qa/dataloaders/market_data.py +117 -0
  96. wbfdm-2.2.1/wbfdm/contrib/qa/dataloaders/officers.py +59 -0
  97. wbfdm-2.2.1/wbfdm/contrib/qa/dataloaders/reporting_dates.py +67 -0
  98. wbfdm-2.2.1/wbfdm/contrib/qa/dataloaders/statements.py +267 -0
  99. wbfdm-2.2.1/wbfdm/contrib/qa/jinja2/qa/sql/companies.sql +100 -0
  100. wbfdm-2.2.1/wbfdm/contrib/qa/jinja2/qa/sql/ibes/base_estimates.sql +33 -0
  101. wbfdm-2.2.1/wbfdm/contrib/qa/jinja2/qa/sql/ibes/calendarized.sql +37 -0
  102. wbfdm-2.2.1/wbfdm/contrib/qa/jinja2/qa/sql/ibes/complete.sql +9 -0
  103. wbfdm-2.2.1/wbfdm/contrib/qa/jinja2/qa/sql/ibes/estimates.sql +3 -0
  104. wbfdm-2.2.1/wbfdm/contrib/qa/jinja2/qa/sql/ibes/financials.sql +79 -0
  105. wbfdm-2.2.1/wbfdm/contrib/qa/jinja2/qa/sql/instruments.sql +100 -0
  106. wbfdm-2.2.1/wbfdm/contrib/qa/jinja2/qa/sql/quotes.sql +98 -0
  107. wbfdm-2.2.1/wbfdm/contrib/qa/sync/exchanges.py +70 -0
  108. wbfdm-2.2.1/wbfdm/contrib/qa/sync/instruments.py +94 -0
  109. wbfdm-2.2.1/wbfdm/contrib/qa/sync/utils.py +241 -0
  110. wbfdm-2.2.1/wbfdm/contrib/qa/tasks.py +0 -0
  111. wbfdm-2.2.1/wbfdm/dataloaders/__init__.py +0 -0
  112. wbfdm-2.2.1/wbfdm/dataloaders/cache.py +129 -0
  113. wbfdm-2.2.1/wbfdm/dataloaders/protocols.py +112 -0
  114. wbfdm-2.2.1/wbfdm/dataloaders/proxies.py +201 -0
  115. wbfdm-2.2.1/wbfdm/dataloaders/types.py +209 -0
  116. wbfdm-2.2.1/wbfdm/dynamic_preferences_registry.py +45 -0
  117. wbfdm-2.2.1/wbfdm/enums.py +657 -0
  118. wbfdm-2.2.1/wbfdm/factories/__init__.py +13 -0
  119. wbfdm-2.2.1/wbfdm/factories/classifications.py +56 -0
  120. wbfdm-2.2.1/wbfdm/factories/controversies.py +27 -0
  121. wbfdm-2.2.1/wbfdm/factories/exchanges.py +21 -0
  122. wbfdm-2.2.1/wbfdm/factories/instrument_list.py +22 -0
  123. wbfdm-2.2.1/wbfdm/factories/instrument_prices.py +79 -0
  124. wbfdm-2.2.1/wbfdm/factories/instruments.py +63 -0
  125. wbfdm-2.2.1/wbfdm/factories/instruments_relationships.py +31 -0
  126. wbfdm-2.2.1/wbfdm/factories/options.py +66 -0
  127. wbfdm-2.2.1/wbfdm/figures/__init__.py +1 -0
  128. wbfdm-2.2.1/wbfdm/figures/financials/__init__.py +1 -0
  129. wbfdm-2.2.1/wbfdm/figures/financials/financial_analysis_charts.py +469 -0
  130. wbfdm-2.2.1/wbfdm/figures/financials/financials_charts.py +711 -0
  131. wbfdm-2.2.1/wbfdm/filters/__init__.py +31 -0
  132. wbfdm-2.2.1/wbfdm/filters/classifications.py +100 -0
  133. wbfdm-2.2.1/wbfdm/filters/exchanges.py +22 -0
  134. wbfdm-2.2.1/wbfdm/filters/financials.py +95 -0
  135. wbfdm-2.2.1/wbfdm/filters/financials_analysis.py +119 -0
  136. wbfdm-2.2.1/wbfdm/filters/instrument_prices.py +112 -0
  137. wbfdm-2.2.1/wbfdm/filters/instruments.py +198 -0
  138. wbfdm-2.2.1/wbfdm/filters/utils.py +44 -0
  139. wbfdm-2.2.1/wbfdm/import_export/__init__.py +0 -0
  140. wbfdm-2.2.1/wbfdm/import_export/backends/__init__.py +0 -0
  141. wbfdm-2.2.1/wbfdm/import_export/backends/cbinsights/__init__.py +2 -0
  142. wbfdm-2.2.1/wbfdm/import_export/backends/cbinsights/deals.py +44 -0
  143. wbfdm-2.2.1/wbfdm/import_export/backends/cbinsights/equities.py +41 -0
  144. wbfdm-2.2.1/wbfdm/import_export/backends/cbinsights/mixin.py +15 -0
  145. wbfdm-2.2.1/wbfdm/import_export/backends/cbinsights/utils/__init__.py +0 -0
  146. wbfdm-2.2.1/wbfdm/import_export/backends/cbinsights/utils/classifications.py +4150 -0
  147. wbfdm-2.2.1/wbfdm/import_export/backends/cbinsights/utils/client.py +217 -0
  148. wbfdm-2.2.1/wbfdm/import_export/backends/refinitiv/__init__.py +5 -0
  149. wbfdm-2.2.1/wbfdm/import_export/backends/refinitiv/daily_fundamental.py +36 -0
  150. wbfdm-2.2.1/wbfdm/import_export/backends/refinitiv/fiscal_period.py +63 -0
  151. wbfdm-2.2.1/wbfdm/import_export/backends/refinitiv/forecast.py +178 -0
  152. wbfdm-2.2.1/wbfdm/import_export/backends/refinitiv/fundamental.py +103 -0
  153. wbfdm-2.2.1/wbfdm/import_export/backends/refinitiv/geographic_segment.py +32 -0
  154. wbfdm-2.2.1/wbfdm/import_export/backends/refinitiv/instrument.py +55 -0
  155. wbfdm-2.2.1/wbfdm/import_export/backends/refinitiv/instrument_price.py +77 -0
  156. wbfdm-2.2.1/wbfdm/import_export/backends/refinitiv/mixin.py +29 -0
  157. wbfdm-2.2.1/wbfdm/import_export/backends/refinitiv/utils/__init__.py +1 -0
  158. wbfdm-2.2.1/wbfdm/import_export/backends/refinitiv/utils/controller.py +182 -0
  159. wbfdm-2.2.1/wbfdm/import_export/handlers/__init__.py +0 -0
  160. wbfdm-2.2.1/wbfdm/import_export/handlers/instrument.py +253 -0
  161. wbfdm-2.2.1/wbfdm/import_export/handlers/instrument_list.py +101 -0
  162. wbfdm-2.2.1/wbfdm/import_export/handlers/instrument_price.py +71 -0
  163. wbfdm-2.2.1/wbfdm/import_export/handlers/option.py +54 -0
  164. wbfdm-2.2.1/wbfdm/import_export/handlers/private_equities.py +49 -0
  165. wbfdm-2.2.1/wbfdm/import_export/parsers/__init__.py +0 -0
  166. wbfdm-2.2.1/wbfdm/import_export/parsers/cbinsights/__init__.py +0 -0
  167. wbfdm-2.2.1/wbfdm/import_export/parsers/cbinsights/deals.py +39 -0
  168. wbfdm-2.2.1/wbfdm/import_export/parsers/cbinsights/equities.py +56 -0
  169. wbfdm-2.2.1/wbfdm/import_export/parsers/cbinsights/fundamentals.py +45 -0
  170. wbfdm-2.2.1/wbfdm/import_export/parsers/refinitiv/__init__.py +0 -0
  171. wbfdm-2.2.1/wbfdm/import_export/parsers/refinitiv/daily_fundamental.py +7 -0
  172. wbfdm-2.2.1/wbfdm/import_export/parsers/refinitiv/forecast.py +7 -0
  173. wbfdm-2.2.1/wbfdm/import_export/parsers/refinitiv/fundamental.py +9 -0
  174. wbfdm-2.2.1/wbfdm/import_export/parsers/refinitiv/geographic_segment.py +7 -0
  175. wbfdm-2.2.1/wbfdm/import_export/parsers/refinitiv/instrument.py +75 -0
  176. wbfdm-2.2.1/wbfdm/import_export/parsers/refinitiv/instrument_price.py +26 -0
  177. wbfdm-2.2.1/wbfdm/import_export/parsers/refinitiv/utils.py +96 -0
  178. wbfdm-2.2.1/wbfdm/import_export/resources/__init__.py +0 -0
  179. wbfdm-2.2.1/wbfdm/import_export/resources/classification.py +23 -0
  180. wbfdm-2.2.1/wbfdm/import_export/resources/instrument_prices.py +33 -0
  181. wbfdm-2.2.1/wbfdm/import_export/resources/instruments.py +176 -0
  182. wbfdm-2.2.1/wbfdm/jinja2.py +7 -0
  183. wbfdm-2.2.1/wbfdm/management/__init__.py +30 -0
  184. wbfdm-2.2.1/wbfdm/menu.py +11 -0
  185. wbfdm-2.2.1/wbfdm/migrations/0001_initial.py +71 -0
  186. wbfdm-2.2.1/wbfdm/migrations/0002_rename_statements_instrumentlookup_financials_and_more.py +144 -0
  187. wbfdm-2.2.1/wbfdm/migrations/0003_instrument_estimate_backend_and_more.py +34 -0
  188. wbfdm-2.2.1/wbfdm/migrations/0004_rename_financials_instrumentlookup_statements_and_more.py +86 -0
  189. wbfdm-2.2.1/wbfdm/migrations/0005_instrument_corporate_action_backend.py +29 -0
  190. wbfdm-2.2.1/wbfdm/migrations/0006_instrument_officer_backend.py +29 -0
  191. wbfdm-2.2.1/wbfdm/migrations/0007_instrument_country_instrument_currency_and_more.py +117 -0
  192. wbfdm-2.2.1/wbfdm/migrations/0008_controversy.py +75 -0
  193. wbfdm-2.2.1/wbfdm/migrations/0009_alter_controversy_flag_alter_controversy_initiated_and_more.py +85 -0
  194. wbfdm-2.2.1/wbfdm/migrations/0010_classification_classificationgroup_deal_exchange_and_more.py +1299 -0
  195. wbfdm-2.2.1/wbfdm/migrations/0011_delete_instrumentlookup_instrument_corporate_actions_and_more.py +169 -0
  196. wbfdm-2.2.1/wbfdm/migrations/0012_instrumentprice_created_instrumentprice_modified.py +564 -0
  197. wbfdm-2.2.1/wbfdm/migrations/0013_instrument_is_investable_universe_and_more.py +199 -0
  198. wbfdm-2.2.1/wbfdm/migrations/0014_alter_controversy_instrument.py +22 -0
  199. wbfdm-2.2.1/wbfdm/migrations/0015_instrument_instrument_investible_index.py +16 -0
  200. wbfdm-2.2.1/wbfdm/migrations/0016_instrumenttype_name_repr.py +18 -0
  201. wbfdm-2.2.1/wbfdm/migrations/0017_instrument_instrument_security_index.py +16 -0
  202. wbfdm-2.2.1/wbfdm/migrations/0018_instrument_instrument_level_index.py +20 -0
  203. wbfdm-2.2.1/wbfdm/migrations/0019_alter_controversy_source.py +17 -0
  204. wbfdm-2.2.1/wbfdm/migrations/0020_optionaggregate_option_and_more.py +249 -0
  205. wbfdm-2.2.1/wbfdm/migrations/0021_delete_instrumentdailystatistics.py +15 -0
  206. wbfdm-2.2.1/wbfdm/migrations/0022_instrument_cusip_option_open_interest_20d_and_more.py +91 -0
  207. wbfdm-2.2.1/wbfdm/migrations/0023_instrument_unique_ric_instrument_unique_rmc_and_more.py +53 -0
  208. wbfdm-2.2.1/wbfdm/migrations/0024_option_open_interest_10d_option_volume_10d_and_more.py +36 -0
  209. wbfdm-2.2.1/wbfdm/migrations/0025_instrument_is_primary_and_more.py +29 -0
  210. wbfdm-2.2.1/wbfdm/migrations/0026_instrument_is_cash_equivalent.py +30 -0
  211. wbfdm-2.2.1/wbfdm/migrations/0027_remove_instrument_unique_ric_and_more.py +100 -0
  212. wbfdm-2.2.1/wbfdm/migrations/__init__.py +0 -0
  213. wbfdm-2.2.1/wbfdm/models/__init__.py +4 -0
  214. wbfdm-2.2.1/wbfdm/models/esg/__init__.py +1 -0
  215. wbfdm-2.2.1/wbfdm/models/esg/controversies.py +81 -0
  216. wbfdm-2.2.1/wbfdm/models/exchanges/__init__.py +1 -0
  217. wbfdm-2.2.1/wbfdm/models/exchanges/exchanges.py +223 -0
  218. wbfdm-2.2.1/wbfdm/models/fields.py +117 -0
  219. wbfdm-2.2.1/wbfdm/models/fk_fields.py +403 -0
  220. wbfdm-2.2.1/wbfdm/models/indicators.py +0 -0
  221. wbfdm-2.2.1/wbfdm/models/instruments/__init__.py +19 -0
  222. wbfdm-2.2.1/wbfdm/models/instruments/classifications.py +265 -0
  223. wbfdm-2.2.1/wbfdm/models/instruments/instrument_lists.py +120 -0
  224. wbfdm-2.2.1/wbfdm/models/instruments/instrument_prices.py +540 -0
  225. wbfdm-2.2.1/wbfdm/models/instruments/instrument_relationships.py +251 -0
  226. wbfdm-2.2.1/wbfdm/models/instruments/instrument_requests.py +196 -0
  227. wbfdm-2.2.1/wbfdm/models/instruments/instruments.py +991 -0
  228. wbfdm-2.2.1/wbfdm/models/instruments/llm/__init__.py +1 -0
  229. wbfdm-2.2.1/wbfdm/models/instruments/llm/create_instrument_news_relationships.py +78 -0
  230. wbfdm-2.2.1/wbfdm/models/instruments/mixin/__init__.py +0 -0
  231. wbfdm-2.2.1/wbfdm/models/instruments/mixin/financials_computed.py +804 -0
  232. wbfdm-2.2.1/wbfdm/models/instruments/mixin/financials_serializer_fields.py +1407 -0
  233. wbfdm-2.2.1/wbfdm/models/instruments/mixin/instruments.py +294 -0
  234. wbfdm-2.2.1/wbfdm/models/instruments/options.py +225 -0
  235. wbfdm-2.2.1/wbfdm/models/instruments/private_equities.py +59 -0
  236. wbfdm-2.2.1/wbfdm/models/instruments/querysets.py +73 -0
  237. wbfdm-2.2.1/wbfdm/models/instruments/utils.py +41 -0
  238. wbfdm-2.2.1/wbfdm/preferences.py +21 -0
  239. wbfdm-2.2.1/wbfdm/serializers/__init__.py +4 -0
  240. wbfdm-2.2.1/wbfdm/serializers/esg.py +36 -0
  241. wbfdm-2.2.1/wbfdm/serializers/exchanges.py +39 -0
  242. wbfdm-2.2.1/wbfdm/serializers/instruments/__init__.py +37 -0
  243. wbfdm-2.2.1/wbfdm/serializers/instruments/classifications.py +139 -0
  244. wbfdm-2.2.1/wbfdm/serializers/instruments/instrument_lists.py +61 -0
  245. wbfdm-2.2.1/wbfdm/serializers/instruments/instrument_prices.py +73 -0
  246. wbfdm-2.2.1/wbfdm/serializers/instruments/instrument_relationships.py +170 -0
  247. wbfdm-2.2.1/wbfdm/serializers/instruments/instrument_requests.py +61 -0
  248. wbfdm-2.2.1/wbfdm/serializers/instruments/instruments.py +274 -0
  249. wbfdm-2.2.1/wbfdm/serializers/instruments/mixins.py +104 -0
  250. wbfdm-2.2.1/wbfdm/serializers/officers.py +20 -0
  251. wbfdm-2.2.1/wbfdm/signals.py +7 -0
  252. wbfdm-2.2.1/wbfdm/sync/__init__.py +0 -0
  253. wbfdm-2.2.1/wbfdm/sync/abstract.py +31 -0
  254. wbfdm-2.2.1/wbfdm/sync/runner.py +22 -0
  255. wbfdm-2.2.1/wbfdm/tasks.py +69 -0
  256. wbfdm-2.2.1/wbfdm/tests/__init__.py +0 -0
  257. wbfdm-2.2.1/wbfdm/tests/analysis/__init__.py +0 -0
  258. wbfdm-2.2.1/wbfdm/tests/analysis/financial_analysis/__init__.py +0 -0
  259. wbfdm-2.2.1/wbfdm/tests/analysis/financial_analysis/test_statement_with_estimates.py +392 -0
  260. wbfdm-2.2.1/wbfdm/tests/analysis/financial_analysis/test_utils.py +322 -0
  261. wbfdm-2.2.1/wbfdm/tests/analysis/test_esg.py +159 -0
  262. wbfdm-2.2.1/wbfdm/tests/conftest.py +92 -0
  263. wbfdm-2.2.1/wbfdm/tests/dataloaders/__init__.py +0 -0
  264. wbfdm-2.2.1/wbfdm/tests/dataloaders/test_cache.py +73 -0
  265. wbfdm-2.2.1/wbfdm/tests/models/__init__.py +0 -0
  266. wbfdm-2.2.1/wbfdm/tests/models/test_classifications.py +99 -0
  267. wbfdm-2.2.1/wbfdm/tests/models/test_exchanges.py +7 -0
  268. wbfdm-2.2.1/wbfdm/tests/models/test_instrument_list.py +117 -0
  269. wbfdm-2.2.1/wbfdm/tests/models/test_instrument_prices.py +306 -0
  270. wbfdm-2.2.1/wbfdm/tests/models/test_instruments.py +202 -0
  271. wbfdm-2.2.1/wbfdm/tests/models/test_merge.py +99 -0
  272. wbfdm-2.2.1/wbfdm/tests/models/test_options.py +69 -0
  273. wbfdm-2.2.1/wbfdm/tests/test_tasks.py +6 -0
  274. wbfdm-2.2.1/wbfdm/tests/tests.py +10 -0
  275. wbfdm-2.2.1/wbfdm/urls.py +222 -0
  276. wbfdm-2.2.1/wbfdm/utils.py +54 -0
  277. wbfdm-2.2.1/wbfdm/viewsets/__init__.py +10 -0
  278. wbfdm-2.2.1/wbfdm/viewsets/configs/__init__.py +5 -0
  279. wbfdm-2.2.1/wbfdm/viewsets/configs/buttons/__init__.py +8 -0
  280. wbfdm-2.2.1/wbfdm/viewsets/configs/buttons/classifications.py +23 -0
  281. wbfdm-2.2.1/wbfdm/viewsets/configs/buttons/exchanges.py +9 -0
  282. wbfdm-2.2.1/wbfdm/viewsets/configs/buttons/instrument_prices.py +49 -0
  283. wbfdm-2.2.1/wbfdm/viewsets/configs/buttons/instruments.py +283 -0
  284. wbfdm-2.2.1/wbfdm/viewsets/configs/display/__init__.py +22 -0
  285. wbfdm-2.2.1/wbfdm/viewsets/configs/display/classifications.py +138 -0
  286. wbfdm-2.2.1/wbfdm/viewsets/configs/display/esg.py +75 -0
  287. wbfdm-2.2.1/wbfdm/viewsets/configs/display/exchanges.py +42 -0
  288. wbfdm-2.2.1/wbfdm/viewsets/configs/display/instrument_lists.py +137 -0
  289. wbfdm-2.2.1/wbfdm/viewsets/configs/display/instrument_prices.py +199 -0
  290. wbfdm-2.2.1/wbfdm/viewsets/configs/display/instrument_requests.py +116 -0
  291. wbfdm-2.2.1/wbfdm/viewsets/configs/display/instruments.py +618 -0
  292. wbfdm-2.2.1/wbfdm/viewsets/configs/display/instruments_relationships.py +65 -0
  293. wbfdm-2.2.1/wbfdm/viewsets/configs/display/monthly_performances.py +72 -0
  294. wbfdm-2.2.1/wbfdm/viewsets/configs/display/officers.py +16 -0
  295. wbfdm-2.2.1/wbfdm/viewsets/configs/display/prices.py +21 -0
  296. wbfdm-2.2.1/wbfdm/viewsets/configs/display/statement_with_estimates.py +101 -0
  297. wbfdm-2.2.1/wbfdm/viewsets/configs/display/statements.py +48 -0
  298. wbfdm-2.2.1/wbfdm/viewsets/configs/endpoints/__init__.py +41 -0
  299. wbfdm-2.2.1/wbfdm/viewsets/configs/endpoints/classifications.py +87 -0
  300. wbfdm-2.2.1/wbfdm/viewsets/configs/endpoints/esg.py +20 -0
  301. wbfdm-2.2.1/wbfdm/viewsets/configs/endpoints/exchanges.py +6 -0
  302. wbfdm-2.2.1/wbfdm/viewsets/configs/endpoints/financials_analysis.py +65 -0
  303. wbfdm-2.2.1/wbfdm/viewsets/configs/endpoints/instrument_lists.py +38 -0
  304. wbfdm-2.2.1/wbfdm/viewsets/configs/endpoints/instrument_prices.py +51 -0
  305. wbfdm-2.2.1/wbfdm/viewsets/configs/endpoints/instrument_requests.py +20 -0
  306. wbfdm-2.2.1/wbfdm/viewsets/configs/endpoints/instruments.py +13 -0
  307. wbfdm-2.2.1/wbfdm/viewsets/configs/endpoints/instruments_relationships.py +31 -0
  308. wbfdm-2.2.1/wbfdm/viewsets/configs/endpoints/statements.py +6 -0
  309. wbfdm-2.2.1/wbfdm/viewsets/configs/menus/__init__.py +9 -0
  310. wbfdm-2.2.1/wbfdm/viewsets/configs/menus/classifications.py +19 -0
  311. wbfdm-2.2.1/wbfdm/viewsets/configs/menus/exchanges.py +10 -0
  312. wbfdm-2.2.1/wbfdm/viewsets/configs/menus/instrument_lists.py +10 -0
  313. wbfdm-2.2.1/wbfdm/viewsets/configs/menus/instruments.py +20 -0
  314. wbfdm-2.2.1/wbfdm/viewsets/configs/menus/instruments_relationships.py +33 -0
  315. wbfdm-2.2.1/wbfdm/viewsets/configs/titles/__init__.py +42 -0
  316. wbfdm-2.2.1/wbfdm/viewsets/configs/titles/classifications.py +79 -0
  317. wbfdm-2.2.1/wbfdm/viewsets/configs/titles/esg.py +11 -0
  318. wbfdm-2.2.1/wbfdm/viewsets/configs/titles/exchanges.py +12 -0
  319. wbfdm-2.2.1/wbfdm/viewsets/configs/titles/financial_ratio_analysis.py +6 -0
  320. wbfdm-2.2.1/wbfdm/viewsets/configs/titles/financials_analysis.py +50 -0
  321. wbfdm-2.2.1/wbfdm/viewsets/configs/titles/instrument_prices.py +50 -0
  322. wbfdm-2.2.1/wbfdm/viewsets/configs/titles/instrument_requests.py +16 -0
  323. wbfdm-2.2.1/wbfdm/viewsets/configs/titles/instruments.py +31 -0
  324. wbfdm-2.2.1/wbfdm/viewsets/configs/titles/instruments_relationships.py +21 -0
  325. wbfdm-2.2.1/wbfdm/viewsets/configs/titles/market_data.py +13 -0
  326. wbfdm-2.2.1/wbfdm/viewsets/configs/titles/prices.py +15 -0
  327. wbfdm-2.2.1/wbfdm/viewsets/configs/titles/statement_with_estimates.py +10 -0
  328. wbfdm-2.2.1/wbfdm/viewsets/esg.py +72 -0
  329. wbfdm-2.2.1/wbfdm/viewsets/exchanges.py +63 -0
  330. wbfdm-2.2.1/wbfdm/viewsets/financial_analysis/__init__.py +3 -0
  331. wbfdm-2.2.1/wbfdm/viewsets/financial_analysis/financial_metric_analysis.py +85 -0
  332. wbfdm-2.2.1/wbfdm/viewsets/financial_analysis/financial_ratio_analysis.py +85 -0
  333. wbfdm-2.2.1/wbfdm/viewsets/financial_analysis/statement_with_estimates.py +145 -0
  334. wbfdm-2.2.1/wbfdm/viewsets/instruments/__init__.py +80 -0
  335. wbfdm-2.2.1/wbfdm/viewsets/instruments/classifications.py +279 -0
  336. wbfdm-2.2.1/wbfdm/viewsets/instruments/financials_analysis.py +614 -0
  337. wbfdm-2.2.1/wbfdm/viewsets/instruments/instrument_lists.py +77 -0
  338. wbfdm-2.2.1/wbfdm/viewsets/instruments/instrument_prices.py +542 -0
  339. wbfdm-2.2.1/wbfdm/viewsets/instruments/instrument_requests.py +51 -0
  340. wbfdm-2.2.1/wbfdm/viewsets/instruments/instruments.py +106 -0
  341. wbfdm-2.2.1/wbfdm/viewsets/instruments/instruments_relationships.py +235 -0
  342. wbfdm-2.2.1/wbfdm/viewsets/instruments/utils.py +27 -0
  343. wbfdm-2.2.1/wbfdm/viewsets/market_data.py +172 -0
  344. wbfdm-2.2.1/wbfdm/viewsets/mixins.py +9 -0
  345. wbfdm-2.2.1/wbfdm/viewsets/officers.py +27 -0
  346. wbfdm-2.2.1/wbfdm/viewsets/prices.py +62 -0
  347. wbfdm-2.2.1/wbfdm/viewsets/statements/__init__.py +1 -0
  348. wbfdm-2.2.1/wbfdm/viewsets/statements/statements.py +100 -0
  349. wbfdm-2.2.1/wbfdm/viewsets/technical_analysis/__init__.py +1 -0
  350. wbfdm-2.2.1/wbfdm/viewsets/technical_analysis/monthly_performances.py +93 -0
wbfdm-2.2.1/.gitignore ADDED
@@ -0,0 +1,181 @@
1
+ ~
2
+
3
+ # Docker volumes
4
+ volumes/
5
+ # Poetry auth file
6
+ auth.toml
7
+
8
+ media/*
9
+ media/
10
+ mediafiles/
11
+ mediafiles/*
12
+ test/*
13
+ staticfiles/*
14
+ staticfiles/
15
+ #
16
+ # Byte-compiled / optimized / DLL files
17
+ __pycache__/
18
+ *.py[cod]
19
+ *$py.class
20
+
21
+ # C extensions
22
+ *.so
23
+
24
+ # Distribution / packaging
25
+ .Python
26
+ build/
27
+ develop-eggs/
28
+ dist/
29
+ info/
30
+ downloads/
31
+ eggs/
32
+ .eggs/
33
+ lib/
34
+ lib64/
35
+ parts/
36
+ sdist/
37
+ var/
38
+ wheels/
39
+ share/python-wheels/
40
+ *.egg-info/
41
+ .installed.cfg
42
+ *.egg
43
+ MANIFEST
44
+
45
+ # PyInstaller
46
+ # Usually these files are written by a python script from a template
47
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
48
+ *.manifest
49
+ *.spec
50
+
51
+ # Installer logs
52
+ pip-log.txt
53
+ pip-delete-this-directory.txt
54
+
55
+ # Unit test / coverage reports
56
+ htmlcov/
57
+ .tox/
58
+ .nox/
59
+ .coverage
60
+ .coverage.*
61
+ .cache
62
+ .dccache
63
+ nosetests.xml
64
+ coverage.xml
65
+ *.cover
66
+ *.py,cover
67
+ .hypothesis/
68
+ .pytest_cache/
69
+ cover/
70
+ report.xml
71
+ */report.xml
72
+
73
+ # Translations
74
+ *.mo
75
+ *.pot
76
+
77
+ # Django stuff:
78
+ *.log
79
+ local_settings.py
80
+ *.sqlite3
81
+ db.sqlite3-journal
82
+
83
+ # Flask stuff:
84
+ instance/
85
+ .webassets-cache
86
+
87
+ # Scrapy stuff:
88
+ .scrapy
89
+
90
+ # Sphinx documentation
91
+ docs/_build/
92
+
93
+ # PyBuilder
94
+ .pybuilder/
95
+ target/
96
+
97
+ # Jupyter Notebook
98
+ .ipynb_checkpoints
99
+ *.ipynb
100
+ # IPython
101
+ profile_default/
102
+ ipython_config.py
103
+
104
+ # pyenv
105
+ # For a library or package, you might want to ignore these files since the code is
106
+ # intended to run in multiple environments; otherwise, check them in:
107
+ # .python-version
108
+
109
+ # pipenv
110
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
111
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
112
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
113
+ # install all needed dependencies.
114
+ #Pipfile.lock
115
+
116
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
117
+ __pypackages__/
118
+
119
+ # Celery stuff
120
+ celerybeat-schedule
121
+ celerybeat.pid
122
+
123
+ # SageMath parsed files
124
+ *.sage.py
125
+
126
+ # Environments
127
+ .env
128
+ .envrc
129
+ .venv
130
+ env/
131
+ venv/
132
+ ENV/
133
+ env.bak/
134
+ venv.bak/
135
+ .vscode/
136
+ .idea/
137
+ .idea.bkp/
138
+
139
+ # Spyder project settings
140
+ .spyderproject
141
+ .spyproject
142
+
143
+ # Rope project settings
144
+ .ropeproject
145
+
146
+ # mkdocs documentation
147
+ /site
148
+
149
+ # mypy
150
+ .mypy_cache/
151
+ .dmypy.json
152
+ dmypy.json
153
+
154
+ # Pyre type checker
155
+ .pyre/
156
+
157
+ # pytype static type analyzer
158
+ .pytype/
159
+ crm/
160
+ # Cython debug symbols
161
+ cython_debug/
162
+
163
+ # Gitlab Runner
164
+ builds
165
+ builds/
166
+
167
+ # Integrator Office 365 : reverse proxy tunnel for outlook365
168
+ ngrok
169
+ */ngrok
170
+ /modules/**/system/
171
+
172
+ /modules/wbmailing/files/*
173
+ /modules/wbmailing/mailing/*
174
+
175
+ /projects/*/requirements.txt
176
+ public
177
+
178
+ # Ignore archive localization generated folder
179
+ backend/modules/**/archive/*
180
+ **/**/requirements.txt
181
+ CHANGELOG-*
wbfdm-2.2.1/PKG-INFO ADDED
@@ -0,0 +1,15 @@
1
+ Metadata-Version: 2.3
2
+ Name: wbfdm
3
+ Version: 2.2.1
4
+ Summary: The workbench module ensures rapid access to diverse financial data (market, fundamental, forecasts, ESG), with features for storing instruments, classifying them, and conducting financial analysis.
5
+ Author-email: Christopher Wittlinger <c.wittlinger@stainly.com>
6
+ Requires-Dist: roman==4.*
7
+ Requires-Dist: stockstats==0.6.*
8
+ Requires-Dist: wbcore
9
+ Requires-Dist: wbnews
10
+ Provides-Extra: dsws
11
+ Requires-Dist: datastreampy==2.0.*; extra == 'dsws'
12
+ Requires-Dist: requests-cache==1.0.*; extra == 'dsws'
13
+ Provides-Extra: qa
14
+ Requires-Dist: jinjasql2==0.1.*; extra == 'qa'
15
+ Requires-Dist: mssql-django==1.4.*; extra == 'qa'
@@ -0,0 +1,43 @@
1
+ [project]
2
+ name = "wbfdm"
3
+ description = "The workbench module ensures rapid access to diverse financial data (market, fundamental, forecasts, ESG), with features for storing instruments, classifying them, and conducting financial analysis."
4
+ authors = [{ name = "Christopher Wittlinger", email = "c.wittlinger@stainly.com"}]
5
+ dynamic = ["version"]
6
+
7
+ dependencies = [
8
+ "wbcore",
9
+ "wbnews",
10
+ "stockstats == 0.6.*",
11
+ "roman == 4.*",
12
+ ]
13
+
14
+ [project.optional-dependencies]
15
+ qa = [
16
+ "mssql-django == 1.4.*",
17
+ "jinjasql2 == 0.1.*",
18
+ ]
19
+ dsws = [
20
+ "requests-cache == 1.0.*",
21
+ "datastreampy == 2.0.*",
22
+ ]
23
+
24
+ [tool.uv.sources]
25
+ wbcore = { workspace = true }
26
+ wbnews = { workspace = true }
27
+
28
+ [tool.uv]
29
+ package = true
30
+
31
+ [tool.hatch.version]
32
+ path = "../../pyproject.toml"
33
+
34
+ [tool.hatch.build.targets.sdist]
35
+ include = ["wbfdm/*"]
36
+
37
+ [tool.hatch.build.targets.wheel]
38
+ packages = ["wbfdm"]
39
+ only-packages = true
40
+
41
+ [build-system]
42
+ requires = ["hatchling"]
43
+ build-backend = "hatchling.build"
@@ -0,0 +1,2 @@
1
+ __version__ = "1.0.0"
2
+
@@ -0,0 +1,42 @@
1
+ from django.contrib import admin
2
+
3
+ from .instruments import InstrumentModelAdmin, InstrumentTypeModelAdmin
4
+ from .classifications import ClassificationAdmin, ClassificationGroupAdmin
5
+ from .exchanges import ExchangeModelAdmin
6
+ from .instrument_lists import InstrumentListAdmin
7
+ from .instruments_relationships import InstrumentFavoriteGroupModelAdmin
8
+ from .esg import ControversyModelAdmin
9
+ from .exchanges import ExchangeModelAdmin
10
+ from .instrument_prices import InstrumentPriceAdmin
11
+ from .instrument_requests import InstrumentRequestModelAdmin
12
+ from .options import OptionModelAdmin, OptionAggregateModelAdmin
13
+
14
+
15
+ class ReadOnlyAdmin(admin.ModelAdmin):
16
+ readonly_fields = []
17
+
18
+ def get_readonly_fields(self, request, obj=None):
19
+ return (
20
+ list(self.readonly_fields)
21
+ + [field.name for field in obj._meta.fields] # type: ignore
22
+ + [field.name for field in obj._meta.many_to_many] # type: ignore
23
+ )
24
+
25
+ def has_add_permission(self, request):
26
+ return False
27
+
28
+ def has_delete_permission(self, request, obj=None):
29
+ return False
30
+
31
+
32
+ class ReadOnlyTabularInline(admin.TabularInline):
33
+ show_change_link = True
34
+
35
+ def has_change_permission(self, request, obj=None):
36
+ return False
37
+
38
+ def has_add_permission(self, request, obj=None):
39
+ return False
40
+
41
+ def has_delete_permission(self, request, obj=None):
42
+ return False
@@ -0,0 +1,39 @@
1
+ from django.contrib import admin
2
+ from reversion_compare.admin import CompareVersionAdmin
3
+ from wbfdm.models import Classification, ClassificationGroup
4
+
5
+
6
+ class ClassificationInLine(admin.TabularInline):
7
+ model = Classification
8
+ fields = ["code_aggregated", "name"]
9
+ extra = 0
10
+
11
+
12
+ @admin.register(ClassificationGroup)
13
+ class ClassificationGroupAdmin(CompareVersionAdmin):
14
+ list_display = ["name", "max_depth", "is_primary"]
15
+
16
+ search_fields = ["name"]
17
+ ordering = ["name"]
18
+
19
+ def reversion_register(self, model, **options):
20
+ options = {
21
+ "ignore_duplicates": True,
22
+ }
23
+ super().reversion_register(model, **options)
24
+
25
+
26
+ @admin.register(Classification)
27
+ class ClassificationAdmin(CompareVersionAdmin):
28
+ list_display = ["code_aggregated", "name", "level"]
29
+
30
+ search_fields = ["code_aggregated", "name"]
31
+ inlines = [ClassificationInLine]
32
+ ordering = ["code_aggregated"]
33
+ list_filter = ("height", "level", "group")
34
+
35
+ def reversion_register(self, model, **options):
36
+ options = {
37
+ "ignore_duplicates": True,
38
+ }
39
+ super().reversion_register(model, **options)
@@ -0,0 +1,23 @@
1
+ from django.contrib import admin
2
+ from wbfdm.models import Controversy
3
+
4
+
5
+ @admin.register(Controversy)
6
+ class ControversyModelAdmin(admin.ModelAdmin):
7
+ search_fields = (
8
+ "headline",
9
+ "description",
10
+ "source",
11
+ )
12
+ raw_id_fields = ["instrument"]
13
+ list_display = (
14
+ "initiated",
15
+ "review",
16
+ "headline",
17
+ "description",
18
+ "source",
19
+ "status",
20
+ "type",
21
+ "severity",
22
+ "company_response",
23
+ )
@@ -0,0 +1,53 @@
1
+ from django import forms
2
+ from django.contrib import admin
3
+ from wbfdm.models import Exchange
4
+
5
+
6
+ class CsvImportForm(forms.Form):
7
+ csv_file = forms.FileField()
8
+
9
+
10
+ @admin.register(Exchange)
11
+ class ExchangeModelAdmin(admin.ModelAdmin):
12
+ list_display = (
13
+ "source_id",
14
+ "name",
15
+ "mic_code",
16
+ "operating_mic_code",
17
+ "bbg_exchange_codes",
18
+ "bbg_composite",
19
+ "country",
20
+ )
21
+ search_fields = (
22
+ "name",
23
+ "operating_mic_code",
24
+ "mic_code",
25
+ "bbg_exchange_codes",
26
+ "bbg_composite",
27
+ "refinitiv_identifier_code",
28
+ "comments",
29
+ )
30
+ list_filter = ["country"]
31
+ fieldsets = (
32
+ (
33
+ "Main Data",
34
+ {
35
+ "fields": (
36
+ (
37
+ "name",
38
+ "opening_time",
39
+ "closing_time",
40
+ ),
41
+ ("mic_code", "mic_name"),
42
+ ("operating_mic_code", "operating_mic_name"),
43
+ ("bbg_exchange_codes", "bbg_composite_primary", "bbg_composite"),
44
+ ("refinitiv_identifier_code", "refinitiv_mnemonic"),
45
+ ("country", "website"),
46
+ ("comments",),
47
+ )
48
+ },
49
+ ),
50
+ )
51
+
52
+ def get_queryset(self, request):
53
+ return super().get_queryset(request).select_related("country")
@@ -0,0 +1,23 @@
1
+ from django.contrib import admin
2
+ from wbfdm.models import InstrumentList, InstrumentListThroughModel
3
+
4
+
5
+ class InstrumentInstrumentList(admin.TabularInline):
6
+ model = InstrumentListThroughModel
7
+ fk_name = "instrument_list"
8
+ fields = ["instrument_str", "instrument", "validated", "from_date", "to_date"]
9
+
10
+ raw_id_fields = ["instrument", "instrument_list"]
11
+
12
+ def get_queryset(self, request):
13
+ return super().get_queryset(request).select_related("instrument")
14
+
15
+
16
+ @admin.register(InstrumentList)
17
+ class InstrumentListAdmin(admin.ModelAdmin):
18
+ search_fields = ("name", "instrument_list_type")
19
+ list_display = ("name", "instrument_list_type")
20
+
21
+ inlines = [
22
+ InstrumentInstrumentList,
23
+ ]
@@ -0,0 +1,62 @@
1
+ import pandas as pd
2
+ from django.contrib import admin
3
+ from wbcore.admin import ExportCsvMixin, ImportCsvMixin
4
+ from wbfdm.models import Instrument, InstrumentPrice
5
+
6
+
7
+ @admin.register(InstrumentPrice)
8
+ class InstrumentPriceAdmin(ExportCsvMixin, ImportCsvMixin, admin.ModelAdmin):
9
+ change_list_template = "wbcore/admin/change_list.html"
10
+ # fsm_field = ["status"]
11
+ list_display = ("date", "instrument", "net_value", "gross_value", "calculated")
12
+
13
+ ordering = ("-date",)
14
+
15
+ autocomplete_fields = ["instrument"]
16
+ fieldsets = (
17
+ (
18
+ "Main Data",
19
+ {
20
+ "fields": (
21
+ (
22
+ "instrument",
23
+ "date",
24
+ "import_source",
25
+ "calculated",
26
+ ),
27
+ ("net_value", "gross_value"),
28
+ )
29
+ },
30
+ ),
31
+ (
32
+ "Extra Data",
33
+ {
34
+ "fields": (
35
+ ("volume", "volume_50d", "volume_200d"),
36
+ ("outstanding_shares", "market_capitalization", "market_capitalization_consolidated"),
37
+ )
38
+ },
39
+ ),
40
+ (
41
+ "Computed fields",
42
+ {
43
+ "fields": (
44
+ "lock_statistics",
45
+ ("sharpe_ratio", "correlation", "beta"),
46
+ )
47
+ },
48
+ ),
49
+ )
50
+
51
+ raw_id_fields = ["import_source", "instrument"]
52
+
53
+ actions = ["export_as_csv"]
54
+
55
+ def manipulate_df(self, df):
56
+ df["instrument"] = df["instrument"].apply(lambda x: Instrument.objects.get(id=x))
57
+ df["date"] = pd.to_datetime(df["date"])
58
+ return df
59
+
60
+ def process_model(self, model):
61
+ query_params = {"instrument": model["instrument"], "date": model["date"]}
62
+ self.model.objects.update_or_create(**query_params, defaults=model)
@@ -0,0 +1,33 @@
1
+ from django.contrib import admin
2
+ from wbfdm.models import InstrumentRequest
3
+
4
+
5
+ @admin.register(InstrumentRequest)
6
+ class InstrumentRequestModelAdmin(admin.ModelAdmin):
7
+ search_fields = (
8
+ "created_instrument__computed_str",
9
+ "requester__comptuted_str",
10
+ )
11
+ raw_id_fields = ["created_instrument", "requester"]
12
+ list_display = (
13
+ "status",
14
+ "requester",
15
+ "handler",
16
+ "notes",
17
+ "created",
18
+ "created_instrument",
19
+ )
20
+ readonly_fields = ["created"]
21
+ fieldsets = (
22
+ (
23
+ "Main Data",
24
+ {
25
+ "fields": (
26
+ ("status", "created", "created_instrument"),
27
+ ("requester", "handler"),
28
+ ("notes",),
29
+ ("instrument_data",),
30
+ )
31
+ },
32
+ ),
33
+ )
@@ -0,0 +1,117 @@
1
+ from django.contrib import admin
2
+ from wbfdm.models import Instrument, InstrumentType
3
+ from wbfdm.models.instruments.instruments import import_prices_as_task
4
+
5
+ from .instruments_relationships import (
6
+ InstrumentClassificationThroughModelAdmin,
7
+ RelatedInstrumentThroughModelInlineAdmin,
8
+ )
9
+
10
+
11
+ class InstrumentInline(admin.TabularInline):
12
+ verbose_name = "Child"
13
+ verbose_names = "Children"
14
+ model = Instrument
15
+ fields = ("name", "exchange", "is_investable_universe", "is_security", "is_primary")
16
+ autocomplete_fields = ("exchange",)
17
+ show_change_link = True
18
+ extra = 0
19
+
20
+
21
+ @admin.register(InstrumentType)
22
+ class InstrumentTypeModelAdmin(admin.ModelAdmin):
23
+ list_display = ("name", "key", "is_security", "is_classifiable")
24
+
25
+
26
+ @admin.register(Instrument)
27
+ class InstrumentModelAdmin(admin.ModelAdmin):
28
+ list_display = (
29
+ "_is_investable",
30
+ "is_investable_universe",
31
+ "is_security",
32
+ "is_primary",
33
+ "instrument_type",
34
+ "name",
35
+ "source",
36
+ "source_id",
37
+ "exchange",
38
+ "ticker",
39
+ "refinitiv_identifier_code",
40
+ "refinitiv_mnemonic_code",
41
+ "isin",
42
+ "currency",
43
+ "country",
44
+ )
45
+ list_filter = ["instrument_type", "is_investable_universe", "is_security", "is_managed", "is_primary"]
46
+ fieldsets = (
47
+ (
48
+ "Instrument Information",
49
+ {
50
+ "fields": (
51
+ ("name", "name_repr", "computed_str"),
52
+ ("parent", "instrument_type"),
53
+ ("is_cash", "is_security", "is_managed", "is_investable_universe", "is_primary"),
54
+ ("inception_date", "delisted_date"),
55
+ ("primary_url", "additional_urls"),
56
+ (
57
+ "ticker",
58
+ "identifier",
59
+ "refinitiv_identifier_code",
60
+ "refinitiv_mnemonic_code",
61
+ ),
62
+ (
63
+ "cusip",
64
+ "sedol",
65
+ "valoren",
66
+ ),
67
+ ("isin", "old_isins", "tags"),
68
+ ("currency", "country", "headquarter_city", "headquarter_address"),
69
+ (
70
+ "exchange",
71
+ "import_source",
72
+ "base_color",
73
+ ),
74
+ ("description",),
75
+ ("dl_parameters", "source", "source_id"),
76
+ )
77
+ },
78
+ ),
79
+ )
80
+ search_fields = (
81
+ "name",
82
+ "name_repr",
83
+ "isin",
84
+ "ticker",
85
+ "computed_str",
86
+ "refinitiv_identifier_code",
87
+ "refinitiv_mnemonic_code",
88
+ "cusip",
89
+ "sedol",
90
+ "valoren",
91
+ "source_id",
92
+ )
93
+
94
+ autocomplete_fields = ["parent", "currency", "country", "headquarter_city", "related_instruments", "tags"]
95
+ readonly_fields = ["computed_str", "last_update", "last_valuation_date"]
96
+ inlines = [InstrumentInline, RelatedInstrumentThroughModelInlineAdmin, InstrumentClassificationThroughModelAdmin]
97
+ raw_id_fields = [
98
+ "import_source",
99
+ ]
100
+
101
+ actions = ["reimport_prices_since_inception"]
102
+
103
+ def reimport_prices_since_inception(self, request, queryset):
104
+ for instrument in queryset:
105
+ for investable_children in instrument.get_descendants(include_self=True).filter(
106
+ is_investable_universe=True
107
+ ): # trigger the recomputation for all children within the investable universe
108
+ import_prices_as_task.delay(investable_children.id, clear=True)
109
+
110
+ def isin(self, obj):
111
+ return obj.isin
112
+
113
+ def ric(self, obj):
114
+ return obj.ric
115
+
116
+ def get_queryset(self, request):
117
+ return super().get_queryset(request).select_related("currency", "country", "instrument_type")
@@ -0,0 +1,25 @@
1
+ from django.contrib import admin
2
+ from wbfdm.models import (
3
+ InstrumentClassificationThroughModel,
4
+ InstrumentFavoriteGroup,
5
+ RelatedInstrumentThroughModel,
6
+ )
7
+
8
+
9
+ @admin.register(InstrumentFavoriteGroup)
10
+ class InstrumentFavoriteGroupModelAdmin(admin.ModelAdmin):
11
+ list_display = ("name", "owner", "public", "primary")
12
+ autocomplete_fields = ["instruments", "owner"]
13
+
14
+
15
+ class InstrumentClassificationThroughModelAdmin(admin.TabularInline):
16
+ list_display = ("classification", "is_favorite")
17
+ model = InstrumentClassificationThroughModel
18
+ fk_name = "instrument"
19
+ autocomplete_fields = ["classification"]
20
+
21
+
22
+ class RelatedInstrumentThroughModelInlineAdmin(admin.TabularInline):
23
+ model = RelatedInstrumentThroughModel
24
+ fk_name = "instrument"
25
+ autocomplete_fields = ["related_instrument"]