Skip to content

Commit dbaed7a

Browse files
committed
bump: version 0.8.0 → 0.9.0
1 parent 1649d20 commit dbaed7a

15 files changed

Lines changed: 321 additions & 165 deletions

File tree

CHANGELOG.md

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,26 @@
1-
# Changelog
1+
# CHANGELOG
22

3-
## Version 0.0.1 (development)
43

5-
- First pre-alpha
6-
- ...
4+
5+
## [v0.9.0](https://github.com/dornech/equities-classifier/releases/tag/v0.9.0) (2026-08-28)
6+
7+
### Features
8+
9+
- SeekingAlpha as new datasource and Ticker_US as identifier type incl. test cases
10+
(['23c521c'](https://github.com/dornech/equities-classifier/commit/23c521c508c341959d983dc4f13ca99366320523))
11+
- Yahoo as new datasource
12+
(['6891085'](https://github.com/dornech/equities-classifier/commit/6891085906c8c162b1b4bd669bbed1d24178c42f))
13+
14+
### Bug fixes
15+
16+
- Add missing docstrings
17+
(['1649d20'](https://github.com/dornech/equities-classifier/commit/1649d20ca77790ec90a18aef0fbdff899440e066))
18+
- Minor error Morningstar client
19+
(['466e581'](https://github.com/dornech/equities-classifier/commit/466e581a497a33faf43ba8648b84f3060d3d22d9))
20+
- Improvements data provider clients
21+
(['94b6f89'](https://github.com/dornech/equities-classifier/commit/94b6f890d004c5c081d5c814dd51b694ccbf6135))
22+
- Improvements MotleyFool
23+
(['4acc884'](https://github.com/dornech/equities-classifier/commit/4acc884e170733f56062915c602dfd158e4cef64))
724

825
## [v0.8.0](https://github.com/dornech/equities-classifier/releases/tag/v0.8.0) (2026-08-20)
926

@@ -21,6 +38,7 @@
2138
- Improve OpenFIGI record comprehension
2239
(['112f5d2'](https://github.com/dornech/equities-classifier/commit/112f5d242f8650d4722cf56533bce37d1f843f2f))
2340

41+
2442
## [v0.7.2](https://github.com/dornech/equities-classifier/releases/tag/v0.7.2) (2026-08-18)
2543

2644
### Bug fixes
@@ -37,6 +55,7 @@
3755
### Testing
3856

3957

58+
4059
## [v0.7.1](https://github.com/dornech/equities-classifier/releases/tag/v0.7.1) (2026-08-16)
4160

4261
### Features
@@ -53,6 +72,7 @@
5372
- Improve conftest.py
5473
(['e026111'](https://github.com/dornech/equities-classifier/commit/e02611124cfdbaf7776bb82003ae84f0d40dab5d))
5574

75+
5676
## [v0.7.0](https://github.com/dornech/equities-classifier/releases/tag/v0.7.0) (2026-08-15)
5777

5878
### Features
@@ -82,6 +102,7 @@
82102
- **deps**: Bump sigstore/gh-action-sigstore-python from 3.4.0 to 3.5.0
83103
(['b1a7108'](https://github.com/dornech/equities-classifier/commit/b1a71083cab762c755eb799e608f415320617dfc))
84104

105+
85106
## [v0.6.0](https://github.com/dornech/equities-classifier/releases/tag/v0.6.0) (2026-08-12)
86107

87108
### Features
@@ -96,6 +117,7 @@
96117
- Switch from undetected-chromedriver to undetected, add missing dependency lxml
97118
(['6eb361d'](https://github.com/dornech/equities-classifier/commit/6eb361d8ab08e930e6d2936ad318f82634796dbd))
98119

120+
99121
## [v0.5.1](https://github.com/dornech/equities-classifier/releases/tag/v0.5.1) (2026-08-09)
100122

101123
### Features
@@ -114,6 +136,7 @@
114136
- Optimize GitHub actions resource usage, avoid especially very expensive macOS-actions
115137
(['0910fee'](https://github.com/dornech/equities-classifier/commit/0910fee0ed47b5cc6c377ee250ae79b8a7ba0204))
116138

139+
117140
## [v0.5.0](https://github.com/dornech/equities-classifier/releases/tag/v0.5.0) (2026-08-06)
118141

119142
### Features
@@ -128,6 +151,7 @@
128151
- Various fixes to overcome GitHub lint issues and clean ups
129152
(['8df8fea'](https://github.com/dornech/equities-classifier/commit/8df8fead70db1b42ce9b63363748e43bb9d58314))
130153

154+
131155
## [v0.4.1](https://github.com/dornech/equities-classifier/releases/tag/v0.4.1) (2026-08-05)
132156

133157
### Bug fixes
@@ -139,6 +163,7 @@
139163
- Ruff errors in Morningstar client
140164
(['34f9e37'](https://github.com/dornech/equities-classifier/commit/34f9e37d38008add042c40378c1b3c9d4ab43e0b))
141165

166+
142167
## [v0.4.0](https://github.com/dornech/equities-classifier/releases/tag/v0.4.0) (2026-08-05)
143168

144169
### Features
@@ -164,13 +189,15 @@
164189
- Archive latest changes resolver/connector before deleting
165190
(['74015ff'](https://github.com/dornech/equities-classifier/commit/74015ff6d44d5d80fd67b5b2d1b93a99d071da89))
166191

192+
167193
## [v0.3.2](https://github.com/dornech/equities-classifier/releases/tag/v0.3.2) (2026-08-01)
168194

169195
### Bug fixes
170196

171197
- OpenFIGI client - testcase with http-request and corrections
172198
(['d6bab53'](https://github.com/dornech/equities-classifier/commit/d6bab532eeb5061627721b6592bf0dbb6b12a267))
173199

200+
174201
## [v0.3.1](https://github.com/dornech/equities-classifier/releases/tag/v0.3.1) (2026-08-01)
175202

176203
### Bug fixes
@@ -180,20 +207,23 @@
180207
- OpenFIGI client - use SHARE_CLASS_FIGI instead FIGI
181208
(['57ea785'](https://github.com/dornech/equities-classifier/commit/57ea785b2f43414d26463fd45a7857c2b016219f))
182209

210+
183211
## [v0.3.0](https://github.com/dornech/equities-classifier/releases/tag/v0.3.0) (2026-08-01)
184212

185213
### Features
186214

187215
- OpenFIGI client
188216
(['f2fb32f'](https://github.com/dornech/equities-classifier/commit/f2fb32fe8198c236db12003ddd4d1a8c796c0a28))
189217

218+
190219
## [v0.2.0](https://github.com/dornech/equities-classifier/releases/tag/v0.2.0) (2026-07-30)
191220

192221
### Features
193222

194223
- Add abstract resolver and connector interfaces
195224
(['e93b9c3'](https://github.com/dornech/equities-classifier/commit/e93b9c36fb6e44417fb7aae6d29b3e2c0e55034a))
196225

226+
197227
## [v0.1.0](https://github.com/dornech/equities-classifier/releases/tag/v0.1.0) (2026-07-30)
198228

199229
### Features

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ exclude = [
9999
[tool.commitizen]
100100
name = "cz_customize"
101101
version_scheme = "pep440"
102-
version = "0.8.0"
102+
version = "0.9.0"
103103
version_files = ["pyproject.toml:version"]
104104
tag_format = "v$version"
105105
# retry_after_failure = false

src/equities_classifier/classification/classificationhelper.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,7 @@
1111
# fmt: off
1212

1313

14-
from equities_classifier.enums import (
15-
DataSourceID,
16-
ClassificationSystemID,
17-
ClassificationLevel,
18-
)
14+
from equities_classifier.enums import DataSourceID, ClassificationSystemID, ClassificationLevel
1915
from equities_classifier.exceptions import ClassificationError
2016
from equities_classifier.logginghelper import logger_equities_classifier
2117

src/equities_classifier/classification/generator.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,11 @@
1010
from collections.abc import Callable, Mapping
1111
from dataclasses import dataclass
1212

13-
from equities_classifier.enums import (
14-
DataSourceID,
15-
ClassificationLevel,
16-
)
17-
from equities_classifier.models import (
18-
ClassificationSystem,
19-
ClassificationNode,
20-
Security,
21-
SecurityClassification,
22-
)
13+
from equities_classifier.enums import DataSourceID, ClassificationLevel
14+
from equities_classifier.models import ClassificationSystem, ClassificationNode, Security, SecurityClassification
2315
from equities_classifier.classification.systems import (
24-
GECS,
25-
resolve_gecs_supersector,
26-
GICS,
27-
resolve_gics_motleyfool,
16+
GECS, resolve_gecs_supersector,
17+
GICS, resolve_gics_motleyfool, # resolve_gics_seekingalpha
2818
)
2919

3020

@@ -60,6 +50,16 @@ class ClassificationSource:
6050
resolver=resolve_gics_motleyfool,
6151
)
6252

53+
_SOURCE_GICS_SEEKINGALPHA = ClassificationSource(
54+
datasource=DataSourceID.MOTLEYFOOL,
55+
system=GICS,
56+
level_attributes={
57+
ClassificationLevel.LEVEL1: "sector",
58+
ClassificationLevel.LEVEL4: "subindustry",
59+
},
60+
# resolver=resolve_gics_seekingalpha,
61+
)
62+
6363

6464
class ClassificationGenerator:
6565
"""Generate classifications from Security provider attributes."""
@@ -74,6 +74,7 @@ def __init__(
7474
self._sources: tuple[ClassificationSource, ...] = (
7575
_SOURCE_GECS_MORNINGSTAR,
7676
_SOURCE_GICS_MOTLEYFOOL,
77+
_SOURCE_GICS_SEEKINGALPHA
7778
)
7879
else:
7980
self._sources = sources

src/equities_classifier/classification/systems.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,8 @@
2020

2121
from rapidfuzz.fuzz import ratio
2222

23-
from equities_classifier.enums import (
24-
DataSourceID,
25-
ClassificationSystemID,
26-
ClassificationLevel,
27-
)
28-
from equities_classifier.models import (
29-
ClassificationSystem,
30-
ClassificationNode,
31-
)
23+
from equities_classifier.enums import DataSourceID, ClassificationSystemID, ClassificationLevel
24+
from equities_classifier.models import ClassificationSystem, ClassificationNode
3225
from equities_classifier.classification.classificationhelper import ClassificationHelper
3326
from gics import GICS as GICSDefinition
3427

@@ -224,7 +217,7 @@ def resolve_gics_motleyfool(
224217
code=industry_group_code,
225218
)
226219

227-
# Level 3 comes from Motley Fool but gets the canonical GICS code/name.
220+
# Level 3 comes from Motley Fool-but gets the canonical GICS code/name.
228221
industry_name = GICS_DICT.get(industry_code)
229222
if industry_name is not None:
230223
result[ClassificationLevel.LEVEL3] = ClassificationNode(
@@ -237,6 +230,14 @@ def resolve_gics_motleyfool(
237230
return result
238231

239232

233+
# def resolve_gics_seekingalpha(
234+
# nodes: Mapping[ClassificationLevel, ClassificationNode],
235+
# ) -> Mapping[ClassificationLevel, ClassificationNode]:
236+
# """Resolve and validate SeekingAlpha GICS classification."""
237+
#
238+
# pass
239+
240+
240241
# Yahoo
241242

242243
YAHOOCS = ClassificationSystem(

src/equities_classifier/matching/matcher.py

Lines changed: 67 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,12 @@
2626
class MatchType(Enum):
2727
"""Security matching result."""
2828

29-
TICKER_AND_ISIN = "ticker_and_isin"
29+
ISIN_TICKER = "isin_ticker"
30+
ISIN_TICKER_US = "isin_ticker_us"
3031
ISIN_NAME = "isin_name"
32+
TICKER_COUNTRY_NAME = "ticker_country_name"
3133
TICKER_NAME = "ticker_name"
34+
TICKER_US_NAME = "ticker_us_name"
3235

3336

3437
@dataclass(frozen=True, slots=True)
@@ -59,29 +62,46 @@ def match(
5962
) -> MatchResult:
6063
"""Match SecurityProviderRecords according to matching hierarchy."""
6164

62-
left_ticker = left.identifier_value(SecurityIdentifierType.TICKER,)
63-
right_ticker = right.identifier_value(SecurityIdentifierType.TICKER,)
65+
left_ticker = left.identifier_value(SecurityIdentifierType.TICKER)
66+
left_ticker_cleaned = left.identifier_value_cleaned(SecurityIdentifierType.TICKER)
67+
left_ticker_country = left.identifier_country(SecurityIdentifierType.TICKER)
68+
left_ticker_us = left.identifier_country(SecurityIdentifierType.TICKER_US)
69+
right_ticker = right.identifier_value(SecurityIdentifierType.TICKER)
70+
right_ticker_cleaned = right.identifier_value_cleaned(SecurityIdentifierType.TICKER)
71+
right_ticker_country = right.identifier_country(SecurityIdentifierType.TICKER)
72+
right_ticker_us = right.identifier_country(SecurityIdentifierType.TICKER_US)
6473

6574
left_isin = left.identifier_value(SecurityIdentifierType.ISIN,)
6675
right_isin = right.identifier_value(SecurityIdentifierType.ISIN,)
6776

68-
# 1. Ticker + ISIN
77+
# 1a. Ticker + ISIN
6978
if (
70-
left_ticker
71-
and right_ticker
79+
left_ticker_cleaned
80+
and right_ticker_cleaned
7281
and left_isin
7382
and right_isin
74-
and left_ticker == right_ticker
83+
and left_ticker_cleaned == right_ticker_cleaned
84+
and left_isin == right_isin
85+
):
86+
return MatchResult(matched=True, match_type=MatchType.ISIN_TICKER)
87+
88+
# 1b. Ticker + ISIN
89+
if (
90+
left_ticker_us
91+
and right_ticker_us
92+
and left_isin
93+
and right_isin
94+
and left_ticker_us == right_ticker_us
7595
and left_isin == right_isin
7696
):
77-
return MatchResult(matched=True, match_type=MatchType.TICKER_AND_ISIN,)
97+
return MatchResult(matched=True, match_type=MatchType.ISIN_TICKER_US)
7898

7999
# 2. ISIN + similar name
80100
if (
81101
left_isin
82102
and right_isin
83103
and left_isin == right_isin
84-
and left_ticker != right_ticker
104+
and left_ticker_cleaned != right_ticker_cleaned
85105
):
86106
similarity = name_similarity(left.name, right.name)
87107

@@ -93,12 +113,32 @@ def match(
93113
name_similarity=similarity,
94114
)
95115

96-
# 3. Ticker + similar name
116+
# 3. Ticker incl. country postfix + similar name
97117
if (
98-
left_ticker
118+
not (left_isin and right_isin)
119+
and left_ticker
120+
and left_ticker_country
99121
and right_ticker
122+
and right_ticker_country
100123
and left_ticker == right_ticker
101124
):
125+
126+
similarity = name_similarity(left.name, right.name)
127+
128+
if similarity >= self._name_similarity_threshold:
129+
return MatchResult(
130+
matched=True,
131+
match_type=MatchType.TICKER_COUNTRY_NAME,
132+
name_similarity=similarity,
133+
)
134+
135+
# 4. Ticker + similar name
136+
if (
137+
not (left_isin and right_isin)
138+
and left_ticker_cleaned
139+
and right_ticker_cleaned
140+
and left_ticker_cleaned == right_ticker_cleaned
141+
):
102142
similarity = name_similarity(left.name, right.name)
103143

104144
if similarity >= self._name_similarity_threshold:
@@ -108,4 +148,20 @@ def match(
108148
name_similarity=similarity,
109149
)
110150

151+
# 5. Ticker-US + similar name
152+
if (
153+
not (left_isin and right_isin)
154+
and left_ticker_us
155+
and right_ticker_us
156+
and left_ticker_us == right_ticker_us
157+
):
158+
similarity = name_similarity(left.name, right.name)
159+
160+
if similarity >= self._name_similarity_threshold:
161+
return MatchResult(
162+
matched=True,
163+
match_type=MatchType.TICKER_US_NAME,
164+
name_similarity=similarity,
165+
)
166+
111167
return MatchResult(matched=False)

0 commit comments

Comments
 (0)