wbfdm 1.44.2__py2.py3-none-any.whl → 1.44.3__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/analysis/technical_analysis/traces.py +2 -1
- wbfdm/migrations/0029_alter_instrumentprice_volume.py +18 -0
- wbfdm/models/instruments/instrument_lists.py +2 -1
- wbfdm/models/instruments/instrument_prices.py +10 -3
- wbfdm/models/instruments/llm/create_instrument_news_relationships.py +34 -26
- wbfdm/serializers/instruments/classifications.py +8 -8
- wbfdm/serializers/instruments/instruments.py +0 -3
- wbfdm/viewsets/instruments/classifications.py +13 -0
- wbfdm/viewsets/instruments/instrument_prices.py +2 -1
- wbfdm/viewsets/instruments/instruments_relationships.py +44 -36
- {wbfdm-1.44.2.dist-info → wbfdm-1.44.3.dist-info}/METADATA +2 -2
- {wbfdm-1.44.2.dist-info → wbfdm-1.44.3.dist-info}/RECORD +13 -12
- {wbfdm-1.44.2.dist-info → wbfdm-1.44.3.dist-info}/WHEEL +0 -0
|
@@ -43,7 +43,8 @@ class TechnicalAnalysisTraceFactory:
|
|
|
43
43
|
name = str(self.ta.instrument)
|
|
44
44
|
line_options = line_options if line_options else {}
|
|
45
45
|
text = []
|
|
46
|
-
|
|
46
|
+
if base_series is not None and not base_series.empty:
|
|
47
|
+
prefix = f"Normalized {prefix}"
|
|
47
48
|
format_template = "{y:.2%}" if percent_format else "{y:.2f}"
|
|
48
49
|
hovertemplate = "<b>" + prefix + "</b>: %" + format_template
|
|
49
50
|
# If a base series is present, we add a line into the hover template to show the difference
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Generated by Django 5.0.10 on 2025-02-03 10:25
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
('wbfdm', '0028_instrumentprice_annualized_daily_volatility'),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AlterField(
|
|
14
|
+
model_name='instrumentprice',
|
|
15
|
+
name='volume',
|
|
16
|
+
field=models.FloatField(default=0.0, help_text='The Volume of the Asset on the price date of the Asset.', verbose_name='Volume'),
|
|
17
|
+
),
|
|
18
|
+
]
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from django.db import models
|
|
2
2
|
from slugify import slugify
|
|
3
3
|
from wbcore.contrib.io.mixins import ImportMixin
|
|
4
|
+
from wbcore.contrib.notifications.utils import create_notification_type
|
|
4
5
|
from wbcore.models import WBModel
|
|
5
6
|
from wbcore.utils.models import ComplexToStringMixin
|
|
6
7
|
from wbfdm.import_export.handlers.instrument_list import InstrumentListImportHandler
|
|
@@ -51,7 +52,7 @@ class InstrumentListThroughModel(ImportMixin, ComplexToStringMixin):
|
|
|
51
52
|
]
|
|
52
53
|
|
|
53
54
|
notification_types = [
|
|
54
|
-
(
|
|
55
|
+
create_notification_type(
|
|
55
56
|
"wbfdm.instrument_list_add",
|
|
56
57
|
"Instrument added to Instrument List",
|
|
57
58
|
"A notification when an instrument gets added to a list.",
|
|
@@ -211,8 +211,7 @@ class InstrumentPrice(
|
|
|
211
211
|
########################################################
|
|
212
212
|
|
|
213
213
|
volume = models.FloatField(
|
|
214
|
-
|
|
215
|
-
blank=True,
|
|
214
|
+
default=0.0,
|
|
216
215
|
verbose_name="Volume",
|
|
217
216
|
help_text="The Volume of the Asset on the price date of the Asset.",
|
|
218
217
|
)
|
|
@@ -340,7 +339,6 @@ class InstrumentPrice(
|
|
|
340
339
|
|
|
341
340
|
if self.market_capitalization_consolidated is None:
|
|
342
341
|
self.market_capitalization_consolidated = self.market_capitalization
|
|
343
|
-
|
|
344
342
|
super().save(*args, **kwargs)
|
|
345
343
|
|
|
346
344
|
def __str__(self):
|
|
@@ -399,6 +397,15 @@ class InstrumentPrice(
|
|
|
399
397
|
"""
|
|
400
398
|
return self.instrument.nominal_value(self.date)
|
|
401
399
|
|
|
400
|
+
def fill_market_capitalization(self):
|
|
401
|
+
if self.market_capitalization is None:
|
|
402
|
+
with suppress(InstrumentPrice.DoesNotExist):
|
|
403
|
+
self.market_capitalization = (
|
|
404
|
+
self.instrument.valuations.filter(date__lt=self.date, market_capitalization__isnull=False)
|
|
405
|
+
.latest("date")
|
|
406
|
+
.market_capitalization
|
|
407
|
+
)
|
|
408
|
+
|
|
402
409
|
def compute_and_update_statistics(self, min_period: int = 20):
|
|
403
410
|
prices_df = (
|
|
404
411
|
pd.DataFrame(
|
|
@@ -6,6 +6,9 @@ from langchain_core.messages import HumanMessage, SystemMessage
|
|
|
6
6
|
from pydantic import BaseModel, Field
|
|
7
7
|
from wbcore.contrib.ai.exceptions import APIStatusErrors
|
|
8
8
|
from wbcore.contrib.ai.llm.utils import run_llm
|
|
9
|
+
import logging
|
|
10
|
+
|
|
11
|
+
logger = logging.getLogger("llm")
|
|
9
12
|
|
|
10
13
|
|
|
11
14
|
class CompanyModel(BaseModel):
|
|
@@ -46,33 +49,38 @@ def run_company_extraction_llm(title: str, description: str, *args) -> list[dict
|
|
|
46
49
|
from wbfdm.import_export.handlers.instrument import InstrumentLookup
|
|
47
50
|
from wbfdm.models import Instrument
|
|
48
51
|
|
|
49
|
-
res = run_llm(
|
|
50
|
-
prompt=[
|
|
51
|
-
SystemMessage(
|
|
52
|
-
content="You will be parsed a news article, please provide the name of the publicly listed companies mentioned in the article, along with their ISIN, ticker, RIC, sentiment, and analysis."
|
|
53
|
-
),
|
|
54
|
-
HumanMessage(content=f"Title: {title}, Description: {description}"),
|
|
55
|
-
],
|
|
56
|
-
output_model=CompaniesModel,
|
|
57
|
-
)
|
|
58
52
|
relationships = []
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
53
|
+
|
|
54
|
+
try:
|
|
55
|
+
res = run_llm(
|
|
56
|
+
prompt=[
|
|
57
|
+
SystemMessage(
|
|
58
|
+
content="You will be parsed a news article, please provide the name of the publicly listed companies mentioned in the article, along with their ISIN, ticker, RIC, sentiment, and analysis."
|
|
59
|
+
),
|
|
60
|
+
HumanMessage(content=f"Title: {title}, Description: {description}"),
|
|
61
|
+
],
|
|
62
|
+
output_model=CompaniesModel,
|
|
67
63
|
)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
64
|
+
instrument_ct = ContentType.objects.get_for_model(Instrument)
|
|
65
|
+
for company in res.get("companies", []):
|
|
66
|
+
instrument = InstrumentLookup(Instrument).lookup(
|
|
67
|
+
only_security=True,
|
|
68
|
+
name=company.name,
|
|
69
|
+
isin=company.isin,
|
|
70
|
+
ticker=company.ticker,
|
|
71
|
+
refinitiv_identifier_code=company.refinitiv_identifier_code,
|
|
76
72
|
)
|
|
77
|
-
|
|
73
|
+
if instrument is not None:
|
|
74
|
+
relationships.append(
|
|
75
|
+
{
|
|
76
|
+
"content_type_id": instrument_ct.id,
|
|
77
|
+
"object_id": instrument.get_root().id,
|
|
78
|
+
"sentiment": company.sentiment,
|
|
79
|
+
"analysis": company.analysis,
|
|
80
|
+
}
|
|
81
|
+
)
|
|
82
|
+
except tuple(APIStatusErrors) as e: # for APIStatusError, we let celery retry it
|
|
83
|
+
raise e
|
|
84
|
+
except Exception as e: # otherwise we log the error and silently fail
|
|
85
|
+
logger.error(str(e))
|
|
78
86
|
return relationships
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from rest_framework import serializers as rf_serializers
|
|
2
2
|
from rest_framework.reverse import reverse
|
|
3
3
|
from wbcore import serializers as wb_serializers
|
|
4
|
-
from wbcore.serializers import DefaultAttributeFromRemoteField
|
|
4
|
+
from wbcore.serializers import DefaultAttributeFromRemoteField, DefaultFromView
|
|
5
5
|
from wbfdm.models.instruments import Classification, ClassificationGroup
|
|
6
6
|
from wbfdm.preferences import get_default_classification_group
|
|
7
7
|
|
|
@@ -62,7 +62,7 @@ class ClassificationModelSerializer(wb_serializers.ModelSerializer):
|
|
|
62
62
|
default=DefaultAttributeFromRemoteField("parent_id", Classification, source="group"),
|
|
63
63
|
)
|
|
64
64
|
_group = ClassificationGroupRepresentationSerializer(source="group")
|
|
65
|
-
code_aggregated = wb_serializers.CharField(required=False, default="")
|
|
65
|
+
code_aggregated = wb_serializers.CharField(required=False, default=DefaultFromView("next_valid_code_aggregated"))
|
|
66
66
|
level_representation = wb_serializers.CharField(required=False, default="")
|
|
67
67
|
description = wb_serializers.TextAreaField(label="Description", allow_null=True, allow_blank=True, required=False)
|
|
68
68
|
|
|
@@ -72,12 +72,12 @@ class ClassificationModelSerializer(wb_serializers.ModelSerializer):
|
|
|
72
72
|
"childs": reverse("wbfdm:classificationparent-classification-list", args=[instance.id], request=request),
|
|
73
73
|
}
|
|
74
74
|
if instance.children.exists():
|
|
75
|
-
resources[
|
|
76
|
-
"iciclechart"
|
|
77
|
-
|
|
78
|
-
resources[
|
|
79
|
-
"treechart"
|
|
80
|
-
|
|
75
|
+
resources["iciclechart"] = (
|
|
76
|
+
f'{reverse("wbfdm:classificationgroup-iciclechart-list", args=[instance.group.id], request=request)}?top_classification={instance.id}'
|
|
77
|
+
)
|
|
78
|
+
resources["treechart"] = (
|
|
79
|
+
f'{reverse("wbfdm:classificationgroup-treechart-list", args=[instance.group.id], request=request)}?top_classification={instance.id}'
|
|
80
|
+
)
|
|
81
81
|
|
|
82
82
|
resources["instruments"] = reverse("wbfdm:classification-instrument-list", args=[instance.id], request=request)
|
|
83
83
|
|
|
@@ -97,6 +97,19 @@ class ClassificationModelViewSet(InternalUserPermissionMixin, RevisionMixin, vie
|
|
|
97
97
|
title_config_class = ClassificationTitleConfig
|
|
98
98
|
button_config_class = ClassificationButtonConfig
|
|
99
99
|
|
|
100
|
+
@cached_property
|
|
101
|
+
def next_valid_code_aggregated(self) -> str:
|
|
102
|
+
group = None
|
|
103
|
+
parent = None
|
|
104
|
+
if group_id := self.kwargs.get("group_id", None):
|
|
105
|
+
group = ClassificationGroup.objects.get(id=group_id)
|
|
106
|
+
elif parent_id := self.kwargs.get("parent_id", None):
|
|
107
|
+
parent = Classification.objects.get(id=parent_id)
|
|
108
|
+
group = parent.group
|
|
109
|
+
if group:
|
|
110
|
+
return Classification.get_next_valid_code(group, parent=parent)
|
|
111
|
+
return ""
|
|
112
|
+
|
|
100
113
|
|
|
101
114
|
class ClassificationClassificationGroupModelViewSet(ClassificationModelViewSet):
|
|
102
115
|
endpoint_config_class = ClassificationClassificationGroupEndpointConfig
|
|
@@ -530,7 +530,8 @@ class BestAndWorstReturnsInstrumentPandasView(InstrumentMixin, InternalUserPermi
|
|
|
530
530
|
|
|
531
531
|
def get_dataframe(self, request, queryset, **kwargs):
|
|
532
532
|
df_to_display = pd.DataFrame()
|
|
533
|
-
|
|
533
|
+
from_date, to_date = get_date_interval_from_request(self.request, date_range_fieldname="date")
|
|
534
|
+
if not (prices_df := self.instrument.get_prices_df(from_date=from_date, to_date=to_date)).empty:
|
|
534
535
|
returns_df = FinancialStatistics(prices_df).get_best_and_worst_returns(freq=request.GET.get("frequency"))
|
|
535
536
|
if not returns_df.empty and returns_df.shape[0] > 0:
|
|
536
537
|
df_to_display["date_best_returns"] = returns_df["Date Best Return"].dt.strftime("%Y-%m-%d")
|
|
@@ -121,6 +121,43 @@ class RelatedInstrumentThroughInstrumentModelViewSet(
|
|
|
121
121
|
return super().get_queryset().filter(instrument=self.instrument)
|
|
122
122
|
|
|
123
123
|
|
|
124
|
+
def get_classified_instrument_serializer_class(classification_grouo_id: int) -> type:
|
|
125
|
+
"""
|
|
126
|
+
Unwrap defined serializer class and inject the metric fields into a new class
|
|
127
|
+
"""
|
|
128
|
+
|
|
129
|
+
group = ClassificationGroup.objects.get(id=classification_grouo_id)
|
|
130
|
+
|
|
131
|
+
attrs = dict()
|
|
132
|
+
serializer_fields = [
|
|
133
|
+
"id",
|
|
134
|
+
"instrument",
|
|
135
|
+
"_instrument",
|
|
136
|
+
"classification",
|
|
137
|
+
"_classification",
|
|
138
|
+
"is_favorite",
|
|
139
|
+
"tags",
|
|
140
|
+
"_tags",
|
|
141
|
+
]
|
|
142
|
+
for field_name in group.get_fields_names(sep="_"):
|
|
143
|
+
base_field_name = f"classification_{field_name}"
|
|
144
|
+
# representation_field_name = f"_classification_{field_name}"
|
|
145
|
+
attrs[base_field_name] = wb_serializers.CharField(read_only=True)
|
|
146
|
+
serializer_fields.append(base_field_name)
|
|
147
|
+
|
|
148
|
+
class BaseClassifiedInstrumentModelSerializer(TagSerializerMixin, wb_serializers.ModelSerializer):
|
|
149
|
+
_instrument = ClassifiableInstrumentRepresentationSerializer(source="instrument")
|
|
150
|
+
_classification = ClassificationRepresentationSerializer(source="classification", label_key="{{name}}")
|
|
151
|
+
|
|
152
|
+
class Meta:
|
|
153
|
+
model = InstrumentClassificationThroughModel
|
|
154
|
+
fields = read_only_fields = serializer_fields
|
|
155
|
+
|
|
156
|
+
serializer_class = type("ClassifiedInstrumentModelSerializer", (BaseClassifiedInstrumentModelSerializer,), attrs)
|
|
157
|
+
|
|
158
|
+
return serializer_class
|
|
159
|
+
|
|
160
|
+
|
|
124
161
|
class ClassifiedInstrumentModelViewSet(InternalUserPermissionMixin, viewsets.ModelViewSet):
|
|
125
162
|
queryset = InstrumentClassificationThroughModel.objects.all()
|
|
126
163
|
display_config_class = ClassifiedInstrumentDisplayConfig
|
|
@@ -135,43 +172,14 @@ class ClassifiedInstrumentModelViewSet(InternalUserPermissionMixin, viewsets.Mod
|
|
|
135
172
|
ordering_fields.append(f"classification_{field_name}")
|
|
136
173
|
return ordering_fields
|
|
137
174
|
|
|
138
|
-
def
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
group = self.classification_group
|
|
144
|
-
|
|
145
|
-
attrs = dict()
|
|
146
|
-
serializer_fields = [
|
|
147
|
-
"id",
|
|
148
|
-
"instrument",
|
|
149
|
-
"_instrument",
|
|
150
|
-
"classification",
|
|
151
|
-
"_classification",
|
|
152
|
-
"is_favorite",
|
|
153
|
-
"tags",
|
|
154
|
-
"_tags",
|
|
155
|
-
]
|
|
156
|
-
for field_name in group.get_fields_names(sep="_"):
|
|
157
|
-
base_field_name = f"classification_{field_name}"
|
|
158
|
-
# representation_field_name = f"_classification_{field_name}"
|
|
159
|
-
attrs[base_field_name] = wb_serializers.CharField(read_only=True)
|
|
160
|
-
serializer_fields.append(base_field_name)
|
|
161
|
-
|
|
162
|
-
class BaseClassifiedInstrumentModelSerializer(TagSerializerMixin, wb_serializers.ModelSerializer):
|
|
163
|
-
_instrument = ClassifiableInstrumentRepresentationSerializer(source="instrument")
|
|
164
|
-
_classification = ClassificationRepresentationSerializer(source="classification", label_key="{{name}}")
|
|
165
|
-
|
|
166
|
-
class Meta:
|
|
167
|
-
model = InstrumentClassificationThroughModel
|
|
168
|
-
fields = read_only_fields = serializer_fields
|
|
169
|
-
|
|
170
|
-
serializer_class = type(
|
|
171
|
-
"ClassifiedInstrumentModelSerializer", (BaseClassifiedInstrumentModelSerializer,), attrs
|
|
172
|
-
)
|
|
175
|
+
def get_resource_serializer_class(self):
|
|
176
|
+
return {
|
|
177
|
+
"serializer_class_path": "wbfdm.viewsets.instruments.instruments_relationships.get_classified_instrument_serializer_class",
|
|
178
|
+
"serializer_class_method_args": [self.classification_group.id],
|
|
179
|
+
}
|
|
173
180
|
|
|
174
|
-
|
|
181
|
+
def get_serializer_class(self):
|
|
182
|
+
return get_classified_instrument_serializer_class(self.classification_group.id)
|
|
175
183
|
|
|
176
184
|
def get_filterset_class(self, request):
|
|
177
185
|
group = self.classification_group
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: wbfdm
|
|
3
|
-
Version: 1.44.
|
|
3
|
+
Version: 1.44.3
|
|
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.*
|
|
@@ -9,7 +9,7 @@ Requires-Dist: stockstats==0.6.*
|
|
|
9
9
|
Requires-Dist: wbcore
|
|
10
10
|
Requires-Dist: wbnews
|
|
11
11
|
Provides-Extra: dsws
|
|
12
|
-
Requires-Dist: datastreampy==2.0
|
|
12
|
+
Requires-Dist: datastreampy==2.0.21; extra == 'dsws'
|
|
13
13
|
Requires-Dist: requests-cache==1.0.*; extra == 'dsws'
|
|
14
14
|
Provides-Extra: qa
|
|
15
15
|
Requires-Dist: jinjasql2==0.1.*; extra == 'qa'
|
|
@@ -33,7 +33,7 @@ wbfdm/analysis/financial_analysis/statement_with_estimates.py,sha256=w-V6O3EnO0I
|
|
|
33
33
|
wbfdm/analysis/financial_analysis/utils.py,sha256=F8ij4pgkw5Qad4_95S32O_Z1vd0rs-GYh-zZpt6WVgM,13576
|
|
34
34
|
wbfdm/analysis/technical_analysis/__init__.py,sha256=nQdpDl2okzWID6UT7fyfl36RSLNO1ZZzxRt_mkGVVkY,50
|
|
35
35
|
wbfdm/analysis/technical_analysis/technical_analysis.py,sha256=MkK5HrLz9_TCVAv4qDDZjx6EIqsvusMYB7ybg3MvSsg,4961
|
|
36
|
-
wbfdm/analysis/technical_analysis/traces.py,sha256=
|
|
36
|
+
wbfdm/analysis/technical_analysis/traces.py,sha256=GhyvVzdg1fmG5i1fai2zz9BnJ__5NH1-eKml2owXIO4,6484
|
|
37
37
|
wbfdm/backends/dto.py,sha256=5IdeGVsrk8trEi9rqtq-zisqiEDE_VLBP8RxlfZZnjk,596
|
|
38
38
|
wbfdm/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
39
39
|
wbfdm/contrib/dsws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -213,6 +213,7 @@ wbfdm/migrations/0025_instrument_is_primary_and_more.py,sha256=K6FmQZ4nkc4KT4q6r
|
|
|
213
213
|
wbfdm/migrations/0026_instrument_is_cash_equivalent.py,sha256=lvPcG-_DNaL6OrJoIW0Zeg5FdROqF_1zLsEvF45kSTw,891
|
|
214
214
|
wbfdm/migrations/0027_remove_instrument_unique_ric_and_more.py,sha256=xO8pftdONzE_IV5uG9br0UOsZjKQo9S1v-UO_J0cVpE,3459
|
|
215
215
|
wbfdm/migrations/0028_instrumentprice_annualized_daily_volatility.py,sha256=pO5MKIH9sIduCj44n_13yy_OgwutTuCIiNzXwKrvqQ4,477
|
|
216
|
+
wbfdm/migrations/0029_alter_instrumentprice_volume.py,sha256=0UFUwEaBcqiWjKw6un1gf8sluKCRRh9snDM4z4THDw8,510
|
|
216
217
|
wbfdm/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
217
218
|
wbfdm/models/__init__.py,sha256=PWsLtlKJFDYycCohPbjsRLeWi1xaxEkZbaoUKo0yOBU,96
|
|
218
219
|
wbfdm/models/fields.py,sha256=eQ_6EnDBMy0U7WzE2DsdXIXOJH5dFiIN2VbO2Svw4R0,3942
|
|
@@ -224,8 +225,8 @@ wbfdm/models/exchanges/__init__.py,sha256=sScz2KX9fxhhmi4CEUssC8HCL4ENvrIqSSwk0_
|
|
|
224
225
|
wbfdm/models/exchanges/exchanges.py,sha256=j-C22QPZEg-Mb6KCer7RRMVOcP1mprTc380zFtGJlhs,7272
|
|
225
226
|
wbfdm/models/instruments/__init__.py,sha256=OvEkECJaCubBQC7B9yUrx15V982labvegeGXyEASVno,636
|
|
226
227
|
wbfdm/models/instruments/classifications.py,sha256=EeZ_P8f1F1NfjUmLf9fDMF0iPM73qxQoArUfvjuCwHg,10906
|
|
227
|
-
wbfdm/models/instruments/instrument_lists.py,sha256=
|
|
228
|
-
wbfdm/models/instruments/instrument_prices.py,sha256=
|
|
228
|
+
wbfdm/models/instruments/instrument_lists.py,sha256=U_H9QMrhE6n0v7vHs8MwCHrjF1jihgb1FVzPKhTl6f8,4233
|
|
229
|
+
wbfdm/models/instruments/instrument_prices.py,sha256=0sj_oWyNCp9HTdmDGbTcOw5GXsYt7hUkVm0wJTdY2Cg,21869
|
|
229
230
|
wbfdm/models/instruments/instrument_relationships.py,sha256=qhnxwyg8EQa0HAhN_qvTKEynJGvzEpi-XRJpYFdi7J8,10621
|
|
230
231
|
wbfdm/models/instruments/instrument_requests.py,sha256=tM0ey0zhQlPgjSwmqPvYyO-HFIXVywl3Pw2XcpOkSPs,7766
|
|
231
232
|
wbfdm/models/instruments/instruments.py,sha256=Tz1kagBoenacppxNNBvH9MJMMRjJfUyg-Yu9jPpeHW4,39352
|
|
@@ -234,7 +235,7 @@ wbfdm/models/instruments/private_equities.py,sha256=YFWAKKSD4lb_J1HCJPfKdPzzkjsn
|
|
|
234
235
|
wbfdm/models/instruments/querysets.py,sha256=f6-OI0uf65Y9vOuVVedtOQEtqAcebcpzSRSABSmnw8c,2482
|
|
235
236
|
wbfdm/models/instruments/utils.py,sha256=69SBbxnMNK9mi5OxFOSUhNXhUzw7FRWLwwkORK1kKUY,1364
|
|
236
237
|
wbfdm/models/instruments/llm/__init__.py,sha256=dSmxRmEWb0A4O_lUoWuRKt2mBtUuLCTPVVJqGyi_n40,52
|
|
237
|
-
wbfdm/models/instruments/llm/create_instrument_news_relationships.py,sha256=
|
|
238
|
+
wbfdm/models/instruments/llm/create_instrument_news_relationships.py,sha256=_rKfrguya1FUraC0WbvXmLOtRD3EvnZe9Lcga4ngTds,3373
|
|
238
239
|
wbfdm/models/instruments/mixin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
239
240
|
wbfdm/models/instruments/mixin/financials_computed.py,sha256=L5wjXDsR0maiwfOKP6KyWNJNH4nGOoAjSc_hDM7fsj0,35105
|
|
240
241
|
wbfdm/models/instruments/mixin/financials_serializer_fields.py,sha256=Au3P9LqByh5LGyv8w_miJamtHiEerOGZQhM1NzrfECM,68768
|
|
@@ -244,12 +245,12 @@ wbfdm/serializers/esg.py,sha256=kd8ZBJfub2orpVJWBbV3naq3V0BordKwdxM9H3IMn7w,1085
|
|
|
244
245
|
wbfdm/serializers/exchanges.py,sha256=9--9WWlDjSyjSVoPkofHmCgtSp38pn2rTqcQ-RWDrS4,1174
|
|
245
246
|
wbfdm/serializers/officers.py,sha256=yrBJqnwxS5Eq0aGcRKe0FbEYEvDFpZlb8gzgfU9pRyk,473
|
|
246
247
|
wbfdm/serializers/instruments/__init__.py,sha256=fOhGE_NJx62PTsMPd8A15eGUM2ret2RI1w15-B_uW8A,1610
|
|
247
|
-
wbfdm/serializers/instruments/classifications.py,sha256=
|
|
248
|
+
wbfdm/serializers/instruments/classifications.py,sha256=ysb8W8sVp-Mz31cwO6ZIRCM8sf1UnMVPszNt7NWjcsQ,5668
|
|
248
249
|
wbfdm/serializers/instruments/instrument_lists.py,sha256=fh2HGrVMP0TPVFMmNA54l-qP0sXSTMs-Oer4QpUqeUQ,1915
|
|
249
250
|
wbfdm/serializers/instruments/instrument_prices.py,sha256=yU3coJ6M6BWt7PSupBCG509iIIlgRv9zTvnbrKcf5yo,2592
|
|
250
251
|
wbfdm/serializers/instruments/instrument_relationships.py,sha256=0AkA_gOUTQTaV6dgzqR5doc4rTli-7Grb1_So1b3rPw,6653
|
|
251
252
|
wbfdm/serializers/instruments/instrument_requests.py,sha256=vAaObfiRJegM44KfevzSOxP8JsfTBzeCigATpi6f9jU,2175
|
|
252
|
-
wbfdm/serializers/instruments/instruments.py,sha256=
|
|
253
|
+
wbfdm/serializers/instruments/instruments.py,sha256=8l5lhevKdgOmgvJtw4Nph98zZUYsQI8qaSBPX1cij4Y,11524
|
|
253
254
|
wbfdm/serializers/instruments/mixins.py,sha256=kxvjgi6zgAeIDkryDm3x3VYtiwP-rk4mcI825RsVXWM,4394
|
|
254
255
|
wbfdm/sync/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
255
256
|
wbfdm/sync/abstract.py,sha256=u1zjHT0ZJabUZpy3_EUCTtEig0p5Fuhlx69O9BsV_Gs,849
|
|
@@ -337,18 +338,18 @@ wbfdm/viewsets/financial_analysis/financial_ratio_analysis.py,sha256=YtsSJUnqHjT
|
|
|
337
338
|
wbfdm/viewsets/financial_analysis/financial_summary.py,sha256=GHXIBZ6lHmFGxqAT6YMVB7f86BsGu6K--CbUECj0xfY,9245
|
|
338
339
|
wbfdm/viewsets/financial_analysis/statement_with_estimates.py,sha256=1GiSgKZR8iyNK6yJs79eLSt7bo60KQoTv4o3vBsc9xU,6098
|
|
339
340
|
wbfdm/viewsets/instruments/__init__.py,sha256=uydDdU6oZ6W2lgFkr3-cU7WZU7TeokXAA1J0xEgiLD0,2826
|
|
340
|
-
wbfdm/viewsets/instruments/classifications.py,sha256=
|
|
341
|
+
wbfdm/viewsets/instruments/classifications.py,sha256=IfJH1lBdWLJWLkb2CcKAevhkoy52WIRaD0zl1s1qco8,11946
|
|
341
342
|
wbfdm/viewsets/instruments/financials_analysis.py,sha256=oTSaq_Zq6VQs_RgCGWbIJHHT89CZjoZD1bd4X2sQZdo,29201
|
|
342
343
|
wbfdm/viewsets/instruments/instrument_lists.py,sha256=MgEAz60mat0oocC_9_93TtZ7m6ICdm_-SXGAgVzMnSY,2877
|
|
343
|
-
wbfdm/viewsets/instruments/instrument_prices.py,sha256=
|
|
344
|
+
wbfdm/viewsets/instruments/instrument_prices.py,sha256=DeEoHrkPar9E-HwGzmmMRcxEg96IyKjlrOByMzvTLLc,24007
|
|
344
345
|
wbfdm/viewsets/instruments/instrument_requests.py,sha256=PiKWCDdcGpdDJqby1QTotSItOVYe_IrCSYrIXOrMRb8,1838
|
|
345
346
|
wbfdm/viewsets/instruments/instruments.py,sha256=rdj5O7HEYbFzKvXuGbwoubGER18DxSK6uIPw71CLE9c,3866
|
|
346
|
-
wbfdm/viewsets/instruments/instruments_relationships.py,sha256=
|
|
347
|
+
wbfdm/viewsets/instruments/instruments_relationships.py,sha256=cCpw1mKNCCLKcSxMutzwXMpjQx0trmvX8MwJ3FqDsdI,10436
|
|
347
348
|
wbfdm/viewsets/instruments/utils.py,sha256=SQAdQSgYwUwhlFBbYkZd1VMDmtfoj9XLj1RGBUzzre8,1144
|
|
348
349
|
wbfdm/viewsets/statements/__init__.py,sha256=odxtFYUDICPmz8WCE3nx93EvKZLSPBEI4d7pozcQz2A,47
|
|
349
350
|
wbfdm/viewsets/statements/statements.py,sha256=AVU5A7p63uWITEcMDl95iKyN-fBO5RwJlbxHrJZvz7o,4083
|
|
350
351
|
wbfdm/viewsets/technical_analysis/__init__.py,sha256=qtCIBg0uSiZeJq_1tEQFilnorMBkMe6uCMfqar6-cLE,77
|
|
351
352
|
wbfdm/viewsets/technical_analysis/monthly_performances.py,sha256=8VgafjW4efEJKTfBqUvAu-EG2eNawl2Cmh9QFt4sN8w,3973
|
|
352
|
-
wbfdm-1.44.
|
|
353
|
-
wbfdm-1.44.
|
|
354
|
-
wbfdm-1.44.
|
|
353
|
+
wbfdm-1.44.3.dist-info/METADATA,sha256=oF_DOkBoHr4HOdVA-6KpQE7aJsPuJMExS-nShHcgYOw,737
|
|
354
|
+
wbfdm-1.44.3.dist-info/WHEEL,sha256=tkmg4JIqwd9H8mL30xA7crRmoStyCtGp0VWshokd1Jc,105
|
|
355
|
+
wbfdm-1.44.3.dist-info/RECORD,,
|
|
File without changes
|