BackcastPro 0.1.0__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.

@@ -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}")
@@ -1,7 +0,0 @@
1
- """Data and utilities for testing."""
2
-
3
- from .JapanStock import DataReader, JapanStocks
4
-
5
-
6
- TOYOTA = DataReader('72030')
7
-
@@ -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.1.0.dist-info/METADATA,sha256=UNGbp380xNNQdfZHVbE6we8QrH2iPXhlMwhks_A2Z5A,2149
12
- backcastpro-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
13
- backcastpro-0.1.0.dist-info/top_level.txt,sha256=GiP-TX_Bc2jjwHS9cx0VCrW27e9JPbhWWnqGxa5B4Fs,12
14
- backcastpro-0.1.0.dist-info/RECORD,,