Skip to content

Commit 4091430

Browse files
authored
V2.1.1 (#51)
* update readme * updated pkg version and added blank recommendations and test * added recommendations and tests
1 parent f4a0694 commit 4091430

File tree

6 files changed

+86
-6
lines changed

6 files changed

+86
-6
lines changed

poetry.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "py-alpaca-api"
3-
version = "2.1.0"
3+
version = "2.1.1"
44
description = "Python package, for communicating with Alpaca Markets REST API."
55
authors = ["TexasCoding <[email protected]>"]
66
readme = "README.md"

src/py_alpaca_api/trading/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
# from py_alpaca_api.trading.stock import Stock
77
from py_alpaca_api.trading.account import Account
88
from py_alpaca_api.trading.orders import Orders
9+
from py_alpaca_api.trading.recommendations import Recommendations
910
from py_alpaca_api.trading.watchlists import Watchlist
1011

1112

@@ -31,3 +32,4 @@ def _initialize_components(self, headers: Dict[str, str], base_url: str):
3132
self.orders = Orders(headers=headers, base_url=base_url)
3233
self.watchlists = Watchlist(headers=headers, base_url=base_url)
3334
self.news = News(headers=headers)
35+
self.recommendations = Recommendations()

src/py_alpaca_api/trading/news.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def scrape_article(url: str) -> str:
4949
Returns:
5050
str: The text content of the article, or None if the article body is not found.
5151
"""
52-
time.sleep(1)
52+
time.sleep(1) # Sleep for 1 second to avoid rate limiting
5353
headers = {
5454
"accept": "*/*",
5555
"accept-encoding": "gzip, deflate, br",
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import time
2+
from typing import Any, Dict, Union
3+
import pandas as pd
4+
import yfinance as yf
5+
6+
7+
class Recommendations:
8+
def __init__(self) -> None:
9+
pass
10+
11+
@staticmethod
12+
def get_recommendations(symbol: str) -> Union[Dict[Any, Any], pd.DataFrame]:
13+
"""
14+
Retrieves the latest recommendations for a given stock symbol.
15+
16+
Args:
17+
symbol (str): The stock symbol for which to retrieve recommendations.
18+
19+
Returns:
20+
dict: A dictionary containing the latest recommendations for the stock symbol.
21+
"""
22+
time.sleep(1) # To avoid hitting the API rate limit
23+
ticker = yf.Ticker(symbol)
24+
recommendations = ticker.recommendations
25+
26+
return recommendations
27+
28+
def get_sentiment(self, symbol: str) -> str:
29+
"""
30+
Retrieves the sentiment for a given stock symbol based on the latest recommendations.
31+
32+
Args:
33+
symbol (str): The stock symbol for which to retrieve the sentiment.
34+
35+
Returns:
36+
str: The sentiment for the stock symbol, either "BULLISH", "BEARISH", or "NEUTRAL".
37+
"""
38+
39+
recommendations = self.get_recommendations(symbol)
40+
if recommendations.empty:
41+
return "NEUTRAL"
42+
buy = recommendations["strongBuy"].sum() + recommendations["buy"].sum()
43+
sell = (
44+
recommendations["strongSell"].sum()
45+
+ recommendations["sell"].sum()
46+
+ recommendations["hold"].sum()
47+
)
48+
return "BULLISH" if (buy / (buy + sell)) > 0.7 else "BEARISH"
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import os
2+
import pandas as pd
3+
import pytest
4+
from py_alpaca_api import PyAlpacaAPI
5+
6+
api_key = os.environ.get("ALPACA_API_KEY")
7+
api_secret = os.environ.get("ALPACA_SECRET_KEY")
8+
9+
10+
@pytest.fixture
11+
def news():
12+
return PyAlpacaAPI(api_key=api_key, api_secret=api_secret).trading.recommendations
13+
14+
15+
def test_get_recommendations(news):
16+
recommendations = news.get_recommendations("AAPL")
17+
assert len(recommendations) > 0
18+
assert isinstance(recommendations, pd.DataFrame)
19+
assert "period" in recommendations.columns
20+
assert "strongBuy" in recommendations.columns
21+
assert "buy" in recommendations.columns
22+
assert "hold" in recommendations.columns
23+
assert "sell" in recommendations.columns
24+
assert "strongSell" in recommendations.columns
25+
26+
27+
def test_get_sentiment(news):
28+
sentiment = news.get_sentiment("AAPL")
29+
assert isinstance(sentiment, str)
30+
assert sentiment in ["BULLISH", "BEARISH", "NEUTRAL"]

0 commit comments

Comments
 (0)