neurostats-API 0.0.21__py3-none-any.whl → 0.0.22__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/fetchers/balance_sheet.py +138 -111
- neurostats_API/fetchers/base.py +89 -74
- neurostats_API/fetchers/cash_flow.py +120 -111
- neurostats_API/fetchers/finance_overview.py +2 -2
- neurostats_API/fetchers/month_revenue.py +1 -1
- neurostats_API/fetchers/profit_lose.py +188 -113
- neurostats_API/fetchers/tech.py +73 -33
- neurostats_API/fetchers/tej_finance_report.py +230 -335
- neurostats_API/tools/company_list/tw.json +2175 -0
- neurostats_API/tools/tej_db/tej_db_skip_index.yaml +3 -1
- neurostats_API/tools/tej_db/tej_db_thousand_index.yaml +0 -1
- neurostats_API/tools/twse/balance_sheet.yaml +35 -0
- neurostats_API/tools/twse/cash_flow_percentage.yaml +39 -0
- neurostats_API/tools/twse/finance_overview_dict.yaml +185 -0
- neurostats_API/tools/twse/profit_lose.yaml +143 -0
- neurostats_API/utils/__init__.py +0 -1
- neurostats_API/utils/calculate_value.py +99 -1
- neurostats_API/utils/data_process.py +43 -15
- {neurostats_API-0.0.21.dist-info → neurostats_API-0.0.22.dist-info}/METADATA +3 -3
- neurostats_API-0.0.22.dist-info/RECORD +34 -0
- neurostats_API/utils/fetcher.py +0 -1056
- neurostats_API-0.0.21.dist-info/RECORD +0 -30
- /neurostats_API/tools/{seasonal_data_field_dict.txt → twse/seasonal_data_field_dict.txt} +0 -0
- {neurostats_API-0.0.21.dist-info → neurostats_API-0.0.22.dist-info}/WHEEL +0 -0
- {neurostats_API-0.0.21.dist-info → neurostats_API-0.0.22.dist-info}/top_level.txt +0 -0
neurostats_API/fetchers/tech.py
CHANGED
@@ -12,7 +12,9 @@ class TechFetcher(StatsFetcher):
|
|
12
12
|
"""
|
13
13
|
|
14
14
|
super().__init__(ticker, db_client)
|
15
|
-
|
15
|
+
if (ticker in self.tw_company_list.keys()):
|
16
|
+
self.collection = self.db["TWN/APIPRCD"]
|
17
|
+
|
16
18
|
self.full_ohlcv = self._get_ohlcv()
|
17
19
|
self.basic_indexes = [
|
18
20
|
'SMA5', 'SMA20', 'SMA60', 'EMA5', 'EMA20', 'EMA40', 'EMA12',
|
@@ -55,49 +57,31 @@ class TechFetcher(StatsFetcher):
|
|
55
57
|
# 先對yf search
|
56
58
|
if self.ticker in ['GSPC', 'IXIC', 'DJI', 'TWII']:
|
57
59
|
full_tick = f'^{self.ticker}'
|
58
|
-
|
60
|
+
elif(self.ticker in self.tw_company_list.keys()):
|
59
61
|
full_tick = f'{self.ticker}.tw'
|
62
|
+
else:
|
63
|
+
full_tick = f"{self.ticker}"
|
60
64
|
|
61
65
|
df = self.conduct_yf_search(full_tick)
|
62
66
|
|
63
|
-
if
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
+
if (
|
68
|
+
self.ticker in self.tw_company_list.keys() and
|
69
|
+
not self.has_required_columns(df, required_cols)
|
70
|
+
):
|
67
71
|
full_tick = f'{self.ticker}.two'
|
68
72
|
|
69
73
|
df = self.conduct_yf_search(full_tick)
|
70
74
|
|
71
75
|
if (df.empty):
|
72
|
-
raise ValueError(f"No data found for ticker: {self.ticker}")
|
76
|
+
raise ValueError(f"No data found for ticker: {self.ticker}")\
|
77
|
+
|
78
|
+
return df[required_cols]
|
73
79
|
|
74
80
|
except (KeyError, ValueError, TypeError) as e:
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
tej_name_proj = {
|
80
|
-
tej_name: org_name
|
81
|
-
for tej_name, org_name in zip(tej_required_cols, required_cols)
|
82
|
-
}
|
83
|
-
|
84
|
-
query = {'ticker': self.ticker}
|
85
|
-
ticker_full = self.collection.find_one(query)
|
86
|
-
|
87
|
-
if not ticker_full:
|
88
|
-
raise ValueError("No ticker found in database")
|
89
|
-
|
90
|
-
daily_data = ticker_full.get("data", [])
|
91
|
-
if not isinstance(daily_data, list):
|
92
|
-
raise TypeError("Expected 'daily_data' to be a list.")
|
93
|
-
|
94
|
-
df = pd.DataFrame(daily_data)
|
95
|
-
|
96
|
-
if not self.has_required_columns(df, tej_required_cols):
|
97
|
-
raise KeyError(f"Missing required columns")
|
98
|
-
df = df.rename(columns=tej_name_proj)
|
99
|
-
|
100
|
-
return df[required_cols]
|
81
|
+
if (self.collection_name in ['TWN/APIPRCD']):
|
82
|
+
return self.conduct_db_search_tej()
|
83
|
+
elif (self.collection_name == 'us_stats'):
|
84
|
+
return self.conduct_db_search_us()
|
101
85
|
|
102
86
|
def get_daily(self):
|
103
87
|
|
@@ -141,6 +125,62 @@ class TechFetcher(StatsFetcher):
|
|
141
125
|
)
|
142
126
|
|
143
127
|
return df
|
128
|
+
|
129
|
+
def conduct_db_search_tej(self):
|
130
|
+
# 再對TEJ search
|
131
|
+
tej_required_cols = [
|
132
|
+
"mdate", "open_d", 'high_d', 'low_d', 'close_d', 'vol'
|
133
|
+
]
|
134
|
+
|
135
|
+
required_cols = ['date', 'open', 'high', 'low', 'close', 'volume']
|
136
|
+
tej_name_proj = {
|
137
|
+
tej_name: org_name
|
138
|
+
for tej_name, org_name in zip(tej_required_cols, required_cols)
|
139
|
+
}
|
140
|
+
|
141
|
+
query = {'ticker': self.ticker}
|
142
|
+
ticker_full = self.collection.find_one(query)
|
143
|
+
|
144
|
+
if not ticker_full:
|
145
|
+
raise ValueError("No ticker found in database")
|
146
|
+
|
147
|
+
daily_data = ticker_full.get("data", [])
|
148
|
+
if not isinstance(daily_data, list):
|
149
|
+
raise TypeError("Expected 'daily_data' to be a list.")
|
150
|
+
|
151
|
+
df = pd.DataFrame(daily_data)
|
152
|
+
|
153
|
+
if not self.has_required_columns(df, tej_required_cols):
|
154
|
+
raise KeyError(f"Missing required columns")
|
155
|
+
df = df.rename(columns=tej_name_proj)
|
156
|
+
|
157
|
+
return df[required_cols]
|
158
|
+
|
159
|
+
def conduct_db_search_us(self):
|
160
|
+
required_cols = ['date', 'open', 'high', 'low', 'close', 'volume']
|
161
|
+
|
162
|
+
query = {'ticker': self.ticker}
|
163
|
+
filter_query = {"daily_data" : 1, "_id": 0}
|
164
|
+
ticker_full = self.collection.find_one(query, filter_query)
|
165
|
+
|
166
|
+
if not ticker_full:
|
167
|
+
raise ValueError("No ticker found in database")
|
168
|
+
|
169
|
+
daily_data = ticker_full.get("daily_data", [])
|
170
|
+
if not isinstance(daily_data, list):
|
171
|
+
raise TypeError("Expected 'daily_data' to be a list.")
|
172
|
+
|
173
|
+
df = pd.DataFrame(daily_data)
|
174
|
+
|
175
|
+
if not self.has_required_columns(df, required_cols):
|
176
|
+
missing_cols = [col for col in required_cols if col not in df.columns]
|
177
|
+
missing_cols = ",".join(missing_cols)
|
178
|
+
print(Warning(f"{missing_cols} not in columns"))
|
179
|
+
for col in missing_cols:
|
180
|
+
df[col] = pd.NA
|
181
|
+
# raise KeyError(f"Missing required columns")
|
182
|
+
|
183
|
+
return df[required_cols]
|
144
184
|
|
145
185
|
|
146
186
|
class TechProcessor:
|