@@ -131,64 +131,63 @@ def calculate_stock_trend(stock_data):
131131 else:
132132 return "Neutral"
133133
134- def get_action_recommendation(public_opinion, stock_trend, stock_price_data):
134+ def display_stock_info(stock, rank):
135+ print(f"{rank}. {stock['company_name']} ({stock['stock_number']}):")
136+ print(f" Current Price: ¥{stock['current_stock_price']:.2f}" if stock['current_stock_price'] else " Current Price: N/A")
137+ print(f" Nikkei's Impression: {stock['nikkei_sentiment']}")
138+ print(f" Yahoo's Impression: {stock['yahoo_sentiment']}")
139+ print(f" Overall Sentiment: {stock['overall_sentiment']}")
140+ print(f" Stock Trend: {stock['stock_trend']}")
141+ print(f" Recommendation: {stock['action_recommendation']}")
142+ print()
143+
144+ def get_action_recommendation(public_opinion, stock_trend, stock_price_data, purchase_price=None):
135145 if not stock_price_data:
136146 return "Insufficient data for recommendation"
137147
138- opinion_score = {
139- "Very Positive": 2, "Positive": 1, "Neutral": 0, "Negative": -1, "Very Negative": -2
140- }
141- trend_score = {
142- "Strong Uptrend": 2, "Uptrend": 1, "Neutral": 0, "Downtrend": -1, "Strong Downtrend": -2
143- }
148+ opinion_score = {"Very Positive": 2, "Positive": 1, "Neutral": 0, "Negative": -1, "Very Negative": -2}
149+ trend_score = {"V-Shape Recovery": 1, "Upward Trend": 1, "Downward Trend": -1, "No specific pattern identified": 0}
144150
145- total_score = opinion_score[ public_opinion] + trend_score[ stock_trend]
151+ total_score = opinion_score.get( public_opinion, 0) + trend_score.get( stock_trend, 0)
146152
147- # Calculate average price and standard deviation
148153 prices = [price for _, price in stock_price_data]
154+ current_price = prices[0]
149155 avg_price = np.mean(prices)
150156 std_dev = np.std(prices)
151157
152- current_price = stock_price_data[0][1] # Most recent price
158+ owns_stock = purchase_price is not None
153159
154- if total_score >= 2:
155- # Buy recommendation: Set target slightly below current price
156- target_price = max(current_price * 0.98, avg_price - 0.5 * std_dev)
157- return f"Buy (Target: ¥{target_price:.2f})"
158- elif total_score <= -2:
159- # Sell recommendation: Set target slightly above current price
160- target_price = min(current_price * 1.02, avg_price + 0.5 * std_dev)
161- return f"Sell (Target: ¥{target_price:.2f})"
160+ if owns_stock:
161+ price_change = (current_price - purchase_price) / purchase_price * 100
162+
163+ if total_score > 0:
164+ action = "Hold"
165+ explanation = f"Positive outlook. You're currently up {price_change:.2f}%. Consider holding for potential further gains."
166+ elif total_score < 0:
167+ action = "Consider Selling"
168+ explanation = f"Negative outlook. You're currently {'up' if price_change > 0 else 'down'} {abs(price_change):.2f}%. Consider selling to {'lock in profits' if price_change > 0 else 'minimize losses'}."
169+ else:
170+ action = "Hold and Monitor"
171+ explanation = f"Mixed signals. You're currently {'up' if price_change > 0 else 'down'} {abs(price_change):.2f}%. Monitor the stock closely for changes in sentiment or market trends."
172+
173+ if price_change > 20:
174+ explanation += " However, with significant gains, consider taking partial profits."
175+ elif price_change < -20:
176+ explanation += " However, with significant losses, reassess your investment thesis."
162177 else:
163- return "Hold"
178+ if total_score > 0:
179+ target_price = max(current_price * 0.99, avg_price - 0.5 * std_dev)
180+ action = f"Consider Buying (Target: ¥{target_price:.2f})"
181+ explanation = "Positive outlook. Consider buying near the suggested target price."
182+ elif total_score < 0:
183+ action = "Hold Off"
184+ explanation = "Negative outlook. It might be better to wait for a more favorable entry point."
185+ else:
186+ action = "Monitor"
187+ explanation = "Mixed signals. Monitor the stock for a clearer trend before making a decision."
164188
165- def display_stock_info(stock, rank):
166- print(f"{rank}. {stock['company_name']} ({stock['stock_number']}):")
167- print(f" Current Price: ¥{stock['current_stock_price']:.2f}" if stock['current_stock_price'] else " Current Price: N/A")
168- print(f" Nikkei's Impression: {stock['nikkei_sentiment']}")
169- print(f" Yahoo's Impression: {stock['yahoo_sentiment']}")
170- print(f" Overall Public Opinion: {stock['overall_sentiment']}")
171- print(f" Stock Trend: {stock['stock_trend']}")
172- print(f" Action: {stock['action']}")
173- print()
189+ return f"{action}\nExplanation: {explanation}"
174190
175- def display_detailed_analysis(stock):
176- print(f"\nDetailed Analysis for {stock['company_name']} ({stock['stock_number']}):")
177- print(f"Current Price: ¥{stock['current_stock_price']:.2f}" if stock['current_stock_price'] else "Current Price: N/A")
178- print(f"Nikkei's Impression: {stock['nikkei_sentiment']}")
179- print(f"Yahoo's Impression: {stock['yahoo_sentiment']}")
180- print(f"Overall Public Opinion: {stock['overall_sentiment']}")
181- print(f"Stock Trend: {stock['stock_trend']}")
182- print(f"Action: {stock['action']}")
183- print("\nNikkei News:")
184- for i, news in enumerate(stock['nikkei_news'], 1):
185- print(f" {i}. {news['title']}")
186- print(f" URL: {news['url']}")
187- print("\nYahoo Finance News:")
188- for i, news in enumerate(stock['yahoo_news'], 1):
189- print(f" {i}. {news['title']}")
190- print(f" URL: {news['url']}")
191- print()
192191
193192def interactive_results_display(stock_analysis):
194193 current_index = 0
@@ -199,16 +198,19 @@ def interactive_results_display(stock_analysis):
199198 if current_index + 10 >= len(stock_analysis):
200199 print("End of list reached.")
201200
202- user_input = input("Type 'continue' to see more results, '#<rank>' to see detailed analysis for a stock, '#buy', '#sell', or '#hold' to see top stocks for each action , or 'exit' to quit: ").strip().lower()
201+ user_input = input("Type 'continue' to see more results, '#<rank>' to see detailed analysis for a stock, '#recommend' to see top recommended stocks , or 'exit' to quit: ").strip().lower()
203202
204203 if user_input == 'continue' and current_index + 10 < len(stock_analysis):
205204 current_index += 10
206205 elif user_input.startswith('#'):
207- if user_input[1:] in ['buy', 'sell', 'hold']:
208- action = user_input[1:].capitalize()
209- top_stocks = [s for s in stock_analysis if s['action'].startswith(action)][:5]
210- print(f"\nTop 5 stocks to {action}:")
211- for i, stock in enumerate(top_stocks, 1):
206+ if user_input[1:] == 'recommend':
207+ recommended_stocks = sorted(
208+ [s for s in stock_analysis if 'Buy' in s['action_recommendation'] or 'Hold' in s['action_recommendation']],
209+ key=lambda x: x['current_stock_price'],
210+ reverse=True
211+ )[:5]
212+ print("\nTop 5 Recommended Stocks:")
213+ for i, stock in enumerate(recommended_stocks, 1):
212214 display_stock_info(stock, i)
213215 else:
214216 try:
@@ -222,14 +224,39 @@ def interactive_results_display(stock_analysis):
222224 elif user_input == 'exit':
223225 break
224226 else:
225- print("Invalid input. Please type 'continue', '#<rank>', '#buy', '#sell', '#hold', or 'exit'.")
227+ print("Invalid input. Please type 'continue', '#<rank>', '#recommend', or 'exit'.")
228+
229+ def display_detailed_analysis(stock):
230+ print(f"\nDetailed Analysis for {stock['company_name']} ({stock['stock_number']}):")
231+ print(f"Current Price: ¥{stock['current_stock_price']:.2f}" if stock['current_stock_price'] else "Current Price: N/A")
232+ if stock['purchase_price']:
233+ print(f"Purchase Price: ¥{stock['purchase_price']:.2f}")
234+ price_change = ((stock['current_stock_price'] - stock['purchase_price']) / stock['purchase_price']) * 100
235+ print(f"Price Change: {price_change:.2f}%")
236+ print(f"Nikkei's Impression: {stock['nikkei_sentiment']}")
237+ print(f"Yahoo's Impression: {stock['yahoo_sentiment']}")
238+ print(f"Overall Sentiment: {stock['overall_sentiment']}")
239+ print(f"Stock Trend: {stock['stock_trend']}")
240+ print(f"Recommendation: {stock['action_recommendation']}")
241+ print("\nNikkei News:")
242+ for i, news in enumerate(stock['nikkei_news'], 1):
243+ print(f" {i}. {news['title']}")
244+ print(f" URL: {news['url']}")
245+ print("\nYahoo Finance News:")
246+ for i, news in enumerate(stock['yahoo_news'], 1):
247+ print(f" {i}. {news['title']}")
248+ print(f" URL: {news['url']}")
249+ print()
226250
227251def main():
228252 stock_data = get_stock_codes_and_names()
229253 if not stock_data:
230254 print("Failed to retrieve stock data. Please check your internet connection and try again.")
231255 return
232256
257+ total_stocks = len(stock_data)
258+ print(f"Total stocks to process: {total_stocks}")
259+
233260 ja_tokenizer = AutoTokenizer.from_pretrained("jarvisx17/japanese-sentiment-analysis")
234261 ja_model = AutoModelForSequenceClassification.from_pretrained("jarvisx17/japanese-sentiment-analysis")
235262
@@ -238,8 +265,10 @@ def main():
238265
239266 stock_analysis = []
240267
241- for stock_number, company_name in stock_data:
268+ for index, ( stock_number, company_name) in enumerate( stock_data, 1) :
242269 try:
270+ print(f"Processing: {company_name} ({stock_number}) - {index}/{total_stocks}", end='\r')
271+
243272 nikkei_news_data = scrape_nikkei_news(stock_number)
244273 yahoo_finance_news_data = scrape_yahoo_finance_news(stock_number)
245274
@@ -256,7 +285,7 @@ def main():
256285 current_stock_price = stock_price_data[0][1] if stock_price_data else None
257286 stock_trend = calculate_stock_trend(stock_price_data)
258287
259- action = get_action_recommendation(overall_sentiment, stock_trend, stock_price_data) if stock_price_data else "Insufficient data"
288+ action_recommendation = get_action_recommendation(overall_sentiment, stock_trend, stock_price_data)
260289
261290 stock_analysis.append({
262291 'stock_number': stock_number,
@@ -266,16 +295,15 @@ def main():
266295 'yahoo_sentiment': yahoo_finance_overall_sentiment,
267296 'overall_sentiment': overall_sentiment,
268297 'stock_trend': stock_trend,
269- 'action ': action ,
298+ 'action_recommendation ': action_recommendation ,
270299 'nikkei_news': nikkei_news_data,
271300 'yahoo_news': yahoo_finance_news_data
272301 })
273-
274- print(f"Processed {company_name} ({stock_number})")
275302
276303 except Exception as e:
277- print(f"Error processing {company_name} ({stock_number}): {str(e)}")
304+ print(f"\nError processing {company_name} ({stock_number}): {str(e)}")
278305
306+ print("\nAll stocks processed.")
279307 interactive_results_display(stock_analysis)
280308
281309if __name__ == '__main__':
0 commit comments