BackcastPro 0.6.3__tar.gz → 0.6.4__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 (90) hide show
  1. backcastpro-0.6.4/.claude/hand-off-download.md +59 -0
  2. {backcastpro-0.6.3 → backcastpro-0.6.4}/.claude/settings.local.json +14 -1
  3. {backcastpro-0.6.3 → backcastpro-0.6.4}/.github/workflows/publish-pypi.yml +1 -0
  4. {backcastpro-0.6.3 → backcastpro-0.6.4}/PKG-INFO +1 -1
  5. {backcastpro-0.6.3 → backcastpro-0.6.4}/pyproject.toml +2 -3
  6. {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/__init__.py +2 -0
  7. {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/_broker.py +9 -2
  8. {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/backtest.py +3 -3
  9. {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_backtest_api.py +2 -2
  10. {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_backtest_step_loop.py +2 -9
  11. {backcastpro-0.6.3 → backcastpro-0.6.4}/uv.lock +555 -0
  12. {backcastpro-0.6.3 → backcastpro-0.6.4}/.coverage +0 -0
  13. {backcastpro-0.6.3 → backcastpro-0.6.4}/.gcloudignore +0 -0
  14. {backcastpro-0.6.3 → backcastpro-0.6.4}/.github/workflows/docs.yml +0 -0
  15. {backcastpro-0.6.3 → backcastpro-0.6.4}/.github/workflows/publish-dockerhub.yml +0 -0
  16. {backcastpro-0.6.3 → backcastpro-0.6.4}/.gitignore +0 -0
  17. {backcastpro-0.6.3 → backcastpro-0.6.4}/.python-version +0 -0
  18. {backcastpro-0.6.3 → backcastpro-0.6.4}/.vscode/launch.json +0 -0
  19. {backcastpro-0.6.3 → backcastpro-0.6.4}/.vscode/settings.json +0 -0
  20. {backcastpro-0.6.3 → backcastpro-0.6.4}/AGENTS.md +0 -0
  21. {backcastpro-0.6.3 → backcastpro-0.6.4}/CLAUDE.md +0 -0
  22. {backcastpro-0.6.3 → backcastpro-0.6.4}/README.md +0 -0
  23. {backcastpro-0.6.3 → backcastpro-0.6.4}/cloud-job/.env.example +0 -0
  24. {backcastpro-0.6.3 → backcastpro-0.6.4}/cloud-job/Dockerfile +0 -0
  25. {backcastpro-0.6.3 → backcastpro-0.6.4}/cloud-job/update_stocks_price.py +0 -0
  26. {backcastpro-0.6.3 → backcastpro-0.6.4}/cloud-run/.env.example +0 -0
  27. {backcastpro-0.6.3 → backcastpro-0.6.4}/cloud-run/Dockerfile +0 -0
  28. {backcastpro-0.6.3 → backcastpro-0.6.4}/cloud-run/main.py +0 -0
  29. {backcastpro-0.6.3 → backcastpro-0.6.4}/cloud-run/requirements.txt +0 -0
  30. {backcastpro-0.6.3 → backcastpro-0.6.4}/docs/cloud-run-updater.md +0 -0
  31. {backcastpro-0.6.3 → backcastpro-0.6.4}/docs/design-decisions.md +0 -0
  32. {backcastpro-0.6.3 → backcastpro-0.6.4}/docs/developer-guide.md +0 -0
  33. {backcastpro-0.6.3 → backcastpro-0.6.4}/docs/examples/SmaCross.py +0 -0
  34. {backcastpro-0.6.3 → backcastpro-0.6.4}/docs/examples/marimo_replay.py +0 -0
  35. {backcastpro-0.6.3 → backcastpro-0.6.4}/docs/execution-logic-report.md +0 -0
  36. {backcastpro-0.6.3 → backcastpro-0.6.4}/docs/how-to-deploy-to-PyPI.md +0 -0
  37. {backcastpro-0.6.3 → backcastpro-0.6.4}/docs/img/logo.drawio.svg +0 -0
  38. {backcastpro-0.6.3 → backcastpro-0.6.4}/docs/index.md +0 -0
  39. {backcastpro-0.6.3 → backcastpro-0.6.4}/docs/privacy.md +0 -0
  40. {backcastpro-0.6.3 → backcastpro-0.6.4}/docs/troubleshooting.md +0 -0
  41. {backcastpro-0.6.3 → backcastpro-0.6.4}/docs/tutorial.md +0 -0
  42. {backcastpro-0.6.3 → backcastpro-0.6.4}/mkdocs.yml +0 -0
  43. {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/_stats.py +0 -0
  44. {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/api/__init__.py +0 -0
  45. {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/api/cloud_run_client.py +0 -0
  46. {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/api/db_manager.py +0 -0
  47. {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/api/db_stocks_board.py +0 -0
  48. {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/api/db_stocks_daily.py +0 -0
  49. {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/api/db_stocks_info.py +0 -0
  50. {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/api/stocks_board.py +0 -0
  51. {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/api/stocks_info.py +0 -0
  52. {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/api/stocks_price.py +0 -0
  53. {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/order.py +0 -0
  54. {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/position.py +0 -0
  55. {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/trade.py +0 -0
  56. {backcastpro-0.6.3 → backcastpro-0.6.4}/src/__init__.py +0 -0
  57. {backcastpro-0.6.3 → backcastpro-0.6.4}/src/trading_data/__init__.py +0 -0
  58. {backcastpro-0.6.3 → backcastpro-0.6.4}/src/trading_data/lib/__init__.py +0 -0
  59. {backcastpro-0.6.3 → backcastpro-0.6.4}/src/trading_data/lib/e_api.py +0 -0
  60. {backcastpro-0.6.3 → backcastpro-0.6.4}/src/trading_data/lib/jquants.py +0 -0
  61. {backcastpro-0.6.3 → backcastpro-0.6.4}/src/trading_data/lib/kabusap.py +0 -0
  62. {backcastpro-0.6.3 → backcastpro-0.6.4}/src/trading_data/lib/stooq.py +0 -0
  63. {backcastpro-0.6.3 → backcastpro-0.6.4}/src/trading_data/lib/util.py +0 -0
  64. {backcastpro-0.6.3 → backcastpro-0.6.4}/src/trading_data/stocks_board.py +0 -0
  65. {backcastpro-0.6.3 → backcastpro-0.6.4}/src/trading_data/stocks_info.py +0 -0
  66. {backcastpro-0.6.3 → backcastpro-0.6.4}/src/trading_data/stocks_price.py +0 -0
  67. {backcastpro-0.6.3 → backcastpro-0.6.4}/test_output.txt +0 -0
  68. {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/import_equities_trades.py +0 -0
  69. {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/import_minute_bars.py +0 -0
  70. {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_backtest_set_data.py +0 -0
  71. {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_cloud_run_client.py +0 -0
  72. {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_cloud_run_main.py +0 -0
  73. {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_db_manager.py +0 -0
  74. {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_db_stocks_board.py +0 -0
  75. {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_db_stocks_daily.py +0 -0
  76. {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_db_stocks_info.py +0 -0
  77. {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_e_api.py +0 -0
  78. {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_j-quants.py +0 -0
  79. {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_kabusap.py +0 -0
  80. {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_order.py +0 -0
  81. {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_position.py +0 -0
  82. {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_relative_size_option_c.py +0 -0
  83. {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_stats.py +0 -0
  84. {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_stocks_board_wrapper.py +0 -0
  85. {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_stocks_info_wrapper.py +0 -0
  86. {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_stocks_price_wrapper.py +0 -0
  87. {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_stooq.py +0 -0
  88. {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_trade.py +0 -0
  89. {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_update_stocks_price.py +0 -0
  90. {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_util.py +0 -0
@@ -0,0 +1,59 @@
1
+ # J-Quants データダウンロード引継ぎ資料
2
+
3
+ ## 目的
4
+ J-Quants Webサイトから2026年1月(月次分)および2月(日次分)の以下のデータを `S:\j-quants` にダウンロードする。
5
+ - 株価四本値 (Daily Bars)
6
+ - 株価分足 (Minute Bars)
7
+ - 株価ティック (Trades)
8
+
9
+ ## 作業状況
10
+ - ブラウザエージェントは既に J-Quants ダッシュボードにログイン済みです。
11
+ - ファイルキーのパターンは特定済みですが、取得用URL(署名付きURL)は **300秒(5分)で有効期限が切れる** ため、一括でURLを取得してからダウンロードするのではなく、取得後すぐにダウンロードする必要があります。
12
+
13
+ ## 対象ファイルリスト (2026年)
14
+
15
+ ### 1. 2026年1月 (月次一括)
16
+ - `equities_bars_daily_202601.csv.gz`
17
+ - `equities_bars_minute_202601.csv.gz`
18
+ - `equities_trades_202601.csv.gz`
19
+
20
+ ### 2. 2026年2月 (日次)
21
+ 日付: 02, 03, 04, 05, 06, 09, 10, 12, 13, 16, 17, 18
22
+ (例: `equities_bars_daily_20260218.csv.gz`)
23
+
24
+ ## URL取得方法 (ブラウザエージェントへの依頼)
25
+ ダッシュボードページ (`https://jpx-jquants.com/ja/dashboard/downloads/price-data/stocks`) で以下のJavaScriptを実行してURLを取得してください。
26
+
27
+ ```javascript
28
+ (async () => {
29
+ const key = "対象のファイルキー"; // 例: equities/bars/daily/live/equities_bars_daily_20260218.csv.gz
30
+ const res = await fetch('/api/trpc/bulk.bulkGet?batch=1', {
31
+ method: 'POST',
32
+ headers: { 'Content-Type': 'application/json' },
33
+ body: JSON.stringify({ "0": { "json": { "key": key } } })
34
+ });
35
+ const data = await res.json();
36
+ return data[0]?.result?.data?.json; // 署名付きURLが返る
37
+ })()
38
+ ```
39
+
40
+ ### キーの指定ルール
41
+ - **2026/01**: `equities/[カテゴリ]/historical/2026/equities_[名前]_202601.csv.gz`
42
+ - **2026/02**: `equities/[カテゴリ]/live/equities_[名前]_202602[日付].csv.gz`
43
+ - カテゴリ/名前の対応:
44
+ - 株価四本値: `bars/daily` / `bars_daily`
45
+ - 株価分足: `bars/minute` / `bars_minute`
46
+ - 株価ティック: `trades` / `trades`
47
+
48
+ ## ダウンロード実行方法 (PowerShell)
49
+ 取得したURL(`$URL`)を使って、Windowsの `curl.exe` で保存します。
50
+
51
+ ```powershell
52
+ curl.exe -L "$URL" -o "S:\j-quants\filename.csv.gz"
53
+ ```
54
+
55
+ ## 注意事項
56
+ - **有効期限**: URLは5分で切れます。1ファイルずつ「URL取得 -> 即座にダウンロード」のサイクルを繰り返してください。
57
+ - **保存先**: `S:\j-quants` 固定です。
58
+ - **2月のキー**: 現在(2026/02)は `live` パスにあるものが多いですが、失敗した場合は `historical/2026/02/` パスを試してください。
59
+ - **残存ファイル**: `S:\j-quants` に容量0のファイルや無効なXMLエラーが含まれるファイルがある場合は上書きしてください。
@@ -11,7 +11,20 @@
11
11
  "Bash(git -C \"D:/Documents/marimo\" show sasa/markdown:\"frontend/src/components/editor/renderers/cell-3d-wrapper.css\")",
12
12
  "Bash(pushd:*)",
13
13
  "Bash(git stash:*)",
14
- "Read(//c/Users/sasac/AppData/Roaming/marimo/**)"
14
+ "Read(//c/Users/sasac/AppData/Roaming/marimo/**)",
15
+ "Bash(npx:*)",
16
+ "Bash(where:*)",
17
+ "Bash(node -e \"console.log\\(require\\(''child_process''\\).execSync\\(''npx.cmd @playwright/mcp@latest --help''\\).toString\\(\\).substring\\(0, 200\\)\\)\")",
18
+ "Bash(npm ls:*)",
19
+ "Bash(npm cache:*)",
20
+ "Bash(npx.cmd:*)",
21
+ "Bash(claude mcp add:*)",
22
+ "Bash(CLAUDE_CODE_GIT_BASH_PATH=\"/c/Program Files/Git/bin/bash.exe\" claude mcp add --transport stdio --scope user playwright -- npx.cmd @playwright/mcp@latest)",
23
+ "Bash(node -e \":*)",
24
+ "Bash(node -e:*)",
25
+ "mcp__playwright__browser_navigate",
26
+ "mcp__playwright__browser_take_screenshot",
27
+ "Read(//c/Users/sasai/Downloads/logs_57994019762/**)"
15
28
  ],
16
29
  "additionalDirectories": [
17
30
  "d:\\Documents\\BackcastPro",
@@ -43,6 +43,7 @@ jobs:
43
43
 
44
44
  - name: TestPyPIにパブリッシュ
45
45
  if: steps.check_pypi.outputs.exists == 'false'
46
+ continue-on-error: true
46
47
  run: uv publish --publish-url https://test.pypi.org/legacy/
47
48
  env:
48
49
  UV_PUBLISH_TOKEN: ${{ secrets.TEST_PYPI_TOKEN }}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: BackcastPro
3
- Version: 0.6.3
3
+ Version: 0.6.4
4
4
  Summary: トレーディング戦略のためのPythonバックテストライブラリ
5
5
  Project-URL: Homepage, https://github.com/botterYosuke/BackcastPro/
6
6
  Project-URL: Issues, https://github.com/botterYosuke/BackcastPro/issues
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "BackcastPro"
7
- version = "0.6.3"
7
+ version = "0.6.4"
8
8
  authors = [
9
9
  { name="botterYosuke" },
10
10
  ]
@@ -30,7 +30,7 @@ dependencies = [
30
30
  "duckdb>=0.9.0",
31
31
  "plotly>=5.0.0",
32
32
  "anywidget>=0.9.21",
33
- "msgpack>=1.0.0",
33
+ "msgpack>=1.0.0"
34
34
  ]
35
35
 
36
36
  [project.optional-dependencies]
@@ -70,4 +70,3 @@ cloud-job = [
70
70
  "requests>=2.25.0",
71
71
  "yfinance>=0.2.0",
72
72
  ]
73
-
@@ -11,6 +11,7 @@ BackcastPro をご利用いただきありがとうございます。
11
11
  ※ 使い始めはチュートリアル → 詳細はAPIリファレンスをご参照ください。
12
12
  """
13
13
  from .backtest import Backtest
14
+ from ._broker import BankruptError
14
15
 
15
16
  from .api.stocks_price import get_stock_daily
16
17
  from .api.stocks_board import get_stock_board
@@ -18,6 +19,7 @@ from .api.stocks_info import get_stock_info
18
19
 
19
20
  __all__ = [
20
21
  'Backtest',
22
+ 'BankruptError',
21
23
  'get_stock_daily',
22
24
  'get_stock_board',
23
25
  'get_stock_info',
@@ -17,6 +17,11 @@ if TYPE_CHECKING:
17
17
  pass
18
18
 
19
19
 
20
+ class BankruptError(Exception):
21
+ """エクイティが0以下になった場合に発生する破産例外"""
22
+ pass
23
+
24
+
20
25
  class _Broker:
21
26
  """
22
27
  バックテストにおける証券取引の実行、注文管理、ポジション管理、損益計算を担当します。
@@ -199,7 +204,9 @@ class _Broker:
199
204
  price = self._data[trade.code].Close.iloc[-1]
200
205
  self._close_trade(trade, price, self._current_time)
201
206
  self._cash = 0
202
- raise Exception
207
+ raise BankruptError(
208
+ f"エクイティが0以下になりました (equity={equity:.2f})"
209
+ )
203
210
 
204
211
  def _process_orders(self):
205
212
  data = self._data
@@ -254,7 +261,7 @@ class _Broker:
254
261
  else:
255
262
  # 成行注文(Market-if-touched / market order)
256
263
  # 条件付き注文は常に次の始値で
257
- prev_close = df.Close.iloc[-2]
264
+ prev_close = df.Close.iloc[-2] if len(df) >= 2 else df.Close.iloc[-1]
258
265
  price = prev_close if self._trade_on_close and not order.is_contingent else open
259
266
  if stop_price:
260
267
  price = max(price, stop_price) if order.is_long else min(price, stop_price)
@@ -11,7 +11,7 @@ from typing import Callable, List, Optional, Tuple, Union
11
11
  import numpy as np
12
12
  import pandas as pd
13
13
 
14
- from ._broker import _Broker
14
+ from ._broker import _Broker, BankruptError
15
15
  from ._stats import compute_stats
16
16
  from .position import Position
17
17
 
@@ -304,7 +304,7 @@ class Backtest:
304
304
  try:
305
305
  self._broker_instance._data = self._current_data
306
306
  self._broker_instance.next(current_time)
307
- except Exception:
307
+ except BankruptError:
308
308
  self._is_finished = True
309
309
  return False
310
310
 
@@ -547,7 +547,7 @@ class Backtest:
547
547
  "progress": float(self.progress),
548
548
  "equity": float(self.equity),
549
549
  "cash": float(self.cash),
550
- "position": self.position.to_dict(),
550
+ "position": self.position.size,
551
551
  "positions": positions,
552
552
  "closed_trades": len(self.closed_trades),
553
553
  "step_index": self.step_index,
@@ -1,11 +1,11 @@
1
1
  """
2
2
  TDD Tests for BackcastPro Public API Extensions
3
3
 
4
- Goal: Add public API for marimo-independent state access and callback mechanism.
4
+ Goal: Add public API for state access and callback mechanism.
5
5
 
6
6
  Phase 1 Tests:
7
7
  1. step_index property - read-only access to _step_index
8
- 2. get_state_snapshot() - returns current state as dict (marimo-independent)
8
+ 2. get_state_snapshot() - returns current state as dict
9
9
  3. add_trade_callback() - multiple callback registration for trade events
10
10
 
11
11
  These tests follow TDD (Red-Green-Refactor):
@@ -2,16 +2,12 @@
2
2
  TDD Tests for Backtest Step Loop Mechanism
3
3
 
4
4
  Goal: Verify that the step loop mechanism works correctly for game loop integration.
5
- This tests the core backtest step behavior that the marimo game loop relies on:
6
5
 
7
6
  1. bt.step() increments _step_index correctly
8
7
  2. bt.step() returns True while there are more steps
9
8
  3. bt.step() returns False when finished
10
9
  4. bt.is_finished reflects the correct state
11
10
  5. Multiple step() calls in a loop work correctly
12
-
13
- These tests do NOT test marimo UI parts (mo.state, mo.Thread),
14
- but focus on the underlying BackcastPro logic.
15
11
  """
16
12
 
17
13
  import pytest
@@ -332,7 +328,7 @@ class TestStepLoop:
332
328
 
333
329
  class TestGameLoopSimulation:
334
330
  """
335
- Simulate the marimo game loop pattern:
331
+ Simulate the game loop pattern:
336
332
 
337
333
  def _game_loop():
338
334
  while bt.is_finished == False:
@@ -346,7 +342,7 @@ class TestGameLoopSimulation:
346
342
 
347
343
  def test_game_loop_pattern_basic(self):
348
344
  """
349
- Test the basic game loop pattern without marimo state.
345
+ Test the basic game loop pattern.
350
346
  """
351
347
  code = "TEST"
352
348
  df = create_sample_df(10)
@@ -625,9 +621,6 @@ class TestMultipleStocksStepLoop:
625
621
  class TestStrategyDataAccess:
626
622
  """
627
623
  Test that strategy can access bt.data during step().
628
-
629
- This is critical for the marimo game loop where the strategy
630
- needs to read current data on each step.
631
624
  """
632
625
 
633
626
  def test_strategy_can_access_data_on_first_step(self):