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/__init__.py +28 -0
- BackcastPro/_broker.py +430 -0
- BackcastPro/_stats.py +177 -0
- BackcastPro/api/__init__.py +4 -0
- BackcastPro/api/board.py +130 -0
- BackcastPro/api/chart.py +527 -0
- BackcastPro/api/db_manager.py +283 -0
- BackcastPro/api/db_stocks_board.py +428 -0
- BackcastPro/api/db_stocks_daily.py +507 -0
- BackcastPro/api/db_stocks_info.py +260 -0
- BackcastPro/api/lib/__init__.py +4 -0
- BackcastPro/api/lib/e_api.py +588 -0
- BackcastPro/api/lib/jquants.py +384 -0
- BackcastPro/api/lib/kabusap.py +222 -0
- BackcastPro/api/lib/stooq.py +409 -0
- BackcastPro/api/lib/util.py +38 -0
- BackcastPro/api/stocks_board.py +77 -0
- BackcastPro/api/stocks_info.py +88 -0
- BackcastPro/api/stocks_price.py +131 -0
- BackcastPro/backtest.py +594 -0
- BackcastPro/order.py +161 -0
- BackcastPro/position.py +60 -0
- BackcastPro/trade.py +227 -0
- backcastpro-0.3.4.dist-info/METADATA +112 -0
- backcastpro-0.3.4.dist-info/RECORD +26 -0
- backcastpro-0.3.4.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
from .lib.jquants import jquants
|
|
2
|
+
from .lib.e_api import e_api
|
|
3
|
+
from .lib.kabusap import kabusap
|
|
4
|
+
from .lib.stooq import stooq_daily_quotes
|
|
5
|
+
from .db_stocks_daily import db_stocks_daily
|
|
6
|
+
from .lib.util import _Timestamp
|
|
7
|
+
|
|
8
|
+
import pandas as pd
|
|
9
|
+
import threading
|
|
10
|
+
from datetime import datetime
|
|
11
|
+
import logging
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
logger.setLevel(logging.INFO)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class stocks_price:
|
|
18
|
+
"""
|
|
19
|
+
銘柄の株価データを取得するためのクラス
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(self):
|
|
23
|
+
self.db = db_stocks_daily()
|
|
24
|
+
|
|
25
|
+
def get_japanese_stock_price_data(
|
|
26
|
+
self, code="", from_: datetime = None, to: datetime = None
|
|
27
|
+
) -> pd.DataFrame:
|
|
28
|
+
# 銘柄コードの検証
|
|
29
|
+
if not code or not isinstance(code, str) or not code.strip():
|
|
30
|
+
raise ValueError("銘柄コードが指定されていません")
|
|
31
|
+
|
|
32
|
+
# from_/to の柔軟入力(str/date/pd.Timestamp)を正規化
|
|
33
|
+
norm_from = _Timestamp(from_)
|
|
34
|
+
norm_to = _Timestamp(to)
|
|
35
|
+
|
|
36
|
+
if norm_from and norm_to and norm_from > norm_to:
|
|
37
|
+
raise ValueError("開始日が終了日より後になっています")
|
|
38
|
+
|
|
39
|
+
# DBファイルの準備(存在しなければFTPからダウンロードを試行)
|
|
40
|
+
self.db.ensure_db_ready(code)
|
|
41
|
+
|
|
42
|
+
# 1) cacheフォルダから取得
|
|
43
|
+
df = self.db.load_stock_prices_from_cache(code, norm_from, norm_to)
|
|
44
|
+
if df is not None and not df.empty:
|
|
45
|
+
return df
|
|
46
|
+
|
|
47
|
+
# 2) 立花証券 e-支店から取得
|
|
48
|
+
if not hasattr(self, "e_shiten"):
|
|
49
|
+
self.e_shiten = e_api()
|
|
50
|
+
if self.e_shiten.isEnable:
|
|
51
|
+
df = self.e_shiten.get_daily_quotes(code=code, from_=norm_from, to=norm_to)
|
|
52
|
+
if df is not None and not df.empty:
|
|
53
|
+
# DataFrameをcacheフォルダに保存
|
|
54
|
+
## 非同期、遅延を避けるためデーモンスレッドで実行
|
|
55
|
+
threading.Thread(
|
|
56
|
+
target=self.db.save_stock_prices, args=(code, df), daemon=True
|
|
57
|
+
).start()
|
|
58
|
+
return df
|
|
59
|
+
|
|
60
|
+
# 3) J-Quantsから取得
|
|
61
|
+
if not hasattr(self, "jq"):
|
|
62
|
+
self.jq = jquants()
|
|
63
|
+
if self.jq.isEnable:
|
|
64
|
+
df = self.jq.get_daily_quotes(code=code, from_=norm_from, to=norm_to)
|
|
65
|
+
if df is not None and not df.empty:
|
|
66
|
+
# DataFrameをcacheフォルダに保存
|
|
67
|
+
## 非同期、遅延を避けるためデーモンスレッドで実行
|
|
68
|
+
threading.Thread(
|
|
69
|
+
target=self.db.save_stock_prices, args=(code, df), daemon=True
|
|
70
|
+
).start()
|
|
71
|
+
return df
|
|
72
|
+
|
|
73
|
+
# 4) stooqから取得
|
|
74
|
+
df = stooq_daily_quotes(code=code, from_=norm_from, to=norm_to)
|
|
75
|
+
if df is not None and not df.empty:
|
|
76
|
+
# DataFrameをcacheフォルダに保存
|
|
77
|
+
## 非同期、遅延を避けるためデーモンスレッドで実行
|
|
78
|
+
threading.Thread(
|
|
79
|
+
target=self.db.save_stock_prices, args=(code, df), daemon=True
|
|
80
|
+
).start()
|
|
81
|
+
return df
|
|
82
|
+
|
|
83
|
+
raise ValueError(f"日本株式銘柄の取得に失敗しました: {code}")
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def get_stock_daily(code, from_: datetime = None, to: datetime = None) -> pd.DataFrame:
|
|
87
|
+
"""
|
|
88
|
+
株価四本値(/prices/daily_quotes)
|
|
89
|
+
|
|
90
|
+
- 株価は分割・併合を考慮した調整済み株価(小数点第2位四捨五入)と調整前の株価を取得することができます。
|
|
91
|
+
- データの取得では、銘柄コード(code)または日付(date)の指定が必須となります。
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
code: 銘柄コード(例: "7203.JP")
|
|
95
|
+
from_: 開始日(datetime, str, または None)
|
|
96
|
+
to: 終了日(datetime, str, または None)
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
DataFrame: 株価データ(DatetimeIndexとして日付がインデックスに設定されている)
|
|
100
|
+
"""
|
|
101
|
+
from .stocks_price import stocks_price
|
|
102
|
+
__sp__ = stocks_price()
|
|
103
|
+
|
|
104
|
+
# 株価データを取得(内部で自動的にデータベースに保存される)
|
|
105
|
+
df = __sp__.get_japanese_stock_price_data(code=code, from_=from_, to=to)
|
|
106
|
+
|
|
107
|
+
# DatetimeIndexであることを保証
|
|
108
|
+
if df is not None and not df.empty:
|
|
109
|
+
if not isinstance(df.index, pd.DatetimeIndex):
|
|
110
|
+
# Date列がある場合はそれをインデックスに設定
|
|
111
|
+
if 'Date' in df.columns:
|
|
112
|
+
df = df.copy()
|
|
113
|
+
df['Date'] = pd.to_datetime(df['Date'])
|
|
114
|
+
df = df.set_index('Date')
|
|
115
|
+
elif 'date' in df.columns:
|
|
116
|
+
df = df.copy()
|
|
117
|
+
df['date'] = pd.to_datetime(df['date'])
|
|
118
|
+
df = df.set_index('date')
|
|
119
|
+
df.index.name = 'Date'
|
|
120
|
+
else:
|
|
121
|
+
import warnings
|
|
122
|
+
warnings.warn(
|
|
123
|
+
f"get_stock_daily('{code}') が返したDataFrameにDate列がなく、"
|
|
124
|
+
"インデックスもDatetimeIndexではありません。",
|
|
125
|
+
stacklevel=2
|
|
126
|
+
)
|
|
127
|
+
# 日付順にソート
|
|
128
|
+
if isinstance(df.index, pd.DatetimeIndex):
|
|
129
|
+
df = df.sort_index()
|
|
130
|
+
|
|
131
|
+
return df
|