BackcastPro 0.0.5__py3-none-any.whl → 0.1.1__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.
Potentially problematic release.
This version of BackcastPro might be problematic. Click here for more details.
- BackcastPro/__init__.py +4 -5
- BackcastPro/_broker.py +160 -156
- BackcastPro/_stats.py +22 -14
- BackcastPro/backtest.py +94 -70
- BackcastPro/order.py +10 -0
- BackcastPro/position.py +1 -2
- BackcastPro/strategy.py +12 -6
- BackcastPro/trade.py +60 -28
- {backcastpro-0.0.5.dist-info → backcastpro-0.1.1.dist-info}/METADATA +4 -5
- backcastpro-0.1.1.dist-info/RECORD +12 -0
- BackcastPro/data/JapanStock.py +0 -171
- BackcastPro/data/__init__.py +0 -7
- backcastpro-0.0.5.dist-info/RECORD +0 -14
- {backcastpro-0.0.5.dist-info → backcastpro-0.1.1.dist-info}/WHEEL +0 -0
- {backcastpro-0.0.5.dist-info → backcastpro-0.1.1.dist-info}/top_level.txt +0 -0
BackcastPro/data/JapanStock.py
DELETED
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
"""Data reader for fetching stock price data from API."""
|
|
2
|
-
|
|
3
|
-
import os
|
|
4
|
-
import requests
|
|
5
|
-
import pandas as pd
|
|
6
|
-
from datetime import datetime, timedelta
|
|
7
|
-
from typing import Union
|
|
8
|
-
from dotenv import load_dotenv
|
|
9
|
-
|
|
10
|
-
# Load environment variables from .env file in project root
|
|
11
|
-
load_dotenv()
|
|
12
|
-
|
|
13
|
-
BACKCASTPRO_API_URL= 'http://backcastpro.i234.me'
|
|
14
|
-
|
|
15
|
-
def DataReader(code: str,
|
|
16
|
-
start_date: Union[str, datetime, None] = None,
|
|
17
|
-
end_date: Union[str, datetime, None] = None) -> pd.DataFrame:
|
|
18
|
-
"""
|
|
19
|
-
Fetch stock price data from API.
|
|
20
|
-
|
|
21
|
-
Args:
|
|
22
|
-
code (str): Stock code (e.g., '7203' for Toyota)
|
|
23
|
-
start_date (Union[str, datetime, None], optional): Start date for data retrieval.
|
|
24
|
-
If None, defaults to 1 year ago.
|
|
25
|
-
end_date (Union[str, datetime, None], optional): End date for data retrieval.
|
|
26
|
-
If None, defaults to today.
|
|
27
|
-
|
|
28
|
-
Returns:
|
|
29
|
-
pd.DataFrame: Stock price data with columns like 'Open', 'High', 'Low', 'Close', 'Volume'
|
|
30
|
-
|
|
31
|
-
Raises:
|
|
32
|
-
requests.RequestException: If API request fails
|
|
33
|
-
ValueError: If dates are invalid or API returns error
|
|
34
|
-
"""
|
|
35
|
-
# Set default dates if not provided
|
|
36
|
-
if end_date is None:
|
|
37
|
-
end_date = datetime.now()
|
|
38
|
-
if start_date is None:
|
|
39
|
-
start_date = end_date - timedelta(days=365)
|
|
40
|
-
|
|
41
|
-
# Convert datetime objects to string format if needed
|
|
42
|
-
if isinstance(start_date, datetime):
|
|
43
|
-
start_date_str = start_date.strftime('%Y-%m-%d')
|
|
44
|
-
else:
|
|
45
|
-
start_date_str = str(start_date)
|
|
46
|
-
|
|
47
|
-
if isinstance(end_date, datetime):
|
|
48
|
-
end_date_str = end_date.strftime('%Y-%m-%d')
|
|
49
|
-
else:
|
|
50
|
-
end_date_str = str(end_date)
|
|
51
|
-
|
|
52
|
-
# Construct API URL
|
|
53
|
-
base_url = os.getenv('BACKCASTPRO_API_URL')
|
|
54
|
-
if not base_url:
|
|
55
|
-
base_url = BACKCASTPRO_API_URL
|
|
56
|
-
|
|
57
|
-
# Ensure base_url doesn't end with slash and path starts with slash
|
|
58
|
-
base_url = base_url.rstrip('/')
|
|
59
|
-
url = f"{base_url}/api/stocks/price?code={code}&start_date={start_date_str}&end_date={end_date_str}"
|
|
60
|
-
|
|
61
|
-
try:
|
|
62
|
-
# Make API request
|
|
63
|
-
response = requests.get(url, timeout=30)
|
|
64
|
-
response.raise_for_status()
|
|
65
|
-
|
|
66
|
-
# Parse JSON response
|
|
67
|
-
data = response.json()
|
|
68
|
-
|
|
69
|
-
# Convert to DataFrame
|
|
70
|
-
if isinstance(data, dict):
|
|
71
|
-
if 'price_data' in data:
|
|
72
|
-
df = pd.DataFrame(data['price_data'])
|
|
73
|
-
elif 'data' in data:
|
|
74
|
-
df = pd.DataFrame(data['data'])
|
|
75
|
-
elif 'prices' in data:
|
|
76
|
-
df = pd.DataFrame(data['prices'])
|
|
77
|
-
elif 'results' in data:
|
|
78
|
-
df = pd.DataFrame(data['results'])
|
|
79
|
-
else:
|
|
80
|
-
# If it's a single dict, wrap it in a list
|
|
81
|
-
df = pd.DataFrame([data])
|
|
82
|
-
elif isinstance(data, list):
|
|
83
|
-
# If response is directly a list
|
|
84
|
-
df = pd.DataFrame(data)
|
|
85
|
-
else:
|
|
86
|
-
raise ValueError(f"Unexpected response format: {type(data)}")
|
|
87
|
-
|
|
88
|
-
# Ensure proper datetime index
|
|
89
|
-
if 'Date' in df.columns:
|
|
90
|
-
df['Date'] = pd.to_datetime(df['Date'])
|
|
91
|
-
df.set_index('Date', inplace=True)
|
|
92
|
-
elif 'date' in df.columns:
|
|
93
|
-
df['Date'] = pd.to_datetime(df['date'])
|
|
94
|
-
df.set_index('Date', inplace=True)
|
|
95
|
-
elif df.index.name is None or df.index.name == 'index':
|
|
96
|
-
# If no date column, try to parse index as datetime
|
|
97
|
-
try:
|
|
98
|
-
df.index = pd.to_datetime(df.index)
|
|
99
|
-
except:
|
|
100
|
-
pass
|
|
101
|
-
|
|
102
|
-
# Ensure numeric columns are properly typed
|
|
103
|
-
numeric_columns = ['Open', 'High', 'Low', 'Close', 'Volume']
|
|
104
|
-
for col in numeric_columns:
|
|
105
|
-
if col in df.columns:
|
|
106
|
-
df[col] = pd.to_numeric(df[col], errors='coerce')
|
|
107
|
-
|
|
108
|
-
# Add code column to the DataFrame
|
|
109
|
-
df['code'] = code
|
|
110
|
-
|
|
111
|
-
return df
|
|
112
|
-
|
|
113
|
-
except requests.exceptions.RequestException as e:
|
|
114
|
-
raise requests.RequestException(f"Failed to fetch data from API: {e}")
|
|
115
|
-
except Exception as e:
|
|
116
|
-
raise ValueError(f"Error processing API response: {e}")
|
|
117
|
-
|
|
118
|
-
def JapanStocks() -> pd.DataFrame:
|
|
119
|
-
"""
|
|
120
|
-
日本株の銘柄リストを取得
|
|
121
|
-
|
|
122
|
-
Returns:
|
|
123
|
-
pd.DataFrame: 日本株の銘柄リスト(コード、名前、市場、セクター等)
|
|
124
|
-
|
|
125
|
-
Raises:
|
|
126
|
-
requests.RequestException: If API request fails
|
|
127
|
-
ValueError: If API returns error
|
|
128
|
-
"""
|
|
129
|
-
# Construct API URL
|
|
130
|
-
base_url = os.getenv('BACKCASTPRO_API_URL')
|
|
131
|
-
if not base_url:
|
|
132
|
-
base_url = BACKCASTPRO_API_URL
|
|
133
|
-
|
|
134
|
-
# Ensure base_url doesn't end with slash and path starts with slash
|
|
135
|
-
base_url = base_url.rstrip('/')
|
|
136
|
-
url = f"{base_url}/api/stocks"
|
|
137
|
-
|
|
138
|
-
try:
|
|
139
|
-
# Make API request
|
|
140
|
-
response = requests.get(url, timeout=30)
|
|
141
|
-
response.raise_for_status()
|
|
142
|
-
|
|
143
|
-
# Parse JSON response
|
|
144
|
-
data = response.json()
|
|
145
|
-
|
|
146
|
-
# Convert to DataFrame
|
|
147
|
-
if isinstance(data, dict) and 'data' in data:
|
|
148
|
-
df = pd.DataFrame(data['data'])
|
|
149
|
-
elif isinstance(data, list):
|
|
150
|
-
df = pd.DataFrame(data)
|
|
151
|
-
else:
|
|
152
|
-
raise ValueError(f"Unexpected response format: {type(data)}")
|
|
153
|
-
|
|
154
|
-
# Ensure proper column names and types
|
|
155
|
-
if 'code' in df.columns:
|
|
156
|
-
df['code'] = df['code'].astype(str)
|
|
157
|
-
if 'name' in df.columns:
|
|
158
|
-
df['name'] = df['name'].astype(str)
|
|
159
|
-
if 'market' in df.columns:
|
|
160
|
-
df['market'] = df['market'].astype(str)
|
|
161
|
-
if 'sector' in df.columns:
|
|
162
|
-
df['sector'] = df['sector'].astype(str)
|
|
163
|
-
if 'currency' in df.columns:
|
|
164
|
-
df['currency'] = df['currency'].astype(str)
|
|
165
|
-
|
|
166
|
-
return df
|
|
167
|
-
|
|
168
|
-
except requests.exceptions.RequestException as e:
|
|
169
|
-
raise requests.RequestException(f"Failed to fetch data from API: {e}")
|
|
170
|
-
except Exception as e:
|
|
171
|
-
raise ValueError(f"Error processing API response: {e}")
|
BackcastPro/data/__init__.py
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
BackcastPro/__init__.py,sha256=bjVAcDM_rMCxRUjtt3Mz-HTKTIRdcfiMeWfJZOrL2Qk,782
|
|
2
|
-
BackcastPro/_broker.py,sha256=RSI4nOcUG24qfRYEiVI0niWjZ2jqr0RrFA12xVvLIvw,19877
|
|
3
|
-
BackcastPro/_stats.py,sha256=Omcx4BgfddBvnmkYHn4b49TXqCgHYr9McKk46qMKNuM,7843
|
|
4
|
-
BackcastPro/backtest.py,sha256=YL37lPtLK8pRwfLi1EaMThtMu7tz6JSRFLzevT653ik,15025
|
|
5
|
-
BackcastPro/order.py,sha256=6-BkY0PbDaQnVuJ2Vb4pUczmMhlvTO0KmgJ7xb5Pu_M,5501
|
|
6
|
-
BackcastPro/position.py,sha256=7G1fKrCLuW8QACN4mWNvR-6yrk_X9ERFLbqo97LKuX0,2236
|
|
7
|
-
BackcastPro/strategy.py,sha256=KhVXH62QxivI_6C3-7CxjXPXMQ--VMOL3as2iHBGegw,7207
|
|
8
|
-
BackcastPro/trade.py,sha256=8pDyIh96NmzPgEDkYB9h2lekHl3wdK6JeZ5Ix3y8wWQ,7162
|
|
9
|
-
BackcastPro/data/JapanStock.py,sha256=lIyns7Hh7tbGudwOpZ6Dmqf6ucqY8i5VDPNTYyn6hhI,6235
|
|
10
|
-
BackcastPro/data/__init__.py,sha256=3JFR9MCMMlKAaFwP9YGzp3bRnCkKdO5tyG4dpx9KDF4,126
|
|
11
|
-
backcastpro-0.0.5.dist-info/METADATA,sha256=QKvEw7xq_Zwu1HO39jo6LCPjX0P6YzOgS4nl6_0Ylhg,2147
|
|
12
|
-
backcastpro-0.0.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
13
|
-
backcastpro-0.0.5.dist-info/top_level.txt,sha256=GiP-TX_Bc2jjwHS9cx0VCrW27e9JPbhWWnqGxa5B4Fs,12
|
|
14
|
-
backcastpro-0.0.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|