neurostats-API 1.0.0rc1__py3-none-any.whl → 1.0.0rc2__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 +1 -1
- neurostats_API/async_mode/db_extractors/daily/twse_chip.py +5 -0
- neurostats_API/async_mode/db_extractors/seasonal/base.py +76 -83
- neurostats_API/transformers/daily_chip/twse_chip.py +16 -13
- {neurostats_API-1.0.0rc1.dist-info → neurostats_API-1.0.0rc2.dist-info}/METADATA +2 -2
- {neurostats_API-1.0.0rc1.dist-info → neurostats_API-1.0.0rc2.dist-info}/RECORD +8 -8
- {neurostats_API-1.0.0rc1.dist-info → neurostats_API-1.0.0rc2.dist-info}/WHEEL +0 -0
- {neurostats_API-1.0.0rc1.dist-info → neurostats_API-1.0.0rc2.dist-info}/top_level.txt +0 -0
neurostats_API/__init__.py
CHANGED
@@ -34,6 +34,11 @@ class AsyncTWSEChipDBExtractor(BaseDailyTechDBExtractor):
|
|
34
34
|
|
35
35
|
def _prepare_query(self, start_date=None, end_date=None, get_latest = False):
|
36
36
|
query, projection, sort = super()._prepare_query(start_date, end_date, get_latest)
|
37
|
+
query.update(
|
38
|
+
{
|
39
|
+
self.target_column: {"$exists" : True}
|
40
|
+
}
|
41
|
+
)
|
37
42
|
projection.update(
|
38
43
|
{
|
39
44
|
'date': 1,
|
@@ -7,6 +7,7 @@ from neurostats_API.async_mode.db import TWSEDBClient, USDBClient
|
|
7
7
|
from neurostats_API.utils import StatsDateTime, StatsProcessor, NotSupportedError
|
8
8
|
import yaml
|
9
9
|
|
10
|
+
|
10
11
|
class AsyncBaseSeasonalDBExtractor(BaseDBExtractor):
|
11
12
|
|
12
13
|
def __init__(self, ticker, client):
|
@@ -16,41 +17,28 @@ class AsyncBaseSeasonalDBExtractor(BaseDBExtractor):
|
|
16
17
|
self.collection_name = self._get_collection_name()
|
17
18
|
if (self.collection_name is None):
|
18
19
|
raise NotSupportedError(
|
19
|
-
|
20
|
-
)
|
21
|
-
self.collection = self.db_client.get_collection(
|
22
|
-
self.collection_name
|
20
|
+
f"{self.__class__.__name__} only supports {list(self.collection_name_map.keys())}, got {self.zone} with ticker = \"{self.ticker}\""
|
23
21
|
)
|
24
|
-
|
22
|
+
self.collection = self.db_client.get_collection(self.collection_name)
|
23
|
+
|
25
24
|
self.column_name_map = None
|
26
25
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
26
|
async def query_data(
|
31
|
-
self,
|
32
|
-
start_date
|
33
|
-
end_date
|
34
|
-
get_latest
|
27
|
+
self,
|
28
|
+
start_date=None,
|
29
|
+
end_date=None,
|
30
|
+
get_latest=False # 決定是否只取得最新一筆資料
|
35
31
|
):
|
36
32
|
if (start_date is None):
|
37
33
|
start_date = "1991-01-01"
|
38
34
|
if (end_date is None):
|
39
35
|
end_date = self._get_today()
|
40
|
-
|
41
|
-
start_year, start_season = self._get_year_and_season(
|
42
|
-
|
43
|
-
)
|
44
|
-
end_year, end_season = self._get_year_and_season(
|
45
|
-
date = end_date
|
46
|
-
)
|
36
|
+
|
37
|
+
start_year, start_season = self._get_year_and_season(date=start_date)
|
38
|
+
end_year, end_season = self._get_year_and_season(date=end_date)
|
47
39
|
|
48
40
|
query, projection, sort = self._prepare_query(
|
49
|
-
start_year,
|
50
|
-
start_season,
|
51
|
-
end_year,
|
52
|
-
end_season,
|
53
|
-
get_latest
|
41
|
+
start_year, start_season, end_year, end_season, get_latest
|
54
42
|
)
|
55
43
|
cursor = self.collection.find(query, projection).sort(sort)
|
56
44
|
|
@@ -62,35 +50,29 @@ class AsyncBaseSeasonalDBExtractor(BaseDBExtractor):
|
|
62
50
|
return fetched_data
|
63
51
|
|
64
52
|
def _get_collection_name(self):
|
65
|
-
|
53
|
+
|
66
54
|
return self.collection_name_map.get(self.zone, None)
|
67
|
-
|
55
|
+
|
68
56
|
def _get_collection_map(self):
|
69
|
-
return {
|
70
|
-
|
71
|
-
"us": "us_fundamentals"
|
72
|
-
}
|
73
|
-
|
57
|
+
return {"tw": "twse_seasonal_report", "us": "us_fundamentals"}
|
58
|
+
|
74
59
|
def _prepare_query(
|
75
60
|
self,
|
76
|
-
start_year
|
77
|
-
start_season
|
78
|
-
end_year
|
79
|
-
end_season
|
80
|
-
get_latest
|
61
|
+
start_year=None,
|
62
|
+
start_season=None,
|
63
|
+
end_year=None,
|
64
|
+
end_season=None,
|
65
|
+
get_latest=False
|
81
66
|
):
|
82
67
|
chart_name = self.column_name_map.get(self.get_zone(), None)
|
83
68
|
|
84
69
|
query = {
|
85
|
-
"ticker": self.ticker
|
70
|
+
"ticker": self.ticker,
|
71
|
+
"chart_name": {"$exists": True}
|
86
72
|
}
|
87
73
|
|
88
74
|
query = self._update_query_with_year_season(
|
89
|
-
query,
|
90
|
-
start_year,
|
91
|
-
start_season,
|
92
|
-
end_year,
|
93
|
-
end_season
|
75
|
+
query, start_year, start_season, end_year, end_season
|
94
76
|
)
|
95
77
|
|
96
78
|
projection = {
|
@@ -100,60 +82,71 @@ class AsyncBaseSeasonalDBExtractor(BaseDBExtractor):
|
|
100
82
|
"season": 1,
|
101
83
|
chart_name: 1,
|
102
84
|
}
|
103
|
-
|
85
|
+
|
104
86
|
if (get_latest):
|
105
|
-
sort = [
|
106
|
-
("year", DESCENDING),
|
107
|
-
("season", DESCENDING)
|
108
|
-
]
|
87
|
+
sort = [("year", DESCENDING), ("season", DESCENDING)]
|
109
88
|
else:
|
110
|
-
sort = [
|
111
|
-
("year", ASCENDING),
|
112
|
-
("season", ASCENDING)
|
113
|
-
]
|
89
|
+
sort = [("year", ASCENDING), ("season", ASCENDING)]
|
114
90
|
|
115
91
|
return query, projection, sort
|
116
92
|
|
117
|
-
|
118
93
|
def _get_year_and_season(self, date):
|
119
|
-
|
120
|
-
|
94
|
+
if (isinstance(date, str)):
|
95
|
+
date = datetime.strptime(date, "%Y-%m-%d")
|
96
|
+
|
97
|
+
year = date.year
|
98
|
+
month = date.month
|
121
99
|
|
122
|
-
|
123
|
-
month = date.month
|
100
|
+
season = (month - 1) // 3 + 1
|
124
101
|
|
125
|
-
|
102
|
+
return year, season
|
126
103
|
|
127
|
-
return year, season
|
128
|
-
|
129
104
|
def _update_query_with_year_season(
|
130
|
-
self,
|
131
|
-
query,
|
132
|
-
start_year,
|
133
|
-
start_season,
|
134
|
-
end_year,
|
135
|
-
end_season
|
105
|
+
self, query, start_year, start_season, end_year, end_season
|
136
106
|
):
|
137
107
|
if all(v is not None for v in [start_year, start_season]):
|
138
108
|
# 大於start_year條件
|
139
|
-
query.update(
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
109
|
+
query.update(
|
110
|
+
{
|
111
|
+
"$or": [
|
112
|
+
{
|
113
|
+
"year": {
|
114
|
+
"$gt": start_year
|
115
|
+
}
|
116
|
+
},
|
117
|
+
{
|
118
|
+
"year": start_year,
|
119
|
+
"season": {
|
120
|
+
"$gte": start_season
|
121
|
+
}
|
122
|
+
},
|
123
|
+
]
|
124
|
+
}
|
125
|
+
)
|
145
126
|
|
146
127
|
if all(v is not None for v in [end_year, end_season]):
|
147
128
|
# 小於end_year條件
|
148
|
-
query.update(
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
129
|
+
query.update(
|
130
|
+
{
|
131
|
+
"$and":
|
132
|
+
query.get("$and", []) + [
|
133
|
+
{
|
134
|
+
"$or": [
|
135
|
+
{
|
136
|
+
"year": {
|
137
|
+
"$lt": end_year
|
138
|
+
}
|
139
|
+
},
|
140
|
+
{
|
141
|
+
"year": end_year,
|
142
|
+
"season": {
|
143
|
+
"$lte": end_season
|
144
|
+
}
|
145
|
+
},
|
146
|
+
]
|
147
|
+
}
|
148
|
+
]
|
149
|
+
}
|
150
|
+
)
|
151
|
+
|
152
|
+
return query
|
@@ -62,7 +62,9 @@ class TWSEChipTransformer(BaseChipTransformer):
|
|
62
62
|
def _process_latest(self, latest_data: dict, latest_tech: dict, key: str):
|
63
63
|
latest_trade = latest_data.get(key)
|
64
64
|
return {
|
65
|
-
"date":
|
65
|
+
"date":
|
66
|
+
latest_data.get('date',
|
67
|
+
datetime.today().strftime("%Y-%m-%d")),
|
66
68
|
**self._process_latest_trading(latest_trade, latest_tech, key)
|
67
69
|
}
|
68
70
|
|
@@ -182,8 +184,8 @@ class TWSEChipTransformer(BaseChipTransformer):
|
|
182
184
|
)
|
183
185
|
elif (key.find("三大法人") >= 0):
|
184
186
|
self._target_institution(
|
185
|
-
latest_trading, latest_table['institutional_investor'],
|
186
|
-
volume
|
187
|
+
latest_trading, latest_table['institutional_investor'],
|
188
|
+
key, volume
|
187
189
|
)
|
188
190
|
# 計算合計
|
189
191
|
for unit in ['stock', 'percentage']:
|
@@ -321,18 +323,16 @@ class TWSEChipTransformer(BaseChipTransformer):
|
|
321
323
|
2).item()
|
322
324
|
|
323
325
|
def _process_latest_margin(self, latest_trading, *args):
|
326
|
+
|
324
327
|
def _default_margin_chart():
|
325
|
-
dafault_dict = {
|
326
|
-
"financing": {},
|
327
|
-
"short_selling": {}
|
328
|
-
}
|
328
|
+
dafault_dict = {"financing": {}, "short_selling": {}}
|
329
329
|
return {
|
330
330
|
"margin_trading": pd.DataFrame.from_dict(dafault_dict),
|
331
331
|
"security_offset": None
|
332
332
|
}
|
333
|
-
|
333
|
+
|
334
334
|
if (latest_trading is None):
|
335
|
-
return
|
335
|
+
return _default_margin_chart()
|
336
336
|
|
337
337
|
latest_trading['financing']['現償'] = latest_trading['financing'].pop(
|
338
338
|
'現金償還'
|
@@ -354,14 +354,17 @@ class TWSEChipTransformer(BaseChipTransformer):
|
|
354
354
|
}
|
355
355
|
|
356
356
|
def _process_latest_security(self, latest_trading, *args):
|
357
|
+
|
357
358
|
def _default_margin_chart():
|
358
|
-
return
|
359
|
+
return {
|
359
360
|
"stock_lending":
|
360
|
-
pd.DataFrame(
|
361
|
+
pd.DataFrame(
|
362
|
+
index=["當日賣出", "現償", "當日還券", "當日調整", "當日餘額", "次一營業日可限額"]
|
363
|
+
)
|
361
364
|
}
|
362
|
-
|
365
|
+
|
363
366
|
if (latest_trading is None):
|
364
|
-
return
|
367
|
+
return _default_margin_chart()
|
365
368
|
|
366
369
|
latest_stock_lending = latest_trading['stock_lending']
|
367
370
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: neurostats_API
|
3
|
-
Version: 1.0.
|
3
|
+
Version: 1.0.0rc2
|
4
4
|
Summary: The service of NeuroStats website
|
5
5
|
Home-page: https://github.com/NeurowattStats/NeuroStats_API.git
|
6
6
|
Author: JasonWang@Neurowatt
|
@@ -71,7 +71,7 @@ pip install neurostats-API
|
|
71
71
|
```Python
|
72
72
|
>>> import neurostats_API
|
73
73
|
>>> print(neurostats_API.__version__)
|
74
|
-
1.0.
|
74
|
+
1.0.0rc2
|
75
75
|
```
|
76
76
|
|
77
77
|
### 下載舊版
|
@@ -1,4 +1,4 @@
|
|
1
|
-
neurostats_API/__init__.py,sha256=
|
1
|
+
neurostats_API/__init__.py,sha256=58rMdx6r5TIsGQzFXciGec5dDXE4IAHXd4j7caKw624,323
|
2
2
|
neurostats_API/cli.py,sha256=UJSWLIw03P24p-gkBb6JSEI5dW5U12UvLf1L8HjQD-o,873
|
3
3
|
neurostats_API/main.py,sha256=QcsfmWivg2Dnqw3MTJWiI0QvEiRs0VuH-BjwQHFCv00,677
|
4
4
|
neurostats_API/async_mode/__init__.py,sha256=arSINQm3O3g-IwfOSLsGraEj2icJbkuW0t5HLPQ4Xk8,348
|
@@ -13,7 +13,7 @@ neurostats_API/async_mode/db_extractors/daily/__init__.py,sha256=crXYyPT-LnEWsMF
|
|
13
13
|
neurostats_API/async_mode/db_extractors/daily/base.py,sha256=U7cxKHIqSITEoDxqShN-3k7_pzLW-VnKLSsXo-eQh0s,2925
|
14
14
|
neurostats_API/async_mode/db_extractors/daily/tej_chip.py,sha256=Ywc0iIIPWw1VdtVc2_s1CNrgj0_G1wOaGzrgyVTN2k8,414
|
15
15
|
neurostats_API/async_mode/db_extractors/daily/tej_tech.py,sha256=M3k1pmv48DfiUaIfDKx5gk85C5JpmuXdQhRcNzgOhPI,349
|
16
|
-
neurostats_API/async_mode/db_extractors/daily/twse_chip.py,sha256=
|
16
|
+
neurostats_API/async_mode/db_extractors/daily/twse_chip.py,sha256=WICwcsy2m_2ua9UnIjs_SZGFq7m2-UByx9x7TCk_rlY,1490
|
17
17
|
neurostats_API/async_mode/db_extractors/daily/value.py,sha256=j5QjFOhmvVum0D10prcZZ7_sxrojA-b8sP72Ge9lOnY,2859
|
18
18
|
neurostats_API/async_mode/db_extractors/daily/yf.py,sha256=GewIRJ7_baBc9QL7BHVdnxQ0uXYpFNeiPuwKxzByULg,377
|
19
19
|
neurostats_API/async_mode/db_extractors/month_revenue/__init__.py,sha256=VXjEn4xnXsPpt8lq7egSM_3sLnhtOIQG2lNedDC_Shw,50
|
@@ -21,7 +21,7 @@ neurostats_API/async_mode/db_extractors/month_revenue/base.py,sha256=pXK6MEQtwCh
|
|
21
21
|
neurostats_API/async_mode/db_extractors/month_revenue/twse.py,sha256=54HT6ISZYC9uFx-YAcWQN4r3rKuZN0fbC5zgsJE46Ic,197
|
22
22
|
neurostats_API/async_mode/db_extractors/seasonal/__init__.py,sha256=sotZHTbuGH2am48hb0bIGVs3K_14PgMKsO-FEQzF0dI,236
|
23
23
|
neurostats_API/async_mode/db_extractors/seasonal/balance_sheet.py,sha256=67OzGUxZbt7LQ9m3uTcnPPhEYQ17ygEH-Kv1eaR1X2Y,560
|
24
|
-
neurostats_API/async_mode/db_extractors/seasonal/base.py,sha256=
|
24
|
+
neurostats_API/async_mode/db_extractors/seasonal/base.py,sha256=1Un39qDmckL-eL_-QM4BS8M5CCmALZv4g0m6799ez8g,4664
|
25
25
|
neurostats_API/async_mode/db_extractors/seasonal/cashflow.py,sha256=2yOIOMFic9DTeEyhD2xD_tGrtSWb-LirUnN1a5ka_3A,293
|
26
26
|
neurostats_API/async_mode/db_extractors/seasonal/profit_lose.py,sha256=AMKMVIVIBWTRk2b_A33OUuTLrCwc-xYj5fIL4YjLnug,564
|
27
27
|
neurostats_API/async_mode/db_extractors/seasonal/tej.py,sha256=SqObDqR3uOnxXGF12VQz7Rzw7B5YAimY1-nR0ImLkaY,2591
|
@@ -78,7 +78,7 @@ neurostats_API/transformers/cash_flow/us.py,sha256=nRJajeDz4HNkv42NosoP0Jir4tIA0
|
|
78
78
|
neurostats_API/transformers/daily_chip/__init__.py,sha256=e-yvQ94J3dkzRbhZwOiAkyt_ub9bRQ7pAVDbO-61Grw,43
|
79
79
|
neurostats_API/transformers/daily_chip/base.py,sha256=KBsnpACakJh2W-k4Kvv-dVNnSNbUCGMeqvQsTQkz-aE,184
|
80
80
|
neurostats_API/transformers/daily_chip/tej.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
81
|
-
neurostats_API/transformers/daily_chip/twse_chip.py,sha256=
|
81
|
+
neurostats_API/transformers/daily_chip/twse_chip.py,sha256=mUcHHQN9EFJkn1kB5KCcUoZJrHrMPBXotiJKQv7hM4Y,14660
|
82
82
|
neurostats_API/transformers/daily_chip/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
83
83
|
neurostats_API/transformers/daily_chip/utils/institution.py,sha256=1Zj9mxIhvwkmA599a1OYmdorPEAN_U3sl8uhvddxUW0,3384
|
84
84
|
neurostats_API/transformers/daily_chip/utils/margin_trading.py,sha256=oVY_OW63pcSc1TyM_jSPNAoj4HLyZCRshkdsHQsnxyk,38
|
@@ -113,7 +113,7 @@ neurostats_API/utils/datetime.py,sha256=XJya4G8b_-ZOaBbMXgQjWh2MC4wc-o6goQ7EQJQM
|
|
113
113
|
neurostats_API/utils/db_client.py,sha256=OYe6yazcR4Aa6jYmy47JrryUeh2NnKGqY2K_lSZe6i8,455
|
114
114
|
neurostats_API/utils/exception.py,sha256=yv92GVh5uHV1BgRmO4DwJcX_PtE0-TSgQoo3VnZ5hOQ,277
|
115
115
|
neurostats_API/utils/logger.py,sha256=egBiiPGTi5l1FoX_o6EvdGh81R0_k8hFPctSxq8RCoo,693
|
116
|
-
neurostats_API-1.0.
|
117
|
-
neurostats_API-1.0.
|
118
|
-
neurostats_API-1.0.
|
119
|
-
neurostats_API-1.0.
|
116
|
+
neurostats_API-1.0.0rc2.dist-info/METADATA,sha256=xQ479cEYQ3A48QpJlltoMehvj3mG6fxyT09XjWru4SU,2964
|
117
|
+
neurostats_API-1.0.0rc2.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
|
118
|
+
neurostats_API-1.0.0rc2.dist-info/top_level.txt,sha256=nSlQPMG0VtXivJyedp4Bkf86EOy2TpW10VGxolXrqnU,15
|
119
|
+
neurostats_API-1.0.0rc2.dist-info/RECORD,,
|
File without changes
|
File without changes
|