kabukit 0.5.0__py3-none-any.whl → 0.5.2__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/core/prices.py CHANGED
@@ -60,7 +60,7 @@ class Prices(Base):
60
60
  Self: `AdjustedIssuedShares`および`AdjustedTreasuryShares`列が
61
61
  追加された、新しいPricesオブジェクト。
62
62
  """
63
- shares = statements.number_of_shares().rename({"Date": "ReportDate"})
63
+ shares = statements.shares().rename({"Date": "ReportDate"})
64
64
 
65
65
  adjusted = (
66
66
  self.data.join_asof(
@@ -76,29 +76,89 @@ class Prices(Base):
76
76
  .over("Code", "ReportDate")
77
77
  .alias("CumulativeRatio"),
78
78
  )
79
- .select(
80
- "Date",
81
- "Code",
79
+ .with_columns(
82
80
  (pl.col("IssuedShares", "TreasuryShares") * pl.col("CumulativeRatio"))
83
81
  .round(0)
84
82
  .cast(pl.Int64)
85
83
  .name.prefix("Adjusted"),
86
84
  )
85
+ .select("Date", "Code", "AdjustedIssuedShares", "AdjustedTreasuryShares")
87
86
  )
88
87
 
89
88
  data = self.data.join(adjusted, on=["Date", "Code"], how="left")
90
89
 
91
90
  return self.__class__(data)
92
91
 
93
- # def with_yields(self, statements: Statements) -> Self:
94
- # """各種利回り指標(収益利回り、純資産利回り、配当利回り)を計算し、列として追加する。
92
+ def with_market_cap(self) -> Self:
93
+ """時価総額を計算し、列として追加する。
94
+
95
+ このメソッドは、日々の調整前終値 (`RawClose`) と、調整済みの発行済株式数
96
+ (`AdjustedIssuedShares`) および自己株式数 (`AdjustedTreasuryShares`)
97
+ を基に、日次ベースの時価総額を計算します。
98
+
99
+ 計算式:
100
+ 時価総額 = 調整前終値 * (調整済み発行済株式数 - 調整済み自己株式数)
101
+
102
+ Note:
103
+ このメソッドを呼び出す前に、`with_adjusted_shares()` を
104
+ 実行して、調整済みの株式数列を事前に計算しておく必要があります。
105
+
106
+ Returns:
107
+ Self: `MarketCap` 列が追加された、新しいPricesオブジェクト。
108
+ """
109
+ shares = pl.col("AdjustedIssuedShares") - pl.col("AdjustedTreasuryShares")
110
+ data = self.data.with_columns(
111
+ (pl.col("RawClose") * shares).round(0).alias("MarketCap"),
112
+ )
113
+ return self.__class__(data)
114
+
115
+ def with_equity(self, statements: Statements) -> Self:
116
+ """時系列の純資産を列として追加する。
117
+
118
+ Args:
119
+ statements (Statements): 財務データを提供する`Statements`オブジェクト。
120
+
121
+ Returns:
122
+ Self: `Equity` 列が追加された、新しいPricesオブジェクト。
123
+ """
124
+ data = self.data.join_asof(
125
+ statements.equity(),
126
+ on="Date",
127
+ by="Code",
128
+ check_sortedness=False,
129
+ )
130
+ return self.__class__(data)
131
+
132
+ def with_forecast_profit(self, statements: Statements) -> Self:
133
+ """時系列の予想純利益を列として追加する。
134
+
135
+ Args:
136
+ statements (Statements): 財務データを提供する`Statements`オブジェクト。
137
+
138
+ Returns:
139
+ Self: `ForecastProfit` 列が追加された、新しいPricesオブジェクト。
140
+ """
141
+ data = self.data.join_asof(
142
+ statements.forecast_profit(),
143
+ on="Date",
144
+ by="Code",
145
+ check_sortedness=False,
146
+ )
147
+ return self.__class__(data)
148
+
149
+ def with_forecast_dividend(self, statements: Statements) -> Self:
150
+ """時系列の予想年間配当総額を列として追加する。
95
151
 
96
- # Args:
97
- # statements (Statements): 財務データを提供する`Statements`オブジェクト。
152
+ Args:
153
+ statements (Statements): 財務データを提供する`Statements`オブジェクト。
98
154
 
99
- # Returns:
100
- # Self: 各種利回り指標が追加された、新しいPricesオブジェクト。
101
- # """
102
- # prices_with_adjusted_shares = self.with_adjusted_shares(statements)
103
- # data_with_yields = calculate_all_yields(prices_with_adjusted_shares, statements)
104
- # return self.__class__(data_with_yields)
155
+ Returns:
156
+ Self: `ForecastDividend` 列が追加された、新しいPricesオブジェクト。
157
+ """
158
+ data = self.data.join_asof(
159
+ statements.forecast_dividend(),
160
+ on="Date",
161
+ by="Code",
162
+ check_sortedness=False,
163
+ )
164
+ return self.__class__(data)
@@ -11,7 +11,7 @@ if TYPE_CHECKING:
11
11
 
12
12
 
13
13
  class Statements(Base):
14
- def number_of_shares(self) -> DataFrame:
14
+ def shares(self) -> DataFrame:
15
15
  """発行済株式数を取得する。"""
16
16
  return self.data.filter(
17
17
  pl.col("IssuedShares").is_not_null(),
@@ -22,3 +22,68 @@ class Statements(Base):
22
22
  "TreasuryShares",
23
23
  "AverageOutstandingShares",
24
24
  )
25
+
26
+ def equity(self) -> DataFrame:
27
+ """Statementsデータから純資産を抽出する。
28
+
29
+ Returns:
30
+ DataFrame: Date, Code, Equity を含むDataFrame
31
+ """
32
+ return self.data.filter(
33
+ pl.col("Equity").is_not_null(),
34
+ ).select("Date", "Code", "Equity")
35
+
36
+ def forecast_profit(self) -> DataFrame:
37
+ """Statementsデータから予想純利益を抽出する。
38
+
39
+ Returns:
40
+ DataFrame: Date, Code, ForecastProfit を含むDataFrame
41
+ """
42
+ return (
43
+ self.data.with_columns(
44
+ pl.when(pl.col("TypeOfDocument").str.starts_with("FY"))
45
+ .then(pl.col("NextYearForecastProfit"))
46
+ .otherwise(pl.col("ForecastProfit"))
47
+ .alias("ForecastProfit"),
48
+ )
49
+ .filter(pl.col("ForecastProfit").is_not_null())
50
+ .select("Date", "Code", "ForecastProfit")
51
+ )
52
+
53
+ def forecast_dividend(self) -> DataFrame:
54
+ """予想年間配当総額を抽出する。
55
+
56
+ Returns:
57
+ DataFrame: Date, Code, ForecastDividend を含むDataFrame
58
+ """
59
+ # 予想株式数を計算
60
+ forecast_shares = (
61
+ pl.when(pl.col("TypeOfDocument").str.starts_with("FY"))
62
+ .then(
63
+ pl.col("NextYearForecastProfit")
64
+ / pl.col("NextYearForecastEarningsPerShare"),
65
+ )
66
+ .otherwise(pl.col("ForecastProfit") / pl.col("ForecastEarningsPerShare"))
67
+ .alias("ForecastShares")
68
+ )
69
+
70
+ # 年間配当総額を計算
71
+ annual_forecast_dividend = (
72
+ pl.when(pl.col("TypeOfDocument").str.starts_with("FY"))
73
+ .then(
74
+ pl.col("NextYearForecastDividendPerShareAnnual")
75
+ * pl.col("ForecastShares"),
76
+ )
77
+ .otherwise(
78
+ pl.col("ForecastDividendPerShareAnnual") * pl.col("ForecastShares"),
79
+ )
80
+ .round(0)
81
+ .alias("ForecastDividend")
82
+ )
83
+
84
+ return (
85
+ self.data.with_columns(forecast_shares)
86
+ .with_columns(annual_forecast_dividend)
87
+ .filter(pl.col("ForecastDividend").is_not_null())
88
+ .select("Date", "Code", "ForecastDividend")
89
+ )
@@ -41,7 +41,7 @@ async def fetch(
41
41
  DataFrame:
42
42
  すべての銘柄の財務情報を含む単一のDataFrame。
43
43
  """
44
- return await concurrent.fetch(
44
+ data = await concurrent.fetch(
45
45
  JQuantsClient,
46
46
  resource,
47
47
  codes,
@@ -49,6 +49,7 @@ async def fetch(
49
49
  progress=progress,
50
50
  callback=callback,
51
51
  )
52
+ return data.sort("Code", "Date")
52
53
 
53
54
 
54
55
  async def fetch_all(
@@ -12,17 +12,24 @@ if TYPE_CHECKING:
12
12
 
13
13
 
14
14
  def clean(df: DataFrame) -> DataFrame:
15
+ df = df.select(pl.exclude(r"^.*\(REIT\)$"))
16
+ return df.pipe(_rename).pipe(_cast)
17
+
18
+
19
+ def _rename(df: DataFrame) -> DataFrame:
20
+ return df.rename(
21
+ {
22
+ "LocalCode": "Code",
23
+ "NumberOfIssuedAndOutstandingSharesAtTheEndOfFiscalYearIncludingTreasuryStock": "IssuedShares", # noqa: E501
24
+ "NumberOfTreasuryStockAtTheEndOfFiscalYear": "TreasuryShares",
25
+ "AverageNumberOfShares": "AverageOutstandingShares",
26
+ },
27
+ )
28
+
29
+
30
+ def _cast(df: DataFrame) -> DataFrame:
15
31
  return (
16
- df.select(pl.exclude(r"^.*\(REIT\)$"))
17
- .rename(
18
- {
19
- "LocalCode": "Code",
20
- "NumberOfIssuedAndOutstandingSharesAtTheEndOfFiscalYearIncludingTreasuryStock": "IssuedShares", # noqa: E501
21
- "NumberOfTreasuryStockAtTheEndOfFiscalYear": "TreasuryShares",
22
- "AverageNumberOfShares": "AverageOutstandingShares",
23
- },
24
- )
25
- .with_columns(
32
+ df.with_columns(
26
33
  pl.col("^.*Date$").str.to_date("%Y-%m-%d", strict=False),
27
34
  pl.col("DisclosedTime").str.to_time("%H:%M:%S", strict=False),
28
35
  pl.col("TypeOfCurrentPeriod").cast(pl.Categorical),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: kabukit
3
- Version: 0.5.0
3
+ Version: 0.5.2
4
4
  Summary: A Python toolkit for Japanese financial market data, supporting J-Quants and EDINET APIs.
5
5
  Author: daizutabi
6
6
  Author-email: daizutabi <daizutabi@gmail.com>
@@ -28,13 +28,13 @@ License: MIT License
28
28
  Classifier: Development Status :: 4 - Beta
29
29
  Classifier: Programming Language :: Python
30
30
  Classifier: Programming Language :: Python :: 3.13
31
- Requires-Dist: async-typer>=0.1
31
+ Requires-Dist: async-typer>=0.1.10
32
32
  Requires-Dist: holidays>=0.81
33
- Requires-Dist: httpx>=0.28
34
- Requires-Dist: platformdirs>=4
35
- Requires-Dist: polars>=1
36
- Requires-Dist: python-dotenv>=1
37
- Requires-Dist: typer>=0.19
33
+ Requires-Dist: httpx>=0.28.1
34
+ Requires-Dist: platformdirs>=4.4.0
35
+ Requires-Dist: polars>=1.34.0
36
+ Requires-Dist: python-dotenv>=1.1.1
37
+ Requires-Dist: typer>=0.19.2
38
38
  Requires-Python: >=3.13
39
39
  Project-URL: Documentation, https://daizutabi.github.io/kabukit/
40
40
  Project-URL: Issues, https://github.com/daizutabi/kabukit/issues
@@ -13,27 +13,27 @@ kabukit/core/base.py,sha256=YQfGw3P2QshRdut3KhtrAleVvnFsIPOw5oGA9azypAA,1695
13
13
  kabukit/core/client.py,sha256=tVq1r3zpOfjmOtnRI1KPZHgTgBZYIpJzfw15i2kAM48,676
14
14
  kabukit/core/info.py,sha256=5BX7mDavF6g-b0KzHgKIFHUS5701BoaHtw1JcHSsy94,174
15
15
  kabukit/core/list.py,sha256=AjnXzC9XIu21l6IBEHHAS5VAnfxTfkAA9m1WAOZJNa8,174
16
- kabukit/core/prices.py,sha256=8bVNmLulH28cx0xyxa6XjGTOEMWHooAsvqq6kfGiqCI,4209
16
+ kabukit/core/prices.py,sha256=4jL6ItbyVov-G-JuZhvZTzqTDeisHJ9rEPH9wpf3pUg,6382
17
17
  kabukit/core/reports.py,sha256=ch_xe84GbB17JTfmY3ArQqneQ2XOuvrAykBTAyNmWuM,177
18
- kabukit/core/statements.py,sha256=FQDfCn8EBpMHabo5suPEQ49EwgFE4D_kltAXOb0TZjI,537
18
+ kabukit/core/statements.py,sha256=BNVmzTF_GvckRj3TfZT5ZoSBfnK32RzJM8YHpkz-h6Y,2806
19
19
  kabukit/edinet/__init__.py,sha256=PKa4D-jVpeoOkdVp9NwwpgAiGEBjqvmJLmpzF-9SlVk,101
20
20
  kabukit/edinet/client.py,sha256=BlM7pjXpKweOo-ses41JiKinqRn4qerMN5NF7hgYKgg,3275
21
21
  kabukit/edinet/concurrent.py,sha256=2YPzIFuuOB8-gL3CnHIlP486QH5d21qjKNKGCFK7Hzk,4707
22
22
  kabukit/edinet/doc.py,sha256=6ZDgmm8DHmEMOA4NjNz-dHLMc7IzzYn-nVyMQGLWb8I,1220
23
23
  kabukit/jquants/__init__.py,sha256=xY0H6x4_51ZBqbrT2TdmGGFbTD-hosZiDzVIz4UXPv0,112
24
24
  kabukit/jquants/client.py,sha256=shAyJoOHUa3h1fFfHdlm2ZYdQL3Oauy2S9VTJfNb_RI,11523
25
- kabukit/jquants/concurrent.py,sha256=VGpWRq2NoDJCpyLAXegsJYPXvkY1hdjuuxxAprQzwEc,3294
25
+ kabukit/jquants/concurrent.py,sha256=n_HMIQEkj1OqDo75iybzcpzVJkP-pNzjNnv3XTA5sxQ,3331
26
26
  kabukit/jquants/info.py,sha256=AUymo6EtLdJ_L-0yNG1gd7rJ8Jkjw7tvsDM5Vw4QNFA,843
27
27
  kabukit/jquants/prices.py,sha256=oApQpdgzHwPw11XHpdg8ccZS7kybGtV8APZlpD2L3Yw,882
28
28
  kabukit/jquants/schema.py,sha256=aILl9cp9JDOaT2o3UlfavPGQC5s7n0ZkVBGKiTzdogs,9768
29
- kabukit/jquants/statements.py,sha256=b5eS1_XEc9LzVffzjvP9-sXD-11tkY3IDQNP82E64Ww,3069
29
+ kabukit/jquants/statements.py,sha256=fW9YGuqK5W64aWdYtVFzgF14L9H68HPdIfYWxSjc9yg,3173
30
30
  kabukit/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
31
  kabukit/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
32
  kabukit/utils/concurrent.py,sha256=m2zVqJUz4xFVpNbEc9YEaj3Jmbl82njupdm4_rBOoYQ,4510
33
33
  kabukit/utils/config.py,sha256=Jp-2TCnIj_QqA71FzYCkHXbvXvhw_1JVl4PR0foA1vM,618
34
34
  kabukit/utils/date.py,sha256=DEC6Ac5LS8eiW6JtrmcD3U1pX4qzXtx4ale0swpO4Ag,937
35
35
  kabukit/utils/params.py,sha256=qcaJbf6CWPUoZAZsYDTaZSnBUWeAersbWnR_iiYW9GM,1108
36
- kabukit-0.5.0.dist-info/WHEEL,sha256=-neZj6nU9KAMg2CnCY6T3w8J53nx1kFGw_9HfoSzM60,79
37
- kabukit-0.5.0.dist-info/entry_points.txt,sha256=vvX771TemoM-35vVizW3JJ70HvRXnd2tX4P1Btzyoxs,46
38
- kabukit-0.5.0.dist-info/METADATA,sha256=6TCfh48vd6SQb5V4dMVnp7rFpjf2uN8Y5pCWXFtqri0,3187
39
- kabukit-0.5.0.dist-info/RECORD,,
36
+ kabukit-0.5.2.dist-info/WHEEL,sha256=n2u5OFBbdZvCiUKAmfnY1Po2j3FB_NWfuUlt5WiAjrk,79
37
+ kabukit-0.5.2.dist-info/entry_points.txt,sha256=vvX771TemoM-35vVizW3JJ70HvRXnd2tX4P1Btzyoxs,46
38
+ kabukit-0.5.2.dist-info/METADATA,sha256=HCAafrEHVXPOwUFGWhmBK2Q0UFhMcpbMAZk8ZxAWHpo,3207
39
+ kabukit-0.5.2.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: uv 0.8.22
2
+ Generator: uv 0.8.23
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any