kabukit 0.1.0__py3-none-any.whl → 0.1.1__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.
- kabukit/__init__.py +3 -4
- kabukit/cli/__init__.py +0 -0
- kabukit/cli/app.py +22 -0
- kabukit/cli/auth.py +86 -0
- kabukit/concurrent.py +40 -0
- kabukit/config.py +26 -0
- kabukit/edinet/__init__.py +0 -0
- kabukit/edinet/client.py +111 -0
- kabukit/jquants/__init__.py +3 -0
- kabukit/jquants/client.py +218 -180
- kabukit/jquants/info.py +23 -0
- kabukit/jquants/prices.py +0 -0
- kabukit/jquants/schema.py +169 -0
- kabukit/jquants/statements.py +69 -0
- kabukit/jquants/stream.py +122 -0
- kabukit/params.py +47 -0
- kabukit/py.typed +0 -0
- {kabukit-0.1.0.dist-info → kabukit-0.1.1.dist-info}/METADATA +13 -16
- kabukit-0.1.1.dist-info/RECORD +21 -0
- {kabukit-0.1.0.dist-info → kabukit-0.1.1.dist-info}/WHEEL +1 -1
- kabukit-0.1.1.dist-info/entry_points.txt +3 -0
- kabukit/cli.py +0 -40
- kabukit-0.1.0.dist-info/RECORD +0 -8
- kabukit-0.1.0.dist-info/entry_points.txt +0 -3
@@ -0,0 +1,169 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from enum import Enum
|
4
|
+
from typing import TYPE_CHECKING
|
5
|
+
|
6
|
+
if TYPE_CHECKING:
|
7
|
+
from polars import DataFrame
|
8
|
+
|
9
|
+
|
10
|
+
class BaseColumns(Enum):
|
11
|
+
@classmethod
|
12
|
+
def rename(cls, df: DataFrame, *, strict: bool = True) -> DataFrame:
|
13
|
+
"""DataFrameの列名を日本語から英語に変換する。"""
|
14
|
+
return df.rename({x.name: x.value for x in cls}, strict=strict)
|
15
|
+
|
16
|
+
|
17
|
+
class InfoColumns(BaseColumns):
|
18
|
+
Date = "日付"
|
19
|
+
Code = "銘柄コード"
|
20
|
+
CompanyName = "会社名"
|
21
|
+
Sector17CodeName = "17業種コード名"
|
22
|
+
Sector33CodeName = "33業種コード名"
|
23
|
+
ScaleCategory = "規模コード"
|
24
|
+
MarketCodeName = "市場区分名"
|
25
|
+
MarginCodeName = "貸借信用区分名"
|
26
|
+
|
27
|
+
|
28
|
+
class PriceColumns(BaseColumns):
|
29
|
+
Date = "日付"
|
30
|
+
Code = "銘柄コード"
|
31
|
+
Open = "始値"
|
32
|
+
High = "高値"
|
33
|
+
Low = "安値"
|
34
|
+
Close = "終値"
|
35
|
+
UpperLimit = "ストップ高?"
|
36
|
+
LowerLimit = "ストップ安?"
|
37
|
+
Volume = "出来高"
|
38
|
+
TurnoverValue = "売買代金"
|
39
|
+
AdjustmentFactor = "調整係数"
|
40
|
+
AdjustmentOpen = "調整済始値"
|
41
|
+
AdjustmentHigh = "調整済高値"
|
42
|
+
AdjustmentLow = "調整済安値"
|
43
|
+
AdjustmentClose = "調整済終値"
|
44
|
+
AdjustmentVolume = "調整済取引高"
|
45
|
+
|
46
|
+
|
47
|
+
class StatementColumns(BaseColumns):
|
48
|
+
Date = "開示日"
|
49
|
+
Time = "開示時刻"
|
50
|
+
Code = "銘柄コード"
|
51
|
+
DisclosureNumber = "開示番号"
|
52
|
+
TypeOfDocument = "開示書類種別"
|
53
|
+
TypeOfCurrentPeriod = "当会計期間の種類"
|
54
|
+
CurrentPeriodStartDate = "当会計期間開始日"
|
55
|
+
CurrentPeriodEndDate = "当会計期間終了日"
|
56
|
+
CurrentFiscalYearStartDate = "当事業年度開始日"
|
57
|
+
CurrentFiscalYearEndDate = "当事業年度終了日"
|
58
|
+
NextFiscalYearStartDate = "翌事業年度開始日"
|
59
|
+
NextFiscalYearEndDate = "翌事業年度終了日"
|
60
|
+
|
61
|
+
NetSales = "売上高"
|
62
|
+
OperatingProfit = "営業利益"
|
63
|
+
OrdinaryProfit = "経常利益"
|
64
|
+
Profit = "当期純利益"
|
65
|
+
EarningsPerShare = "一株あたり当期純利益"
|
66
|
+
DilutedEarningsPerShare = "潜在株式調整後一株あたり当期純利益"
|
67
|
+
|
68
|
+
TotalAssets = "総資産"
|
69
|
+
Equity = "純資産"
|
70
|
+
EquityToAssetRatio = "自己資本比率"
|
71
|
+
BookValuePerShare = "一株あたり純資産"
|
72
|
+
|
73
|
+
CashFlowsFromOperatingActivities = "営業活動によるキャッシュフロー"
|
74
|
+
CashFlowsFromInvestingActivities = "投資活動によるキャッシュフロー"
|
75
|
+
CashFlowsFromFinancingActivities = "財務活動によるキャッシュフロー"
|
76
|
+
CashAndEquivalents = "現金及び現金同等物期末残高"
|
77
|
+
|
78
|
+
ResultDividendPerShare1stQuarter = "一株あたり配当実績_第1四半期末"
|
79
|
+
ResultDividendPerShare2ndQuarter = "一株あたり配当実績_第2四半期末"
|
80
|
+
ResultDividendPerShare3rdQuarter = "一株あたり配当実績_第3四半期末"
|
81
|
+
ResultDividendPerShareFiscalYearEnd = "一株あたり配当実績_期末"
|
82
|
+
ResultDividendPerShareAnnual = "一株あたり配当実績_合計"
|
83
|
+
ResultTotalDividendPaidAnnual = "配当金総額"
|
84
|
+
ResultPayoutRatioAnnual = "配当性向"
|
85
|
+
|
86
|
+
ForecastDividendPerShare1stQuarter = "一株あたり配当予想_第1四半期末"
|
87
|
+
ForecastDividendPerShare2ndQuarter = "一株あたり配当予想_第2四半期末"
|
88
|
+
ForecastDividendPerShare3rdQuarter = "一株あたり配当予想_第3四半期末"
|
89
|
+
ForecastDividendPerShareFiscalYearEnd = "一株あたり配当予想_期末"
|
90
|
+
ForecastDividendPerShareAnnual = "一株あたり配当予想_合計"
|
91
|
+
ForecastTotalDividendPaidAnnual = "予想配当金総額"
|
92
|
+
ForecastPayoutRatioAnnual = "予想配当性向"
|
93
|
+
|
94
|
+
NextYearForecastDividendPerShare1stQuarter = "一株あたり配当予想_翌事業年度第1四半期末"
|
95
|
+
NextYearForecastDividendPerShare2ndQuarter = "一株あたり配当予想_翌事業年度第2四半期末"
|
96
|
+
NextYearForecastDividendPerShare3rdQuarter = "一株あたり配当予想_翌事業年度第3四半期末"
|
97
|
+
NextYearForecastDividendPerShareFiscalYearEnd = "一株あたり配当予想_翌事業年度期末"
|
98
|
+
NextYearForecastDividendPerShareAnnual = "一株あたり配当予想_翌事業年度合計"
|
99
|
+
NextYearForecastPayoutRatioAnnual = "翌事業年度予想配当性向"
|
100
|
+
|
101
|
+
ForecastNetSales2ndQuarter = "売上高_予想_第2四半期末"
|
102
|
+
ForecastOperatingProfit2ndQuarter = "営業利益_予想_第2四半期末"
|
103
|
+
ForecastOrdinaryProfit2ndQuarter = "経常利益_予想_第2四半期末"
|
104
|
+
ForecastProfit2ndQuarter = "当期純利益_予想_第2四半期末"
|
105
|
+
ForecastEarningsPerShare2ndQuarter = "一株あたり当期純利益_予想_第2四半期末"
|
106
|
+
|
107
|
+
NextYearForecastNetSales2ndQuarter = "売上高_予想_翌事業年度第2四半期末"
|
108
|
+
NextYearForecastOperatingProfit2ndQuarter = "営業利益_予想_翌事業年度第2四半期末"
|
109
|
+
NextYearForecastOrdinaryProfit2ndQuarter = "経常利益_予想_翌事業年度第2四半期末"
|
110
|
+
NextYearForecastProfit2ndQuarter = "当期純利益_予想_翌事業年度第2四半期末"
|
111
|
+
NextYearForecastEarningsPerShare2ndQuarter = "一株あたり当期純利益_予想_翌事業年度第2四半期末"
|
112
|
+
|
113
|
+
ForecastNetSales = "売上高_予想_期末"
|
114
|
+
ForecastOperatingProfit = "営業利益_予想_期末"
|
115
|
+
ForecastOrdinaryProfit = "経常利益_予想_期末"
|
116
|
+
ForecastProfit = "当期純利益_予想_期末"
|
117
|
+
ForecastEarningsPerShare = "一株あたり当期純利益_予想_期末"
|
118
|
+
|
119
|
+
NextYearForecastNetSales = "売上高_予想_翌事業年度期末"
|
120
|
+
NextYearForecastOperatingProfit = "営業利益_予想_翌事業年度期末"
|
121
|
+
NextYearForecastOrdinaryProfit = "経常利益_予想_翌事業年度期末"
|
122
|
+
NextYearForecastProfit = "当期純利益_予想_翌事業年度期末"
|
123
|
+
NextYearForecastEarningsPerShare = "一株あたり当期純利益_予想_翌事業年度期末"
|
124
|
+
|
125
|
+
MaterialChangesInSubsidiaries = "期中における重要な子会社の異動"
|
126
|
+
SignificantChangesInTheScopeOfConsolidation = "期中における連結範囲の重要な変更"
|
127
|
+
ChangesBasedOnRevisionsOfAccountingStandard = "会計基準等の改正に伴う会計方針の変更"
|
128
|
+
ChangesOtherThanOnesBasedOnRevisionsOfAccountingStandard = "会計基準等の改正に伴う変更以外の会計方針の変更"
|
129
|
+
ChangesInAccountingEstimates = "会計上の見積りの変更"
|
130
|
+
RetrospectiveRestatement = "修正再表示"
|
131
|
+
|
132
|
+
NumberOfIssuedAndOutstandingSharesAtTheEndOfFiscalYearIncludingTreasuryStock = "期末発行済株式数"
|
133
|
+
NumberOfTreasuryStockAtTheEndOfFiscalYear = "期末自己株式数"
|
134
|
+
AverageNumberOfShares = "期中平均株式数"
|
135
|
+
|
136
|
+
NonConsolidatedNetSales = "売上高_非連結"
|
137
|
+
NonConsolidatedOperatingProfit = "営業利益_非連結"
|
138
|
+
NonConsolidatedOrdinaryProfit = "経常利益_非連結"
|
139
|
+
NonConsolidatedProfit = "当期純利益_非連結"
|
140
|
+
NonConsolidatedEarningsPerShare = "一株あたり当期純利益_非連結"
|
141
|
+
|
142
|
+
NonConsolidatedTotalAssets = "総資産_非連結"
|
143
|
+
NonConsolidatedEquity = "純資産_非連結"
|
144
|
+
NonConsolidatedEquityToAssetRatio = "自己資本比率_非連結"
|
145
|
+
NonConsolidatedBookValuePerShare = "一株あたり純資産_非連結"
|
146
|
+
|
147
|
+
ForecastNonConsolidatedNetSales2ndQuarter = "売上高_予想_第2四半期末_非連結"
|
148
|
+
ForecastNonConsolidatedOperatingProfit2ndQuarter = "営業利益_予想_第2四半期末_非連結"
|
149
|
+
ForecastNonConsolidatedOrdinaryProfit2ndQuarter = "経常利益_予想_第2四半期末_非連結"
|
150
|
+
ForecastNonConsolidatedProfit2ndQuarter = "当期純利益_予想_第2四半期末_非連結"
|
151
|
+
ForecastNonConsolidatedEarningsPerShare2ndQuarter = "一株あたり当期純利益_予想_第2四半期末_非連結"
|
152
|
+
|
153
|
+
NextYearForecastNonConsolidatedNetSales2ndQuarter = "売上高_予想_翌事業年度第2四半期末_非連結"
|
154
|
+
NextYearForecastNonConsolidatedOperatingProfit2ndQuarter = "営業利益_予想_翌事業年度第2四半期末_非連結"
|
155
|
+
NextYearForecastNonConsolidatedOrdinaryProfit2ndQuarter = "経常利益_予想_翌事業年度第2四半期末_非連結"
|
156
|
+
NextYearForecastNonConsolidatedProfit2ndQuarter = "当期純利益_予想_翌事業年度第2四半期末_非連結"
|
157
|
+
NextYearForecastNonConsolidatedEarningsPerShare2ndQuarter = "一株あたり当期純利益_予想_翌事業年度第2四半期末_非連結"
|
158
|
+
|
159
|
+
ForecastNonConsolidatedNetSales = "売上高_予想_期末_非連結"
|
160
|
+
ForecastNonConsolidatedOperatingProfit = "営業利益_予想_期末_非連結"
|
161
|
+
ForecastNonConsolidatedOrdinaryProfit = "経常利益_予想_期末_非連結"
|
162
|
+
ForecastNonConsolidatedProfit = "当期純利益_予想_期末_非連結"
|
163
|
+
ForecastNonConsolidatedEarningsPerShare = "一株あたり当期純利益_予想_期末_非連結"
|
164
|
+
|
165
|
+
NextYearForecastNonConsolidatedNetSales = "売上高_予想_翌事業年度期末_非連結"
|
166
|
+
NextYearForecastNonConsolidatedOperatingProfit = "営業利益_予想_翌事業年度期末_非連結"
|
167
|
+
NextYearForecastNonConsolidatedOrdinaryProfit = "経常利益_予想_翌事業年度期末_非連結"
|
168
|
+
NextYearForecastNonConsolidatedProfit = "当期純利益_予想_翌事業年度期末_非連結"
|
169
|
+
NextYearForecastNonConsolidatedEarningsPerShare = "一株あたり当期純利益_予想_翌事業年度期末_非連結"
|
@@ -0,0 +1,69 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from typing import TYPE_CHECKING, Any, Protocol
|
4
|
+
|
5
|
+
import polars as pl
|
6
|
+
|
7
|
+
if TYPE_CHECKING:
|
8
|
+
from collections.abc import AsyncIterable, AsyncIterator
|
9
|
+
|
10
|
+
from polars import DataFrame
|
11
|
+
|
12
|
+
class Progress(Protocol):
|
13
|
+
def __call__[T](
|
14
|
+
self,
|
15
|
+
async_iterable: AsyncIterable[T],
|
16
|
+
total: int | None = None,
|
17
|
+
*args: Any,
|
18
|
+
**kwargs: Any,
|
19
|
+
) -> AsyncIterator[T]: ...
|
20
|
+
|
21
|
+
|
22
|
+
def clean(df: DataFrame) -> DataFrame:
|
23
|
+
return (
|
24
|
+
df.select(pl.exclude(r"^.*\(REIT\)$"))
|
25
|
+
.rename(
|
26
|
+
{"DisclosedDate": "Date", "DisclosedTime": "Time", "LocalCode": "Code"},
|
27
|
+
)
|
28
|
+
.with_columns(
|
29
|
+
pl.col("^.*Date$").str.to_date("%Y-%m-%d", strict=False),
|
30
|
+
pl.col("Time").str.to_time("%H:%M:%S", strict=False),
|
31
|
+
pl.col("TypeOfCurrentPeriod").cast(pl.Categorical),
|
32
|
+
)
|
33
|
+
.pipe(_cast_float)
|
34
|
+
.pipe(_cast_bool)
|
35
|
+
)
|
36
|
+
|
37
|
+
|
38
|
+
def _cast_float(df: DataFrame) -> DataFrame:
|
39
|
+
return df.with_columns(
|
40
|
+
pl.col(f"^.*{name}.*$").cast(pl.Float64, strict=False)
|
41
|
+
for name in [
|
42
|
+
"Assets",
|
43
|
+
"BookValue",
|
44
|
+
"Cash",
|
45
|
+
"Distributions",
|
46
|
+
"Dividend",
|
47
|
+
"Earnings",
|
48
|
+
"Equity",
|
49
|
+
"NetSales",
|
50
|
+
"NumberOf",
|
51
|
+
"PayoutRatio",
|
52
|
+
"Profit",
|
53
|
+
]
|
54
|
+
)
|
55
|
+
|
56
|
+
|
57
|
+
def _cast_bool(df: DataFrame) -> DataFrame:
|
58
|
+
columns = df.select(pl.col("^.*Changes.*$")).columns
|
59
|
+
columns.append("RetrospectiveRestatement")
|
60
|
+
|
61
|
+
return df.with_columns(
|
62
|
+
pl.when(pl.col(col) == "true")
|
63
|
+
.then(True) # noqa: FBT003
|
64
|
+
.when(pl.col(col) == "false")
|
65
|
+
.then(False) # noqa: FBT003
|
66
|
+
.otherwise(None)
|
67
|
+
.alias(col)
|
68
|
+
for col in columns
|
69
|
+
)
|
@@ -0,0 +1,122 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from dataclasses import dataclass
|
4
|
+
from typing import TYPE_CHECKING, Any, Protocol
|
5
|
+
|
6
|
+
import polars as pl
|
7
|
+
|
8
|
+
from kabukit.concurrent import collect_fn
|
9
|
+
|
10
|
+
from .client import JQuantsClient
|
11
|
+
from .info import get_codes
|
12
|
+
|
13
|
+
if TYPE_CHECKING:
|
14
|
+
from collections.abc import AsyncIterable, AsyncIterator, Callable, Iterable
|
15
|
+
|
16
|
+
from polars import DataFrame
|
17
|
+
|
18
|
+
class Progress(Protocol):
|
19
|
+
def __call__[T](
|
20
|
+
self,
|
21
|
+
aiterable: AsyncIterable[T],
|
22
|
+
total: int | None = None,
|
23
|
+
*args: Any,
|
24
|
+
**kwargs: Any,
|
25
|
+
) -> AsyncIterator[T]: ...
|
26
|
+
|
27
|
+
|
28
|
+
type Callback = Callable[[DataFrame], DataFrame | None]
|
29
|
+
|
30
|
+
|
31
|
+
@dataclass
|
32
|
+
class Stream:
|
33
|
+
"""JQuantsから各種データを銘柄コードごとにストリーム形式で取得する。"""
|
34
|
+
|
35
|
+
resource: str
|
36
|
+
codes: list[str]
|
37
|
+
max_concurrency: int | None = None
|
38
|
+
|
39
|
+
async def __aiter__(self) -> AsyncIterator[DataFrame]:
|
40
|
+
async with JQuantsClient() as client:
|
41
|
+
fn = getattr(client, f"get_{self.resource}")
|
42
|
+
|
43
|
+
async for df in collect_fn(fn, self.codes, self.max_concurrency):
|
44
|
+
yield df
|
45
|
+
|
46
|
+
|
47
|
+
async def fetch(
|
48
|
+
resource: str,
|
49
|
+
codes: Iterable[str],
|
50
|
+
/,
|
51
|
+
max_concurrency: int | None = None,
|
52
|
+
progress: Progress | None = None,
|
53
|
+
callback: Callback | None = None,
|
54
|
+
) -> DataFrame:
|
55
|
+
"""全銘柄の各種データを取得し、単一のDataFrameにまとめて返す。
|
56
|
+
|
57
|
+
Args:
|
58
|
+
resource (str): 取得するデータの種類。JQuantsClientのメソッド名から"get_"を
|
59
|
+
除いたものを指定する。
|
60
|
+
codes (Iterable[str]): 取得対象の銘柄コードのリスト。
|
61
|
+
max_concurrency (int | None, optional): 同時に実行するリクエストの最大数。
|
62
|
+
指定しないときはデフォルト値が使用される。
|
63
|
+
progress (Progress | None, optional): 進捗表示のための関数。
|
64
|
+
tqdm, marimoなどのライブラリを使用できる。
|
65
|
+
指定しないときは進捗表示は行われない。
|
66
|
+
callback (Callback | None, optional): 各DataFrameに対して適用する
|
67
|
+
コールバック関数。指定しないときはそのままのDataFrameが使用される。
|
68
|
+
|
69
|
+
Returns:
|
70
|
+
DataFrame:
|
71
|
+
すべての銘柄の財務情報を含む単一のDataFrame。
|
72
|
+
"""
|
73
|
+
codes = list(codes)
|
74
|
+
stream = Stream(resource, codes, max_concurrency)
|
75
|
+
|
76
|
+
if progress:
|
77
|
+
stream = progress(aiter(stream), total=len(codes))
|
78
|
+
|
79
|
+
if callback:
|
80
|
+
stream = (x if (r := callback(x)) is None else r async for x in stream)
|
81
|
+
|
82
|
+
return pl.concat([df async for df in stream if not df.is_empty()])
|
83
|
+
|
84
|
+
|
85
|
+
async def fetch_all(
|
86
|
+
resource: str,
|
87
|
+
/,
|
88
|
+
limit: int | None = None,
|
89
|
+
max_concurrency: int | None = None,
|
90
|
+
progress: Progress | None = None,
|
91
|
+
callback: Callback | None = None,
|
92
|
+
) -> DataFrame:
|
93
|
+
"""全銘柄の各種データを取得し、単一のDataFrameにまとめて返す。
|
94
|
+
|
95
|
+
Args:
|
96
|
+
resource (str): 取得するデータの種類。JQuantsClientのメソッド名から"get_"を
|
97
|
+
除いたものを指定する。
|
98
|
+
limit (int | None, optional): 取得する銘柄数の上限。
|
99
|
+
指定しないときはすべての銘柄が対象となる。
|
100
|
+
max_concurrency (int | None, optional): 同時に実行するリクエストの最大数。
|
101
|
+
指定しないときはデフォルト値が使用される。
|
102
|
+
progress (Progress | None, optional): 進捗表示のための関数。
|
103
|
+
tqdm, marimoなどのライブラリを使用できる。
|
104
|
+
指定しないときは進捗表示は行われない。
|
105
|
+
callback (Callback | None, optional): 各DataFrameに対して適用する
|
106
|
+
コールバック関数。指定しないときはそのままのDataFrameが使用される。
|
107
|
+
|
108
|
+
Returns:
|
109
|
+
DataFrame:
|
110
|
+
すべての銘柄の財務情報を含む単一のDataFrame。
|
111
|
+
"""
|
112
|
+
|
113
|
+
codes = await get_codes()
|
114
|
+
codes = codes[:limit]
|
115
|
+
|
116
|
+
return await fetch(
|
117
|
+
resource,
|
118
|
+
codes,
|
119
|
+
max_concurrency=max_concurrency,
|
120
|
+
progress=progress,
|
121
|
+
callback=callback,
|
122
|
+
)
|
kabukit/params.py
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import datetime
|
4
|
+
from typing import TYPE_CHECKING, Any
|
5
|
+
|
6
|
+
if TYPE_CHECKING:
|
7
|
+
from collections.abc import Iterator
|
8
|
+
|
9
|
+
|
10
|
+
def iter_items(kwargs: dict[str, Any]) -> Iterator[tuple[str, Any]]:
|
11
|
+
for key, value in kwargs.items():
|
12
|
+
if value is None:
|
13
|
+
continue
|
14
|
+
|
15
|
+
if key == "from_":
|
16
|
+
yield "from", value
|
17
|
+
else:
|
18
|
+
yield key, value
|
19
|
+
|
20
|
+
|
21
|
+
def get_params(**kwargs: Any) -> dict[str, str]:
|
22
|
+
params: dict[str, str] = {}
|
23
|
+
|
24
|
+
for key, value in iter_items(kwargs):
|
25
|
+
if isinstance(value, datetime.date):
|
26
|
+
params[key] = date_to_str(value)
|
27
|
+
elif not isinstance(value, str):
|
28
|
+
params[key] = str(value)
|
29
|
+
else:
|
30
|
+
params[key] = value
|
31
|
+
|
32
|
+
return params
|
33
|
+
|
34
|
+
|
35
|
+
def date_to_str(date: str | datetime.date) -> str:
|
36
|
+
"""Convert a date object or string to a YYYY-MM-DD string.
|
37
|
+
|
38
|
+
Args:
|
39
|
+
date: The date to convert.
|
40
|
+
|
41
|
+
Returns:
|
42
|
+
The date as a YYYY-MM-DD string.
|
43
|
+
"""
|
44
|
+
if isinstance(date, datetime.date):
|
45
|
+
return date.strftime("%Y-%m-%d")
|
46
|
+
|
47
|
+
return date
|
kabukit/py.typed
ADDED
File without changes
|
@@ -1,14 +1,20 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: kabukit
|
3
|
-
Version: 0.1.
|
4
|
-
Summary:
|
3
|
+
Version: 0.1.1
|
4
|
+
Summary: A Python toolkit for Japanese financial market data, supporting J-Quants and EDINET APIs.
|
5
5
|
Author: Daizu
|
6
6
|
Author-email: Daizu <daizutabi@gmail.com>
|
7
|
-
Requires-Dist:
|
8
|
-
Requires-Dist:
|
9
|
-
Requires-Dist:
|
10
|
-
Requires-Dist:
|
11
|
-
Requires-Dist:
|
7
|
+
Requires-Dist: altair>=5.5.0
|
8
|
+
Requires-Dist: async-typer>=0.1.10
|
9
|
+
Requires-Dist: httpx>=0.28.1
|
10
|
+
Requires-Dist: marimo>=0.15.3
|
11
|
+
Requires-Dist: platformdirs>=4.4.0
|
12
|
+
Requires-Dist: polars>=1.33.1
|
13
|
+
Requires-Dist: python-dotenv>=1.1.1
|
14
|
+
Requires-Dist: typer>=0.17.4
|
15
|
+
Requires-Dist: vegafusion-python-embed>=1.6.9
|
16
|
+
Requires-Dist: vegafusion>=2.0.2
|
17
|
+
Requires-Dist: vl-convert-python>=1.8.0
|
12
18
|
Requires-Python: >=3.13
|
13
19
|
Description-Content-Type: text/markdown
|
14
20
|
|
@@ -16,15 +22,6 @@ Description-Content-Type: text/markdown
|
|
16
22
|
|
17
23
|
A Python toolkit for Japanese financial market data, supporting J-Quants and EDINET APIs.
|
18
24
|
|
19
|
-
## Gemini CLI
|
20
|
-
|
21
|
-
https://github.com/google-gemini/gemini-cli/issues/6297
|
22
|
-
|
23
|
-
```bash
|
24
|
-
echo $GEMINI_CLI_IDE_SERVER_PORT
|
25
|
-
sudo sh -c 'echo "127.0.0.1 host.docker.internal" >> /etc/hosts'
|
26
|
-
```
|
27
|
-
|
28
25
|
## References
|
29
26
|
|
30
27
|
https://jpx.gitbook.io/j-quants-ja/api-reference
|
@@ -0,0 +1,21 @@
|
|
1
|
+
kabukit/__init__.py,sha256=BG0eyWyqbtCG4srA43CgFdxg_8Dn9f5sy5wvsKw2lpQ,127
|
2
|
+
kabukit/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
|
+
kabukit/cli/app.py,sha256=LjAq_Pj5_bokL4bCZ2R8OoP_zEBA-a2EG0Pm1ZCn7o8,491
|
4
|
+
kabukit/cli/auth.py,sha256=4WcL6tcxvk4_V41JSgmtAwFdEdSG53NIa_bl6n_Ns8I,2723
|
5
|
+
kabukit/concurrent.py,sha256=F7yizZvfblcGN3tHmDGvCqrFlA4nxnOJvMPgM_X1I7w,1070
|
6
|
+
kabukit/config.py,sha256=Bsa_BGxNsHyaLWkC99oliRRPmkv5K0YKSdYF-ADGjck,660
|
7
|
+
kabukit/edinet/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
|
+
kabukit/edinet/client.py,sha256=uUIDMzPNrsMJSFe2BLtAEesfISWs4_559vx46o2PfJs,3348
|
9
|
+
kabukit/jquants/__init__.py,sha256=J_rYvBVhVG-F0BPTIgCaOl3zo-rb1tbosI2e7F6ryNQ,71
|
10
|
+
kabukit/jquants/client.py,sha256=g48KCdkLIjXlMBNVF0ea-hks4WGRfqczz8PCoTYsQ6A,11670
|
11
|
+
kabukit/jquants/info.py,sha256=_6W9MSbTDqjV3Yrl9LZNC0BO8A1WTNWqiC0aNwkMcHs,578
|
12
|
+
kabukit/jquants/prices.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
13
|
+
kabukit/jquants/schema.py,sha256=cmm_KOIJs1GknAEWgFiBv9smYw7OSsBeivBHG8ZDjhE,9357
|
14
|
+
kabukit/jquants/statements.py,sha256=oheJpqX7gjptHc1-e_4tSDiU0nha4see6rM0Y3Bn2Y8,1814
|
15
|
+
kabukit/jquants/stream.py,sha256=_sdV1kfFJSagvvsQDv9z1PUlAwn5K9Fe-kgP9tpnyiU,4250
|
16
|
+
kabukit/params.py,sha256=a5QLxTyB6jegeXDerQNmpYEKdZplhL3GnJuK0WRbBtQ,1091
|
17
|
+
kabukit/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
18
|
+
kabukit-0.1.1.dist-info/WHEEL,sha256=Pi5uDq5Fdo_Rr-HD5h9BiPn9Et29Y9Sh8NhcJNnFU1c,79
|
19
|
+
kabukit-0.1.1.dist-info/entry_points.txt,sha256=vvX771TemoM-35vVizW3JJ70HvRXnd2tX4P1Btzyoxs,46
|
20
|
+
kabukit-0.1.1.dist-info/METADATA,sha256=16U7AyT6rTYuugdA7enJblLYSdjzCiV1S9DGhaHeRdQ,1014
|
21
|
+
kabukit-0.1.1.dist-info/RECORD,,
|
kabukit/cli.py
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
"""kabukit CLI."""
|
2
|
-
|
3
|
-
from __future__ import annotations
|
4
|
-
|
5
|
-
from typing import Annotated
|
6
|
-
|
7
|
-
import typer
|
8
|
-
from httpx import HTTPStatusError
|
9
|
-
from typer import Argument, Exit, Option, Typer
|
10
|
-
|
11
|
-
from .jquants.client import JQuantsClient
|
12
|
-
|
13
|
-
app = Typer(add_completion=False)
|
14
|
-
|
15
|
-
|
16
|
-
@app.command()
|
17
|
-
def auth(
|
18
|
-
mailaddress: Annotated[str, Argument(help="J-Quants mail address.")],
|
19
|
-
password: Annotated[str, Option(prompt=True, hide_input=True)],
|
20
|
-
) -> None:
|
21
|
-
"""Authenticate and save/refresh tokens."""
|
22
|
-
client = JQuantsClient()
|
23
|
-
|
24
|
-
try:
|
25
|
-
client.auth(mailaddress, password)
|
26
|
-
except HTTPStatusError as e:
|
27
|
-
typer.echo(f"Authentication failed: {e}")
|
28
|
-
raise Exit(1) from None
|
29
|
-
|
30
|
-
client = JQuantsClient()
|
31
|
-
typer.echo(f"refreshToken: {client.refresh_token[:30]}...")
|
32
|
-
typer.echo(f"idToken: {client.id_token[:30]}...")
|
33
|
-
|
34
|
-
|
35
|
-
@app.command()
|
36
|
-
def version() -> None:
|
37
|
-
"""Show kabukit version."""
|
38
|
-
from importlib.metadata import version
|
39
|
-
|
40
|
-
typer.echo(f"kabukit version: {version('kabukit')}")
|
kabukit-0.1.0.dist-info/RECORD
DELETED
@@ -1,8 +0,0 @@
|
|
1
|
-
kabukit/__init__.py,sha256=iPsCZbh4lCYivLMPEtQphSu9tv-srLArCVs17qV_s1o,53
|
2
|
-
kabukit/cli.py,sha256=Ed990MnPe--Rfjpr5Ow1WuafIQi3e3ASIBqXjN45teM,1005
|
3
|
-
kabukit/jquants/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
|
-
kabukit/jquants/client.py,sha256=ngMl40pXSkzm4C1mQBVFPYr7zHez16HpDVDsO4jr85o,10287
|
5
|
-
kabukit-0.1.0.dist-info/WHEEL,sha256=NHRAbdxxzyL9K3IO2LjmlNqKSyPZnKv2BD16YYVKo18,79
|
6
|
-
kabukit-0.1.0.dist-info/entry_points.txt,sha256=gVuAclA51VqzWiPx_zyB3-0MklaCD1EsC9fsLtX9O_M,42
|
7
|
-
kabukit-0.1.0.dist-info/METADATA,sha256=JQNE2jPQmGSYBHKMZUB--cKdkdX8v1gTdja2asVGXZA,890
|
8
|
-
kabukit-0.1.0.dist-info/RECORD,,
|