neurostats-API 0.0.25rc1__tar.gz → 1.0.0rc2__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.
- neurostats_api-1.0.0rc2/MANIFEST.in +9 -0
- neurostats_api-1.0.0rc2/PKG-INFO +102 -0
- neurostats_api-1.0.0rc2/README.md +85 -0
- {neurostats_api-0.0.25rc1 → neurostats_api-1.0.0rc2}/neurostats_API/__init__.py +1 -1
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/__init__.py +13 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/db/__init__.py +3 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/db/base.py +24 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/db/tej.py +10 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/db/twse.py +8 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/db/us.py +9 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/db_extractors/__init__.py +20 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/db_extractors/base.py +66 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/db_extractors/daily/__init__.py +7 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/db_extractors/daily/base.py +89 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/db_extractors/daily/tej_chip.py +14 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/db_extractors/daily/tej_tech.py +12 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/db_extractors/daily/twse_chip.py +49 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/db_extractors/daily/value.py +93 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/db_extractors/daily/yf.py +12 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/db_extractors/month_revenue/__init__.py +1 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/db_extractors/month_revenue/base.py +140 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/db_extractors/month_revenue/twse.py +5 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/db_extractors/seasonal/__init__.py +4 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/db_extractors/seasonal/balance_sheet.py +19 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/db_extractors/seasonal/base.py +152 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/db_extractors/seasonal/cashflow.py +10 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/db_extractors/seasonal/profit_lose.py +17 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/db_extractors/seasonal/tej.py +87 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/factory/__init__.py +1 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/factory/extractor_factory.py +168 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/factory/transformer_factory.py +164 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/fetchers/__init__.py +10 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/fetchers/balance_sheet.py +31 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/fetchers/base.py +48 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/fetchers/cash_flow.py +56 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/fetchers/finance_overview.py +134 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/fetchers/month_revenue.py +35 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/fetchers/profit_lose.py +46 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/fetchers/tech.py +205 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/fetchers/tej.py +88 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/fetchers/twse_institution.py +62 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/fetchers/twse_margin.py +100 -0
- neurostats_api-1.0.0rc2/neurostats_API/async_mode/fetchers/value.py +76 -0
- neurostats_api-1.0.0rc2/neurostats_API/config/company_list/ticker_index_industry_map.json +7946 -0
- neurostats_api-1.0.0rc2/neurostats_API/config/company_list/us.json +9986 -0
- {neurostats_api-0.0.25rc1/neurostats_API/tools → neurostats_api-1.0.0rc2/neurostats_API/config}/tej_db/tej_db_skip_index.yaml +0 -2
- {neurostats_api-0.0.25rc1/neurostats_API/tools → neurostats_api-1.0.0rc2/neurostats_API/config}/twse/profit_lose.yaml +0 -6
- {neurostats_api-0.0.25rc1 → neurostats_api-1.0.0rc2}/neurostats_API/fetchers/finance_overview.py +27 -5
- neurostats_api-1.0.0rc2/neurostats_API/transformers/__init__.py +40 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/balance_sheet/__init__.py +2 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/balance_sheet/base.py +51 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/balance_sheet/twse.py +76 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/balance_sheet/us.py +30 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/base.py +110 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/cash_flow/__init__.py +2 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/cash_flow/base.py +114 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/cash_flow/twse.py +68 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/cash_flow/us.py +38 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/daily_chip/__init__.py +1 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/daily_chip/base.py +5 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/daily_chip/tej.py +0 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/daily_chip/twse_chip.py +415 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/daily_chip/utils/__init__.py +0 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/daily_chip/utils/institution.py +90 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/daily_chip/utils/margin_trading.py +2 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/daily_chip/utils/security_lending.py +0 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/daily_tech/__init__.py +1 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/daily_tech/base.py +5 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/daily_tech/tech.py +84 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/daily_tech/utils/__init__.py +1 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/daily_tech/utils/processor.py +251 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/finance_overview/__init__.py +2 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/finance_overview/agent_overview.py +55 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/finance_overview/base.py +824 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/finance_overview/stats_overview.py +64 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/month_revenue/__init__.py +1 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/month_revenue/base.py +60 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/month_revenue/twse.py +129 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/profit_lose/__init__.py +2 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/profit_lose/base.py +82 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/profit_lose/twse.py +133 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/profit_lose/us.py +25 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/tej/__init__.py +1 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/tej/base.py +149 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/tej/finance_statement.py +80 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/value/__init__.py +1 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/value/base.py +5 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/value/tej.py +8 -0
- neurostats_api-1.0.0rc2/neurostats_API/transformers/value/twse.py +48 -0
- {neurostats_api-0.0.25rc1 → neurostats_api-1.0.0rc2}/neurostats_API/utils/__init__.py +1 -1
- {neurostats_api-0.0.25rc1 → neurostats_api-1.0.0rc2}/neurostats_API/utils/data_process.py +10 -6
- neurostats_api-1.0.0rc2/neurostats_API/utils/exception.py +11 -0
- neurostats_api-1.0.0rc2/neurostats_API/utils/logger.py +21 -0
- neurostats_api-1.0.0rc2/neurostats_API.egg-info/PKG-INFO +102 -0
- neurostats_api-1.0.0rc2/neurostats_API.egg-info/SOURCES.txt +126 -0
- {neurostats_api-0.0.25rc1 → neurostats_api-1.0.0rc2}/setup.py +2 -2
- neurostats_api-1.0.0rc2/test/test_async_fetcher.py +244 -0
- {neurostats_api-0.0.25rc1 → neurostats_api-1.0.0rc2}/test/test_fetchers.py +8 -8
- {neurostats_api-0.0.25rc1 → neurostats_api-1.0.0rc2}/test/test_tej.py +0 -1
- neurostats_api-0.0.25rc1/MANIFEST.in +0 -9
- neurostats_api-0.0.25rc1/PKG-INFO +0 -858
- neurostats_api-0.0.25rc1/README.md +0 -841
- neurostats_api-0.0.25rc1/neurostats_API/utils/exception.py +0 -3
- neurostats_api-0.0.25rc1/neurostats_API.egg-info/PKG-INFO +0 -858
- neurostats_api-0.0.25rc1/neurostats_API.egg-info/SOURCES.txt +0 -42
- {neurostats_api-0.0.25rc1 → neurostats_api-1.0.0rc2}/neurostats_API/cli.py +0 -0
- {neurostats_api-0.0.25rc1/neurostats_API/tools → neurostats_api-1.0.0rc2/neurostats_API/config}/company_list/tw.json +0 -0
- {neurostats_api-0.0.25rc1/neurostats_API/tools → neurostats_api-1.0.0rc2/neurostats_API/config}/company_list/us_TradingView_list.json +0 -0
- {neurostats_api-0.0.25rc1/neurostats_API/tools → neurostats_api-1.0.0rc2/neurostats_API/config}/tej_db/tej_db_index.yaml +0 -0
- {neurostats_api-0.0.25rc1/neurostats_API/tools → neurostats_api-1.0.0rc2/neurostats_API/config}/tej_db/tej_db_percent_index.yaml +0 -0
- {neurostats_api-0.0.25rc1/neurostats_API/tools → neurostats_api-1.0.0rc2/neurostats_API/config}/tej_db/tej_db_thousand_index.yaml +0 -0
- {neurostats_api-0.0.25rc1/neurostats_API/tools → neurostats_api-1.0.0rc2/neurostats_API/config}/twse/balance_sheet.yaml +0 -0
- {neurostats_api-0.0.25rc1/neurostats_API/tools → neurostats_api-1.0.0rc2/neurostats_API/config}/twse/cash_flow_percentage.yaml +0 -0
- {neurostats_api-0.0.25rc1/neurostats_API/tools → neurostats_api-1.0.0rc2/neurostats_API/config}/twse/finance_overview_dict.yaml +0 -0
- {neurostats_api-0.0.25rc1/neurostats_API/tools → neurostats_api-1.0.0rc2/neurostats_API/config}/twse/seasonal_data_field_dict.txt +0 -0
- {neurostats_api-0.0.25rc1 → neurostats_api-1.0.0rc2}/neurostats_API/fetchers/__init__.py +0 -0
- {neurostats_api-0.0.25rc1 → neurostats_api-1.0.0rc2}/neurostats_API/fetchers/balance_sheet.py +0 -0
- {neurostats_api-0.0.25rc1 → neurostats_api-1.0.0rc2}/neurostats_API/fetchers/base.py +0 -0
- {neurostats_api-0.0.25rc1 → neurostats_api-1.0.0rc2}/neurostats_API/fetchers/cash_flow.py +0 -0
- {neurostats_api-0.0.25rc1 → neurostats_api-1.0.0rc2}/neurostats_API/fetchers/institution.py +0 -0
- {neurostats_api-0.0.25rc1 → neurostats_api-1.0.0rc2}/neurostats_API/fetchers/margin_trading.py +0 -0
- {neurostats_api-0.0.25rc1 → neurostats_api-1.0.0rc2}/neurostats_API/fetchers/month_revenue.py +0 -0
- {neurostats_api-0.0.25rc1 → neurostats_api-1.0.0rc2}/neurostats_API/fetchers/profit_lose.py +0 -0
- {neurostats_api-0.0.25rc1 → neurostats_api-1.0.0rc2}/neurostats_API/fetchers/tech.py +0 -0
- {neurostats_api-0.0.25rc1 → neurostats_api-1.0.0rc2}/neurostats_API/fetchers/tej_finance_report.py +0 -0
- {neurostats_api-0.0.25rc1 → neurostats_api-1.0.0rc2}/neurostats_API/fetchers/value_invest.py +0 -0
- {neurostats_api-0.0.25rc1 → neurostats_api-1.0.0rc2}/neurostats_API/main.py +0 -0
- {neurostats_api-0.0.25rc1 → neurostats_api-1.0.0rc2}/neurostats_API/utils/calculate_value.py +0 -0
- {neurostats_api-0.0.25rc1 → neurostats_api-1.0.0rc2}/neurostats_API/utils/datetime.py +0 -0
- {neurostats_api-0.0.25rc1 → neurostats_api-1.0.0rc2}/neurostats_API/utils/db_client.py +0 -0
- {neurostats_api-0.0.25rc1 → neurostats_api-1.0.0rc2}/neurostats_API.egg-info/dependency_links.txt +0 -0
- {neurostats_api-0.0.25rc1 → neurostats_api-1.0.0rc2}/neurostats_API.egg-info/requires.txt +0 -0
- {neurostats_api-0.0.25rc1 → neurostats_api-1.0.0rc2}/neurostats_API.egg-info/top_level.txt +0 -0
- {neurostats_api-0.0.25rc1 → neurostats_api-1.0.0rc2}/setup.cfg +0 -0
@@ -0,0 +1,9 @@
|
|
1
|
+
recursive-include neurostats_api/config/tej_db *.yaml
|
2
|
+
recursive-include neurostats_api/config/tej_db *.txt
|
3
|
+
recursive-include neurostats_api/config/tej_db *.json
|
4
|
+
recursive-include neurostats_api/config/twse *.yaml
|
5
|
+
recursive-include neurostats_api/config/twse *.txt
|
6
|
+
recursive-include neurostats_api/config/twse *.json
|
7
|
+
recursive-include neurostats_api/config/company_list *.yaml
|
8
|
+
recursive-include neurostats_api/config/company_list *.txt
|
9
|
+
recursive-include neurostats_api/config/company_list *.json
|
@@ -0,0 +1,102 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: neurostats_API
|
3
|
+
Version: 1.0.0rc2
|
4
|
+
Summary: The service of NeuroStats website
|
5
|
+
Home-page: https://github.com/NeurowattStats/NeuroStats_API.git
|
6
|
+
Author: JasonWang@Neurowatt
|
7
|
+
Author-email: jason@neurowatt.ai
|
8
|
+
Requires-Python: >=3.6
|
9
|
+
Description-Content-Type: text/markdown
|
10
|
+
Requires-Dist: numpy
|
11
|
+
Requires-Dist: pandas
|
12
|
+
Requires-Dist: pymongo
|
13
|
+
Requires-Dist: pytz
|
14
|
+
Requires-Dist: python-dotenv
|
15
|
+
Requires-Dist: yfinance
|
16
|
+
Requires-Dist: holidays
|
17
|
+
|
18
|
+
# neurostats_API
|
19
|
+
|
20
|
+
- [檔案架構](#檔案架構)
|
21
|
+
- [下載](#下載)
|
22
|
+
- [使用方法](#使用方法)
|
23
|
+
|
24
|
+
## 檔案架構
|
25
|
+
|
26
|
+
```
|
27
|
+
./neurostats_API
|
28
|
+
├── async_mode
|
29
|
+
│ ├── db
|
30
|
+
│ ├── db_extractors
|
31
|
+
│ │ ├── daily
|
32
|
+
│ │ ├── month_revenue
|
33
|
+
│ │ └── seasonal
|
34
|
+
│ ├── factory
|
35
|
+
│ └── fetchers
|
36
|
+
├── config
|
37
|
+
│ ├── company_list
|
38
|
+
│ ├── tej_db
|
39
|
+
│ └── twse
|
40
|
+
├── fetchers
|
41
|
+
├── transformers
|
42
|
+
│ ├── balance_sheet
|
43
|
+
│ ├── cash_flow
|
44
|
+
│ ├── daily_chip
|
45
|
+
│ │ └── utils
|
46
|
+
│ ├── daily_tech
|
47
|
+
│ │ └── utils
|
48
|
+
│ ├── finance_overview
|
49
|
+
│ ├── month_revenue
|
50
|
+
│ ├── profit_lose
|
51
|
+
│ ├── tej
|
52
|
+
│ └── value
|
53
|
+
└── utils
|
54
|
+
```
|
55
|
+
- `neurostats_API`: 主要的package運行內容
|
56
|
+
- `async_mode`: \[新版新增\]以非同步方式進行DB資料的取得以及回傳資料
|
57
|
+
- `/db`: 連接到伺服器下的特定db
|
58
|
+
- `/db_extractor`: 決定取得db下的哪個collection的檔案,以及取得檔案內容
|
59
|
+
` `/factory`: 使extractor的初始化變得通用
|
60
|
+
- `/fetchers`: 開發者將此套件用於其他專案的接口
|
61
|
+
- `fetchers`: (舊版)回傳service內容的fetcher檔案夾
|
62
|
+
- `transformers`: \[新版新增\] 處理從DB取出的資料,以dictionary的方式回傳需要的資料
|
63
|
+
- `config`: 【新舊通用】存放各種設定檔的dictionary,例如公司名單、各項指標對應的計算欄位、每個項目屬於哪份財報等設定
|
64
|
+
- `utils`: 【新舊通用】class之間通用的函式,例如讀取檔案、計算成長率函式、轉換格式與進位等
|
65
|
+
|
66
|
+
## 下載
|
67
|
+
```
|
68
|
+
pip install neurostats-API
|
69
|
+
```
|
70
|
+
### 確認下載成功
|
71
|
+
```Python
|
72
|
+
>>> import neurostats_API
|
73
|
+
>>> print(neurostats_API.__version__)
|
74
|
+
1.0.0rc2
|
75
|
+
```
|
76
|
+
|
77
|
+
### 下載舊版
|
78
|
+
```
|
79
|
+
pip install neurostats-API==0.0.25
|
80
|
+
```
|
81
|
+
|
82
|
+
## 使用方式 (以Balance_Sheet為例)
|
83
|
+
### Async Mode
|
84
|
+
```
|
85
|
+
from neurostats_API.async_mode.fetchers import AsyncBalanceSheetFetcher
|
86
|
+
from pymongo import AsyncMongoClient
|
87
|
+
|
88
|
+
db_client = AsyncMongoClient("<伺服器的MONGO_URI>")
|
89
|
+
ticker = "2330"
|
90
|
+
|
91
|
+
fetcher = AsyncBalanceSheetFetcher(ticker, db_client)
|
92
|
+
|
93
|
+
data = await fetcher.query_data()
|
94
|
+
|
95
|
+
print(data)
|
96
|
+
```
|
97
|
+
詳細各個fetcher的使用法請到[async_mode的fetchers資料夾下觀看](./neurostats_API/async_mode/fetchers/README.md)
|
98
|
+
|
99
|
+
### Sync Mode
|
100
|
+
(#TODO)
|
101
|
+
|
102
|
+
> 舊版使用方法請到[fetchers資料夾下觀看](./neurostats_API/fetchers/README.md)
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# neurostats_API
|
2
|
+
|
3
|
+
- [檔案架構](#檔案架構)
|
4
|
+
- [下載](#下載)
|
5
|
+
- [使用方法](#使用方法)
|
6
|
+
|
7
|
+
## 檔案架構
|
8
|
+
|
9
|
+
```
|
10
|
+
./neurostats_API
|
11
|
+
├── async_mode
|
12
|
+
│ ├── db
|
13
|
+
│ ├── db_extractors
|
14
|
+
│ │ ├── daily
|
15
|
+
│ │ ├── month_revenue
|
16
|
+
│ │ └── seasonal
|
17
|
+
│ ├── factory
|
18
|
+
│ └── fetchers
|
19
|
+
├── config
|
20
|
+
│ ├── company_list
|
21
|
+
│ ├── tej_db
|
22
|
+
│ └── twse
|
23
|
+
├── fetchers
|
24
|
+
├── transformers
|
25
|
+
│ ├── balance_sheet
|
26
|
+
│ ├── cash_flow
|
27
|
+
│ ├── daily_chip
|
28
|
+
│ │ └── utils
|
29
|
+
│ ├── daily_tech
|
30
|
+
│ │ └── utils
|
31
|
+
│ ├── finance_overview
|
32
|
+
│ ├── month_revenue
|
33
|
+
│ ├── profit_lose
|
34
|
+
│ ├── tej
|
35
|
+
│ └── value
|
36
|
+
└── utils
|
37
|
+
```
|
38
|
+
- `neurostats_API`: 主要的package運行內容
|
39
|
+
- `async_mode`: \[新版新增\]以非同步方式進行DB資料的取得以及回傳資料
|
40
|
+
- `/db`: 連接到伺服器下的特定db
|
41
|
+
- `/db_extractor`: 決定取得db下的哪個collection的檔案,以及取得檔案內容
|
42
|
+
` `/factory`: 使extractor的初始化變得通用
|
43
|
+
- `/fetchers`: 開發者將此套件用於其他專案的接口
|
44
|
+
- `fetchers`: (舊版)回傳service內容的fetcher檔案夾
|
45
|
+
- `transformers`: \[新版新增\] 處理從DB取出的資料,以dictionary的方式回傳需要的資料
|
46
|
+
- `config`: 【新舊通用】存放各種設定檔的dictionary,例如公司名單、各項指標對應的計算欄位、每個項目屬於哪份財報等設定
|
47
|
+
- `utils`: 【新舊通用】class之間通用的函式,例如讀取檔案、計算成長率函式、轉換格式與進位等
|
48
|
+
|
49
|
+
## 下載
|
50
|
+
```
|
51
|
+
pip install neurostats-API
|
52
|
+
```
|
53
|
+
### 確認下載成功
|
54
|
+
```Python
|
55
|
+
>>> import neurostats_API
|
56
|
+
>>> print(neurostats_API.__version__)
|
57
|
+
1.0.0rc2
|
58
|
+
```
|
59
|
+
|
60
|
+
### 下載舊版
|
61
|
+
```
|
62
|
+
pip install neurostats-API==0.0.25
|
63
|
+
```
|
64
|
+
|
65
|
+
## 使用方式 (以Balance_Sheet為例)
|
66
|
+
### Async Mode
|
67
|
+
```
|
68
|
+
from neurostats_API.async_mode.fetchers import AsyncBalanceSheetFetcher
|
69
|
+
from pymongo import AsyncMongoClient
|
70
|
+
|
71
|
+
db_client = AsyncMongoClient("<伺服器的MONGO_URI>")
|
72
|
+
ticker = "2330"
|
73
|
+
|
74
|
+
fetcher = AsyncBalanceSheetFetcher(ticker, db_client)
|
75
|
+
|
76
|
+
data = await fetcher.query_data()
|
77
|
+
|
78
|
+
print(data)
|
79
|
+
```
|
80
|
+
詳細各個fetcher的使用法請到[async_mode的fetchers資料夾下觀看](./neurostats_API/async_mode/fetchers/README.md)
|
81
|
+
|
82
|
+
### Sync Mode
|
83
|
+
(#TODO)
|
84
|
+
|
85
|
+
> 舊版使用方法請到[fetchers資料夾下觀看](./neurostats_API/fetchers/README.md)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
from .fetchers import (
|
2
|
+
AsyncAgentOverviewFetcher,
|
3
|
+
AsyncBalanceSheetFetcher,
|
4
|
+
AsyncCashFlowFetcher,
|
5
|
+
AsyncFinanceOverviewFetcher,
|
6
|
+
AsyncMonthlyRevenueFetcher,
|
7
|
+
AsyncProfitLoseFetcher,
|
8
|
+
AsyncTechFetcher,
|
9
|
+
AsyncTEJSeasonalFetcher,
|
10
|
+
AsyncTWSEInstitutionFetcher,
|
11
|
+
AsyncTWSEMarginFetcher,
|
12
|
+
AsyncTWSEStatsValueFetcher
|
13
|
+
)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
from pymongo import AsyncMongoClient
|
2
|
+
|
3
|
+
class BaseDBClient:
|
4
|
+
def __init__(self, client: AsyncMongoClient, zone= None):
|
5
|
+
self.client = client
|
6
|
+
self.zone = zone or "tw" # 預設台灣
|
7
|
+
self.db = self._select_db()
|
8
|
+
|
9
|
+
def _select_db(self):
|
10
|
+
"""
|
11
|
+
根據 zone 選擇對應的資料庫
|
12
|
+
"""
|
13
|
+
zone_db_map = {
|
14
|
+
"tw": "company_test",
|
15
|
+
"us": "company_us"
|
16
|
+
}
|
17
|
+
db_name = zone_db_map.get(self.zone, "company_test")
|
18
|
+
return self.client[db_name]
|
19
|
+
|
20
|
+
def get_collection(self, collection_name: str):
|
21
|
+
"""
|
22
|
+
傳回指定 collection
|
23
|
+
"""
|
24
|
+
return self.db[collection_name]
|
@@ -0,0 +1,10 @@
|
|
1
|
+
from .base import BaseDBClient
|
2
|
+
import os
|
3
|
+
from pymongo import AsyncMongoClient
|
4
|
+
from dotenv import load_dotenv
|
5
|
+
|
6
|
+
class TEJDBClient(BaseDBClient):
|
7
|
+
def __init__(self, mongo_uri):
|
8
|
+
"""初始化時接收 MongoDB 連接 URI"""
|
9
|
+
super().__init__(mongo_uri, zone = 'tw')
|
10
|
+
self.db = self.client["company_test"]
|
@@ -0,0 +1,20 @@
|
|
1
|
+
from .daily import (
|
2
|
+
AsyncTEJDailyTechDBExtractor,
|
3
|
+
AsyncYFDailyTechDBExtractor,
|
4
|
+
AsyncDailyValueDBExtractor,
|
5
|
+
AsyncTEJDailyValueDBExtractor,
|
6
|
+
AsyncTWSEChipDBExtractor,
|
7
|
+
|
8
|
+
)
|
9
|
+
|
10
|
+
from .month_revenue import (
|
11
|
+
AsyncTWSEMonthlyRevenueExtractor
|
12
|
+
)
|
13
|
+
|
14
|
+
from .seasonal import (
|
15
|
+
AsyncBalanceSheetExtractor,
|
16
|
+
AsyncProfitLoseExtractor,
|
17
|
+
AsyncCashFlowExtractor,
|
18
|
+
AsyncTEJFinanceStatementDBExtractor,
|
19
|
+
AsyncTEJSelfSettlementDBExtractor
|
20
|
+
)
|
@@ -0,0 +1,66 @@
|
|
1
|
+
import abc
|
2
|
+
from datetime import datetime
|
3
|
+
from ..db import TWSEDBClient, USDBClient
|
4
|
+
import json
|
5
|
+
import pytz
|
6
|
+
from neurostats_API.utils import StatsDateTime, StatsProcessor, YoY_Calculator, NoCompanyError
|
7
|
+
|
8
|
+
class BaseDBExtractor(abc.ABC):
|
9
|
+
def __init__(self, ticker, client):
|
10
|
+
self.ticker = ticker
|
11
|
+
self.client = client
|
12
|
+
self.timezone = pytz.timezone("Asia/Taipei")
|
13
|
+
self.tw_company_list = StatsProcessor.load_json("company_list/tw.json")
|
14
|
+
self.us_company_list = StatsProcessor.load_json("company_list/us.json")
|
15
|
+
|
16
|
+
self.company_name, self.zone = self._set_company_name(self.ticker)
|
17
|
+
|
18
|
+
self.db_client = self._set_db_connection()
|
19
|
+
|
20
|
+
def _set_company_name(self, ticker):
|
21
|
+
company_lists = [
|
22
|
+
(self.tw_company_list, 'tw'),
|
23
|
+
(self.us_company_list, 'us')
|
24
|
+
]
|
25
|
+
|
26
|
+
for company_list, zone in company_lists:
|
27
|
+
company_name = company_list.get(ticker, None)
|
28
|
+
if (company_name):
|
29
|
+
return company_name, zone
|
30
|
+
# 沒找到公司名稱
|
31
|
+
raise NoCompanyError(f"Ticker-{ticker} not found in any company lists")
|
32
|
+
|
33
|
+
def _set_db_connection(self):
|
34
|
+
db_map = {
|
35
|
+
'tw': TWSEDBClient,
|
36
|
+
'us': USDBClient
|
37
|
+
}
|
38
|
+
db_client = db_map.get(self.zone, TWSEDBClient)
|
39
|
+
return db_client(self.client)
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
async def query_data(self):
|
44
|
+
"""
|
45
|
+
user使用的接口
|
46
|
+
"""
|
47
|
+
return NotImplementedError()
|
48
|
+
|
49
|
+
@abc.abstractmethod
|
50
|
+
def _prepare_query(self):
|
51
|
+
pass
|
52
|
+
|
53
|
+
def get_company_name(self):
|
54
|
+
"""
|
55
|
+
回傳公司
|
56
|
+
"""
|
57
|
+
return self.company_name
|
58
|
+
|
59
|
+
def get_zone(self):
|
60
|
+
"""
|
61
|
+
公司區域(TW, US)
|
62
|
+
"""
|
63
|
+
return self.zone
|
64
|
+
|
65
|
+
def _get_today(self):
|
66
|
+
return datetime.today()
|
@@ -0,0 +1,89 @@
|
|
1
|
+
from ..base import BaseDBExtractor
|
2
|
+
from datetime import datetime
|
3
|
+
from neurostats_API.utils import NotSupportedError
|
4
|
+
from pymongo import ASCENDING, DESCENDING
|
5
|
+
|
6
|
+
|
7
|
+
class BaseDailyTechDBExtractor(BaseDBExtractor):
|
8
|
+
|
9
|
+
def __init__(self, ticker, client):
|
10
|
+
super().__init__(ticker, client)
|
11
|
+
|
12
|
+
self.collection_name_map = None
|
13
|
+
self.collection_name = self._get_collection_name()
|
14
|
+
|
15
|
+
if (self.collection_name is None):
|
16
|
+
raise NotSupportedError(
|
17
|
+
f"{self.__class__.__name__} only supports {list(self.collection_name_map.keys())}, got {self.zone} with ticker = \"{self.ticker}\""
|
18
|
+
)
|
19
|
+
|
20
|
+
self.collection = self.db_client.get_collection(self.collection_name)
|
21
|
+
|
22
|
+
async def query_data(self, start_date=None, end_date=None, get_latest = False):
|
23
|
+
if (self.collection is None):
|
24
|
+
return []
|
25
|
+
|
26
|
+
if (start_date is None):
|
27
|
+
start_date = "1991-01-01"
|
28
|
+
if (end_date is None):
|
29
|
+
end_date = self._get_today()
|
30
|
+
|
31
|
+
query, projection, sort = self._prepare_query(
|
32
|
+
start_date=start_date, end_date=end_date, get_latest=get_latest
|
33
|
+
)
|
34
|
+
|
35
|
+
if (get_latest):
|
36
|
+
cursor = self.collection.find(query, projection).sort(sort).limit(1)
|
37
|
+
else:
|
38
|
+
cursor = self.collection.find(query, projection).sort(sort)
|
39
|
+
|
40
|
+
fetched_data = [data async for data in cursor]
|
41
|
+
|
42
|
+
return fetched_data
|
43
|
+
|
44
|
+
def _get_collection_name(self):
|
45
|
+
self.collection_name_map = {"tw": "twse_daily_share_price", "us": "us_technical"}
|
46
|
+
collection_name = self.collection_name_map.get(self.zone, None)
|
47
|
+
|
48
|
+
return collection_name
|
49
|
+
|
50
|
+
def _prepare_query(self, start_date=None, end_date=None, get_latest = False):
|
51
|
+
query = {"ticker": self.ticker}
|
52
|
+
|
53
|
+
query = self._update_query_with_date(query, start_date, end_date)
|
54
|
+
|
55
|
+
projection = {
|
56
|
+
"_id": 0,
|
57
|
+
}
|
58
|
+
|
59
|
+
if (get_latest):
|
60
|
+
sort = [("date", DESCENDING)]
|
61
|
+
else:
|
62
|
+
sort = [("date", ASCENDING)]
|
63
|
+
|
64
|
+
return query, projection, sort
|
65
|
+
|
66
|
+
def _update_query_with_date(self, query, start_date, end_date):
|
67
|
+
start_date = self._transform_date(start_date)
|
68
|
+
end_date = self._transform_date(end_date)
|
69
|
+
|
70
|
+
date_range = {"$gte": start_date, "$lte": end_date}
|
71
|
+
|
72
|
+
query.update({"date": date_range})
|
73
|
+
|
74
|
+
return query
|
75
|
+
|
76
|
+
def _transform_date(self, date):
|
77
|
+
if (isinstance(date, str)):
|
78
|
+
try:
|
79
|
+
return datetime.strptime(date, "%Y-%m-%d")
|
80
|
+
except Exception as e:
|
81
|
+
raise ValueError(
|
82
|
+
"date string format imcompatible, should be \"YYYY-MM-DD\""
|
83
|
+
)
|
84
|
+
elif (isinstance(date, datetime)):
|
85
|
+
return date
|
86
|
+
else:
|
87
|
+
raise ValueError(
|
88
|
+
"date type imcompatible, should be string(\"YYYY-MM-DD\") or datetime.datetime"
|
89
|
+
)
|
@@ -0,0 +1,14 @@
|
|
1
|
+
from .base import BaseDailyTechDBExtractor
|
2
|
+
from datetime import datetime
|
3
|
+
from pymongo import ASCENDING, DESCENDING
|
4
|
+
|
5
|
+
|
6
|
+
class AsyncTEJDailyChipDBExtractor(BaseDailyTechDBExtractor):
|
7
|
+
|
8
|
+
def __init__(self, ticker, client):
|
9
|
+
super().__init__(ticker, client)
|
10
|
+
|
11
|
+
def _get_collection_name(self):
|
12
|
+
self.collection_name_map = {"tw": "TEJ_chip"}
|
13
|
+
|
14
|
+
return self.collection_name_map.get(self.zone, None)
|
@@ -0,0 +1,12 @@
|
|
1
|
+
from .base import BaseDailyTechDBExtractor
|
2
|
+
|
3
|
+
|
4
|
+
class AsyncTEJDailyTechDBExtractor(BaseDailyTechDBExtractor):
|
5
|
+
|
6
|
+
def __init__(self, ticker, client):
|
7
|
+
super().__init__(ticker, client)
|
8
|
+
|
9
|
+
def _get_collection_name(self):
|
10
|
+
self.collection_name_map = {"tw": "TEJ_share_price"}
|
11
|
+
|
12
|
+
return self.collection_name_map.get(self.zone, None)
|
@@ -0,0 +1,49 @@
|
|
1
|
+
from .base import BaseDailyTechDBExtractor
|
2
|
+
from datetime import datetime
|
3
|
+
from pymongo import ASCENDING, DESCENDING
|
4
|
+
from neurostats_API.utils import NotSupportedError
|
5
|
+
|
6
|
+
class AsyncTWSEChipDBExtractor(BaseDailyTechDBExtractor):
|
7
|
+
|
8
|
+
def __init__(self, ticker, client, fetch_type = 'I'):
|
9
|
+
|
10
|
+
"""
|
11
|
+
擷取台股每日籌碼資料。
|
12
|
+
|
13
|
+
fetch_type:
|
14
|
+
- 'I' (INSTITUTION): 法人買賣
|
15
|
+
- 'M' (MARGIN): 融資融券餘額變化
|
16
|
+
- 'S' (SECURITY_LENDING): 借券債券
|
17
|
+
|
18
|
+
"""
|
19
|
+
super().__init__(ticker, client)
|
20
|
+
|
21
|
+
column_name_map = {
|
22
|
+
'tw': {
|
23
|
+
"I" : "institution_trading",
|
24
|
+
"M" : "margin_trading",
|
25
|
+
"S" : "security_lending"
|
26
|
+
},
|
27
|
+
}
|
28
|
+
self.target_column = column_name_map[self.zone][fetch_type]
|
29
|
+
|
30
|
+
def _get_collection_name(self):
|
31
|
+
self.collection_name_map = {"tw": "twse_chip"}
|
32
|
+
collection_name = self.collection_name_map.get(self.zone, None)
|
33
|
+
return collection_name
|
34
|
+
|
35
|
+
def _prepare_query(self, start_date=None, end_date=None, get_latest = False):
|
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
|
+
)
|
42
|
+
projection.update(
|
43
|
+
{
|
44
|
+
'date': 1,
|
45
|
+
self.target_column: 1
|
46
|
+
}
|
47
|
+
)
|
48
|
+
|
49
|
+
return query, projection, sort
|
@@ -0,0 +1,93 @@
|
|
1
|
+
from .base import BaseDailyTechDBExtractor
|
2
|
+
from pymongo import ASCENDING, DESCENDING
|
3
|
+
from neurostats_API.utils import NotSupportedError
|
4
|
+
|
5
|
+
class AsyncDailyValueDBExtractor(BaseDailyTechDBExtractor):
|
6
|
+
|
7
|
+
def __init__(self, ticker, client, fetch_type='D'):
|
8
|
+
"""
|
9
|
+
fetch_type:
|
10
|
+
'D': daily
|
11
|
+
'Y': yearly
|
12
|
+
"""
|
13
|
+
self.fetch_type = fetch_type
|
14
|
+
super().__init__(ticker, client)
|
15
|
+
|
16
|
+
def _get_collection_name(self):
|
17
|
+
self.collection_name_map = {
|
18
|
+
"tw": {
|
19
|
+
"D":"twse_daily_share_price",
|
20
|
+
"Y": "twse_yearly_value"
|
21
|
+
}
|
22
|
+
}
|
23
|
+
collection_map = self.collection_name_map.get(self.zone)
|
24
|
+
if (collection_map is None):
|
25
|
+
raise NotSupportedError(f"AsyncDailyValueDBExtractor only supports {self.collection_name_map.keys}, but get {self.zone}")
|
26
|
+
collection_name = collection_map.get(self.fetch_type)
|
27
|
+
if (collection_name is None):
|
28
|
+
raise ValueError(f"AsyncDailyValueDBExtractor: Invalid fetch type : {self.fetch_type}")
|
29
|
+
return collection_name
|
30
|
+
|
31
|
+
def _prepare_query(self, start_date = None, end_date = None, get_latest = False):
|
32
|
+
query_fn_map = {
|
33
|
+
'D': super()._prepare_query,
|
34
|
+
'Y': self._prepare_annual_query
|
35
|
+
}
|
36
|
+
|
37
|
+
query_fn = query_fn_map.get(self.fetch_type)
|
38
|
+
query, projection, sorting = query_fn(start_date=start_date, end_date=end_date, get_latest=get_latest)
|
39
|
+
|
40
|
+
projection.update(
|
41
|
+
{
|
42
|
+
"date": 1,
|
43
|
+
"year": 1,
|
44
|
+
"close": 1,
|
45
|
+
"P_E": 1,
|
46
|
+
"P_B": 1,
|
47
|
+
"P_FCF": 1,
|
48
|
+
"P_S": 1,
|
49
|
+
"EV_S": 1,
|
50
|
+
"EV_OPI": 1,
|
51
|
+
"EV_EBIT": 1,
|
52
|
+
"EV_EBITDA": 1
|
53
|
+
}
|
54
|
+
)
|
55
|
+
|
56
|
+
return query, projection, sorting
|
57
|
+
|
58
|
+
|
59
|
+
def _prepare_annual_query(self, start_date, end_date, get_latest = False):
|
60
|
+
start_date = self._transform_date(start_date)
|
61
|
+
end_date = self._transform_date(end_date)
|
62
|
+
|
63
|
+
start_year = start_date.year - 1911
|
64
|
+
end_year = end_date.year - 1911
|
65
|
+
query = {
|
66
|
+
"ticker": self.ticker,
|
67
|
+
"year": {
|
68
|
+
"$gte": start_year,
|
69
|
+
"$lte": end_year
|
70
|
+
}
|
71
|
+
}
|
72
|
+
|
73
|
+
projection = {
|
74
|
+
"_id": 0,
|
75
|
+
}
|
76
|
+
|
77
|
+
if (get_latest):
|
78
|
+
sort = [("year", DESCENDING)]
|
79
|
+
else:
|
80
|
+
sort = [("year", ASCENDING)]
|
81
|
+
|
82
|
+
return query, projection, sort
|
83
|
+
|
84
|
+
|
85
|
+
class AsyncTEJDailyValueDBExtractor(BaseDailyTechDBExtractor):
|
86
|
+
|
87
|
+
def __init__(self, ticker, mongo_uri):
|
88
|
+
super().__init__(ticker, mongo_uri)
|
89
|
+
|
90
|
+
def _get_collection_name(self):
|
91
|
+
self.collection_name_map = {"tw": "TEJ_share_price"}
|
92
|
+
|
93
|
+
return self.collection_name_map.get(self.zone, None)
|
@@ -0,0 +1,12 @@
|
|
1
|
+
from .base import BaseDailyTechDBExtractor
|
2
|
+
|
3
|
+
|
4
|
+
class AsyncYFDailyTechDBExtractor(BaseDailyTechDBExtractor):
|
5
|
+
|
6
|
+
def __init__(self, ticker, client):
|
7
|
+
super().__init__(ticker, client)
|
8
|
+
|
9
|
+
def _get_collection_name(self):
|
10
|
+
self.collection_name_map = {"tw": "twse_daily_share_price", "us": "us_technical"}
|
11
|
+
|
12
|
+
return self.collection_name_map.get(self.zone, None)
|
@@ -0,0 +1 @@
|
|
1
|
+
from .twse import AsyncTWSEMonthlyRevenueExtractor
|