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.
- backcastpro-0.6.4/.claude/hand-off-download.md +59 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/.claude/settings.local.json +14 -1
- {backcastpro-0.6.3 → backcastpro-0.6.4}/.github/workflows/publish-pypi.yml +1 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/PKG-INFO +1 -1
- {backcastpro-0.6.3 → backcastpro-0.6.4}/pyproject.toml +2 -3
- {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/__init__.py +2 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/_broker.py +9 -2
- {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/backtest.py +3 -3
- {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_backtest_api.py +2 -2
- {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_backtest_step_loop.py +2 -9
- {backcastpro-0.6.3 → backcastpro-0.6.4}/uv.lock +555 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/.coverage +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/.gcloudignore +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/.github/workflows/docs.yml +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/.github/workflows/publish-dockerhub.yml +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/.gitignore +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/.python-version +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/.vscode/launch.json +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/.vscode/settings.json +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/AGENTS.md +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/CLAUDE.md +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/README.md +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/cloud-job/.env.example +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/cloud-job/Dockerfile +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/cloud-job/update_stocks_price.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/cloud-run/.env.example +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/cloud-run/Dockerfile +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/cloud-run/main.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/cloud-run/requirements.txt +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/docs/cloud-run-updater.md +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/docs/design-decisions.md +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/docs/developer-guide.md +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/docs/examples/SmaCross.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/docs/examples/marimo_replay.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/docs/execution-logic-report.md +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/docs/how-to-deploy-to-PyPI.md +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/docs/img/logo.drawio.svg +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/docs/index.md +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/docs/privacy.md +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/docs/troubleshooting.md +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/docs/tutorial.md +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/mkdocs.yml +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/_stats.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/api/__init__.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/api/cloud_run_client.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/api/db_manager.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/api/db_stocks_board.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/api/db_stocks_daily.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/api/db_stocks_info.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/api/stocks_board.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/api/stocks_info.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/api/stocks_price.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/order.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/position.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/src/BackcastPro/trade.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/src/__init__.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/src/trading_data/__init__.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/src/trading_data/lib/__init__.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/src/trading_data/lib/e_api.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/src/trading_data/lib/jquants.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/src/trading_data/lib/kabusap.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/src/trading_data/lib/stooq.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/src/trading_data/lib/util.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/src/trading_data/stocks_board.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/src/trading_data/stocks_info.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/src/trading_data/stocks_price.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/test_output.txt +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/import_equities_trades.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/import_minute_bars.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_backtest_set_data.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_cloud_run_client.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_cloud_run_main.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_db_manager.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_db_stocks_board.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_db_stocks_daily.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_db_stocks_info.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_e_api.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_j-quants.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_kabusap.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_order.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_position.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_relative_size_option_c.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_stats.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_stocks_board_wrapper.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_stocks_info_wrapper.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_stocks_price_wrapper.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_stooq.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_trade.py +0 -0
- {backcastpro-0.6.3 → backcastpro-0.6.4}/tests/test_update_stocks_price.py +0 -0
- {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",
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "BackcastPro"
|
|
7
|
-
version = "0.6.
|
|
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
|
|
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
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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):
|