Skip to content

Commit

Permalink
V2.2.2 (#30)
Browse files Browse the repository at this point in the history
* update version

* tweaks
  • Loading branch information
TexasCoding authored Jun 18, 2024
1 parent 6d39d04 commit 094c9e3
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 28 deletions.
28 changes: 18 additions & 10 deletions src/alpaca_daily_losers/close_positions.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ def __init__(self, trading_client: Trading, stock_client: Stock, py_logger: logg
self.stock = stock_client
self.py_logger = py_logger

def sell_positions_from_criteria(self) -> None:
def sell_positions_from_criteria(
self, stop_loss_percentage: float = 10.0, take_profit_percentage: float = 10.0
) -> None:
"""
Sells positions based on the defined sell criteria, including RSI and
Bollinger Band High Index (BBHI) thresholds, as well as take profit
Expand All @@ -36,7 +38,10 @@ def sell_positions_from_criteria(self) -> None:

# console.print("Selling positions based on criteria...", style="bold green")
try:
stocks_to_sell = self.get_stocks_to_sell()
stocks_to_sell = self.get_stocks_to_sell(
stop_loss_percentage=stop_loss_percentage,
take_profit_percentage=take_profit_percentage,
)
if not stocks_to_sell:
send_message("No sell opportunities found.")
return
Expand Down Expand Up @@ -70,7 +75,9 @@ def _sell_positions(self, stocks_to_sell, current_positions) -> list:
send_message(f"Error selling {symbol}: {e}")
return sold_positions

def get_stocks_to_sell(self) -> list:
def get_stocks_to_sell(
self, stop_loss_percentage: float = 10.0, take_profit_percentage: float = 10.0
) -> list:
"""
Retrieves a list of stocks to sell based on specific criteria.
Expand All @@ -97,16 +104,17 @@ def get_stocks_to_sell(self) -> list:
sell_filtered_df = assets_history[sell_criteria]
stocks_to_sell = sell_filtered_df["symbol"].tolist()

take_profit_list = non_cash_positions[non_cash_positions["profit_pct"] > 8.0][
"symbol"
].tolist()
stop_loss_list = non_cash_positions[non_cash_positions["profit_pct"] < -8.0][
"symbol"
].tolist()
take_profit_list = non_cash_positions[
non_cash_positions["profit_pct"] > take_profit_percentage
]["symbol"].tolist()
stop_loss_list = non_cash_positions[
non_cash_positions["profit_pct"] < -stop_loss_percentage
]["symbol"].tolist()

for take_profit, stop_loss in zip(take_profit_list, stop_loss_list):
for take_profit in take_profit_list:
if take_profit not in stocks_to_sell:
stocks_to_sell.append(take_profit)
for stop_loss in stop_loss_list:
if stop_loss not in stocks_to_sell:
stocks_to_sell.append(stop_loss)

Expand Down
72 changes: 54 additions & 18 deletions src/alpaca_daily_losers/daily_losers.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,14 @@ def __init__(self):
)
self.statistics = Statistics(account=self.alpaca.trading.account, py_logger=py_logger)

def run(self, buy_limit: int = 6, article_limit: int = 4) -> None:
def run(
self,
buy_limit: int = 4,
article_limit: int = 4,
stop_loss_percentage: float = 10.0,
take_profit_percentage: float = 10.0,
future_days: int = 4,
) -> None:
"""
Executes the main logic of the program.
Expand All @@ -55,7 +62,10 @@ def run(self, buy_limit: int = 6, article_limit: int = 4) -> None:
continues to the next step.
"""
try:
self.close.sell_positions_from_criteria()
self.close.sell_positions_from_criteria(
stop_loss_percentage=stop_loss_percentage,
take_profit_percentage=take_profit_percentage,
)
except Exception as e:
py_logger.error(f"Error selling positions from criteria. Error {e}")
pass
Expand All @@ -65,23 +75,29 @@ def run(self, buy_limit: int = 6, article_limit: int = 4) -> None:
py_logger.error(f"Error liquidating positions for capital. Error: {e}")
pass
try:
self.check_for_buy_opportunities(buy_limit=buy_limit, article_limit=article_limit)
self.check_for_buy_opportunities(
buy_limit=buy_limit,
article_limit=article_limit,
future_days=future_days,
)
except Exception as e:
py_logger.error(f"Error entering new positions. Error {e}")

########################################################
# Define the check_for_buy_opportunities method
########################################################
def check_for_buy_opportunities(self, buy_limit: int = 6, article_limit: int = 4) -> None:
def check_for_buy_opportunities(
self, buy_limit: int = 6, article_limit: int = 4, future_days: int = 3
) -> None:
"""
Checks for buy opportunities based on daily losers and opens positions if any are found.
Returns:
None
"""
losers = self.get_daily_losers()
losers = self.get_daily_losers(future_days=future_days)
tickers = self.filter_tickers_with_news(
losers, filter_ticker_limit=buy_limit, article_limit=article_limit
tickers=losers, filter_ticker_limit=buy_limit, article_limit=article_limit
)

if len(tickers) > 0:
Expand Down Expand Up @@ -166,17 +182,17 @@ def filter_tickers_with_news(
self, tickers: list, article_limit: int = 4, filter_ticker_limit: int = 6
) -> list:
"""
Filters a list of tickers based on news sentiment analysis.
Filters a list of tickers based on the number of news articles available and
the sentiment analysis of those articles.
Args:
tickers (list): A list of tickers to filter.
article_limit (int, optional): The maximum number of articles to retrieve for each
ticker. Defaults to 4.
filter_ticker_limit (int, optional): The maximum number of tickers to include
in the filtered list. Defaults to 8.
article_limit (int): The maximum number of articles to consider per ticker.
filter_ticker_limit (int): The maximum number of tickers to include in the
filtered list.
Returns:
list: The filtered list of tickers based on news sentiment analysis.
list: A list of tickers that pass the filtering criteria.
"""

openai = OpenAIAPI()
Expand Down Expand Up @@ -223,16 +239,36 @@ def filter_tickers_with_news(
########################################################
# Define the get_daily_losers method
########################################################
def get_daily_losers(self) -> list:
def get_daily_losers(self, future_days: int = 3) -> list:
"""
Retrieves the daily losers from Alpaca stock predictor,
filters them based on buy criteria,
and updates the watchlist with the filtered losers.
Get a list of daily losers based on the buy criteria.
Parameters:
- future_days (int): The number of future days to consider for the losers.
Returns:
A list of assets in the DailyLosers watchlist.
- list: A list of tickers that meet the buy criteria and have a
bearish or neutral sentiment.
Raises:
- None
Example usage:
losers = get_daily_losers(future_days=3)
print(losers)
Note:
- The buy criteria is defined in the `buy_criteria` method.
- The sentiment for each ticker is checked, and only tickers with a bearish or
neutral sentiment are included in the final list.
- If no daily losers are found, an empty list is returned.
- The 'DailyLosers' watchlist is updated or created with the tickers that meet the criteria.
- The assets in the 'DailyLosers' watchlist are returned.
"""
losers = self.alpaca.stock.predictor.get_losers_to_gainers()

losers = self.alpaca.stock.predictor.get_losers_to_gainers(future_periods=future_days)
losers = get_ticker_data(
tickers=losers, stock_client=self.alpaca.stock, py_logger=py_logger
)
Expand Down
Binary file modified yfinance.cache
Binary file not shown.

0 comments on commit 094c9e3

Please sign in to comment.