neurostats-API 1.0.0rc6__py3-none-any.whl → 1.0.2rc1__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.
- neurostats_API/__init__.py +3 -2
- neurostats_API/async_mode/__init__.py +2 -1
- neurostats_API/async_mode/db_extractors/__init__.py +2 -1
- neurostats_API/async_mode/db_extractors/daily/__init__.py +1 -0
- neurostats_API/async_mode/db_extractors/daily/base.py +11 -4
- neurostats_API/async_mode/db_extractors/daily/us_chip.py +132 -0
- neurostats_API/async_mode/factory/extractor_factory.py +14 -2
- neurostats_API/async_mode/fetchers/__init__.py +2 -1
- neurostats_API/async_mode/fetchers/finance_overview.py +0 -5
- neurostats_API/async_mode/fetchers/us_chip.py +69 -0
- neurostats_API/config/company_list/ticker_to_cik.json +12086 -0
- neurostats_API/fetchers/finance_overview.py +3 -9
- neurostats_API/transformers/__init__.py +3 -1
- neurostats_API/transformers/daily_chip/__init__.py +1 -0
- neurostats_API/transformers/daily_chip/us.py +65 -0
- neurostats_API/utils/__init__.py +1 -1
- {neurostats_API-1.0.0rc6.dist-info → neurostats_API-1.0.2rc1.dist-info}/METADATA +2 -2
- {neurostats_API-1.0.0rc6.dist-info → neurostats_API-1.0.2rc1.dist-info}/RECORD +20 -16
- {neurostats_API-1.0.0rc6.dist-info → neurostats_API-1.0.2rc1.dist-info}/WHEEL +0 -0
- {neurostats_API-1.0.0rc6.dist-info → neurostats_API-1.0.2rc1.dist-info}/top_level.txt +0 -0
neurostats_API/__init__.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
__version__='1.0.
|
1
|
+
__version__='1.0.2rc1'
|
2
2
|
|
3
3
|
from .fetchers import (
|
4
4
|
AgentFinanceOverviewFetcher,
|
@@ -25,5 +25,6 @@ from .async_mode import (
|
|
25
25
|
AsyncTEJSeasonalFetcher,
|
26
26
|
AsyncTWSEInstitutionFetcher,
|
27
27
|
AsyncTWSEMarginFetcher,
|
28
|
-
AsyncTWSEStatsValueFetcher
|
28
|
+
AsyncTWSEStatsValueFetcher,
|
29
|
+
AsyncUSCelebrityFetcher
|
29
30
|
)
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from ..base import BaseDBExtractor
|
2
|
-
from datetime import datetime
|
2
|
+
from datetime import datetime, timezone
|
3
3
|
from neurostats_API.utils import NotSupportedError
|
4
4
|
from pymongo import ASCENDING, DESCENDING
|
5
5
|
|
@@ -73,16 +73,23 @@ class BaseDailyTechDBExtractor(BaseDBExtractor):
|
|
73
73
|
|
74
74
|
return query
|
75
75
|
|
76
|
-
def _transform_date(self, date):
|
76
|
+
def _transform_date(self, date, use_UTC = False):
|
77
77
|
if (isinstance(date, str)):
|
78
78
|
try:
|
79
|
-
|
79
|
+
date = datetime.strptime(date, "%Y-%m-%d")
|
80
|
+
if (use_UTC):
|
81
|
+
date = date.astimezone(tz = timezone.utc)
|
82
|
+
return date
|
80
83
|
except Exception as e:
|
84
|
+
print(e)
|
81
85
|
raise ValueError(
|
82
86
|
"date string format imcompatible, should be \"YYYY-MM-DD\""
|
83
87
|
)
|
84
88
|
elif (isinstance(date, datetime)):
|
85
|
-
|
89
|
+
if (use_UTC):
|
90
|
+
return date.astimezone(tz = timezone.utc)
|
91
|
+
else:
|
92
|
+
return date
|
86
93
|
else:
|
87
94
|
raise ValueError(
|
88
95
|
"date type imcompatible, should be string(\"YYYY-MM-DD\") or datetime.datetime"
|
@@ -0,0 +1,132 @@
|
|
1
|
+
from datetime import datetime, timedelta
|
2
|
+
from pymongo import ASCENDING, DESCENDING
|
3
|
+
from .base import BaseDailyTechDBExtractor
|
4
|
+
from neurostats_API.utils import (
|
5
|
+
NotSupportedError, StatsProcessor
|
6
|
+
)
|
7
|
+
from pymongo import AsyncMongoClient
|
8
|
+
|
9
|
+
class AsyncUS_F13DBExtractor(BaseDailyTechDBExtractor):
|
10
|
+
|
11
|
+
def __init__(self, ticker, client, managerTicker=None):
|
12
|
+
"""
|
13
|
+
ticker: Issuer Ticker, 被持有的股票代碼
|
14
|
+
managerTicker: 持有者的股票代碼
|
15
|
+
"""
|
16
|
+
super().__init__(ticker, client)
|
17
|
+
self.issuerTicker = ticker
|
18
|
+
self.managerTicker = managerTicker
|
19
|
+
|
20
|
+
if (self.get_zone() not in ['us']):
|
21
|
+
raise NotSupportedError("Supports US Company Only")
|
22
|
+
|
23
|
+
def _get_collection_name(self):
|
24
|
+
self.collection_name_map = {"us": "us_F13"}
|
25
|
+
|
26
|
+
return self.collection_name_map.get(self.zone, None)
|
27
|
+
|
28
|
+
def _prepare_query(self, start_date=None, end_date=None, get_latest=False):
|
29
|
+
query = {"issuerTicker": self.issuerTicker}
|
30
|
+
|
31
|
+
if (self.managerTicker):
|
32
|
+
query.update(
|
33
|
+
{
|
34
|
+
"managerTicker": self.managerTicker
|
35
|
+
}
|
36
|
+
)
|
37
|
+
|
38
|
+
query = self._update_query_with_date(query, start_date, end_date)
|
39
|
+
|
40
|
+
projection = {
|
41
|
+
"_id": 0,
|
42
|
+
}
|
43
|
+
|
44
|
+
if (get_latest):
|
45
|
+
sort = [("reportDate", DESCENDING)]
|
46
|
+
else:
|
47
|
+
sort = [("reportDate", ASCENDING)]
|
48
|
+
|
49
|
+
return query, projection, sort
|
50
|
+
|
51
|
+
def _update_query_with_date(self, query, start_date, end_date):
|
52
|
+
start_date = self._transform_date(start_date)
|
53
|
+
end_date = self._transform_date(end_date)
|
54
|
+
|
55
|
+
date_range = {"$gte": start_date, "$lte": end_date}
|
56
|
+
|
57
|
+
query.update({"reportDate": date_range})
|
58
|
+
|
59
|
+
return query
|
60
|
+
|
61
|
+
async def query_data(
|
62
|
+
self, start_date=None, end_date=None, get_latest=False
|
63
|
+
):
|
64
|
+
result = await super().query_data(start_date, end_date, get_latest)
|
65
|
+
|
66
|
+
return result
|
67
|
+
|
68
|
+
class AsyncUS_CelebrityDBExtractor(AsyncUS_F13DBExtractor):
|
69
|
+
"""
|
70
|
+
用於查詢美國名人持股的專用extractor
|
71
|
+
"""
|
72
|
+
def __init__(self, client:AsyncMongoClient, manager_name=None):
|
73
|
+
"""
|
74
|
+
manager_name: 名人名稱
|
75
|
+
"""
|
76
|
+
self.client = client
|
77
|
+
self.zone = "us"
|
78
|
+
self.manager = manager_name
|
79
|
+
self.collection_name_map = {"us": "us_F13"}
|
80
|
+
self.collection = self.client.get_database("company_us").get_collection("us_F13")
|
81
|
+
|
82
|
+
|
83
|
+
def _get_collection_name(self):
|
84
|
+
|
85
|
+
return self.collection_name_map.get(self.zone, None)
|
86
|
+
|
87
|
+
def _prepare_query(
|
88
|
+
self, start_date=None, end_date=None, get_latest=False,
|
89
|
+
value_throshold=None, title=None
|
90
|
+
):
|
91
|
+
|
92
|
+
start_date = self._transform_date(start_date)
|
93
|
+
end_date = self._transform_date(end_date)
|
94
|
+
|
95
|
+
query = {
|
96
|
+
"manager": self.manager,
|
97
|
+
"reportDate": {"$gte": start_date, "$lte": end_date}
|
98
|
+
}
|
99
|
+
|
100
|
+
if value_throshold:
|
101
|
+
query["value"] = {"$gt": value_throshold}
|
102
|
+
|
103
|
+
if title:
|
104
|
+
query["titleOfClass"] = title
|
105
|
+
|
106
|
+
projection = {"_id": 0}
|
107
|
+
|
108
|
+
if (get_latest):
|
109
|
+
sort = [("reportDate", DESCENDING)]
|
110
|
+
else:
|
111
|
+
sort = [("reportDate", ASCENDING)]
|
112
|
+
|
113
|
+
return query, projection, sort
|
114
|
+
|
115
|
+
async def query_data(
|
116
|
+
self, start_date=None, end_date=None, get_latest=False,
|
117
|
+
value_throshold=None, title=None
|
118
|
+
):
|
119
|
+
query, projection, sort = self._prepare_query(
|
120
|
+
start_date=start_date, end_date=end_date, get_latest=get_latest,
|
121
|
+
value_throshold=value_throshold, title=title
|
122
|
+
)
|
123
|
+
|
124
|
+
if (get_latest):
|
125
|
+
cursor = self.collection.find(query, projection).sort(sort).limit(1)
|
126
|
+
else:
|
127
|
+
cursor = self.collection.find(query, projection).sort(sort)
|
128
|
+
|
129
|
+
fetched_data = [data async for data in cursor]
|
130
|
+
|
131
|
+
return fetched_data
|
132
|
+
|
@@ -5,7 +5,7 @@ from neurostats_API.async_mode.db_extractors import (
|
|
5
5
|
AsyncTWSEChipDBExtractor, AsyncTWSEMonthlyRevenueExtractor,
|
6
6
|
AsyncBalanceSheetExtractor, AsyncProfitLoseExtractor,
|
7
7
|
AsyncCashFlowExtractor, AsyncTEJFinanceStatementDBExtractor,
|
8
|
-
AsyncTEJSelfSettlementDBExtractor
|
8
|
+
AsyncTEJSelfSettlementDBExtractor, AsyncUS_F13DBExtractor
|
9
9
|
)
|
10
10
|
from neurostats_API.utils import NotSupportedError
|
11
11
|
|
@@ -139,7 +139,19 @@ EXTRACTOR_MAP: dict[str, ExtractorConfig] = {
|
|
139
139
|
DB_collection: twse_daily_share_price
|
140
140
|
TWSE的評價面
|
141
141
|
"""
|
142
|
-
}
|
142
|
+
},
|
143
|
+
|
144
|
+
|
145
|
+
"US_Chip_F13": {
|
146
|
+
"class_":
|
147
|
+
AsyncUS_F13DBExtractor,
|
148
|
+
"default_kwargs": {},
|
149
|
+
"description":
|
150
|
+
"""
|
151
|
+
DB_collection: "us_F13_flat"
|
152
|
+
US籌碼面(F13)
|
153
|
+
"""
|
154
|
+
},
|
143
155
|
}
|
144
156
|
|
145
157
|
|
@@ -7,4 +7,5 @@ from .twse_margin import AsyncTWSEMarginFetcher
|
|
7
7
|
from .month_revenue import AsyncMonthlyRevenueFetcher
|
8
8
|
from .profit_lose import AsyncProfitLoseFetcher
|
9
9
|
from .value import AsyncTWSEStatsValueFetcher
|
10
|
-
from .tej import AsyncTEJDailyTechFetcher, AsyncTEJSeasonalFetcher
|
10
|
+
from .tej import AsyncTEJDailyTechFetcher, AsyncTEJSeasonalFetcher
|
11
|
+
from .us_chip import AsyncUSChipF13Fetcher, AsyncUSCelebrityFetcher
|
@@ -0,0 +1,69 @@
|
|
1
|
+
from .base import AsyncBaseFetcher
|
2
|
+
from ..db_extractors import (
|
3
|
+
AsyncDailyValueDBExtractor, AsyncTEJDailyValueDBExtractor, AsyncUS_CelebrityDBExtractor
|
4
|
+
)
|
5
|
+
from neurostats_API.async_mode.factory import get_extractor
|
6
|
+
from neurostats_API.transformers import US_F13_Transformer, US_CelebrityTransformer
|
7
|
+
from neurostats_API.utils import NotSupportedError
|
8
|
+
|
9
|
+
|
10
|
+
class AsyncUSChipF13Fetcher(AsyncBaseFetcher):
|
11
|
+
def __init__(self,
|
12
|
+
ticker,
|
13
|
+
client,
|
14
|
+
managerTicker = None,
|
15
|
+
):
|
16
|
+
self.issuerTicker = ticker
|
17
|
+
self.managerTicker = managerTicker
|
18
|
+
self.transformer_map = {"us": US_F13_Transformer}
|
19
|
+
try:
|
20
|
+
self.extractor = get_extractor(
|
21
|
+
"US_Chip_F13", ticker, client, managerTicker=self.managerTicker
|
22
|
+
)
|
23
|
+
|
24
|
+
company_name = self.extractor.get_company_name()
|
25
|
+
zone = self.extractor.get_zone()
|
26
|
+
|
27
|
+
transformer = self.get_transformer(zone)
|
28
|
+
self.transformer = transformer(ticker, company_name, zone)
|
29
|
+
|
30
|
+
except NotSupportedError as e:
|
31
|
+
raise NotSupportedError(
|
32
|
+
f"{self.__class__.__name__} only support {list(self.transformer_map.keys())} companies now, {ticker} is not available"
|
33
|
+
) from e
|
34
|
+
|
35
|
+
async def query_data(
|
36
|
+
self, start_date=None, end_date=None, get_latest=False
|
37
|
+
):
|
38
|
+
fetched_data = await self.extractor.query_data(
|
39
|
+
start_date, end_date, get_latest
|
40
|
+
)
|
41
|
+
|
42
|
+
transformed_data = self.transformer.process_transform(
|
43
|
+
fetched_data
|
44
|
+
)
|
45
|
+
|
46
|
+
return transformed_data
|
47
|
+
|
48
|
+
class AsyncUSCelebrityFetcher(AsyncBaseFetcher):
|
49
|
+
|
50
|
+
def __init__(self, client, manager_name):
|
51
|
+
self.manager_name = manager_name
|
52
|
+
self.extractor = AsyncUS_CelebrityDBExtractor(client, manager_name)
|
53
|
+
self.transformer = US_CelebrityTransformer()
|
54
|
+
|
55
|
+
async def query_data(
|
56
|
+
self, start_date=None, end_date=None, get_latest=False,
|
57
|
+
value_threshold=None, title=None, strftime=None
|
58
|
+
):
|
59
|
+
fetched_data = await self.extractor.query_data(
|
60
|
+
start_date, end_date, get_latest,
|
61
|
+
value_throshold=value_threshold, title=title
|
62
|
+
)
|
63
|
+
|
64
|
+
transformed_data = self.transformer.process_transform(
|
65
|
+
fetched_datas = list(fetched_data),
|
66
|
+
strftime = strftime
|
67
|
+
)
|
68
|
+
|
69
|
+
return transformed_data
|