Skip to content

Commit 83c92ab

Browse files
authored
Update Nikkei 225 evaluation
1 parent 2c6040d commit 83c92ab

1 file changed

Lines changed: 86 additions & 58 deletions

File tree

Nikkei 225 evaluation

Lines changed: 86 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -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

193192
def 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

227251
def 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

281309
if __name__ == '__main__':

0 commit comments

Comments
 (0)