Data API module for retrieving stock prices from various sources.
AlpacaDataAPI
Bases: DataAPI
Alpaca Markets data API implementation with caching.
Source code in Backtesting/data.py
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141 | class AlpacaDataAPI(DataAPI):
"""Alpaca Markets data API implementation with caching."""
def __init__(self):
"""Initialize Alpaca API client from environment variables."""
load_dotenv(find_dotenv())
self.api_key = os.getenv("ALPACA_API_KEY")
self.secret_key = os.getenv("ALPACA_API_SECRET_KEY")
self.connected = False
self.initial_time = InitialConditions.get_initial_time()
self.step_size = InitialConditions.get_time_step_size()
self.data_client = StockHistoricalDataClient(self.api_key, self.secret_key) #alpaca connection
self.price_cache = {}
def get_price(self, stock: str, time_step: int) -> float:
"""Get stock price from Alpaca API with caching.
Args:
stock: Stock symbol.
time_step: Time step index.
Returns:
Stock price as float. Falls back to previous cached price on error.
"""
#checking cache
key = (stock, time_step)
if key in self.price_cache:
return self.price_cache[key][0]
#converting to alpaca format
timestamp = self.initial_time + timedelta(seconds=self.step_size * time_step)
timestamp = timestamp.astimezone(timezone.utc)
start = timestamp
end = (timestamp + timedelta(seconds = self.step_size))
request = StockBarsRequest(
symbol_or_symbols = stock,
timeframe = TimeFrame.Day,
start = start,
end = end,
limit = 1
)
try:
bars = self.data_client.get_stock_bars(request) #StockHistoricalDataClient().get_stock_bars(stock, timeframe, start, limit)
bar = bars[stock][0] #bars can be a multidimensional array since many symbols can be passed. we just use one though
price = bar.close #price at close of interval
self.price_cache[key] = (price, bar.timestamp)
return price
#connection error if client does not connect
except Exception as e:
print(f"could not retrieve price: {e}")
self.price_cache[key] = self.price_cache[(stock, time_step - 1)] #default back to last cached price
return self.price_cache[key][0]
def is_connected(self) -> bool:
"""Check Alpaca API connection status."""
response = requests.get(self.base_url, self.headers)
if response.status_code == 200:
self.connected = True
return self.connected
|
__init__()
Initialize Alpaca API client from environment variables.
Source code in Backtesting/data.py
80
81
82
83
84
85
86
87
88
89 | def __init__(self):
"""Initialize Alpaca API client from environment variables."""
load_dotenv(find_dotenv())
self.api_key = os.getenv("ALPACA_API_KEY")
self.secret_key = os.getenv("ALPACA_API_SECRET_KEY")
self.connected = False
self.initial_time = InitialConditions.get_initial_time()
self.step_size = InitialConditions.get_time_step_size()
self.data_client = StockHistoricalDataClient(self.api_key, self.secret_key) #alpaca connection
self.price_cache = {}
|
get_price(stock, time_step)
Get stock price from Alpaca API with caching.
| Parameters: |
-
stock
(str)
–
-
time_step
(int)
–
|
| Returns: |
-
float
–
Stock price as float. Falls back to previous cached price on error.
|
Source code in Backtesting/data.py
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134 | def get_price(self, stock: str, time_step: int) -> float:
"""Get stock price from Alpaca API with caching.
Args:
stock: Stock symbol.
time_step: Time step index.
Returns:
Stock price as float. Falls back to previous cached price on error.
"""
#checking cache
key = (stock, time_step)
if key in self.price_cache:
return self.price_cache[key][0]
#converting to alpaca format
timestamp = self.initial_time + timedelta(seconds=self.step_size * time_step)
timestamp = timestamp.astimezone(timezone.utc)
start = timestamp
end = (timestamp + timedelta(seconds = self.step_size))
request = StockBarsRequest(
symbol_or_symbols = stock,
timeframe = TimeFrame.Day,
start = start,
end = end,
limit = 1
)
try:
bars = self.data_client.get_stock_bars(request) #StockHistoricalDataClient().get_stock_bars(stock, timeframe, start, limit)
bar = bars[stock][0] #bars can be a multidimensional array since many symbols can be passed. we just use one though
price = bar.close #price at close of interval
self.price_cache[key] = (price, bar.timestamp)
return price
#connection error if client does not connect
except Exception as e:
print(f"could not retrieve price: {e}")
self.price_cache[key] = self.price_cache[(stock, time_step - 1)] #default back to last cached price
return self.price_cache[key][0]
|
is_connected()
Check Alpaca API connection status.
Source code in Backtesting/data.py
| def is_connected(self) -> bool:
"""Check Alpaca API connection status."""
response = requests.get(self.base_url, self.headers)
if response.status_code == 200:
self.connected = True
return self.connected
|
DataAPI
Bases: ABC
Abstract base class for data API implementations.
Source code in Backtesting/data.py
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 | class DataAPI(ABC):
"""Abstract base class for data API implementations."""
@abstractmethod
def get_price(self, stock: str, time_step: int) -> float:
"""Get stock price at given time step.
Args:
stock: Stock symbol.
time_step: Time step index.
Returns:
Stock price as float.
"""
pass
@abstractmethod
def is_connected(self) -> bool:
"""Check if API connection is active.
Returns:
True if connected, False otherwise.
"""
pass
|
get_price(stock, time_step)
abstractmethod
Get stock price at given time step.
| Parameters: |
-
stock
(str)
–
-
time_step
(int)
–
|
Source code in Backtesting/data.py
17
18
19
20
21
22
23
24
25
26
27
28 | @abstractmethod
def get_price(self, stock: str, time_step: int) -> float:
"""Get stock price at given time step.
Args:
stock: Stock symbol.
time_step: Time step index.
Returns:
Stock price as float.
"""
pass
|
is_connected()
abstractmethod
Check if API connection is active.
| Returns: |
-
bool
–
True if connected, False otherwise.
|
Source code in Backtesting/data.py
| @abstractmethod
def is_connected(self) -> bool:
"""Check if API connection is active.
Returns:
True if connected, False otherwise.
"""
pass
|
PolygonDataAPI
Bases: DataAPI
Polygon.io data API implementation.
Source code in Backtesting/data.py
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75 | class PolygonDataAPI(DataAPI):
"""Polygon.io data API implementation."""
def __init__(self, api_key: str):
"""Initialize Polygon API client.
Args:
api_key: Polygon.io API key.
"""
self.api_key = api_key
self.connected = False
self.initial_time = InitialConditions.get_initial_time()
self.step_size = InitialConditions.get_time_step_size()
def get_price(self, stock: str, time_step: int) -> float:
"""Get stock price from Polygon API.
Args:
stock: Stock symbol.
time_step: Time step index.
Returns:
Stock price as float. Returns 0.0 on error.
"""
#convert to polygon format
try:
timestamp = self.initial_time + (self.step_size * time_step)
#TODO
return 0.0
except Exception as e:
print(f"could not retrieve price: {e}")
return 0.0
def is_connected(self) -> bool:
"""Check Polygon API connection status."""
#TODO
return self.connected
|
__init__(api_key)
Initialize Polygon API client.
Source code in Backtesting/data.py
42
43
44
45
46
47
48
49
50
51 | def __init__(self, api_key: str):
"""Initialize Polygon API client.
Args:
api_key: Polygon.io API key.
"""
self.api_key = api_key
self.connected = False
self.initial_time = InitialConditions.get_initial_time()
self.step_size = InitialConditions.get_time_step_size()
|
get_price(stock, time_step)
Get stock price from Polygon API.
| Parameters: |
-
stock
(str)
–
-
time_step
(int)
–
|
| Returns: |
-
float
–
Stock price as float. Returns 0.0 on error.
|
Source code in Backtesting/data.py
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 | def get_price(self, stock: str, time_step: int) -> float:
"""Get stock price from Polygon API.
Args:
stock: Stock symbol.
time_step: Time step index.
Returns:
Stock price as float. Returns 0.0 on error.
"""
#convert to polygon format
try:
timestamp = self.initial_time + (self.step_size * time_step)
#TODO
return 0.0
except Exception as e:
print(f"could not retrieve price: {e}")
return 0.0
|
is_connected()
Check Polygon API connection status.
Source code in Backtesting/data.py
| def is_connected(self) -> bool:
"""Check Polygon API connection status."""
#TODO
return self.connected
|