Skip to content

Commit da3a889

Browse files
Implement endpoints for stocks snapshots
1 parent aa6af33 commit da3a889

6 files changed

+827
-22
lines changed

cli/main.py

+75-13
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@
1010
1111
Save output to a file:
1212
python main.py stocks historical eod-report AAPL 20240101 20240131 --output-file aapl_eod.csv
13+
14+
Stocks Snapshot Data:
15+
Get real-time quotes:
16+
python main.py stocks snapshot quotes AAPL
17+
18+
Get real-time OHLC:
19+
python main.py stocks snapshot ohlc NVDA
20+
21+
Get real-time trades:
22+
python main.py stocks snapshot trades TSLA
1323
"""
1424

1525
import typer
@@ -23,15 +33,21 @@
2333
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
2434

2535
from src.stocks_historical import ThetaDataStocksHistorical
26-
from typing import Optional
36+
from src.stocks import ThetaDataStocksSnapshot
37+
from typing import Optional, List
2738

2839
app = typer.Typer()
2940
stocks_app = typer.Typer()
41+
historical_app = typer.Typer()
42+
snapshot_app = typer.Typer()
3043
options_app = typer.Typer()
3144
app.add_typer(stocks_app, name="stocks")
45+
stocks_app.add_typer(historical_app, name="historical")
46+
stocks_app.add_typer(snapshot_app, name="snapshot")
3247
app.add_typer(options_app, name="options")
3348

3449
historical_data = ThetaDataStocksHistorical(enable_logging=True, use_df=True)
50+
snapshot_data = ThetaDataStocksSnapshot(enable_logging=True, use_df=True)
3551

3652

3753
def save_output(result: pd.DataFrame | dict | None, output_file: Optional[str]):
@@ -61,7 +77,8 @@ def wrapper(*args, **kwargs):
6177
return wrapper
6278

6379

64-
@stocks_app.command(name="eod-report")
80+
# Historical commands
81+
@historical_app.command(name="eod-report")
6582
@with_spinner
6683
def eod_report(
6784
symbol: str, start_date: str, end_date: str, output_file: Optional[str] = None
@@ -71,45 +88,45 @@ def eod_report(
7188
save_output(result, output_file)
7289

7390

74-
@stocks_app.command(name="quotes")
91+
@historical_app.command(name="quotes")
7592
@with_spinner
76-
def quotes(
93+
def historical_quotes(
7794
symbol: str,
7895
start_date: str,
7996
end_date: str,
8097
interval: str = "900000",
8198
output_file: Optional[str] = None,
8299
):
83-
"""Get quotes for a given symbol and date range."""
100+
"""Get historical quotes for a given symbol and date range."""
84101
result = historical_data.get_quotes(symbol, start_date, end_date, interval)
85102
save_output(result, output_file)
86103

87104

88-
@stocks_app.command(name="ohlc")
105+
@historical_app.command(name="ohlc")
89106
@with_spinner
90-
def ohlc(
107+
def historical_ohlc(
91108
symbol: str,
92109
start_date: str,
93110
end_date: str,
94111
interval: str = "900000",
95112
output_file: Optional[str] = None,
96113
):
97-
"""Get OHLC data for a given symbol and date range."""
114+
"""Get historical OHLC data for a given symbol and date range."""
98115
result = historical_data.get_ohlc(symbol, start_date, end_date, interval)
99116
save_output(result, output_file)
100117

101118

102-
@stocks_app.command(name="trades")
119+
@historical_app.command(name="trades")
103120
@with_spinner
104-
def trades(
121+
def historical_trades(
105122
symbol: str, start_date: str, end_date: str, output_file: Optional[str] = None
106123
):
107124
"""Get historical trade data for a given symbol and date range."""
108125
result = historical_data.get_trades(symbol, start_date, end_date)
109126
save_output(result, output_file)
110127

111128

112-
@stocks_app.command(name="trade-quote")
129+
@historical_app.command(name="trade-quote")
113130
@with_spinner
114131
def trade_quote(
115132
symbol: str, start_date: str, end_date: str, output_file: Optional[str] = None
@@ -119,7 +136,7 @@ def trade_quote(
119136
save_output(result, output_file)
120137

121138

122-
@stocks_app.command(name="splits")
139+
@historical_app.command(name="splits")
123140
@with_spinner
124141
def splits(
125142
symbol: str, start_date: str, end_date: str, output_file: Optional[str] = None
@@ -129,7 +146,7 @@ def splits(
129146
save_output(result, output_file)
130147

131148

132-
@stocks_app.command(name="dividends")
149+
@historical_app.command(name="dividends")
133150
@with_spinner
134151
def dividends(
135152
symbol: str, start_date: str, end_date: str, output_file: Optional[str] = None
@@ -139,5 +156,50 @@ def dividends(
139156
save_output(result, output_file)
140157

141158

159+
# Snapshot commands
160+
@snapshot_app.command(name="quotes")
161+
@with_spinner
162+
def snapshot_quotes(
163+
symbol: str, venue: Optional[str] = None, output_file: Optional[str] = None
164+
):
165+
"""Get real-time quotes for a given symbol."""
166+
result = snapshot_data.get_quotes(symbol, venue)
167+
save_output(result, output_file)
168+
169+
170+
@snapshot_app.command(name="bulk-quotes")
171+
@with_spinner
172+
def bulk_quotes(
173+
symbols: List[str], venue: Optional[str] = None, output_file: Optional[str] = None
174+
):
175+
"""Get real-time quotes for multiple symbols."""
176+
result = snapshot_data.get_bulk_quotes(symbols, venue)
177+
save_output(result, output_file)
178+
179+
180+
@snapshot_app.command(name="ohlc")
181+
@with_spinner
182+
def snapshot_ohlc(symbol: str, output_file: Optional[str] = None):
183+
"""Get real-time OHLC data for a given symbol."""
184+
result = snapshot_data.get_ohlc(symbol)
185+
save_output(result, output_file)
186+
187+
188+
@snapshot_app.command(name="bulk-ohlc")
189+
@with_spinner
190+
def bulk_ohlc(symbols: List[str], output_file: Optional[str] = None):
191+
"""Get real-time OHLC data for multiple symbols."""
192+
result = snapshot_data.get_bulk_ohlc(symbols)
193+
save_output(result, output_file)
194+
195+
196+
@snapshot_app.command(name="trades")
197+
@with_spinner
198+
def snapshot_trades(symbol: str, output_file: Optional[str] = None):
199+
"""Get real-time trade data for a given symbol."""
200+
result = snapshot_data.get_trades(symbol)
201+
save_output(result, output_file)
202+
203+
142204
if __name__ == "__main__":
143205
app()

examples/stocks_snapshot_examples.py

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import sys
2+
import os
3+
from functools import wraps
4+
from stocks_historical_examples import example_runner
5+
6+
# Add the parent directory to sys.path
7+
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8+
9+
from src.stocks import ThetaDataStocksSnapshot
10+
11+
snapshot_data = ThetaDataStocksSnapshot(enable_logging=True, use_df=True)
12+
13+
14+
@example_runner
15+
def apple_quotes_example():
16+
return snapshot_data.get_quotes("AAPL")
17+
18+
19+
@example_runner
20+
def microsoft_quotes_nqb_example():
21+
return snapshot_data.get_quotes("MSFT", venue="nqb")
22+
23+
24+
@example_runner
25+
def bulk_quotes_example():
26+
return snapshot_data.get_bulk_quotes(["GOOGL", "AMZN", "TSLA"])
27+
28+
29+
@example_runner
30+
def nvidia_ohlc_example():
31+
return snapshot_data.get_ohlc("NVDA")
32+
33+
34+
@example_runner
35+
def bulk_ohlc_example():
36+
return snapshot_data.get_bulk_ohlc(["INTC", "AMD", "QCOM"])
37+
38+
39+
@example_runner
40+
def tesla_trades_example():
41+
return snapshot_data.get_trades("TSLA")
42+
43+
44+
# Toggle example cases
45+
if __name__ == "__main__":
46+
run_examples = {
47+
"apple_quotes_example": True,
48+
"microsoft_quotes_nqb_example": True,
49+
"bulk_quotes_example": True,
50+
"nvidia_ohlc_example": True,
51+
"bulk_ohlc_example": True,
52+
"tesla_trades_example": True,
53+
}
54+
55+
for example, should_run in run_examples.items():
56+
if should_run:
57+
globals()[example]()

0 commit comments

Comments
 (0)