Skip to content

Commit

Permalink
Refactor Ticker class properties and add calls and
Browse files Browse the repository at this point in the history
puts properties
  • Loading branch information
ahnazary committed Feb 11, 2024
1 parent 8b6213f commit 6018f37
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 28 deletions.
17 changes: 11 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,17 @@ pip install stockdex
```python
from stockdex import Ticker

# Pick arbitrary ticker
ticker = Ticker('AAPL')

summary = ticker.summary()
statistics = ticker.statistics()
income_stmt = ticker.income_stmt()
balance_sheet = ticker.balance_sheet()
cash_flow = ticker.cash_flow()
analysis = ticker.analysis()
summary = ticker.summary
statistics = ticker.statistics
income_stmt = ticker.income_stmt
balance_sheet = ticker.balance_sheet
cash_flow = ticker.cash_flow
analysis = ticker.analysis

# Options
calls = ticker.calls
puts = ticker.puts
```
80 changes: 62 additions & 18 deletions stockdex/ticker.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def get_response(self, url: str, headers: dict = None) -> requests.Response:

return response

@property
def summary(self) -> pd.DataFrame:
"""
Get data for the ticker
Expand Down Expand Up @@ -78,6 +79,7 @@ def summary(self) -> pd.DataFrame:

return data_df.T

@property
def statistics(self) -> pd.DataFrame:
"""
Get statistics for the ticker
Expand All @@ -103,6 +105,7 @@ def statistics(self) -> pd.DataFrame:

return data_df.T

@property
def income_stmt(self) -> pd.DataFrame:
"""
Get income statement for the ticker
Expand Down Expand Up @@ -138,6 +141,7 @@ def income_stmt(self) -> pd.DataFrame:

return data_df.T

@property
def balance_sheet(self) -> pd.DataFrame:
"""
Get balance sheet for the ticker
Expand Down Expand Up @@ -173,6 +177,7 @@ def balance_sheet(self) -> pd.DataFrame:

return data_df.T

@property
def cash_flow(self) -> pd.DataFrame:
"""
Get cash flow for the ticker
Expand Down Expand Up @@ -208,6 +213,7 @@ def cash_flow(self) -> pd.DataFrame:

return data_df.T

@property
def analysis(self) -> pd.DataFrame:
"""
Get analysis for the ticker
Expand Down Expand Up @@ -241,13 +247,13 @@ def analysis(self) -> pd.DataFrame:

return data_df.T

def options(self) -> pd.DataFrame:
@property
def calls(self) -> pd.DataFrame:
"""
TODO: fix this method
Get options for the ticker
Get calls for the ticker
Returns:
pd.DataFrame: A pandas DataFrame including the options
pd.DataFrame: A pandas DataFrame including the calls
visible in the Yahoo Finance statistics page for the ticker
"""

Expand All @@ -260,21 +266,59 @@ def options(self) -> pd.DataFrame:

# gets calls and puts
tables = soup.find_all("table")
result, headers, data = [], [], []
headers, data = [], []

for item in tables:
thead = item.find("thead")
tbody = item.find("tbody")
thead = tables[0].find("thead")
tbody = tables[0].find("tbody")
data_df = pd.DataFrame()

# get headers
for th in thead.find_all("th"):
headers.append(th.text)

# get data
for tr in tbody.find_all("tr"):
row = tr.find_all("td")
data.append([data.text for data in row])

data_df = pd.DataFrame(data, columns=headers)

return data_df

@property
def puts(self) -> pd.DataFrame:
"""
Get puts for the ticker
Returns:
pd.DataFrame: A pandas DataFrame including the puts
visible in the Yahoo Finance statistics page for the ticker
"""

# URL of the website to scrape
url = f"https://finance.yahoo.com/quote/{self.ticker}/options"
response = self.get_response(url, self.request_headers)

# Parse the HTML content of the website
soup = BeautifulSoup(response.content, "html.parser")

# gets calls and puts
tables = soup.find_all("table")
headers, data = [], []

thead = tables[1].find("thead")
tbody = tables[1].find("tbody")
data_df = pd.DataFrame()

# get headers
for th in thead.find_all("th"):
headers.append(th.text)

# get headers
for th in thead.find_all("th"):
headers.append(th.text)
# get data
for tr in tbody.find_all("tr"):
row = tr.find_all("td")
data.append([data.text for data in row])

# get data
for tr in tbody.find_all("tr"):
row = tr.find_all("td")
data.append([data.text for data in row])
data_df = pd.DataFrame(data, columns=headers)

result.append(pd.DataFrame(data, columns=headers))
headers, data = [], []
return result
return data_df
42 changes: 38 additions & 4 deletions tests/test_ticker.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def test_get_response(ticker, expected_response):
)
def test_cash_flow(ticker):
ticker = Ticker(ticker)
cash_flow_df = ticker.cash_flow()
cash_flow_df = ticker.cash_flow

# Check if the response is as expected
assert isinstance(cash_flow_df, pd.DataFrame)
Expand All @@ -50,7 +50,7 @@ def test_cash_flow(ticker):
)
def test_analysis(ticker):
ticker = Ticker(ticker)
analysis_df = ticker.analysis()
analysis_df = ticker.analysis

# Check if the response is as expected
assert isinstance(analysis_df, pd.DataFrame)
Expand All @@ -67,7 +67,7 @@ def test_analysis(ticker):
)
def test_summary(ticker):
ticker = Ticker(ticker)
summary_df = ticker.summary()
summary_df = ticker.summary

# Check if the response is as expected
assert isinstance(summary_df, pd.DataFrame)
Expand Down Expand Up @@ -104,8 +104,42 @@ def test_statistics(ticker):
)
def test_income_stmt(ticker):
ticker = Ticker(ticker)
income_stmt_df = ticker.income_stmt()
income_stmt_df = ticker.income_stmt

# Check if the response is as expected
assert isinstance(income_stmt_df, pd.DataFrame)
assert income_stmt_df.shape[0] > 0


@pytest.mark.parametrize(
"ticker",
[
("AAPL"),
("GOOGL"),
("MSFT"),
],
)
def test_calls(ticker):
ticker = Ticker(ticker)
calls = ticker.calls

# Check if the response is as expected
assert isinstance(calls, pd.DataFrame)
assert calls.shape[0] > 0


@pytest.mark.parametrize(
"ticker",
[
("AAPL"),
("GOOGL"),
("MSFT"),
],
)
def test_puts(ticker):
ticker = Ticker(ticker)
puts = ticker.puts

# Check if the response is as expected
assert isinstance(puts, pd.DataFrame)
assert puts.shape[0] > 0

0 comments on commit 6018f37

Please sign in to comment.