kabukit 0.7.6__tar.gz → 0.8.1__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.
- kabukit-0.8.1/PKG-INFO +113 -0
- kabukit-0.8.1/README.md +52 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/pyproject.toml +15 -6
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/__init__.py +2 -4
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/cli/auth.py +1 -1
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/cli/cache.py +13 -1
- kabukit-0.8.1/src/kabukit/cli/get.py +156 -0
- kabukit-0.7.6/src/kabukit/core/list.py → kabukit-0.8.1/src/kabukit/core/documents.py +1 -1
- kabukit-0.8.1/src/kabukit/edinet/__init__.py +3 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/edinet/client.py +20 -3
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/edinet/concurrent.py +6 -6
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/edinet/doc.py +3 -2
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/jquants/info.py +1 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/utils/concurrent.py +1 -1
- kabukit-0.7.6/PKG-INFO +0 -260
- kabukit-0.7.6/README.md +0 -200
- kabukit-0.7.6/src/kabukit/cli/get.py +0 -169
- kabukit-0.7.6/src/kabukit/core/reports.py +0 -7
- kabukit-0.7.6/src/kabukit/edinet/__init__.py +0 -3
- {kabukit-0.7.6 → kabukit-0.8.1}/LICENSE +0 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/analysis/__init__.py +0 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/analysis/indicators.py +0 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/analysis/preprocess.py +0 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/analysis/screener.py +0 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/analysis/visualization/__init__.py +0 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/analysis/visualization/market.py +0 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/analysis/visualization/prices.py +0 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/cli/__init__.py +0 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/cli/app.py +0 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/core/__init__.py +0 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/core/base.py +0 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/core/client.py +0 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/core/info.py +0 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/core/prices.py +0 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/core/statements.py +0 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/jquants/__init__.py +0 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/jquants/calendar.py +0 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/jquants/client.py +0 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/jquants/concurrent.py +0 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/jquants/prices.py +0 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/jquants/schema.py +0 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/jquants/statements.py +0 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/jquants/topix.py +0 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/py.typed +0 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/utils/__init__.py +0 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/utils/config.py +0 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/utils/date.py +0 -0
- {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/utils/params.py +0 -0
kabukit-0.8.1/PKG-INFO
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
Metadata-Version: 2.3
|
2
|
+
Name: kabukit
|
3
|
+
Version: 0.8.1
|
4
|
+
Summary: A Python toolkit for Japanese financial market data, supporting J-Quants and EDINET APIs.
|
5
|
+
Keywords: J-Quants,EDINET,financial data,stock market,investment,toolkit,finance,trading,data analysis,polars
|
6
|
+
Author: daizutabi
|
7
|
+
Author-email: daizutabi <daizutabi@gmail.com>
|
8
|
+
License: MIT License
|
9
|
+
|
10
|
+
Copyright (c) 2025 Daizu
|
11
|
+
|
12
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
13
|
+
of this software and associated documentation files (the "Software"), to deal
|
14
|
+
in the Software without restriction, including without limitation the rights
|
15
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
16
|
+
copies of the Software, and to permit persons to whom the Software is
|
17
|
+
furnished to do so, subject to the following conditions:
|
18
|
+
|
19
|
+
The above copyright notice and this permission notice shall be included in all
|
20
|
+
copies or substantial portions of the Software.
|
21
|
+
|
22
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
23
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
24
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
25
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
26
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
27
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
28
|
+
SOFTWARE.
|
29
|
+
Classifier: Development Status :: 4 - Beta
|
30
|
+
Classifier: Programming Language :: Python
|
31
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
32
|
+
Classifier: Programming Language :: Python :: 3.12
|
33
|
+
Classifier: Programming Language :: Python :: 3.13
|
34
|
+
Classifier: Programming Language :: Python :: 3.14
|
35
|
+
Classifier: License :: OSI Approved :: MIT License
|
36
|
+
Classifier: Operating System :: OS Independent
|
37
|
+
Classifier: Intended Audience :: Developers
|
38
|
+
Classifier: Intended Audience :: Financial and Insurance Industry
|
39
|
+
Classifier: Intended Audience :: Science/Research
|
40
|
+
Classifier: Topic :: Office/Business :: Financial
|
41
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
42
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
43
|
+
Classifier: Topic :: Utilities
|
44
|
+
Requires-Dist: async-typer>=0.1.10
|
45
|
+
Requires-Dist: httpx>=0.28.1
|
46
|
+
Requires-Dist: platformdirs>=4.5.0
|
47
|
+
Requires-Dist: polars>=1.34.0
|
48
|
+
Requires-Dist: python-dotenv>=1.1.1
|
49
|
+
Requires-Dist: rich>=14.2.0
|
50
|
+
Requires-Dist: tenacity>=9.1.2
|
51
|
+
Requires-Dist: tqdm>=4.67.1
|
52
|
+
Requires-Dist: typer>=0.19.2
|
53
|
+
Requires-Dist: tzdata ; sys_platform == 'win32'
|
54
|
+
Requires-Python: >=3.12
|
55
|
+
Project-URL: Changelog, https://github.com/daizutabi/kabukit/releases
|
56
|
+
Project-URL: Documentation, https://daizutabi.github.io/kabukit/
|
57
|
+
Project-URL: Homepage, https://daizutabi.github.io/kabukit/
|
58
|
+
Project-URL: Issues, https://github.com/daizutabi/kabukit/issues
|
59
|
+
Project-URL: Source, https://github.com/daizutabi/kabukit
|
60
|
+
Description-Content-Type: text/markdown
|
61
|
+
|
62
|
+
# kabukit
|
63
|
+
|
64
|
+
[![PyPI Version][pypi-v-image]][pypi-v-link]
|
65
|
+
[![Python Version][python-v-image]][python-v-link]
|
66
|
+
[![Build Status][GHAction-image]][GHAction-link]
|
67
|
+
[![Coverage Status][codecov-image]][codecov-link]
|
68
|
+
[![Documentation Status][docs-image]][docs-link]
|
69
|
+
|
70
|
+
A Python toolkit for Japanese financial market data,
|
71
|
+
supporting J-Quants and EDINET APIs.
|
72
|
+
|
73
|
+
kabukit は、 [J-Quants API](https://jpx-jquants.com/) および [EDINET API](https://disclosure2dl.edinet-fsa.go.jp/guide/static/disclosure/WZEK0110.html) から、効率的に日本の金融市場データを取得するツールキットです。
|
74
|
+
|
75
|
+
高速なデータ処理ライブラリである [Polars](https://pola.rs/) と、モダンな非同期 HTTP クライアントである [httpx](https://www.python-httpx.org/) を基盤として構築されており、パフォーマンスを重視しています。
|
76
|
+
|
77
|
+
## インストール
|
78
|
+
|
79
|
+
`pip` または `uv` を使ってインストールします。Python バージョンは 3.12 以上が必要です。
|
80
|
+
|
81
|
+
```bash
|
82
|
+
pip install kabukit
|
83
|
+
```
|
84
|
+
|
85
|
+
## コマンドラインから使う
|
86
|
+
|
87
|
+
kabukit は、 [J-Quants API](https://jpx-jquants.com/) および [EDINET API](https://disclosure2dl.edinet-fsa.go.jp/guide/static/disclosure/WZEK0110.html) からデータを取得するための便利なコマンドラインインターフェース(CLI)を提供します。
|
88
|
+
|
89
|
+
具体的な使い方は、次の利用ガイドを参照してください。
|
90
|
+
|
91
|
+
- [コマンドラインインターフェースの使い方](https://daizutabi.github.io/kabukit/guides/cli/)
|
92
|
+
|
93
|
+
## ノートブックから使う
|
94
|
+
|
95
|
+
kabukit は、コマンドラインだけでなく、Python コードからも API として利用できます。httpx を使って非同期でデータを取得するため、[Jupyter](https://jupyter.org/) や [marimo](https://marimo.io/) のような非同期処理を直接扱えるノートブック環境と非常に相性が良いです。
|
96
|
+
|
97
|
+
具体的な使い方は、以下の利用ガイドを参照してください。
|
98
|
+
|
99
|
+
- [J-Quants API の使い方](https://daizutabi.github.io/kabukit/guides/jquants/)
|
100
|
+
- [EDINET API の使い方](https://daizutabi.github.io/kabukit/guides/edinet/)
|
101
|
+
|
102
|
+
<!-- Badges -->
|
103
|
+
|
104
|
+
[pypi-v-image]: https://img.shields.io/pypi/v/kabukit.svg
|
105
|
+
[pypi-v-link]: https://pypi.org/project/kabukit/
|
106
|
+
[python-v-image]: https://img.shields.io/pypi/pyversions/kabukit.svg
|
107
|
+
[python-v-link]: https://pypi.org/project/kabukit
|
108
|
+
[GHAction-image]: https://github.com/daizutabi/kabukit/actions/workflows/ci.yaml/badge.svg?branch=main&event=push
|
109
|
+
[GHAction-link]: https://github.com/daizutabi/kabukit/actions?query=event%3Apush+branch%3Amain
|
110
|
+
[codecov-image]: https://codecov.io/github/daizutabi/kabukit/graph/badge.svg?token=Yu6lAdVVnd
|
111
|
+
[codecov-link]: https://codecov.io/github/daizutabi/kabukit?branch=main
|
112
|
+
[docs-image]: https://img.shields.io/badge/docs-latest-blue.svg
|
113
|
+
[docs-link]: https://daizutabi.github.io/kabukit/
|
kabukit-0.8.1/README.md
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# kabukit
|
2
|
+
|
3
|
+
[![PyPI Version][pypi-v-image]][pypi-v-link]
|
4
|
+
[![Python Version][python-v-image]][python-v-link]
|
5
|
+
[![Build Status][GHAction-image]][GHAction-link]
|
6
|
+
[![Coverage Status][codecov-image]][codecov-link]
|
7
|
+
[![Documentation Status][docs-image]][docs-link]
|
8
|
+
|
9
|
+
A Python toolkit for Japanese financial market data,
|
10
|
+
supporting J-Quants and EDINET APIs.
|
11
|
+
|
12
|
+
kabukit は、 [J-Quants API](https://jpx-jquants.com/) および [EDINET API](https://disclosure2dl.edinet-fsa.go.jp/guide/static/disclosure/WZEK0110.html) から、効率的に日本の金融市場データを取得するツールキットです。
|
13
|
+
|
14
|
+
高速なデータ処理ライブラリである [Polars](https://pola.rs/) と、モダンな非同期 HTTP クライアントである [httpx](https://www.python-httpx.org/) を基盤として構築されており、パフォーマンスを重視しています。
|
15
|
+
|
16
|
+
## インストール
|
17
|
+
|
18
|
+
`pip` または `uv` を使ってインストールします。Python バージョンは 3.12 以上が必要です。
|
19
|
+
|
20
|
+
```bash
|
21
|
+
pip install kabukit
|
22
|
+
```
|
23
|
+
|
24
|
+
## コマンドラインから使う
|
25
|
+
|
26
|
+
kabukit は、 [J-Quants API](https://jpx-jquants.com/) および [EDINET API](https://disclosure2dl.edinet-fsa.go.jp/guide/static/disclosure/WZEK0110.html) からデータを取得するための便利なコマンドラインインターフェース(CLI)を提供します。
|
27
|
+
|
28
|
+
具体的な使い方は、次の利用ガイドを参照してください。
|
29
|
+
|
30
|
+
- [コマンドラインインターフェースの使い方](https://daizutabi.github.io/kabukit/guides/cli/)
|
31
|
+
|
32
|
+
## ノートブックから使う
|
33
|
+
|
34
|
+
kabukit は、コマンドラインだけでなく、Python コードからも API として利用できます。httpx を使って非同期でデータを取得するため、[Jupyter](https://jupyter.org/) や [marimo](https://marimo.io/) のような非同期処理を直接扱えるノートブック環境と非常に相性が良いです。
|
35
|
+
|
36
|
+
具体的な使い方は、以下の利用ガイドを参照してください。
|
37
|
+
|
38
|
+
- [J-Quants API の使い方](https://daizutabi.github.io/kabukit/guides/jquants/)
|
39
|
+
- [EDINET API の使い方](https://daizutabi.github.io/kabukit/guides/edinet/)
|
40
|
+
|
41
|
+
<!-- Badges -->
|
42
|
+
|
43
|
+
[pypi-v-image]: https://img.shields.io/pypi/v/kabukit.svg
|
44
|
+
[pypi-v-link]: https://pypi.org/project/kabukit/
|
45
|
+
[python-v-image]: https://img.shields.io/pypi/pyversions/kabukit.svg
|
46
|
+
[python-v-link]: https://pypi.org/project/kabukit
|
47
|
+
[GHAction-image]: https://github.com/daizutabi/kabukit/actions/workflows/ci.yaml/badge.svg?branch=main&event=push
|
48
|
+
[GHAction-link]: https://github.com/daizutabi/kabukit/actions?query=event%3Apush+branch%3Amain
|
49
|
+
[codecov-image]: https://codecov.io/github/daizutabi/kabukit/graph/badge.svg?token=Yu6lAdVVnd
|
50
|
+
[codecov-link]: https://codecov.io/github/daizutabi/kabukit?branch=main
|
51
|
+
[docs-image]: https://img.shields.io/badge/docs-latest-blue.svg
|
52
|
+
[docs-link]: https://daizutabi.github.io/kabukit/
|
@@ -4,7 +4,7 @@ build-backend = "uv_build"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "kabukit"
|
7
|
-
version = "0.
|
7
|
+
version = "0.8.1"
|
8
8
|
description = "A Python toolkit for Japanese financial market data, supporting J-Quants and EDINET APIs."
|
9
9
|
readme = "README.md"
|
10
10
|
license = { file = "LICENSE" }
|
@@ -25,6 +25,7 @@ classifiers = [
|
|
25
25
|
"Development Status :: 4 - Beta",
|
26
26
|
"Programming Language :: Python",
|
27
27
|
"Programming Language :: Python :: 3 :: Only",
|
28
|
+
"Programming Language :: Python :: 3.12",
|
28
29
|
"Programming Language :: Python :: 3.13",
|
29
30
|
"Programming Language :: Python :: 3.14",
|
30
31
|
"License :: OSI Approved :: MIT License",
|
@@ -37,7 +38,7 @@ classifiers = [
|
|
37
38
|
"Topic :: Scientific/Engineering :: Information Analysis",
|
38
39
|
"Topic :: Utilities",
|
39
40
|
]
|
40
|
-
requires-python = ">=3.
|
41
|
+
requires-python = ">=3.12"
|
41
42
|
dependencies = [
|
42
43
|
"async-typer>=0.1.10",
|
43
44
|
"httpx>=0.28.1",
|
@@ -65,8 +66,7 @@ Source = "https://github.com/daizutabi/kabukit"
|
|
65
66
|
dev = [
|
66
67
|
"altair @ git+https://github.com/vega/altair.git@main",
|
67
68
|
"basedpyright>=1.31.6",
|
68
|
-
"marimo[lsp]>=0.16.5",
|
69
|
-
"numpy>=2.3.3",
|
69
|
+
"marimo[lsp,mcp]>=0.16.5",
|
70
70
|
"pre-commit>=4.3.0",
|
71
71
|
"pytest-asyncio>=1.2.0",
|
72
72
|
"pytest-clarity>=1.0.1",
|
@@ -79,7 +79,16 @@ dev = [
|
|
79
79
|
"vegafusion>=2.0.3",
|
80
80
|
"vl-convert-python>=1.8.0",
|
81
81
|
]
|
82
|
-
docs = [
|
82
|
+
docs = [
|
83
|
+
"ipykernel>=6.30.1",
|
84
|
+
"markdown-exec[ansi]>=1.11.0",
|
85
|
+
"mkapi>=4.5",
|
86
|
+
"mkdocs-material>=9.6.21",
|
87
|
+
"mkdocs-nbsync>=0.1.5",
|
88
|
+
"mkdocs-typer>=0.0.3",
|
89
|
+
"nbconvert>=7.16.6",
|
90
|
+
"pymdownx-cjk-autojoin>=0.2.1",
|
91
|
+
]
|
83
92
|
|
84
93
|
[tool.pytest.ini_options]
|
85
94
|
addopts = ["--cov=kabukit", "--cov-report=lcov:lcov.info", "--doctest-modules"]
|
@@ -95,7 +104,7 @@ skip_covered = true
|
|
95
104
|
|
96
105
|
[tool.ruff]
|
97
106
|
line-length = 88
|
98
|
-
target-version = "
|
107
|
+
target-version = "py312"
|
99
108
|
include = ["src/**/*.py", "tests/**/*.py"]
|
100
109
|
|
101
110
|
[tool.ruff.lint]
|
@@ -1,17 +1,15 @@
|
|
1
|
+
from .core.documents import Documents
|
1
2
|
from .core.info import Info
|
2
|
-
from .core.list import List
|
3
3
|
from .core.prices import Prices
|
4
|
-
from .core.reports import Reports
|
5
4
|
from .core.statements import Statements
|
6
5
|
from .edinet.client import EdinetClient
|
7
6
|
from .jquants.client import JQuantsClient
|
8
7
|
|
9
8
|
__all__ = [
|
9
|
+
"Documents",
|
10
10
|
"EdinetClient",
|
11
11
|
"Info",
|
12
12
|
"JQuantsClient",
|
13
|
-
"List",
|
14
13
|
"Prices",
|
15
|
-
"Reports",
|
16
14
|
"Statements",
|
17
15
|
]
|
@@ -23,7 +23,9 @@ def add_to_tree(tree: Tree, path: Path) -> None:
|
|
23
23
|
branch = tree.add(p.name)
|
24
24
|
add_to_tree(branch, p)
|
25
25
|
else:
|
26
|
-
|
26
|
+
size = p.stat().st_size
|
27
|
+
formatted_size = format_size(size)
|
28
|
+
tree.add(f"{p.name} ({formatted_size})")
|
27
29
|
|
28
30
|
|
29
31
|
@app.command()
|
@@ -59,3 +61,13 @@ def clean() -> None:
|
|
59
61
|
msg += "エラーが発生しました。"
|
60
62
|
typer.secho(msg, fg=typer.colors.RED, bold=True)
|
61
63
|
raise typer.Exit(1) from None
|
64
|
+
|
65
|
+
|
66
|
+
def format_size(size_in_bytes: int) -> str:
|
67
|
+
if size_in_bytes < 1024:
|
68
|
+
return f"{size_in_bytes} B"
|
69
|
+
|
70
|
+
if size_in_bytes < 1024 * 1024:
|
71
|
+
return f"{size_in_bytes / 1024:.1f} KB"
|
72
|
+
|
73
|
+
return f"{size_in_bytes / (1024 * 1024):.1f} MB"
|
@@ -0,0 +1,156 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from typing import TYPE_CHECKING, Annotated, Any
|
4
|
+
|
5
|
+
import typer
|
6
|
+
from async_typer import AsyncTyper
|
7
|
+
from typer import Argument, Option
|
8
|
+
|
9
|
+
if TYPE_CHECKING:
|
10
|
+
from kabukit.core.base import Base
|
11
|
+
|
12
|
+
# pyright: reportMissingTypeStubs=false
|
13
|
+
# pyright: reportUnknownMemberType=false
|
14
|
+
|
15
|
+
app = AsyncTyper(
|
16
|
+
add_completion=False,
|
17
|
+
help="J-Quantsからデータを取得します。",
|
18
|
+
)
|
19
|
+
|
20
|
+
Code = Annotated[
|
21
|
+
str | None,
|
22
|
+
Argument(help="銘柄コード。指定しない場合は全銘柄の情報を取得します。"),
|
23
|
+
]
|
24
|
+
Quiet = Annotated[
|
25
|
+
bool,
|
26
|
+
Option("--quiet", "-q", help="プログレスバーを表示しません。"),
|
27
|
+
]
|
28
|
+
|
29
|
+
|
30
|
+
@app.async_command()
|
31
|
+
async def info(code: Code = None, *, quiet: Quiet = False) -> None:
|
32
|
+
"""上場銘柄一覧を取得します。"""
|
33
|
+
from kabukit.core.info import Info
|
34
|
+
from kabukit.jquants.client import JQuantsClient
|
35
|
+
|
36
|
+
async with JQuantsClient() as client:
|
37
|
+
df = await client.get_info(code)
|
38
|
+
|
39
|
+
if code or not quiet:
|
40
|
+
typer.echo(df)
|
41
|
+
|
42
|
+
if code is None:
|
43
|
+
path = Info(df).write()
|
44
|
+
typer.echo(f"全銘柄の情報を '{path}' に保存しました。")
|
45
|
+
|
46
|
+
|
47
|
+
async def _fetch(
|
48
|
+
code: str | None,
|
49
|
+
target: str,
|
50
|
+
cls: type[Base],
|
51
|
+
fetch_func_name: str,
|
52
|
+
message: str,
|
53
|
+
*,
|
54
|
+
quiet: bool = False,
|
55
|
+
**kwargs: Any,
|
56
|
+
) -> None:
|
57
|
+
"""財務情報・株価情報を取得するための共通処理"""
|
58
|
+
from kabukit.jquants.client import JQuantsClient
|
59
|
+
|
60
|
+
if code is not None:
|
61
|
+
async with JQuantsClient() as client:
|
62
|
+
df = await getattr(client, fetch_func_name)(code)
|
63
|
+
typer.echo(df)
|
64
|
+
return
|
65
|
+
|
66
|
+
import tqdm.asyncio
|
67
|
+
|
68
|
+
from kabukit.jquants.concurrent import fetch_all
|
69
|
+
|
70
|
+
progress = None if quiet else tqdm.asyncio.tqdm
|
71
|
+
|
72
|
+
try:
|
73
|
+
df = await fetch_all(target, progress=progress, **kwargs)
|
74
|
+
except KeyboardInterrupt:
|
75
|
+
typer.echo("中断しました。")
|
76
|
+
raise typer.Exit(1) from None
|
77
|
+
|
78
|
+
if not quiet:
|
79
|
+
typer.echo(df)
|
80
|
+
|
81
|
+
path = cls(df).write()
|
82
|
+
typer.echo(f"全銘柄の{message}を '{path}' に保存しました。")
|
83
|
+
|
84
|
+
|
85
|
+
@app.async_command()
|
86
|
+
async def statements(code: Code = None, *, quiet: Quiet = False) -> None:
|
87
|
+
"""財務情報を取得します。"""
|
88
|
+
from kabukit.core.statements import Statements
|
89
|
+
|
90
|
+
await _fetch(
|
91
|
+
code=code,
|
92
|
+
target="statements",
|
93
|
+
cls=Statements,
|
94
|
+
fetch_func_name="get_statements",
|
95
|
+
message="財務情報",
|
96
|
+
quiet=quiet,
|
97
|
+
)
|
98
|
+
|
99
|
+
|
100
|
+
@app.async_command()
|
101
|
+
async def prices(code: Code = None, *, quiet: Quiet = False) -> None:
|
102
|
+
"""株価情報を取得します。"""
|
103
|
+
from kabukit.core.prices import Prices
|
104
|
+
|
105
|
+
await _fetch(
|
106
|
+
code=code,
|
107
|
+
target="prices",
|
108
|
+
cls=Prices,
|
109
|
+
fetch_func_name="get_prices",
|
110
|
+
message="株価情報",
|
111
|
+
quiet=quiet,
|
112
|
+
max_concurrency=8,
|
113
|
+
)
|
114
|
+
|
115
|
+
|
116
|
+
@app.async_command()
|
117
|
+
async def documents(*, quiet: Quiet = False) -> None:
|
118
|
+
"""書類一覧を取得します。"""
|
119
|
+
import tqdm.asyncio
|
120
|
+
|
121
|
+
from kabukit.core.documents import Documents
|
122
|
+
from kabukit.edinet.concurrent import fetch_documents
|
123
|
+
|
124
|
+
progress = None if quiet else tqdm.asyncio.tqdm
|
125
|
+
|
126
|
+
try:
|
127
|
+
df = await fetch_documents(years=10, progress=progress)
|
128
|
+
except (KeyboardInterrupt, RuntimeError):
|
129
|
+
typer.echo("中断しました。")
|
130
|
+
raise typer.Exit(1) from None
|
131
|
+
|
132
|
+
if not quiet:
|
133
|
+
typer.echo(df)
|
134
|
+
|
135
|
+
path = Documents(df).write()
|
136
|
+
typer.echo(f"書類一覧を '{path}' に保存しました。")
|
137
|
+
|
138
|
+
|
139
|
+
@app.async_command(name="all")
|
140
|
+
async def all_(code: Code = None, *, quiet: Quiet = False) -> None:
|
141
|
+
"""上場銘柄一覧、財務情報、株価情報、書類一覧を連続して取得します。"""
|
142
|
+
typer.echo("上場銘柄一覧を取得します。")
|
143
|
+
await info(code, quiet=quiet)
|
144
|
+
|
145
|
+
typer.echo("---")
|
146
|
+
typer.echo("財務情報を取得します。")
|
147
|
+
await statements(code, quiet=quiet)
|
148
|
+
|
149
|
+
typer.echo("---")
|
150
|
+
typer.echo("株価情報を取得します。")
|
151
|
+
await prices(code, quiet=quiet)
|
152
|
+
|
153
|
+
if code is None:
|
154
|
+
typer.echo("---")
|
155
|
+
typer.echo("書類一覧を取得します。")
|
156
|
+
await documents(quiet=quiet)
|
@@ -14,7 +14,7 @@ from kabukit.core.client import Client
|
|
14
14
|
from kabukit.utils.config import load_dotenv
|
15
15
|
from kabukit.utils.params import get_params
|
16
16
|
|
17
|
-
from .doc import clean_csv,
|
17
|
+
from .doc import clean_csv, clean_documents, read_csv
|
18
18
|
|
19
19
|
if TYPE_CHECKING:
|
20
20
|
import datetime
|
@@ -62,6 +62,15 @@ class EdinetClient(Client):
|
|
62
62
|
return resp
|
63
63
|
|
64
64
|
async def get_count(self, date: str | datetime.date) -> int:
|
65
|
+
"""書類一覧 API を使い、特定の日付の提出書類数を取得する。
|
66
|
+
|
67
|
+
Args:
|
68
|
+
date (str | datetime.date): 取得対象の日付 (YYYY-MM-DD)
|
69
|
+
|
70
|
+
Returns:
|
71
|
+
int: 書類数
|
72
|
+
|
73
|
+
"""
|
65
74
|
params = get_params(date=date, type=1)
|
66
75
|
resp = await self.get("/documents.json", params)
|
67
76
|
data = resp.json()
|
@@ -72,7 +81,15 @@ class EdinetClient(Client):
|
|
72
81
|
|
73
82
|
return metadata["resultset"]["count"]
|
74
83
|
|
75
|
-
async def
|
84
|
+
async def get_documents(self, date: str | datetime.date) -> DataFrame:
|
85
|
+
"""書類一覧 API を使い、特定の日付の提出書類一覧を取得する。
|
86
|
+
|
87
|
+
Args:
|
88
|
+
date (str | datetime.date): 取得対象の日付 (YYYY-MM-DD)
|
89
|
+
|
90
|
+
Returns:
|
91
|
+
DataFrame: 提出書類一覧を格納した DataFrame
|
92
|
+
"""
|
76
93
|
params = get_params(date=date, type=2)
|
77
94
|
resp = await self.get("/documents.json", params)
|
78
95
|
data = resp.json()
|
@@ -85,7 +102,7 @@ class EdinetClient(Client):
|
|
85
102
|
if df.is_empty():
|
86
103
|
return df
|
87
104
|
|
88
|
-
return
|
105
|
+
return clean_documents(df, date)
|
89
106
|
|
90
107
|
async def get_document(self, doc_id: str, doc_type: int) -> Response:
|
91
108
|
params = get_params(type=doc_type)
|
@@ -52,7 +52,7 @@ async def fetch(
|
|
52
52
|
)
|
53
53
|
|
54
54
|
|
55
|
-
async def
|
55
|
+
async def fetch_documents(
|
56
56
|
days: int | None = None,
|
57
57
|
years: int | None = None,
|
58
58
|
limit: int | None = None,
|
@@ -60,11 +60,11 @@ async def fetch_list(
|
|
60
60
|
progress: Progress | None = None,
|
61
61
|
callback: Callback | None = None,
|
62
62
|
) -> DataFrame:
|
63
|
-
"""過去days日またはyears年の文書一覧を取得し、単一のDataFrameにまとめて返す。
|
63
|
+
"""過去 days 日または years 年の文書一覧を取得し、単一の DataFrame にまとめて返す。
|
64
64
|
|
65
65
|
Args:
|
66
|
-
days (int | None): 過去days日の日付リストを取得する。
|
67
|
-
years (int | None): 過去years年の日付リストを取得する。
|
66
|
+
days (int | None): 過去 days 日の日付リストを取得する。
|
67
|
+
years (int | None): 過去 years 年の日付リストを取得する。
|
68
68
|
daysが指定されている場合は無視される。
|
69
69
|
max_concurrency (int | None, optional): 同時に実行するリクエストの最大数。
|
70
70
|
指定しないときはデフォルト値が使用される。
|
@@ -84,13 +84,13 @@ async def fetch_list(
|
|
84
84
|
dates = dates[:limit]
|
85
85
|
|
86
86
|
df = await fetch(
|
87
|
-
"
|
87
|
+
"documents",
|
88
88
|
dates,
|
89
89
|
max_concurrency=max_concurrency,
|
90
90
|
progress=progress,
|
91
91
|
callback=callback,
|
92
92
|
)
|
93
|
-
return df.sort("Date")
|
93
|
+
return df.sort("Date", "Code")
|
94
94
|
|
95
95
|
|
96
96
|
async def fetch_csv(
|
@@ -10,7 +10,7 @@ if TYPE_CHECKING:
|
|
10
10
|
from polars import DataFrame
|
11
11
|
|
12
12
|
|
13
|
-
def
|
13
|
+
def clean_documents(df: DataFrame, date: str | datetime.date) -> DataFrame:
|
14
14
|
if isinstance(date, str):
|
15
15
|
date = (
|
16
16
|
datetime.datetime.strptime(date, "%Y-%m-%d")
|
@@ -35,7 +35,8 @@ def clean_list(df: DataFrame, date: str | datetime.date) -> DataFrame:
|
|
35
35
|
pl.col("^.+Flag$").cast(pl.Int8).cast(pl.Boolean),
|
36
36
|
pl.col("^.+Code$").cast(pl.String),
|
37
37
|
)
|
38
|
-
.
|
38
|
+
.rename({"secCode": "Code"})
|
39
|
+
.select("Date", "Code", pl.exclude("Date", "Code"))
|
39
40
|
)
|
40
41
|
|
41
42
|
|
@@ -51,7 +51,7 @@ async def collect[R](
|
|
51
51
|
tasks = {asyncio.create_task(run(awaitable)) for awaitable in awaitables}
|
52
52
|
|
53
53
|
try:
|
54
|
-
|
54
|
+
for future in asyncio.as_completed(tasks): # async for (python 3.13+)
|
55
55
|
with contextlib.suppress(asyncio.CancelledError):
|
56
56
|
yield await future
|
57
57
|
finally:
|