Skip to content

Commit aa6af33

Browse files
Add CLI wrapper for historical data
1 parent a83145c commit aa6af33

File tree

1 file changed

+143
-0
lines changed

1 file changed

+143
-0
lines changed

cli/main.py

+143
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
"""
2+
Example usage commands:
3+
4+
Stocks Historical Data:
5+
Get end-of-day report:
6+
python main.py stocks historical eod-report AAPL 20240101 20240131
7+
8+
Get quotes:
9+
python main.py stocks historical quotes MSFT 20240101 20240131 --interval 3600000
10+
11+
Save output to a file:
12+
python main.py stocks historical eod-report AAPL 20240101 20240131 --output-file aapl_eod.csv
13+
"""
14+
15+
import typer
16+
import pandas as pd
17+
import sys
18+
import os
19+
from functools import wraps
20+
from rich.progress import Progress, SpinnerColumn, TextColumn
21+
22+
# Add the parent directory to sys.path
23+
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
24+
25+
from src.stocks_historical import ThetaDataStocksHistorical
26+
from typing import Optional
27+
28+
app = typer.Typer()
29+
stocks_app = typer.Typer()
30+
options_app = typer.Typer()
31+
app.add_typer(stocks_app, name="stocks")
32+
app.add_typer(options_app, name="options")
33+
34+
historical_data = ThetaDataStocksHistorical(enable_logging=True, use_df=True)
35+
36+
37+
def save_output(result: pd.DataFrame | dict | None, output_file: Optional[str]):
38+
if isinstance(result, pd.DataFrame):
39+
if output_file:
40+
result.to_csv(output_file, index=False)
41+
typer.echo(f"Data saved to {output_file}")
42+
else:
43+
typer.echo(result.to_string())
44+
else:
45+
typer.echo(result)
46+
47+
48+
def with_spinner(func):
49+
@wraps(func)
50+
def wrapper(*args, **kwargs):
51+
with Progress(
52+
SpinnerColumn(),
53+
TextColumn("[progress.description]{task.description}"),
54+
transient=True,
55+
) as progress:
56+
task = progress.add_task(description="Loading data...", total=None)
57+
result = func(*args, **kwargs)
58+
progress.update(task, completed=True)
59+
return result
60+
61+
return wrapper
62+
63+
64+
@stocks_app.command(name="eod-report")
65+
@with_spinner
66+
def eod_report(
67+
symbol: str, start_date: str, end_date: str, output_file: Optional[str] = None
68+
):
69+
"""Get end-of-day report for a given symbol and date range."""
70+
result = historical_data.get_eod_report(symbol, start_date, end_date)
71+
save_output(result, output_file)
72+
73+
74+
@stocks_app.command(name="quotes")
75+
@with_spinner
76+
def quotes(
77+
symbol: str,
78+
start_date: str,
79+
end_date: str,
80+
interval: str = "900000",
81+
output_file: Optional[str] = None,
82+
):
83+
"""Get quotes for a given symbol and date range."""
84+
result = historical_data.get_quotes(symbol, start_date, end_date, interval)
85+
save_output(result, output_file)
86+
87+
88+
@stocks_app.command(name="ohlc")
89+
@with_spinner
90+
def ohlc(
91+
symbol: str,
92+
start_date: str,
93+
end_date: str,
94+
interval: str = "900000",
95+
output_file: Optional[str] = None,
96+
):
97+
"""Get OHLC data for a given symbol and date range."""
98+
result = historical_data.get_ohlc(symbol, start_date, end_date, interval)
99+
save_output(result, output_file)
100+
101+
102+
@stocks_app.command(name="trades")
103+
@with_spinner
104+
def trades(
105+
symbol: str, start_date: str, end_date: str, output_file: Optional[str] = None
106+
):
107+
"""Get historical trade data for a given symbol and date range."""
108+
result = historical_data.get_trades(symbol, start_date, end_date)
109+
save_output(result, output_file)
110+
111+
112+
@stocks_app.command(name="trade-quote")
113+
@with_spinner
114+
def trade_quote(
115+
symbol: str, start_date: str, end_date: str, output_file: Optional[str] = None
116+
):
117+
"""Get historical trade and quote data for a given symbol and date range."""
118+
result = historical_data.get_trade_quote(symbol, start_date, end_date)
119+
save_output(result, output_file)
120+
121+
122+
@stocks_app.command(name="splits")
123+
@with_spinner
124+
def splits(
125+
symbol: str, start_date: str, end_date: str, output_file: Optional[str] = None
126+
):
127+
"""Get stock split data for a given symbol and date range."""
128+
result = historical_data.get_splits(symbol, start_date, end_date)
129+
save_output(result, output_file)
130+
131+
132+
@stocks_app.command(name="dividends")
133+
@with_spinner
134+
def dividends(
135+
symbol: str, start_date: str, end_date: str, output_file: Optional[str] = None
136+
):
137+
"""Get dividend data for a given symbol and date range."""
138+
result = historical_data.get_dividends(symbol, start_date, end_date)
139+
save_output(result, output_file)
140+
141+
142+
if __name__ == "__main__":
143+
app()

0 commit comments

Comments
 (0)