wbfdm 1.55.10rc0__py2.py3-none-any.whl → 1.56.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.

@@ -39,7 +39,7 @@ class DS2MarketData(Enum):
39
39
 
40
40
 
41
41
  class DatastreamMarketDataDataloader(MarketDataProtocol, Dataloader):
42
- def market_data(
42
+ def market_data( # noqa: C901
43
43
  self,
44
44
  values: list[MarketData] | None = None,
45
45
  from_date: date | None = None,
@@ -148,12 +148,15 @@ def _delist_existing_duplicates(instrument: Instrument) -> None:
148
148
 
149
149
  for identifier_field in unique_identifiers:
150
150
  if identifier := getattr(instrument, identifier_field):
151
- with suppress(Instrument.DoesNotExist):
152
- duplicate = Instrument.objects.get(
153
- is_security=True, delisted_date__isnull=True, **{identifier_field: identifier}
154
- )
155
- duplicate.delisted_date = date.today() - timedelta(days=1)
156
- duplicate.save()
151
+ if instrument.delisted_date: # if delisted, we unset the identifier that can lead to constraint error
152
+ setattr(instrument, identifier_field, None)
153
+ else:
154
+ with suppress(Instrument.DoesNotExist):
155
+ duplicate = Instrument.objects.get(
156
+ is_security=True, delisted_date__isnull=True, **{identifier_field: identifier}
157
+ )
158
+ duplicate.delisted_date = date.today() - timedelta(days=1)
159
+ duplicate.save()
157
160
 
158
161
 
159
162
  def _save_single_instrument(instrument: Instrument) -> None:
@@ -211,7 +214,7 @@ def _bulk_create_instruments_chunk(instruments: list[Instrument], update_unique_
211
214
  )
212
215
  except IntegrityError:
213
216
  # we caught an integrity error on the bulk save, so we try to save one by one
214
- logger.info(
217
+ logger.error(
215
218
  "we detected an integrity error while bulk saving instruments. We save them one by one and delist the already existing instrument from the db if we can. "
216
219
  )
217
220
  for instrument in instruments:
@@ -290,7 +293,7 @@ def trigger_partial_update(
290
293
  else:
291
294
  with connections["qa"].cursor() as cursor:
292
295
  cursor.execute(
293
- "SELECT MAX(last_user_update) FROM sys.dm_db_index_usage_stats WHERE OBJECT_NAME(object_id) = %S'",
296
+ "SELECT MAX(last_user_update) FROM sys.dm_db_index_usage_stats WHERE OBJECT_NAME(object_id) = %s'",
294
297
  (table_change_name,),
295
298
  )
296
299
  max_last_updated_qa = (
@@ -26,7 +26,6 @@ class FakeDateRange(wb_filters.FilterSet):
26
26
 
27
27
  class InstrumentPriceFilterSet(wb_filters.FilterSet):
28
28
  date = wb_filters.FinancialPerformanceDateRangeFilter(
29
- method=wb_filters.DateRangeFilter.base_date_range_filter_method,
30
29
  label="Date Range",
31
30
  required=True,
32
31
  clearable=False,
@@ -46,7 +46,7 @@ class InstrumentLookup:
46
46
  cache_key = self._get_cache_key(**kwargs)
47
47
  self.cache[cache_key] = instrument
48
48
 
49
- def _lookup_security(
49
+ def _lookup_security( # noqa: C901
50
50
  self,
51
51
  instrument_type=None,
52
52
  currency=None,
@@ -57,7 +57,6 @@ class InstrumentLookup:
57
57
  **identifiers,
58
58
  ):
59
59
  identifiers = {k: v for k, v in identifiers.items() if v is not None}
60
-
61
60
  instrument = None
62
61
 
63
62
  # We need to lookup ticker because some provider gives us ticker with or without space in it
@@ -113,33 +112,41 @@ class InstrumentLookup:
113
112
  conditions.append(Q(**{f"{field}": field_value}))
114
113
  if field == "isin":
115
114
  conditions.append(Q(old_isins__contains=[field_value]))
115
+ if field == "ticker":
116
+ conditions.append(Q(ticker__regex=rf"^{field_value}([A-Za-z]?|\.?[A-Za-z])$"))
117
+ conditions.append(Q(refinitiv_mnemonic_code=f"@{field_value}"))
118
+
116
119
  if conditions:
117
120
  instruments = instruments.filter(reduce(operator.or_, conditions))
118
-
119
- if currency: # if currency is provides, we use it as validator
121
+ if (
122
+ currency and instruments.filter(currency=currency).exists()
123
+ ): # if currency is provides, we use it as validator
120
124
  instruments = instruments.filter(currency=currency)
121
-
122
125
  if exchange:
123
126
  instruments_tmp = instruments.filter(exchange=exchange)
124
127
  if instruments_tmp.exists():
125
128
  instruments = instruments_tmp
129
+
126
130
  # last chance
127
131
  if name and instruments.count() > 1:
128
132
  instruments = instruments.annotate(similarity_score=TrigramSimilarity("name", name))
129
133
  if instruments.filter(similarity_score__gt=self.trigram_similarity_min_score).count() == 1:
130
134
  instruments = instruments.filter(similarity_score__gt=self.trigram_similarity_min_score)
135
+
131
136
  if instruments.count() == 1:
132
137
  instrument = instruments.first()
133
- elif instrument_type and identifiers:
138
+ elif instrument_type and (name or identifiers):
134
139
  # if instrument type was provided but we still didn't find the security, we try without the instrument type in case it was mislabeled
135
140
  instrument = self._lookup_security(
136
141
  only_investable_universe=only_investable_universe,
137
142
  exact_lookup=exact_lookup,
138
143
  currency=currency,
139
144
  exchange=exchange,
145
+ name=name,
140
146
  **identifiers,
141
147
  )
142
- if not instrument and name and identifiers:
148
+ if not instrument and identifiers:
149
+ identifiers.pop(list(identifiers.keys())[0])
143
150
  # Sometime, identifier provided emptied the queryset of possible instruments. In a last chance approach, we try to only look for security with the given name
144
151
  instrument = self._lookup_security(
145
152
  only_investable_universe=only_investable_universe,
@@ -148,6 +155,7 @@ class InstrumentLookup:
148
155
  currency=currency,
149
156
  exchange=exchange,
150
157
  name=name,
158
+ **identifiers,
151
159
  )
152
160
  if instrument and only_investable_universe and not instrument.is_security and instrument.parent:
153
161
  instrument = instrument.parent
@@ -671,11 +671,11 @@ class Instrument(ComplexToStringMixin, TagModelMixin, ImportMixin, InstrumentPMS
671
671
  raise ValidationError("An instrument in the investable universe cannot have children")
672
672
  return self
673
673
 
674
- def pre_save(self):
674
+ def pre_save(self): # noqa: C901
675
675
  if self.instrument_type:
676
676
  self.is_security = self.instrument_type.is_security
677
- if self.delisted_date:
678
- self.is_security = False
677
+ # if self.delisted_date:
678
+ # self.is_security = False
679
679
  if not self.name_repr:
680
680
  self.name_repr = self.name
681
681
  if not self.founded_year and self.inception_date:
@@ -139,7 +139,7 @@ class StatementWithEstimatesPandasViewSet(InstrumentMixin, ExportPandasAPIViewSe
139
139
  return self.df.columns
140
140
 
141
141
  def get_ordering_fields(self):
142
- return self.columns
142
+ return [x for x in self.columns if x != "progress"]
143
143
 
144
144
  @cached_property
145
145
  def year_columns(self):
@@ -118,7 +118,7 @@ class ValuationRatiosChartView(InstrumentMixin, viewsets.ChartViewSet):
118
118
  filterset_class = FinancialAnalysisValuationRatiosFilterSet
119
119
  LIST_DOCUMENTATION = "wbfdm/markdown/documentation/financial_analysis_instrument_ratios.md"
120
120
 
121
- def get_plotly(self, queryset):
121
+ def get_plotly(self, queryset): # noqa: C901
122
122
  # Set plotly as the default plotting lib
123
123
  pd.options.plotting.backend = "plotly"
124
124
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wbfdm
3
- Version: 1.55.10rc0
3
+ Version: 1.56.1
4
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
5
  Author-email: Christopher Wittlinger <c.wittlinger@stainly.com>
6
6
  Requires-Dist: roman==4.*
@@ -102,7 +102,7 @@ wbfdm/contrib/qa/dataloaders/adjustments.py,sha256=YAYAiCm71QjPt5dZwzezgCQpm5zRW
102
102
  wbfdm/contrib/qa/dataloaders/corporate_actions.py,sha256=NWk8OCem9niwY5mJCIR11_Wq2gVBbtcrAZedTpzQDYc,2964
103
103
  wbfdm/contrib/qa/dataloaders/financials.py,sha256=xUHpvhUkvmdPL_RyWCrs7XgChgTklX5qemmaXMedgkY,3475
104
104
  wbfdm/contrib/qa/dataloaders/fx_rates.py,sha256=IYkUV8_8Vmvm4_K9xJpz7VaTgjQUz0y4pb3KyaoiqCM,1985
105
- wbfdm/contrib/qa/dataloaders/market_data.py,sha256=HS_vVGY7FxZOUl9zSIDRDv_h4MvDwhLpH8VS2a1H8Bg,7995
105
+ wbfdm/contrib/qa/dataloaders/market_data.py,sha256=whb3xE0A36xly2_bCImgesgYjETOwTYB1DVDXBRz2UI,8009
106
106
  wbfdm/contrib/qa/dataloaders/officers.py,sha256=s3kW3sgsXuGE0T-TaZwxrF3YrUN-2v-_hN4ugupryic,2944
107
107
  wbfdm/contrib/qa/dataloaders/reporting_dates.py,sha256=q25ccB0pbGfLJLV1A1_AY1XYWJ_Fa10egY09L1J-C5A,2628
108
108
  wbfdm/contrib/qa/dataloaders/statements.py,sha256=6k8dDwJPLY6XE3G5ZA03_4wRvT7XduRsro4lzuAWCvM,10337
@@ -117,7 +117,7 @@ wbfdm/contrib/qa/jinja2/qa/sql/ibes/estimates.sql,sha256=OWgeogSFj7-OdXvJTvNsThN
117
117
  wbfdm/contrib/qa/jinja2/qa/sql/ibes/financials.sql,sha256=i8esPCG_ARiXlfSKajqBRH0jiXT_efOvw3No6zEvwn4,2612
118
118
  wbfdm/contrib/qa/sync/exchanges.py,sha256=XU7dj-rQzMlDku9lnmAACaTRoxx8pFSyr5kCK79cYAc,3124
119
119
  wbfdm/contrib/qa/sync/instruments.py,sha256=8aTQVJ_cw1phe4FWikn79pjCfUijaTcwkdhQCtSXKH0,3156
120
- wbfdm/contrib/qa/sync/utils.py,sha256=OcukNGyC1S1LZvLt1us5ZejxHcgBRRwLMqs0TWgCztA,11986
120
+ wbfdm/contrib/qa/sync/utils.py,sha256=CwcUJoCjLBY7brx4KdgNw2JdVw9dklvt8JMaWCfnnQ0,12204
121
121
  wbfdm/dataloaders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
122
122
  wbfdm/dataloaders/cache.py,sha256=K9BeVxT7p-BMvjurINt18bfrUDccp840uIjfDBLJRNk,4841
123
123
  wbfdm/dataloaders/protocols.py,sha256=QLa0y890gwnTeDGTnM58iNEYxugzj9Q9bmIRoapzc_0,3211
@@ -141,7 +141,7 @@ wbfdm/filters/classifications.py,sha256=8tKTAPwMzOIXkGWa4ez1layLBAlkDtdG53-75Rg0
141
141
  wbfdm/filters/exchanges.py,sha256=84N4AQoCwgdnxTxmhMob5Yndfr5gy_DRQ_-m2ilVLVM,835
142
142
  wbfdm/filters/financials.py,sha256=jdubT5xfFTMcwJSbC_z0WkF8KlO6eAxkaMS7-oQFFp0,2512
143
143
  wbfdm/filters/financials_analysis.py,sha256=aDA33RhKCOmA62GwuAr5xDK71T0racdyDUEaxOBp4Oc,4401
144
- wbfdm/filters/instrument_prices.py,sha256=Nt-fInhTM_LRwwmT3U-b0eWoxe-EYEdv77wLEHkZqUc,3710
144
+ wbfdm/filters/instrument_prices.py,sha256=R1K8xrvOgPB4m3tWItz_3TMUw7a7UeKe4D3h28xe_3w,3637
145
145
  wbfdm/filters/instruments.py,sha256=giL1QaJqGPRV1BBzmsPjxgCOCPuSNT5HkO27Q0kF-i4,7967
146
146
  wbfdm/filters/utils.py,sha256=6IpNoZ_yjRUCdpVXrj3kriTceAX-VGrS5NpZA2NgSmY,1870
147
147
  wbfdm/import_export/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -165,7 +165,7 @@ wbfdm/import_export/backends/refinitiv/mixin.py,sha256=DlNHOWOO71PgY0umaZd0Nbbjs
165
165
  wbfdm/import_export/backends/refinitiv/utils/__init__.py,sha256=Rz38xsLAHEyEwIuJksejYExEznlPJb9tRzwJ7JG9L1s,35
166
166
  wbfdm/import_export/backends/refinitiv/utils/controller.py,sha256=SCmVSyHo-NHDL1mzneS_Gl4JYrvEUhahOQfBmNSKnI8,7354
167
167
  wbfdm/import_export/handlers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
168
- wbfdm/import_export/handlers/instrument.py,sha256=bAnar0Row9Km5NGRV0eddQ2cWvzeQsMHHSWjDqYAufc,12676
168
+ wbfdm/import_export/handlers/instrument.py,sha256=BeDhlwoMXLREH7wno7mcpaAKj4Vg0SpHEKiIr0dgTl0,13134
169
169
  wbfdm/import_export/handlers/instrument_list.py,sha256=mZRfpJFi6BhhrjH2qaFEPqqCK2ybg-DQm43Uck7G9_w,4864
170
170
  wbfdm/import_export/handlers/instrument_price.py,sha256=RbNTo78zZuttzlVFKxJrHcW7DRfcsta7QDEI8OiiDrA,3498
171
171
  wbfdm/import_export/handlers/option.py,sha256=MPzluMPJ3Yu7Ahmw9BA7-ssAbvPDdyca_rC-YVhU8bY,2378
@@ -242,7 +242,7 @@ wbfdm/models/instruments/instrument_lists.py,sha256=GxfFyfYxEcJS36LAarHja49TOM8f
242
242
  wbfdm/models/instruments/instrument_prices.py,sha256=K7oMIz76WSrLmpNwcabThvtrP6WpBZZnrE9CHB5-UPQ,22345
243
243
  wbfdm/models/instruments/instrument_relationships.py,sha256=orBZY46jDvPfgkXakBRiByib5M_Iyeyelzg3CZWozSM,10777
244
244
  wbfdm/models/instruments/instrument_requests.py,sha256=XbpofRS8WHadHlTFjvXJyd0o7K9r2pzJtnpjVQZOLdI,7832
245
- wbfdm/models/instruments/instruments.py,sha256=NIAZLH0ArrlkJ2t9cf1J2nA3TPwcILQwIF5AzadQycs,44533
245
+ wbfdm/models/instruments/instruments.py,sha256=TbSOdQOzIcuS1KdPlFnpQmbrdv6NNzieQ26m-OoV-3Y,44551
246
246
  wbfdm/models/instruments/options.py,sha256=AW6mwvVL8IN9K6dEApJsGgDz7T8SBIxQrJvQZ804oas,7286
247
247
  wbfdm/models/instruments/private_equities.py,sha256=-MYXLLvcOO3JVvSpT2H_HxbQzZasipPUQyUgwoaW5xw,2275
248
248
  wbfdm/models/instruments/querysets.py,sha256=7r3pXNlpROkYgKc6gQH07RNeWX6jGeBAPUabUevE6Jo,11587
@@ -350,10 +350,10 @@ wbfdm/viewsets/financial_analysis/__init__.py,sha256=cTTcvGnhz2Ep9RpkyUyTOpjTXJz
350
350
  wbfdm/viewsets/financial_analysis/financial_metric_analysis.py,sha256=ISG53diS2LcjxH7Fex1wsMGHTHoRdLDHwLDKn3qA4UE,3328
351
351
  wbfdm/viewsets/financial_analysis/financial_ratio_analysis.py,sha256=szq78oFKCxVjUkCVzsU7Ditq0qQlwcrnvnXVIao18Ic,3122
352
352
  wbfdm/viewsets/financial_analysis/financial_summary.py,sha256=MWz5Nip5ePKkHX3W7bYJRvzY_hCvSsHmKd0gvvPtXL8,9245
353
- wbfdm/viewsets/financial_analysis/statement_with_estimates.py,sha256=wnBxS3b0Hsl2IfNU7WCOcRndNW8JckWDmGrgHrBmhWE,6216
353
+ wbfdm/viewsets/financial_analysis/statement_with_estimates.py,sha256=rhGxXFjTcDZ9zq0e9Djh2x9p7iBZUQ9Al-mdAvg2bBI,6248
354
354
  wbfdm/viewsets/instruments/__init__.py,sha256=uydDdU6oZ6W2lgFkr3-cU7WZU7TeokXAA1J0xEgiLD0,2826
355
355
  wbfdm/viewsets/instruments/classifications.py,sha256=CMRTeI6hUClXzZUr7PeRWBXhT9fMiPiu-FvNP_jUQkM,11947
356
- wbfdm/viewsets/instruments/financials_analysis.py,sha256=eWJI1oKxFFHw0X5THFL6IemhcHZAauyNc5yD4aQpO58,29074
356
+ wbfdm/viewsets/instruments/financials_analysis.py,sha256=bobhqY23m83v53BJIe8mWz99ZpaT7u4Y6zgPS9-ozBs,29088
357
357
  wbfdm/viewsets/instruments/instrument_lists.py,sha256=hwwHDNpHjjffxw08N_1LtkL5Fdi8c1Om-PLz6pTu4Ok,2878
358
358
  wbfdm/viewsets/instruments/instrument_prices.py,sha256=9mdNPU1D6ZFS5Bf0U1d3c6ZlYSCjrNMWv6Vhas3D8Ns,24075
359
359
  wbfdm/viewsets/instruments/instrument_requests.py,sha256=mmaARNl6ymDdlcLzcu16vVfFsunhtJkMw2r2NBfUp9U,1839
@@ -364,6 +364,6 @@ wbfdm/viewsets/statements/__init__.py,sha256=odxtFYUDICPmz8WCE3nx93EvKZLSPBEI4d7
364
364
  wbfdm/viewsets/statements/statements.py,sha256=gA6RCI8-B__JwjEb6OZxpn8Y-9aF-YQ3HIQ7e1vfJMw,4304
365
365
  wbfdm/viewsets/technical_analysis/__init__.py,sha256=qtCIBg0uSiZeJq_1tEQFilnorMBkMe6uCMfqar6-cLE,77
366
366
  wbfdm/viewsets/technical_analysis/monthly_performances.py,sha256=O1j8CGfOranL74LqVvcf7jERaDIboEJZiBf_AbbVDQ8,3974
367
- wbfdm-1.55.10rc0.dist-info/METADATA,sha256=0uOFbPkv-nVIC7jk_YD3QoHVF_S1cE3Koi2unpPWiqA,772
368
- wbfdm-1.55.10rc0.dist-info/WHEEL,sha256=tkmg4JIqwd9H8mL30xA7crRmoStyCtGp0VWshokd1Jc,105
369
- wbfdm-1.55.10rc0.dist-info/RECORD,,
367
+ wbfdm-1.56.1.dist-info/METADATA,sha256=1amTw1NVPFrkD5-cfIQg7dYw5VmkqfEgLy_PFrz546c,768
368
+ wbfdm-1.56.1.dist-info/WHEEL,sha256=tkmg4JIqwd9H8mL30xA7crRmoStyCtGp0VWshokd1Jc,105
369
+ wbfdm-1.56.1.dist-info/RECORD,,