neurostats-API 0.0.17__tar.gz → 0.0.19__tar.gz

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.
Files changed (40) hide show
  1. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/PKG-INFO +56 -26
  2. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/README.md +55 -25
  3. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API/__init__.py +3 -2
  4. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API/fetchers/__init__.py +1 -1
  5. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API/fetchers/base.py +54 -15
  6. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API/fetchers/tech.py +107 -80
  7. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API/fetchers/tej_finance_report.py +191 -98
  8. neurostats_api-0.0.19/neurostats_API/tools/tej_db_index.yaml +135 -0
  9. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API.egg-info/PKG-INFO +56 -26
  10. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API.egg-info/SOURCES.txt +1 -0
  11. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/setup.py +1 -1
  12. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/test/test_fetchers.py +9 -0
  13. neurostats_api-0.0.19/test/test_tej.py +53 -0
  14. neurostats_api-0.0.17/test/test_tej.py +0 -26
  15. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/MANIFEST.in +0 -0
  16. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API/cli.py +0 -0
  17. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API/fetchers/balance_sheet.py +0 -0
  18. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API/fetchers/cash_flow.py +0 -0
  19. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API/fetchers/finance_overview.py +0 -0
  20. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API/fetchers/institution.py +0 -0
  21. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API/fetchers/margin_trading.py +0 -0
  22. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API/fetchers/month_revenue.py +0 -0
  23. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API/fetchers/profit_lose.py +0 -0
  24. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API/fetchers/value_invest.py +0 -0
  25. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API/main.py +0 -0
  26. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API/tools/balance_sheet.yaml +0 -0
  27. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API/tools/cash_flow_percentage.yaml +0 -0
  28. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API/tools/finance_overview_dict.yaml +0 -0
  29. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API/tools/profit_lose.yaml +0 -0
  30. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API/tools/seasonal_data_field_dict.txt +0 -0
  31. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API/utils/__init__.py +0 -0
  32. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API/utils/calculate_value.py +0 -0
  33. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API/utils/data_process.py +0 -0
  34. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API/utils/datetime.py +0 -0
  35. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API/utils/db_client.py +0 -0
  36. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API/utils/fetcher.py +0 -0
  37. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API.egg-info/dependency_links.txt +0 -0
  38. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API.egg-info/requires.txt +0 -0
  39. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/neurostats_API.egg-info/top_level.txt +0 -0
  40. {neurostats_api-0.0.17 → neurostats_api-0.0.19}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: neurostats_API
3
- Version: 0.0.17
3
+ Version: 0.0.19
4
4
  Summary: The service of NeuroStats website
5
5
  Home-page: https://github.com/NeurowattStats/NeuroStats_API.git
6
6
  Author: JasonWang@Neurowatt
@@ -774,43 +774,73 @@ YoY_10 1.420500e-01 1.586797e-01 1.551364e-01
774
774
  }
775
775
  ```
776
776
 
777
+ ### 公司自結資料
778
+ ```Python
779
+ from neurostats_API import FinanceReportFetcher
777
780
 
778
- ## 版本紀錄
779
- ## 0.0.16
780
- - 處理ValueFetcher的error #issue76
781
+ fetcher = FinanceReportFetcher(
782
+ mongo_uri = mongo_uri,
783
+ db_name = db_name,
784
+ collection_name = collection_name
785
+ )
781
786
 
782
- - tej_fetcher新增 QOQ, YOY功能
787
+ data = fetcher.get(
788
+ ticker = "2330" # 任意的股票代碼
789
+ fetch_mode = fetcher.FetchMode.QOQ_NOCAL # 取得模式
790
+ start_date = "2005-01-01",
791
+ end_date = "2024-12-31",
792
+ report_type = "Q",
793
+ indexes = []
794
+ ) # -> pd.DataFrame or Dict[pd.DataFrame]
795
+ ```
796
+ - `ticker`: 股票代碼
783
797
 
784
- ## 0.0.15
785
- - TechFetcher中新增指數條件
798
+ - `fetch_mode` : 取得模式,為`fetcher.YOY_NOCAL` 或 `fetcher.QOQ_NOCAL`
799
+ - `YOY_NOCAL`: 以end_date為準,取得與end_date同季的歷年資料,時間範圍以start_date為起始
800
+ > 例如`start_date = "2020-07-01"`, `end_date = "2024-01-01"`,會回傳2020~2024的第一季資料
786
801
 
787
- - 新增tej_fetcher索取TEJ相關的資料
802
+ - `QOQ_NOCAL`: 時間範圍內的每季資料
788
803
 
789
- - package新增depensnecy,可以安裝需要的相關package
804
+ - `QOQ`: 時間範圍內每季的每個index的數值以及QoQ
790
805
 
791
- ## 0.0.14
792
- - 修改部分財報資料錯誤的乘以1000的問題
806
+ - `YoY`: 以end_date為準,取得與end_date同季的歷年資料以及成長率,時間範圍以start_date為起始
793
807
 
794
- - 新增例外處理: 若資料庫對於季資料一部分index缺失的情況下仍會盡可能去將資料蒐集並呈現
808
+ - `start_date`: 開始日期,不設定時預設為`2005-01-01`
795
809
 
796
- ### 0.0.13
797
- - value_fetcher 新增獲得一序列評價的功能
810
+ - `end_date`: 結束日期,不設定時預設為資料庫最新資料的日期
798
811
 
799
- ### 0.0.12
800
- - 新增資券變化(margin trading)
812
+ - `report_type`: 選擇哪種報告,預設為`Q`
813
+ - `A`: 當年累計
814
+ - `Q`: 當季數值
815
+ - `TTM`: 移動四季 (包括當季在內,往前累計四個季度)
801
816
 
802
- - 修改法人買賣(institution_trading)的query方式
817
+ - `indexes`: 選擇的column,需要以TEJ提供的欄位名稱為準,不提供時或提供`[]`會回傳全部column
818
+ - 範例輸入: `['bp41', 'bp51']`
803
819
 
804
- ### 0.0.11
805
- - 修復財務分析的千元計算問題
820
+ [TEJ資料集連結](https://tquant.tejwin.com/%E8%B3%87%E6%96%99%E9%9B%86/)
821
+ 請看 `公司自結數`
806
822
 
807
- - 籌碼面新增法人買賣(institution_trading)
823
+ ### 開高低收
824
+ ```Python
825
+ mongo_uri = <MongoDB 的 URI>
826
+ db_name = 'company' # 連接的DB名稱
827
+ collection_name = "TWN/APIPRCD" # 連接的collection對象
828
+ from neurostats_API import TEJStockPriceFetcher
808
829
 
809
- - 將財報三表與月營收的資料型態與數值做轉換(%轉字串, 千元乘以1000)
810
- ### 0.0.10
811
- - 更新指標的資料型態: 單位為千元乘以1000之後回傳整數
830
+ fetcher = TEJStockPriceFetcher(
831
+ mongo_uri = mongo_uri,
832
+ db_name = db_name,
833
+ collection_name = collection_name
834
+ )
812
835
 
813
- - 處理銀行公司在finanace_overview會報錯誤的問題(未完全解決,因銀行公司財報有許多名稱不同,目前都會顯示為None)
836
+ data = fetcher.get(
837
+ ticker = "2330" # 任意的股票代碼
838
+ start_date = "2005-01-01",
839
+ period = "3m"
840
+ ) # -> pd.DataFrame
841
+ ```
842
+ - `ticker`: 股票代碼
843
+ - `start_date`: 搜尋範圍的開始日期
844
+ - `period`: 搜尋的時間範圍長度
814
845
 
815
- ### 0.0.9
816
- - 更新指標的資料型態: 單位為日, %, 倍轉為字串
846
+ `period`與`start_date`同時存在時以period優先
@@ -758,43 +758,73 @@ YoY_10 1.420500e-01 1.586797e-01 1.551364e-01
758
758
  }
759
759
  ```
760
760
 
761
+ ### 公司自結資料
762
+ ```Python
763
+ from neurostats_API import FinanceReportFetcher
761
764
 
762
- ## 版本紀錄
763
- ## 0.0.16
764
- - 處理ValueFetcher的error #issue76
765
+ fetcher = FinanceReportFetcher(
766
+ mongo_uri = mongo_uri,
767
+ db_name = db_name,
768
+ collection_name = collection_name
769
+ )
765
770
 
766
- - tej_fetcher新增 QOQ, YOY功能
771
+ data = fetcher.get(
772
+ ticker = "2330" # 任意的股票代碼
773
+ fetch_mode = fetcher.FetchMode.QOQ_NOCAL # 取得模式
774
+ start_date = "2005-01-01",
775
+ end_date = "2024-12-31",
776
+ report_type = "Q",
777
+ indexes = []
778
+ ) # -> pd.DataFrame or Dict[pd.DataFrame]
779
+ ```
780
+ - `ticker`: 股票代碼
767
781
 
768
- ## 0.0.15
769
- - TechFetcher中新增指數條件
782
+ - `fetch_mode` : 取得模式,為`fetcher.YOY_NOCAL` 或 `fetcher.QOQ_NOCAL`
783
+ - `YOY_NOCAL`: 以end_date為準,取得與end_date同季的歷年資料,時間範圍以start_date為起始
784
+ > 例如`start_date = "2020-07-01"`, `end_date = "2024-01-01"`,會回傳2020~2024的第一季資料
770
785
 
771
- - 新增tej_fetcher索取TEJ相關的資料
786
+ - `QOQ_NOCAL`: 時間範圍內的每季資料
772
787
 
773
- - package新增depensnecy,可以安裝需要的相關package
788
+ - `QOQ`: 時間範圍內每季的每個index的數值以及QoQ
774
789
 
775
- ## 0.0.14
776
- - 修改部分財報資料錯誤的乘以1000的問題
790
+ - `YoY`: 以end_date為準,取得與end_date同季的歷年資料以及成長率,時間範圍以start_date為起始
777
791
 
778
- - 新增例外處理: 若資料庫對於季資料一部分index缺失的情況下仍會盡可能去將資料蒐集並呈現
792
+ - `start_date`: 開始日期,不設定時預設為`2005-01-01`
779
793
 
780
- ### 0.0.13
781
- - value_fetcher 新增獲得一序列評價的功能
794
+ - `end_date`: 結束日期,不設定時預設為資料庫最新資料的日期
782
795
 
783
- ### 0.0.12
784
- - 新增資券變化(margin trading)
796
+ - `report_type`: 選擇哪種報告,預設為`Q`
797
+ - `A`: 當年累計
798
+ - `Q`: 當季數值
799
+ - `TTM`: 移動四季 (包括當季在內,往前累計四個季度)
785
800
 
786
- - 修改法人買賣(institution_trading)的query方式
801
+ - `indexes`: 選擇的column,需要以TEJ提供的欄位名稱為準,不提供時或提供`[]`會回傳全部column
802
+ - 範例輸入: `['bp41', 'bp51']`
787
803
 
788
- ### 0.0.11
789
- - 修復財務分析的千元計算問題
804
+ [TEJ資料集連結](https://tquant.tejwin.com/%E8%B3%87%E6%96%99%E9%9B%86/)
805
+ 請看 `公司自結數`
790
806
 
791
- - 籌碼面新增法人買賣(institution_trading)
807
+ ### 開高低收
808
+ ```Python
809
+ mongo_uri = <MongoDB 的 URI>
810
+ db_name = 'company' # 連接的DB名稱
811
+ collection_name = "TWN/APIPRCD" # 連接的collection對象
812
+ from neurostats_API import TEJStockPriceFetcher
792
813
 
793
- - 將財報三表與月營收的資料型態與數值做轉換(%轉字串, 千元乘以1000)
794
- ### 0.0.10
795
- - 更新指標的資料型態: 單位為千元乘以1000之後回傳整數
814
+ fetcher = TEJStockPriceFetcher(
815
+ mongo_uri = mongo_uri,
816
+ db_name = db_name,
817
+ collection_name = collection_name
818
+ )
796
819
 
797
- - 處理銀行公司在finanace_overview會報錯誤的問題(未完全解決,因銀行公司財報有許多名稱不同,目前都會顯示為None)
820
+ data = fetcher.get(
821
+ ticker = "2330" # 任意的股票代碼
822
+ start_date = "2005-01-01",
823
+ period = "3m"
824
+ ) # -> pd.DataFrame
825
+ ```
826
+ - `ticker`: 股票代碼
827
+ - `start_date`: 搜尋範圍的開始日期
828
+ - `period`: 搜尋的時間範圍長度
798
829
 
799
- ### 0.0.9
800
- - 更新指標的資料型態: 單位為日, %, 倍轉為字串
830
+ `period`與`start_date`同時存在時以period優先
@@ -1,4 +1,4 @@
1
- __version__='0.0.16'
1
+ __version__='0.0.19'
2
2
 
3
3
  from .fetchers import (
4
4
  BalanceSheetFetcher,
@@ -9,5 +9,6 @@ from .fetchers import (
9
9
  MarginTradingFetcher,
10
10
  MonthRevenueFetcher,
11
11
  TechFetcher,
12
- ProfitLoseFetcher
12
+ TEJStockPriceFetcher,
13
+ ProfitLoseFetcher,
13
14
  )
@@ -2,7 +2,7 @@ from .base import StatsDateTime, StatsFetcher
2
2
  from .balance_sheet import BalanceSheetFetcher
3
3
  from .cash_flow import CashFlowFetcher
4
4
  from .finance_overview import FinanceOverviewFetcher
5
- from .tej_finance_report import FinanceReportFetcher
5
+ from .tej_finance_report import FinanceReportFetcher, TEJStockPriceFetcher
6
6
  from .tech import TechFetcher
7
7
  from .institution import InstitutionFetcher
8
8
  from .margin_trading import MarginTradingFetcher
@@ -1,4 +1,5 @@
1
1
  import abc
2
+ from typing import Union
2
3
  from pymongo import MongoClient
3
4
  import pandas as pd
4
5
  import json
@@ -53,8 +54,8 @@ class StatsFetcher:
53
54
  season = (month - 1) // 3 + 1
54
55
 
55
56
  return StatsDateTime(date, year, month, day, season)
56
-
57
- def has_required_columns(self, df:pd.DataFrame, required_cols=None):
57
+
58
+ def has_required_columns(self, df: pd.DataFrame, required_cols=None):
58
59
  """
59
60
  Check if the required columns are present in the DataFrame.
60
61
 
@@ -68,23 +69,22 @@ class StatsFetcher:
68
69
  """
69
70
  if required_cols is None:
70
71
  required_cols = ['date', 'open', 'high', 'low', 'close', 'volume']
71
-
72
+
72
73
  return all(col in df.columns for col in required_cols)
73
74
 
74
75
 
75
76
  class BaseTEJFetcher(abc.ABC):
76
77
 
77
- def __init__(self):
78
- self.client = None
79
- self.db = None
80
- self.collection = None
81
-
82
78
  @abc.abstractmethod
83
79
  def get(self):
84
80
  pass
85
81
 
86
82
  def get_latest_data_time(self, ticker):
87
- latest_data = self.collection.find_one({"ticker": ticker}, {"last_update": 1, "_id": 0})
83
+ latest_data = self.collection.find_one(
84
+ {"ticker": ticker}, {
85
+ "last_update": 1,
86
+ "_id": 0
87
+ })
88
88
 
89
89
  try:
90
90
  latest_date = latest_data['last_update']["latest_data_date"]
@@ -93,11 +93,16 @@ class BaseTEJFetcher(abc.ABC):
93
93
 
94
94
  return latest_date
95
95
 
96
- def cal_YoY(self, data_dict: dict, start_year: int, end_year: int, season: int):
96
+ def cal_YoY(
97
+ self, data_dict: dict, start_year: int, end_year: int, season: int):
97
98
  year_shifts = [1, 3, 5, 10]
98
99
  return_dict = {}
99
100
  for year in range(start_year, end_year + 1):
100
- year_data = data_dict[f"{year}Q{season}"]
101
+ try:
102
+ year_data = data_dict[f"{year}Q{season}"].copy()
103
+ except KeyError as e:
104
+ continue
105
+
101
106
  year_keys = list(year_data.keys())
102
107
  for key in year_keys:
103
108
  if (key in 'season'):
@@ -109,9 +114,11 @@ class BaseTEJFetcher(abc.ABC):
109
114
  for shift in year_shifts:
110
115
  this_value = year_data[key]
111
116
  try:
112
- past_year = str(year - shift)
117
+ past_year = year - shift
113
118
  last_value = data_dict[f"{past_year}Q{season}"][key]
114
- temp_dict[f"YoY_{shift}"] = YoY_Calculator.cal_growth(this_value, last_value, delta=shift)
119
+ temp_dict[
120
+ f"YoY_{shift}"] = YoY_Calculator.cal_growth(
121
+ this_value, last_value, delta=shift)
115
122
  except Exception as e:
116
123
  temp_dict[f"YoY_{shift}"] = None
117
124
 
@@ -149,9 +156,11 @@ class BaseTEJFetcher(abc.ABC):
149
156
  temp_dict = {"value": this_value}
150
157
 
151
158
  try:
152
- last_value = data_dict[f"{last_year}Q{last_season}"][key]['value']
159
+ last_value = data_dict[f"{last_year}Q{last_season}"][
160
+ key]['value']
153
161
 
154
- temp_dict['growth'] = YoY_Calculator.cal_growth(this_value, last_value, delta=1)
162
+ temp_dict['growth'] = YoY_Calculator.cal_growth(
163
+ this_value, last_value, delta=1)
155
164
  except Exception as e:
156
165
  temp_dict['growth'] = None
157
166
 
@@ -169,3 +178,33 @@ class BaseTEJFetcher(abc.ABC):
169
178
  for key in data_dict.keys():
170
179
  data_dict[key] = pd.DataFrame.from_dict(data_dict[key])
171
180
  return data_dict
181
+
182
+ def set_time_shift(self, date: Union[str, datetime], period: str):
183
+ if (isinstance(date, str)):
184
+ date = datetime.strptime(date, "%Y-%m-%d")
185
+ if (period == '1d'):
186
+ return date - timedelta(days=1)
187
+
188
+ elif (period == '7d'):
189
+ return date - timedelta(days=7)
190
+
191
+ elif (period == '1m'):
192
+ return date - timedelta(days=30)
193
+
194
+ elif (period == '3m'):
195
+ return date - timedelta(days=90)
196
+
197
+ elif (period == '1y'):
198
+ return date - timedelta(days=365)
199
+
200
+ elif (period == '3y'):
201
+ return date - timedelta(days=365 * 3)
202
+
203
+ elif (period == '5y'):
204
+ return date - timedelta(days=365 * 5)
205
+
206
+ elif (period == '10y'):
207
+ return date - timedelta(days=365 * 10)
208
+
209
+ elif (period == 'all'):
210
+ return datetime.strptime("1991-01-01", "%Y-%m-%d")