BackcastPro 0.3.4__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.
BackcastPro/order.py ADDED
@@ -0,0 +1,161 @@
1
+ """
2
+ 注文管理モジュール。
3
+ """
4
+
5
+ from typing import TYPE_CHECKING, Optional
6
+
7
+ if TYPE_CHECKING:
8
+ from ._broker import _Broker
9
+ from .trade import Trade
10
+
11
+
12
+ class Order:
13
+ """
14
+ `Strategy.buy()`と`Strategy.sell()`を通じて新しい注文を出します。
15
+ `Strategy.orders`を通じて既存の注文を照会します。
16
+
17
+ 注文が実行または[約定]されると、`Trade`が発生します。
18
+
19
+ 出されたがまだ約定されていない注文の側面を変更したい場合は、
20
+ キャンセルして新しい注文を出してください。
21
+
22
+ すべての出された注文は[取消注文まで有効]です。
23
+ """
24
+
25
+ def __init__(self, broker: '_Broker',
26
+ code: str,
27
+ size: float,
28
+ limit_price: Optional[float] = None,
29
+ stop_price: Optional[float] = None,
30
+ sl_price: Optional[float] = None,
31
+ tp_price: Optional[float] = None,
32
+ parent_trade: Optional['Trade'] = None,
33
+ tag: object = None):
34
+ self.__code = code
35
+ self.__broker = broker
36
+ assert size != 0
37
+ self.__size = size
38
+ self.__limit_price = limit_price
39
+ self.__stop_price = stop_price
40
+ self.__sl_price = sl_price
41
+ self.__tp_price = tp_price
42
+ self.__parent_trade = parent_trade
43
+ self.__tag = tag
44
+
45
+ def _replace(self, **kwargs):
46
+ for k, v in kwargs.items():
47
+ setattr(self, f'_{self.__class__.__qualname__}__{k}', v)
48
+ return self
49
+
50
+
51
+ def cancel(self):
52
+ """注文をキャンセルします。"""
53
+ self.__broker.orders.remove(self)
54
+ trade = self.__parent_trade
55
+ if trade:
56
+ if self is trade._sl_order:
57
+ trade._replace(sl_order=None)
58
+ elif self is trade._tp_order:
59
+ trade._replace(tp_order=None)
60
+ else:
61
+ pass # Order placed by Trade.close()
62
+
63
+ # Fields getters
64
+
65
+ @property
66
+ def code(self) -> str:
67
+ """
68
+ 注文対象の銘柄コード。
69
+ """
70
+ return self.__code
71
+
72
+ @property
73
+ def size(self) -> float:
74
+ """
75
+ 注文サイズ(ショート注文の場合は負の値)。
76
+
77
+ サイズが0と1の間の値の場合、現在利用可能な流動性(現金 + `Position.pl` - 使用済みマージン)の
78
+ 割合として解釈されます。
79
+ 1以上の値は絶対的なユニット数を示します。
80
+ """
81
+ return self.__size
82
+
83
+ @property
84
+ def limit(self) -> Optional[float]:
85
+ """
86
+ [指値注文]の注文指値価格、または[成行注文]の場合はNone(次に利用可能な価格で約定)。
87
+
88
+ [limit orders]: https://www.investopedia.com/terms/l/limitorder.asp
89
+ [market orders]: https://www.investopedia.com/terms/m/marketorder.asp
90
+ """
91
+ return self.__limit_price
92
+
93
+ @property
94
+ def stop(self) -> Optional[float]:
95
+ """
96
+ [ストップリミット/ストップ成行]注文の注文ストップ価格。
97
+ ストップが設定されていない場合、またはストップ価格が既にヒットした場合はNone。
98
+
99
+ [_]: https://www.investopedia.com/terms/s/stoporder.asp
100
+ """
101
+ return self.__stop_price
102
+
103
+ @property
104
+ def sl(self) -> Optional[float]:
105
+ """
106
+ ストップロス価格。設定されている場合、この注文の実行後に`Trade`に対して
107
+ 新しい条件付きストップ成行注文が配置されます。
108
+ `Trade.sl`も参照してください。
109
+ """
110
+ return self.__sl_price
111
+
112
+ @property
113
+ def tp(self) -> Optional[float]:
114
+ """
115
+ テイクプロフィット価格。設定されている場合、この注文の実行後に`Trade`に対して
116
+ 新しい条件付き指値注文が配置されます。
117
+ `Trade.tp`も参照してください。
118
+ """
119
+ return self.__tp_price
120
+
121
+ @property
122
+ def parent_trade(self):
123
+ return self.__parent_trade
124
+
125
+ @property
126
+ def tag(self):
127
+ """
128
+ 任意の値(文字列など)。設定されている場合、この注文と関連する`Trade`の
129
+ 追跡が可能になります(`Trade.tag`を参照)。
130
+ """
131
+ return self.__tag
132
+
133
+ __pdoc__ = {'Order.parent_trade': False}
134
+
135
+ # Extra properties
136
+
137
+ @property
138
+ def is_long(self):
139
+ """注文がロングの場合(注文サイズが正)にTrueを返します。"""
140
+ return self.__size > 0
141
+
142
+ @property
143
+ def is_short(self):
144
+ """注文がショートの場合(注文サイズが負)にTrueを返します。"""
145
+ return self.__size < 0
146
+
147
+ @property
148
+ def is_contingent(self):
149
+ """
150
+ [条件付き]注文、つまりアクティブな取引に配置された[OCO]ストップロスおよび
151
+ テイクプロフィットブラケット注文の場合にTrueを返します。
152
+ 親`Trade`がクローズされると、残りの条件付き注文はキャンセルされます。
153
+
154
+ `Trade.sl`と`Trade.tp`を通じて条件付き注文を変更できます。
155
+
156
+ [contingent]: https://www.investopedia.com/terms/c/contingentorder.asp
157
+ [OCO]: https://www.investopedia.com/terms/o/oco.asp
158
+ """
159
+ return bool((parent := self.__parent_trade) and
160
+ (self is parent._sl_order or
161
+ self is parent._tp_order))
@@ -0,0 +1,60 @@
1
+ """
2
+ ポジション管理モジュール。
3
+ """
4
+
5
+ from typing import TYPE_CHECKING
6
+
7
+ if TYPE_CHECKING:
8
+ from ._broker import _Broker
9
+
10
+
11
+ class Position:
12
+ """
13
+ 現在保有している資産ポジション。
14
+ `backtesting.backtesting.Strategy.next`内で
15
+ `backtesting.backtesting.Strategy.position`として利用可能です。
16
+ ブール値コンテキストで使用できます。例:
17
+
18
+ if self.position:
19
+ ... # ポジションがあります(ロングまたはショート)
20
+ """
21
+
22
+ def __init__(self, broker: '_Broker'):
23
+ self.__broker = broker
24
+
25
+ def __bool__(self):
26
+ return self.size != 0
27
+
28
+ @property
29
+ def size(self) -> float:
30
+ """資産単位でのポジションサイズ。ショートポジションの場合は負の値。"""
31
+ return sum(trade.size for trade in self.__broker.trades)
32
+
33
+ @property
34
+ def pl(self) -> float:
35
+ """現在のポジションの利益(正)または損失(負)を現金単位で。"""
36
+ return sum(trade.pl for trade in self.__broker.trades)
37
+
38
+ @property
39
+ def pl_pct(self) -> float:
40
+ """現在のポジションの利益(正)または損失(負)をパーセントで。"""
41
+ total_invested = sum(trade.entry_price * abs(trade.size) for trade in self.__broker.trades)
42
+ return (self.pl / total_invested) * 100 if total_invested else 0
43
+
44
+ @property
45
+ def is_long(self) -> bool:
46
+ """ポジションがロング(ポジションサイズが正)の場合True。"""
47
+ return self.size > 0
48
+
49
+ @property
50
+ def is_short(self) -> bool:
51
+ """ポジションがショート(ポジションサイズが負)の場合True。"""
52
+ return self.size < 0
53
+
54
+ def close(self, portion: float = 1.):
55
+ """
56
+ 各アクティブな取引の「一部」を決済することで、ポジションの一部を決済します。詳細は「Trade.close」を参照してください。
57
+ """
58
+ for trade in self.__broker.trades:
59
+ trade.close(portion)
60
+
BackcastPro/trade.py ADDED
@@ -0,0 +1,227 @@
1
+ """
2
+ 取引管理モジュール。
3
+ """
4
+
5
+ import numpy as np
6
+ import pandas as pd
7
+ from copy import copy
8
+ from math import copysign
9
+ from typing import TYPE_CHECKING, Optional, Union
10
+
11
+ if TYPE_CHECKING:
12
+ from ._broker import _Broker
13
+ from .order import Order
14
+
15
+
16
+ class Trade:
17
+ """
18
+ `Order`が約定されると、アクティブな`Trade`が発生します。
19
+ アクティブな取引は`Strategy.trades`で、クローズされた決済済み取引は`Strategy.closed_trades`で見つけることができます。
20
+ """
21
+ def __init__(self, broker: '_Broker', code: str, size: int, entry_price: float, entry_time: Union[pd.Timestamp, int], tag):
22
+ self.__broker = broker
23
+ self.__code = code
24
+ self.__size = size
25
+ self.__entry_price = entry_price
26
+ self.__exit_price: Optional[float] = None
27
+ self.__entry_time: Union[pd.Timestamp, int] = entry_time
28
+ self.__exit_time: Optional[Union[pd.Timestamp, int]] = None
29
+ self.__sl_order: Optional[Order] = None
30
+ self.__tp_order: Optional[Order] = None
31
+ self.__tag = tag
32
+ self._commissions = 0
33
+
34
+ def _replace(self, **kwargs):
35
+ for k, v in kwargs.items():
36
+ setattr(self, f'_{self.__class__.__qualname__}__{k}', v)
37
+ return self
38
+
39
+ def _copy(self, **kwargs):
40
+ return copy(self)._replace(**kwargs)
41
+
42
+ def close(self, portion: float = 1.):
43
+ """次の市場価格で取引の`portion`をクローズする新しい`Order`を出します。"""
44
+ assert 0 < portion <= 1, "portion must be a fraction between 0 and 1"
45
+ # Ensure size is an int to avoid rounding errors on 32-bit OS
46
+ size = copysign(max(1, int(round(abs(self.__size) * portion))), -self.__size)
47
+ from .order import Order
48
+ order = Order(self.__broker, self.__code, size, parent_trade=self, tag=self.__tag)
49
+ self.__broker.orders.insert(0, order)
50
+
51
+ # Fields getters
52
+
53
+ @property
54
+ def code(self):
55
+ """取引対象銘柄"""
56
+ return self.__code
57
+
58
+ @property
59
+ def size(self):
60
+ """取引サイズ(ボリューム;ショート取引の場合は負の値)。"""
61
+ return self.__size
62
+
63
+ @property
64
+ def entry_price(self) -> float:
65
+ """取引エントリー価格。"""
66
+ return self.__entry_price
67
+
68
+ @property
69
+ def exit_price(self) -> Optional[float]:
70
+ """取引エグジット価格(取引がまだアクティブな場合はNone)。"""
71
+ return self.__exit_price
72
+
73
+ @property
74
+ def entry_bar(self) -> int:
75
+ """
76
+ 取引がエントリーされた時のローソク足バーのインデックス。
77
+
78
+ .. deprecated:: 0.1.0
79
+ `entry_time`プロパティを使用してください。
80
+ """
81
+ import warnings
82
+ warnings.warn(
83
+ "entry_barプロパティは非推奨です。entry_timeプロパティを使用してください。",
84
+ DeprecationWarning,
85
+ stacklevel=2
86
+ )
87
+ # データからインデックスを逆算
88
+ try:
89
+ data_index = self.__broker._data[self.__code].index
90
+ return data_index.get_loc(self.__entry_time)
91
+ except (KeyError, TypeError):
92
+ # インデックスが見つからない場合は0を返す
93
+ return 0
94
+
95
+ @property
96
+ def exit_bar(self) -> Optional[int]:
97
+ """
98
+ 取引がエグジットされた時のローソク足バーのインデックス
99
+ (取引がまだアクティブな場合はNone)。
100
+
101
+ .. deprecated:: 0.1.0
102
+ `exit_time`プロパティを使用してください。
103
+ """
104
+ import warnings
105
+ warnings.warn(
106
+ "exit_barプロパティは非推奨です。exit_timeプロパティを使用してください。",
107
+ DeprecationWarning,
108
+ stacklevel=2
109
+ )
110
+ if self.__exit_time is None:
111
+ return None
112
+ try:
113
+ data_index = self.__broker._data[self.__code].index
114
+ return data_index.get_loc(self.__exit_time)
115
+ except (KeyError, TypeError):
116
+ # インデックスが見つからない場合はNoneを返す
117
+ return None
118
+
119
+ @property
120
+ def entry_time(self) -> Union[pd.Timestamp, int]:
121
+ """取引がエントリーされた日時。"""
122
+ return self.__entry_time
123
+
124
+ @property
125
+ def exit_time(self) -> Optional[Union[pd.Timestamp, int]]:
126
+ """取引がエグジットされた日時。"""
127
+ return self.__exit_time
128
+
129
+ @property
130
+ def tag(self):
131
+ """
132
+ この取引を開始した`Order`から継承されたタグ値。
133
+
134
+ 取引の追跡や条件付きロジック/サブグループ分析に使用できます。
135
+
136
+ `Order.tag`も参照してください。
137
+ """
138
+ return self.__tag
139
+
140
+ @property
141
+ def _sl_order(self):
142
+ return self.__sl_order
143
+
144
+ @property
145
+ def _tp_order(self):
146
+ return self.__tp_order
147
+
148
+ # Extra properties
149
+
150
+ @property
151
+ def is_long(self):
152
+ """取引がロングの場合True(取引サイズが正の値)。"""
153
+ return self.__size > 0
154
+
155
+ @property
156
+ def is_short(self):
157
+ """取引がショートの場合True(取引サイズが負の値)。"""
158
+ return not self.is_long
159
+
160
+ @property
161
+ def pl(self):
162
+ """
163
+ 取引の利益(正の値)または損失(負の値)を現金単位で表示。
164
+ 手数料は取引がクローズされた後にのみ反映されます。
165
+ """
166
+ price = self.__exit_price or self.__broker.last_price(self.__code)
167
+ return (self.__size * (price - self.__entry_price)) - self._commissions
168
+
169
+ @property
170
+ def pl_pct(self):
171
+ """取引の利益(正の値)または損失(負の値)をパーセントで表示。"""
172
+ price = self.__exit_price or self.__broker.last_price(self.__code)
173
+ gross_pl_pct = copysign(1, self.__size) * (price / self.__entry_price - 1)
174
+
175
+ # 取引全体のサイズに対する手数料を個別単位に換算
176
+ commission_pct = self._commissions / (abs(self.__size) * self.__entry_price)
177
+ return gross_pl_pct - commission_pct
178
+
179
+ @property
180
+ def value(self):
181
+ """取引の総価値を現金単位で表示(ボリューム × 価格)。"""
182
+ price = self.__exit_price or self.__broker.last_price(self.__code)
183
+ return abs(self.__size) * price
184
+
185
+ # SL/TP management API
186
+
187
+ @property
188
+ def sl(self):
189
+ """
190
+ 取引をクローズするストップロス価格。
191
+
192
+ この変数は書き込み可能です。新しい価格値を割り当てることで、
193
+ 既存のSLオーダーを作成または修正します。
194
+ `None`を割り当てることでキャンセルできます。
195
+ """
196
+ return self.__sl_order and self.__sl_order.stop
197
+
198
+ @sl.setter
199
+ def sl(self, price: float):
200
+ self.__set_contingent('sl', price)
201
+
202
+ @property
203
+ def tp(self):
204
+ """
205
+ 取引をクローズするテイクプロフィット価格。
206
+
207
+ このプロパティは書き込み可能です。新しい価格値を割り当てることで、
208
+ 既存のTPオーダーを作成または修正します。
209
+ `None`を割り当てることでキャンセルできます。
210
+ """
211
+ return self.__tp_order and self.__tp_order.limit
212
+
213
+ @tp.setter
214
+ def tp(self, price: float):
215
+ self.__set_contingent('tp', price)
216
+
217
+ def __set_contingent(self, type, price):
218
+ assert type in ('sl', 'tp')
219
+ assert price is None or 0 < price < np.inf, f'Make sure 0 < price < inf! price: {price}'
220
+ attr = f'_{self.__class__.__qualname__}__{type}_order'
221
+ order: Order = getattr(self, attr)
222
+ if order:
223
+ order.cancel()
224
+ if price:
225
+ kwargs = {'stop': price} if type == 'sl' else {'limit': price}
226
+ order = self.__broker.new_order(self.code, -self.size, trade=self, tag=self.tag, **kwargs)
227
+ setattr(self, attr, order)
@@ -0,0 +1,112 @@
1
+ Metadata-Version: 2.4
2
+ Name: BackcastPro
3
+ Version: 0.3.4
4
+ Summary: トレーディング戦略のためのPythonバックテストライブラリ
5
+ Project-URL: Homepage, https://github.com/botterYosuke/BackcastPro/
6
+ Project-URL: Issues, https://github.com/botterYosuke/BackcastPro/issues
7
+ Project-URL: Logo, https://raw.githubusercontent.com/botterYosuke/BackcastPro/main/docs/img/logo.drawio.svg
8
+ Author: botterYosuke
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.9
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Requires-Python: >=3.9
17
+ Requires-Dist: anywidget>=0.9.21
18
+ Requires-Dist: duckdb>=0.9.0
19
+ Requires-Dist: matplotlib>=3.0.0
20
+ Requires-Dist: numpy>=1.20.0
21
+ Requires-Dist: pandas>=1.3.0
22
+ Requires-Dist: plotly>=5.0.0
23
+ Requires-Dist: python-dotenv>=0.19.0
24
+ Requires-Dist: requests>=2.25.0
25
+ Requires-Dist: scipy>=1.7.0
26
+ Provides-Extra: all
27
+ Requires-Dist: yfinance>=0.2.0; extra == 'all'
28
+ Provides-Extra: yfinance
29
+ Requires-Dist: yfinance>=0.2.0; extra == 'yfinance'
30
+ Description-Content-Type: text/markdown
31
+
32
+ # <img src="https://raw.githubusercontent.com/botterYosuke/BackcastPro/main/docs/img/logo.drawio.svg" alt="BackcastPro Logo" width="40" height="24"> BackcastPro
33
+
34
+ トレーディング戦略のためのPythonバックテストライブラリ。
35
+ **リプレイ型シミュレーター**で、1バーずつ時間を進めながらチャートと売買を可視化できます。
36
+
37
+ ## インストール(Windows)
38
+
39
+ ### PyPIから(エンドユーザー向け)
40
+
41
+ ```powershell
42
+ python -m pip install BackcastPro
43
+ ```
44
+
45
+ ### 開発用インストール
46
+
47
+ ```powershell
48
+ git clone <repository-url>
49
+ cd BackcastPro
50
+ python -m venv .venv
51
+ .\.venv\Scripts\Activate.ps1
52
+ python -m pip install -e .
53
+ python -m pip install -r requirements.txt
54
+ ```
55
+
56
+ ## 使用方法
57
+
58
+ ### 基本的な使い方
59
+
60
+ ```python
61
+ from BackcastPro import Backtest
62
+ import pandas as pd
63
+
64
+ # データ準備
65
+ df = pd.read_csv("AAPL.csv", index_col=0, parse_dates=True)
66
+ bt = Backtest(data={"AAPL": df}, cash=100000)
67
+
68
+ # 戦略関数
69
+ def my_strategy(bt):
70
+ if bt.position == 0:
71
+ bt.buy(tag="entry")
72
+ elif bt.position > 0:
73
+ bt.sell(tag="exit")
74
+
75
+ # ステップ実行
76
+ while not bt.is_finished:
77
+ my_strategy(bt)
78
+ bt.step()
79
+
80
+ # 結果を取得
81
+ results = bt.finalize()
82
+ print(results)
83
+ ```
84
+
85
+ ### 一括実行
86
+
87
+ ```python
88
+ bt = Backtest(data={"AAPL": df}, cash=100000)
89
+ results = bt.run_with_strategy(my_strategy)
90
+ ```
91
+
92
+ ### marimo連携(リプレイ型シミュレーター)
93
+
94
+ ```python
95
+ import marimo as mo
96
+
97
+ slider = mo.ui.slider(start=1, stop=len(bt.index), value=1, label="時間")
98
+ bt.goto(slider.value, strategy=my_strategy)
99
+ chart = bt.chart() # plotlyローソク足 + 売買マーカー
100
+
101
+ mo.vstack([slider, chart])
102
+ ```
103
+
104
+ ## ドキュメント
105
+
106
+ - [ドキュメント一覧](https://github.com/botterYosuke/BackcastPro/blob/main/docs/index.md)
107
+
108
+ ## バグ報告 / サポート
109
+
110
+ - バグ報告や要望は GitHub Issues へ
111
+ - 質問は Discord コミュニティへ([招待リンク](https://discord.gg/fzJTbpzE))
112
+ - 使い方はドキュメントをご参照ください
@@ -0,0 +1,26 @@
1
+ BackcastPro/__init__.py,sha256=vY2nk7aULUyIbW6ftJEgshANUZLSdY1l1PS0zJVfza4,1148
2
+ BackcastPro/_broker.py,sha256=VAHJ9A8JRxEue7bBr6RnwMOjDQy-4zPWRGFogoot6ck,20729
3
+ BackcastPro/_stats.py,sha256=378fs_XUyJo0etwZYnamB_69GjJFvzAmURv4fki4F9w,8260
4
+ BackcastPro/backtest.py,sha256=hUTJJRDkuf5R-Z0iYkdsuxXN-WxJ16osZh3IdIKCVh0,23199
5
+ BackcastPro/order.py,sha256=ir8FbZkWSHD1VdfWs1HlWm-xM_7zmwV4OumIK74xjIU,5545
6
+ BackcastPro/position.py,sha256=5yfeTJFWZdptxDkz14-IRvco13098WAWeB3A6zTQcDE,2077
7
+ BackcastPro/trade.py,sha256=QWISxpBNfdjNRX9K1yq-w6uLH2-E9_E0anqdWpo-2As,8113
8
+ BackcastPro/api/__init__.py,sha256=0sbuGUTeTsxJI9ZIJ5bL665kSh4cxO77ooojxnj0m8g,59
9
+ BackcastPro/api/board.py,sha256=DnzStITA2XfV6ZLW6vfPSKUxE09c0LLiWvVqCQ8oOrE,4861
10
+ BackcastPro/api/chart.py,sha256=-5hlOKF14xKfuouS6Ct1Hy7SG3bm1uZT7Bg48cldr54,15678
11
+ BackcastPro/api/db_manager.py,sha256=aKMoI6mJ0rv4NE5Zri9yh9aCIpL3oZcf5FtHTLGAHKQ,13051
12
+ BackcastPro/api/db_stocks_board.py,sha256=2vEn6BpDKu1mRS7eGxWMEnqa-APfea6wzfMNtm6Pa_g,18219
13
+ BackcastPro/api/db_stocks_daily.py,sha256=NTLrNA9-akqCU9rxRPZxHGv6SitKj2RlYvYhInP4ypo,21872
14
+ BackcastPro/api/db_stocks_info.py,sha256=anEI-DuA1_h1tMJItmqdkvIiCvlxVz2yQqmACKKRdrs,11029
15
+ BackcastPro/api/stocks_board.py,sha256=rUEno0Isy9d-AoMiPGMBF6G5FtU55VHprOs5sal4oWc,2829
16
+ BackcastPro/api/stocks_info.py,sha256=jU108M3MCm0bT1t1YtMJppPWaCHYgpD7A2O9YSle6Kk,3232
17
+ BackcastPro/api/stocks_price.py,sha256=PezgWJtVstfAFZ615S5WXHxEw8QrAxzzAQ1w_WXlPWc,5174
18
+ BackcastPro/api/lib/__init__.py,sha256=XbMfpIz8vom84qygXaCEUVJHhlIh9AxSa0oCkGOvgkI,50
19
+ BackcastPro/api/lib/e_api.py,sha256=BjYbk9beGtd1smLCpTo_ZFiM7-OZuufCz3cQjb_mG9A,23563
20
+ BackcastPro/api/lib/jquants.py,sha256=PCo8KlD4_Tl6HExQxpnTW-tN2XkAT6pHjRJuv20RhwQ,12826
21
+ BackcastPro/api/lib/kabusap.py,sha256=CoZ9FEYDcfoAbGdWhSW9V7D_EMjSJVQ8xHOARQN9kIc,9441
22
+ BackcastPro/api/lib/stooq.py,sha256=goPssHTORTmvkQz6Og_A-WDatZ-Bh3EikL0_9kG6dZQ,16334
23
+ BackcastPro/api/lib/util.py,sha256=Jwdlo9cvVVUQ9RP42VhI7C9BDXbm6N2y9539gMmwI80,950
24
+ backcastpro-0.3.4.dist-info/METADATA,sha256=p0zpeB4ioB85bmnUMQo1WmTw3cN_ZcO87KcS3FyCPNg,3279
25
+ backcastpro-0.3.4.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
26
+ backcastpro-0.3.4.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any