Skip to main content
Glama
osamadev

Financial MCP Server

by osamadev
alerts.py8.54 kB
import yfinance as yf from services.telegram_alerts import send_telegram_alert import logging import json import os from pathlib import Path logger = logging.getLogger(__name__) def load_alerts_config(): """Load alerts configuration from JSON file.""" try: config_path = Path(__file__).parent.parent / 'config' / 'alerts_config.json' with open(config_path, 'r') as f: config = json.load(f) # Flatten the sector-based structure into a simple ticker-rules dictionary alerts = {} for sector in config.values(): for ticker, details in sector.items(): # Copy all alert parameters alerts[ticker] = details.copy() return alerts except Exception as e: logger.error(f"Error loading alerts configuration: {str(e)}") return {} async def check_alerts(tickers=None): """ Check alerts for stocks with focus on trading signals. Args: tickers (list): Optional list of ticker symbols to check. If None, checks all stocks. """ triggered = [] try: alerts_config = load_alerts_config() if not alerts_config: logger.error("No alerts configuration loaded") return ["⚠️ Error: Could not load alerts configuration"] # Filter tickers if specific ones are requested check_tickers = tickers if tickers else alerts_config.keys() for ticker in check_tickers: try: if ticker not in alerts_config: if tickers: # Only show error if specifically requested triggered.append(f"⚠️ No configuration found for {ticker}") continue rules = alerts_config[ticker] data = yf.Ticker(ticker) price = data.info.get("regularMarketPrice") description = rules.get("description", "") if price: logger.info(f"Current price for {ticker}: ${price}") # Strong buy signal if "strong_buy" in rules and price <= rules["strong_buy"]: msg = f"🟢 Strong Buy Signal: {ticker} at ${price}\n" \ f"• Price at/below strong buy level ${rules['strong_buy']}" if description: msg += f"\nNote: {description}" triggered.append(msg) # Regular buy signal elif "below" in rules and price < rules["below"]: msg = f"🟢 Buy Signal: {ticker} at ${price}\n" \ f"• Price below buy threshold ${rules['below']}" if description: msg += f"\nNote: {description}" triggered.append(msg) # Strong sell signal elif "strong_sell" in rules and price >= rules["strong_sell"]: msg = f"🔴 Strong Sell Signal: {ticker} at ${price}\n" \ f"• Price at/above strong sell level ${rules['strong_sell']}" if description: msg += f"\nNote: {description}" triggered.append(msg) # Regular sell signal elif "above" in rules and price > rules["above"]: msg = f"🔴 Sell Signal: {ticker} at ${price}\n" \ f"• Price above sell threshold ${rules['above']}" if description: msg += f"\nNote: {description}" triggered.append(msg) # No signals but ticker was specifically requested elif tickers: msg = f"ℹ️ {ticker} at ${price} - No trading signals triggered" if description: msg += f"\nNote: {description}" triggered.append(msg) except Exception as e: logger.error(f"Error checking alerts for {ticker}: {str(e)}") if tickers: # Only show errors for specifically requested tickers triggered.append(f"⚠️ Error checking {ticker}: {str(e)}") if triggered: header = "💰 Trading Signals Alert" if tickers: header += f" for {', '.join(tickers)}" summary = f"{header}:\n\n" + "\n\n".join(triggered) try: await send_telegram_alert(summary) logger.info("Trading signals sent successfully") except Exception as e: logger.error(f"Error sending alerts: {str(e)}") return triggered except Exception as e: logger.error(f"Unexpected error in check_alerts: {str(e)}") return [f"⚠️ System error: {str(e)}"] async def check_trading_opportunities(ticker): """ Check for buying and selling opportunities for a specific stock. Args: ticker (str): The stock ticker to check Returns: list: List of trading opportunities """ try: alerts_config = load_alerts_config() if not alerts_config or ticker.upper() not in alerts_config: return [f"⚠️ No configuration found for {ticker}"] rules = alerts_config[ticker.upper()] data = yf.Ticker(ticker) ticker_info = data.info if not ticker_info: return [f"⚠️ Could not get data for {ticker}"] price = ticker_info.get("regularMarketPrice") if not price: return [f"⚠️ Could not get current price for {ticker}"] opportunities = [] description = rules.get("description", "") # Check for buying opportunities if price <= rules.get("strong_buy", float('inf')): opportunities.append(f"🟢 Strong Buy Signal for {ticker} at ${price}") opportunities.append(f"• Price at/below strong buy level ${rules['strong_buy']}") elif price <= rules.get("below", float('inf')): opportunities.append(f"🟢 Buy Signal for {ticker} at ${price}") opportunities.append(f"• Price below buy threshold ${rules['below']}") # Check for selling opportunities if price >= rules.get("strong_sell", float('-inf')): opportunities.append(f"🔴 Strong Sell Signal for {ticker} at ${price}") opportunities.append(f"• Price at/above strong sell level ${rules['strong_sell']}") elif price >= rules.get("above", float('-inf')): opportunities.append(f"🔴 Sell Signal for {ticker} at ${price}") opportunities.append(f"• Price above sell threshold ${rules['above']}") # Check support/resistance levels if "support_levels" in rules: for level in rules["support_levels"]: if abs(price - level) <= (level * 0.01): # Within 1% of support opportunities.append(f"📊 Near support level ${level} (potential buy zone)") if "resistance_levels" in rules: for level in rules["resistance_levels"]: if abs(price - level) <= (level * 0.01): # Within 1% of resistance opportunities.append(f"📊 Near resistance level ${level} (potential sell zone)") if opportunities: if description: opportunities.append(f"\nNote: {description}") else: opportunities = [f"ℹ️ No immediate trading opportunities for {ticker} at ${price}"] return opportunities except Exception as e: logger.error(f"Error checking trading opportunities for {ticker}: {str(e)}") return [f"⚠️ Error checking {ticker}: {str(e)}"] async def send_trading_alert(ticker): """ Send trading opportunities alert for a specific stock. Args: ticker (str): The stock ticker to check """ try: opportunities = await check_trading_opportunities(ticker) if opportunities: summary = f"💰 Trading Opportunities for {ticker}:\n\n" + "\n".join(opportunities) await send_telegram_alert(summary) return opportunities except Exception as e: logger.error(f"Error sending trading alert for {ticker}: {str(e)}") return [f"⚠️ Error: {str(e)}"]

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/osamadev/financial_mcp_server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server