Skip to content

Commit

Permalink
Adds Yahoo Finance client
Browse files Browse the repository at this point in the history
  • Loading branch information
javadebadi committed Jul 30, 2024
1 parent 6ab4fda commit 5ceac39
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 20 deletions.
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ pydantic==2.7.0
numpy~=1.24
scipy==1.13.1
TA-Lib
matplotlib
matplotlib
yfinance~=0.2
3 changes: 2 additions & 1 deletion requirements_dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ invoke==2.2.0
black==24.4.0
flake8==7.0.0
blacken-docs==1.16.0
setuptools==71.1.0
setuptools==71.1.0
pandas-stubs
44 changes: 28 additions & 16 deletions requirements_lock.txt
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
alembic==1.13.1
annotated-types==0.6.0
annotated-types==0.7.0
autoflake==2.3.1
beautifulsoup4==4.12.3
black==24.4.0
blacken-docs==1.16.0
certifi==2024.2.2
build==1.2.1
certifi==2024.7.4
charset-normalizer==3.3.2
click==8.1.7
contourpy==1.2.1
cycler==0.12.1
docutils==0.21.2
flake8==7.0.0
fonttools==4.53.1
frozendict==2.4.4
html5lib==1.1
idna==3.7
importlib_metadata==7.1.0
importlib_metadata==8.2.0
iniconfig==2.0.0
invoke==2.2.0
isort==5.13.2
Expand All @@ -21,44 +24,53 @@ jaraco.context==5.3.0
jaraco.functools==4.0.1
keyring==25.2.1
kiwisolver==1.4.5
Mako==1.3.5
lxml==5.2.2
markdown-it-py==3.0.0
MarkupSafe==2.1.5
matplotlib==3.9.1
mccabe==0.7.0
mdurl==0.1.2
more-itertools==10.2.0
more-itertools==10.3.0
multitasking==0.0.11
mypy==1.9.0
mypy-extensions==1.0.0
nh3==0.2.17
nh3==0.2.18
numpy==1.26.4
packaging==24.0
pandas==2.2.2
pandas-stubs==2.2.2.240603
pathspec==0.12.1
peewee==3.17.6
pillow==10.4.0
pkginfo==1.10.0
pip-tools==7.4.1
pkginfo==1.11.1
platformdirs==4.2.2
pluggy==1.5.0
psycopg2-binary==2.9.9
pycodestyle==2.11.1
pydantic==2.7.0
pydantic_core==2.18.1
pyflakes==3.2.0
Pygments==2.18.0
pyparsing==3.1.2
pyproject_hooks==1.1.0
pytest==8.1.1
python-dateutil==2.9.0.post0
readme_renderer==43.0
requests==2.31.0
pytz==2024.1
readme_renderer==44.0
requests==2.32.3
requests-toolbelt==1.0.0
rfc3986==2.0.0
rich==13.7.1
scipy==1.13.1
setuptools==71.1.0
six==1.16.0
SQLAlchemy==2.0.30
soupsieve==2.5
TA-Lib==0.4.32
twine==5.0.0
typing_extensions==4.11.0
urllib3==2.2.1
types-pytz==2024.1.0.20240417
typing_extensions==4.12.2
tzdata==2024.1
urllib3==2.2.2
webencodings==0.5.1
wheel==0.43.0
zipp==3.18.2
yfinance==0.2.41
zipp==3.19.2
7 changes: 5 additions & 2 deletions typings/talib/abstract/__init__.pyi
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from typing import Any
from numpy import ndarray, dtype, floating, float64
from numpy import ndarray, dtype, float64

def OBV(close: list[float] | ndarray[Any, dtype[float64]], volume: list[float] | ndarray[Any, dtype[float64]]) -> list[float]: ...
def OBV(
close: list[float] | ndarray[Any, dtype[float64]],
volume: list[float] | ndarray[Any, dtype[float64]],
) -> list[float]: ...
24 changes: 24 additions & 0 deletions typings/yfinance/__init__.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from typing import Any
import pandas as pd

def download(
tickers: str,
start: str | None = None,
end: str | None = None,
actions: bool = False,
threads: bool = True,
ignore_tz: bool | None = None,
group_by: str = "column",
auto_adjust: bool = False,
back_adjust: bool = False,
repair: bool = False,
keepna: bool = False,
progress: bool = True,
period: str = "max",
interval: str = "1d",
prepost: bool = False,
proxy: str | None = None,
rounding: bool = False,
timeout: int | float = 10,
session: Any | None = None,
) -> pd.DataFrame: ...
Empty file added xarizmi/opendata/__init__.py
Empty file.
75 changes: 75 additions & 0 deletions xarizmi/opendata/yahoo_finance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
"""A client to download Yahoo Finance data
"""

from datetime import datetime

import pandas as pd
import yfinance as yf

from xarizmi.candlestick import CandlestickChart


class YahooFinanceDailyDataClient:

def __init__(
self,
symbol: str,
start_date: str = "1900-01-01",
end_date: str | None = None,
) -> None:
self.symbol = symbol
self.start_date = start_date
self.end_date = end_date

def extract(self) -> list[dict[str, str | float | pd.Timestamp]] | None:
stock_data: pd.DataFrame = yf.download(
self.symbol, start=self.start_date, end=self.end_date
)

if stock_data.empty:
print("Error fetching data for symbol:", self.symbol)
return None

# Reset the index to get 'Date' as a column
stock_data.reset_index(inplace=True)

return stock_data.to_dict(orient="records") # type: ignore

def transform(
self, data_list: list[dict[str, str | float | pd.Timestamp]]
) -> list[dict[str, str | float | datetime | dict[str, dict[str, str]]]]:
candles_data = []
for single_candle_data in data_list:
temp = {}
temp["open"] = single_candle_data["Open"]
temp["high"] = single_candle_data["High"]
temp["low"] = single_candle_data["Low"]
temp["close"] = single_candle_data["Close"]
temp["volume"] = single_candle_data["Volume"]
temp["datetime"] = single_candle_data["Date"].to_pydatetime() # type: ignore # noqa:E501
temp["interval_type"] = "1day"
temp["symbol"] = {
"base_currency": {"name": self.symbol},
"quote_currency": {"name": "CAD"},
"fee_currency": {"name": "CAD"},
} # type: ignore
candles_data.append(temp)
return candles_data # type: ignore

def save_file(
self,
candles_data: list[
dict[str, str | float | datetime | dict[str, dict[str, str]]]
],
filepath: str,
indent: int = 4,
) -> None:
candles = CandlestickChart.model_validate({"candles": candles_data})
with open(filepath, "w") as f:
f.write(candles.model_dump_json(indent=indent))

def etl(self, filepath: str) -> None:
data_list = self.extract()
if data_list:
candles_data = self.transform(data_list=data_list)
self.save_file(candles_data=candles_data, filepath=filepath)

0 comments on commit 5ceac39

Please sign in to comment.