diff --git a/week4/community-contributions/ai_stock_trading/README.md b/week4/community-contributions/ai_stock_trading/README.md index 3a56e71..95abada 100644 --- a/week4/community-contributions/ai_stock_trading/README.md +++ b/week4/community-contributions/ai_stock_trading/README.md @@ -1,41 +1,63 @@ -# 📈 Stock Analysis & Sharia Compliance Tool +# 📈 AI Stock Trading & Sharia Compliance Platform -A comprehensive Gradio-based web application that provides AI-powered stock analysis with Islamic Sharia compliance assessment. This tool combines real-time financial data, technical analysis, and AI-driven insights to help users make informed investment decisions while adhering to Islamic finance principles. +A comprehensive **Streamlit-based** web application that provides AI-powered stock analysis with Islamic Sharia compliance assessment. This professional-grade platform combines real-time financial data from USA and Egyptian markets, advanced technical analysis, and institutional-quality AI-driven insights to help users make informed investment decisions while adhering to Islamic finance principles. -![Stock Analysis Interface](https://img.shields.io/badge/Interface-Gradio-blue) -![AI Powered](https://img.shields.io/badge/AI-OpenAI%20GPT--4o--mini-green) -![Islamic Finance](https://img.shields.io/badge/Islamic-Sharia%20Compliant-gold) +## 📸 Application Screenshots -## 🌟 Features +### Home View +![Home View](screenshots/home.png) +*Main application interface with market selection and stock input* -### 📊 **Multi-Period Stock Analysis** -- Fetches historical data for 1 month, 1 year, and 5 years -- Calculates key financial metrics: returns, volatility, volume, price ranges -- Comprehensive technical analysis with statistical insights +### Chat Interface +![Chat Interface](screenshots/chat.png) +*Interactive chat for trading advice, Sharia compliance, and stock analysis* -### 🤖 **AI-Powered Trade Recommendations** -- Uses OpenAI GPT-4o-mini for intelligent analysis -- Provides clear BUY/HOLD/SELL recommendations -- Numerical justification based on multi-timeframe data -- Considers risk factors and market trends +### Dashboard View +![Dashboard View](screenshots/dashboard.png) +*Comprehensive dashboard with KPIs, charts, and real-time metrics* -### ☪️ **Sharia Compliance Assessment** -- Analyzes company business activities for Islamic compliance -- Provides HALAL/HARAM/DOUBTFUL rulings -- Confidence scores (0-100) for each assessment -- Detailed justification based on Islamic finance principles +## 🎯 Key Features -### 📈 **Interactive Visualizations** +### 📊 **Comprehensive Stock Analysis** +- Real-time data fetching from multiple markets (USA, Egypt) +- Advanced technical indicators (RSI, MACD, Bollinger Bands, Moving Averages) +- Risk assessment and volatility analysis +- Performance metrics across multiple time periods + +### 🤖 **AI-Powered Trading Decisions** +- GPT-4 powered investment recommendations +- Buy/Hold/Sell signals with confidence scores +- Price targets and stop-loss suggestions +- Algorithmic + AI combined decision making + +### ☪️ **Sharia Compliance Checking** +- Islamic finance principles assessment +- Halal/Haram rulings with detailed reasoning +- Business activity and financial ratio screening +- Alternative investment suggestions + +### 💬 **Natural Language Interface** +- Interactive chat interface for stock discussions +- Ask questions in plain English +- Context-aware responses about selected stocks +- Quick action buttons for common queries + +### 📈 **Interactive Dashboards** +- Comprehensive metrics dashboard +- Multiple chart types (Price, Performance, Risk, Trading Signals) +- Real-time data visualization with Plotly +- Exportable analysis reports - Real-time price charts with volume data - Professional matplotlib-based visualizations - Price statistics and performance metrics - Responsive chart interface -### 🖥️ **User-Friendly Interface** -- Clean, modern Gradio web interface -- Two-column layout for optimal user experience -- Example stock buttons for quick testing -- Real-time analysis progress tracking +### 🖥️ **Professional Interface** +- Clean, modern Streamlit web interface +- Multi-market support (USA & Egyptian stocks) +- Interactive chat interface with context awareness +- Real-time KPI dashboard with currency formatting +- Quick action buttons for common analysis tasks ## 🚀 Quick Start @@ -56,83 +78,116 @@ cd ai_stock_trading pip install -r requirements.txt ``` -3. **Set up OpenAI API Key** +3. **Set up environment variables** +Create a `.env` file in the project root: ```bash -export OPENAI_API_KEY="your-api-key-here" -``` - -Or set it in the notebook: -```python -import os -os.environ["OPENAI_API_KEY"] = "your-api-key-here" +OPENAI_API_KEY=your-api-key-here ``` ### Running the Application -1. **Open the Jupyter notebook** +1. **Launch the Streamlit app** ```bash -jupyter notebook stock_analysis_sharia_compliance.ipynb +streamlit run main_app.py ``` -2. **Run all cells** to initialize the functions +2. **Access the web interface** at `http://localhost:8501` -3. **Launch the interface** by running the final cell +3. **Select your market** (USA or Egypt) from the sidebar -4. **Access the web interface** at `http://localhost:7860` +4. **Enter a stock symbol** and start analyzing! ## 📖 How to Use -1. **Enter a stock ticker** (e.g., AAPL, MSFT, GOOGL) in the input field -2. **Click "Analyze Stock"** to start the analysis -3. **Review the results**: - - **Trade Advice**: AI-generated BUY/HOLD/SELL recommendation - - **Sharia Assessment**: Islamic compliance ruling with confidence score - - **Price Chart**: 1-month interactive price and volume chart +1. **Select Market**: Choose between USA or Egypt from the sidebar +2. **Enter Stock Symbol**: Input a ticker (e.g., AAPL for USA, ABUK.CA for Egypt) +3. **View Dashboard**: See real-time KPIs, price charts, and key metrics +4. **Use Chat Interface**: Ask questions or request specific analysis: + - "Give me trading advice for AAPL" + - "Is this stock Sharia compliant?" + - "What's the price target?" +5. **Review Professional Analysis**: + - **Trading Recommendations**: Institutional-grade BUY/HOLD/SELL advice + - **Sharia Compliance**: Comprehensive Islamic finance screening + - **Technical Analysis**: Advanced indicators and risk assessment ### Example Tickers to Try -| Ticker | Company | Expected Sharia Status | -|--------|---------|----------------------| -| **AAPL** | Apple Inc. | ✅ Likely Halal (Technology) | -| **MSFT** | Microsoft Corp. | ✅ Likely Halal (Technology) | -| **JNJ** | Johnson & Johnson | ✅ Likely Halal (Healthcare) | -| **BAC** | Bank of America | ❌ Likely Haram (Banking/Interest) | -| **KO** | Coca-Cola | ⚠️ May be Doubtful | +#### USA Market +| Ticker | Company | Sector | Expected Sharia Status | +|--------|---------|--------|-----------------------| +| **AAPL** | Apple Inc. | Technology | ✅ Likely Halal | +| **MSFT** | Microsoft Corp. | Technology | ✅ Likely Halal | +| **GOOGL** | Alphabet Inc. | Technology | ✅ Likely Halal | +| **JNJ** | Johnson & Johnson | Healthcare | ✅ Likely Halal | +| **BAC** | Bank of America | Banking | ❌ Likely Haram | +| **JPM** | JPMorgan Chase | Banking | ❌ Likely Haram | -## 🛠️ Technical Implementation +#### Egypt Market +| Ticker | Company | Sector | Expected Sharia Status | +|--------|---------|--------|-----------------------| +| **ABUK.CA** | Abu Qir Fertilizers | Industrial | ✅ Likely Halal | +| **ETEL.CA** | Egyptian Telecom | Telecom | ✅ Likely Halal | +| **HRHO.CA** | Hassan Allam Holding | Construction | ✅ Likely Halal | +| **CIB.CA** | Commercial Intl Bank | Banking | ❌ Likely Haram | -### Core Components +## 🔧 Technical Implementation -1. **Data Fetching Tool** (`fetch_history`) - - Uses yfinance API for real-time stock data - - Supports multiple time periods and intervals - - Error handling for invalid tickers +### Modular Architecture -2. **Analysis Tool** (`summarize`) - - Calculates financial metrics - - Annualized volatility calculation - - Price performance analysis +The platform is built with a clean, modular architecture using separate tool modules: -3. **Trade Decision Tool** (`get_trade_advice`) - - OpenAI GPT-4o-mini integration - - Multi-period analysis prompts - - Structured recommendation format +#### 1. **Stock Fetching Module** (`tools/fetching.py`) +- **Multi-Market Support**: USA (75+ stocks) and Egypt (50+ stocks) with proper currency handling +- **Real-Time Data**: Uses yfinance API with robust error handling +- **Currency Formatting**: Automatic USD/EGP formatting based on market +- **Stock Info Enrichment**: Company details, market cap, sector classification -4. **Sharia Compliance Tool** (`assess_sharia`) - - Company profile extraction - - Islamic finance criteria evaluation - - Confidence scoring system +#### 2. **Technical Analysis Module** (`tools/analysis.py`) +- **Advanced Indicators**: RSI, MACD, Bollinger Bands, Moving Averages +- **Risk Metrics**: Volatility analysis, Sharpe ratio, maximum drawdown +- **Performance Analysis**: Multi-timeframe returns and trend analysis +- **Professional Calculations**: Annualized metrics and statistical analysis -5. **Charting Tool** (`plot_price`) - - Matplotlib-based visualizations - - Price and volume charts - - Professional styling +#### 3. **Trading Decisions Module** (`tools/trading_decisions.py`) +- **Institutional-Grade AI**: Senior analyst persona with 15+ years experience +- **Professional Standards**: BUY/HOLD/SELL with confidence, price targets, stop-loss +- **Risk Management**: Risk-reward ratios, time horizons, risk assessment +- **Robust JSON Parsing**: Handles malformed AI responses with fallback logic -### AI Prompts +#### 4. **Sharia Compliance Module** (`tools/sharia_compliance.py`) +- **Comprehensive Screening**: Business activities, financial ratios, trading practices +- **AAOIFI Standards**: Debt-to-assets < 33%, interest income < 5% +- **Prohibited Activities**: 50+ categories including banking, gambling, alcohol +- **User-Triggered Analysis**: Only shows when specifically requested -The application uses carefully crafted prompts for: -- **Financial Analysis**: Multi-timeframe technical analysis with numerical justification -- **Sharia Assessment**: Islamic finance principles evaluation with scholarly approach +#### 5. **Charting Module** (`tools/charting.py`) +- **Professional Visualizations**: Plotly-based interactive charts +- **Multiple Chart Types**: Price, volume, technical indicators +- **Responsive Design**: Mobile-friendly chart rendering +- **Export Capabilities**: PNG/HTML export functionality + +#### 6. **Main Application** (`main_app.py`) +- **Streamlit Interface**: Modern, responsive web application +- **Chat Integration**: Context-aware conversational interface +- **Real-Time KPIs**: Live dashboard with key metrics +- **Session Management**: Persistent data across user interactions + +### AI Integration + +The platform leverages OpenAI's GPT-4o-mini with specialized prompts: + +#### Trading Analysis Prompts +- **Senior Analyst Persona**: 15+ years institutional experience +- **Professional Standards**: Risk-reward ratios, logical price targets +- **Structured Output**: JSON format with validation and error handling +- **Technical Focus**: Based on RSI, MACD, trend analysis, volume patterns + +#### Sharia Compliance Prompts +- **Islamic Scholar Approach**: Follows AAOIFI and DSN standards +- **Comprehensive Screening**: Business activities, financial ratios, trading practices +- **Scholarly Reasoning**: Detailed justification with Islamic finance principles +- **Confidence Scoring**: Quantified certainty levels for rulings ## 📊 Sample Analysis Output @@ -227,6 +282,27 @@ Contributions are welcome! Please feel free to submit issues, feature requests, - Historical backtesting - Mobile-responsive design +### 🔮 Future Work: MCP Integration + +We plan to implement a **Model Context Protocol (MCP) layer** to make all trading tools accessible as standardized MCP tools: + +#### Planned MCP Tools: +- **`stock_fetcher`** - Real-time market data retrieval for USA/Egypt markets +- **`technical_analyzer`** - Advanced technical analysis with 20+ indicators +- **`sharia_checker`** - Islamic finance compliance screening +- **`trading_advisor`** - AI-powered institutional-grade recommendations +- **`risk_assessor`** - Portfolio risk analysis and management +- **`chart_generator`** - Professional financial visualizations + +#### Benefits of MCP Integration: +- **Standardized Interface**: Consistent tool access across different AI systems +- **Interoperability**: Easy integration with other MCP-compatible platforms +- **Scalability**: Modular architecture for adding new financial tools +- **Reusability**: Tools can be used independently or combined +- **Professional Integration**: Compatible with institutional trading platforms + +This will enable the platform to serve as a comprehensive financial analysis toolkit that can be integrated into various AI-powered trading systems and workflows. + ## 📄 License This project is for educational purposes. Please ensure compliance with: diff --git a/week4/community-contributions/ai_stock_trading/main_app.py b/week4/community-contributions/ai_stock_trading/main_app.py new file mode 100644 index 0000000..b2e5a04 --- /dev/null +++ b/week4/community-contributions/ai_stock_trading/main_app.py @@ -0,0 +1,549 @@ +""" +Main Streamlit Application for AI Stock Trading with Sharia Compliance +""" + +import streamlit as st +import pandas as pd +import os +from dotenv import load_dotenv + +# Import our custom tools +from tools.fetching import stock_fetcher, get_available_stocks +from tools.analysis import stock_analyzer +from tools.trading_decisions import trading_engine +from tools.sharia_compliance import sharia_checker +from tools.charting import chart_generator + +# Load environment variables +load_dotenv() + +# Page configuration +st.set_page_config( + page_title="AI Stock Trading & Sharia Compliance", + page_icon="📈", + layout="wide", + initial_sidebar_state="expanded" +) + +class StockTradingApp: + def __init__(self): + self.initialize_session_state() + self.setup_sidebar() + + def initialize_session_state(self): + if 'selected_country' not in st.session_state: + st.session_state.selected_country = 'USA' + if 'selected_stock' not in st.session_state: + st.session_state.selected_stock = None + if 'stock_data' not in st.session_state: + st.session_state.stock_data = {} + if 'chat_history' not in st.session_state: + st.session_state.chat_history = [] + if 'current_page' not in st.session_state: + st.session_state.current_page = 'home' + + def setup_sidebar(self): + with st.sidebar: + st.title("🏛️ Navigation") + + page = st.radio( + "Select Page:", + ["🏠 Home", "💬 Chat Interface", "📊 Dashboard"], + key="page_selector" + ) + + page_mapping = { + "🏠 Home": "home", + "💬 Chat Interface": "chat", + "📊 Dashboard": "dashboard" + } + st.session_state.current_page = page_mapping[page] + + st.divider() + self.render_stock_selector() + st.divider() + self.show_api_status() + + def render_stock_selector(self): + st.subheader("🌍 Stock Selection") + + countries = ['USA', 'Egypt'] + selected_country = st.selectbox( + "Select Country:", + countries, + index=countries.index(st.session_state.selected_country), + key="country_selector" + ) + + if selected_country != st.session_state.selected_country: + st.session_state.selected_country = selected_country + st.session_state.selected_stock = None + + available_stocks = get_available_stocks(selected_country) + + if available_stocks: + stock_names = list(available_stocks.keys()) + current_index = 0 + + if st.session_state.selected_stock: + current_symbol = st.session_state.selected_stock + for i, (name, symbol) in enumerate(available_stocks.items()): + if symbol == current_symbol: + current_index = i + break + + selected_stock_name = st.selectbox( + "Select Stock:", + stock_names, + index=current_index, + key="stock_selector" + ) + + selected_symbol = available_stocks[selected_stock_name] + + if selected_symbol != st.session_state.selected_stock: + st.session_state.selected_stock = selected_symbol + st.session_state.stock_data = {} + st.session_state.chat_history = [] + + if st.session_state.selected_stock: + st.success(f"Selected: {selected_stock_name} ({selected_symbol})") + else: + st.error(f"No stocks available for {selected_country}") + + def show_api_status(self): + st.subheader("API Used") + openai_key = os.getenv('OPENAI_API_KEY') + if openai_key: + st.success("✅ OpenAI Connected") + else: + st.error("❌ Not Connected") + + def run(self): + st.title("🤖 AI Stock Trading") + st.markdown("*Intelligent stock analysis with Islamic finance compliance*") + + if st.session_state.current_page == 'home': + self.render_home_page() + elif st.session_state.current_page == 'chat': + self.render_chat_page() + elif st.session_state.current_page == 'dashboard': + self.render_dashboard_page() + + def render_home_page(self): + st.header("🏠 Welcome to AI Stock Trading Platform") + + st.markdown(""" + Get intelligent stock analysis with Islamic finance compliance checking. + Select a country and stock from the sidebar to begin. + + **Key Features:** + - 📊 Real-time stock analysis with advanced indicators + - 🤖 AI-powered trading recommendations + - ☪️ Sharia compliance assessment + - 💬 Natural language chat interface + + **Supported Markets:** 🇺🇸 USA | 🇪🇬 Egypt + + *Disclaimer: For educational purposes only. Not financial advice.* + """) + + if st.session_state.selected_stock: + st.divider() + st.subheader(f"📊 Quick Analysis: {st.session_state.selected_stock}") + with st.spinner("Loading quick analysis..."): + self.show_quick_analysis() + + def show_quick_analysis(self): + symbol = st.session_state.selected_stock + country = st.session_state.selected_country + try: + data = stock_fetcher.fetch_stock_data(symbol, period="1mo") + stock_info = stock_fetcher.get_stock_info(symbol, country) + + if not data.empty: + col1, col2, col3, col4 = st.columns(4) + + current_price = data['Close'].iloc[-1] + price_change = data['Close'].iloc[-1] - data['Close'].iloc[-2] if len(data) > 1 else 0 + price_change_pct = (price_change / data['Close'].iloc[-2] * 100) if len(data) > 1 else 0 + + with col1: + formatted_price = stock_fetcher.format_price_with_currency(current_price, country) + price_change_str = f"{price_change:+.2f} ({price_change_pct:+.1f}%)" + st.metric("Current Price", formatted_price, price_change_str) + + with col2: + high_52w = stock_info.get('fifty_two_week_high', 0) + formatted_high = stock_fetcher.format_price_with_currency(high_52w, country) + st.metric("52W High", formatted_high) + + with col3: + low_52w = stock_info.get('fifty_two_week_low', 0) + formatted_low = stock_fetcher.format_price_with_currency(low_52w, country) + st.metric("52W Low", formatted_low) + + with col4: + market_cap = stock_info.get('market_cap', 0) + currency = stock_fetcher.get_market_currency(country) + if market_cap > 1e9: + if currency == 'EGP': + market_cap_str = f"{market_cap/1e9:.1f}B EGP" + else: + market_cap_str = f"${market_cap/1e9:.1f}B" + elif market_cap > 1e6: + if currency == 'EGP': + market_cap_str = f"{market_cap/1e6:.1f}M EGP" + else: + market_cap_str = f"${market_cap/1e6:.1f}M" + else: + if currency == 'EGP': + market_cap_str = f"{market_cap:,.0f} EGP" + else: + market_cap_str = f"${market_cap:,.0f}" + st.metric("Market Cap", market_cap_str) + + st.info(f"**{stock_info.get('company_name', 'N/A')}** | " + f"Sector: {stock_info.get('sector', 'N/A')} | " + f"Industry: {stock_info.get('industry', 'N/A')}") + + except Exception as e: + st.error(f"Error loading quick analysis: {str(e)}") + + def load_stock_analysis(self, symbol: str): + try: + country = st.session_state.selected_country + data = stock_fetcher.fetch_stock_data(symbol, period="1y") + stock_info = stock_fetcher.get_stock_info(symbol, country) + analysis = stock_analyzer.analyze_stock(data) + trading_decision = trading_engine.get_trading_recommendation(symbol, analysis, stock_info) + sharia_compliance = sharia_checker.check_sharia_compliance(symbol, stock_info, analysis) + + st.session_state.stock_data[symbol] = { + 'data': data, + 'stock_info': stock_info, + 'analysis': analysis, + 'trading_decision': trading_decision, + 'sharia_compliance': sharia_compliance + } + except Exception as e: + st.error(f"Error loading analysis for {symbol}: {str(e)}") + + def render_chat_page(self): + st.header("💬 AI Stock Analysis Chat") + + if not st.session_state.selected_stock: + st.warning("⚠️ Please select a stock from the sidebar to start chatting.") + return + + symbol = st.session_state.selected_stock + st.info(f"💬 Chatting about: **{symbol}**") + + if symbol not in st.session_state.stock_data: + with st.spinner("Loading stock data and analysis..."): + self.load_stock_analysis(symbol) + + self.render_chat_interface() + + def render_chat_interface(self): + symbol = st.session_state.selected_stock + + if st.session_state.chat_history: + for message in st.session_state.chat_history: + if message['role'] == 'user': + st.chat_message("user").write(message['content']) + else: + st.chat_message("assistant").write(message['content']) + else: + welcome_msg = f""" + 👋 Hello! I'm your AI stock analysis assistant. I can help you with: + + • **Technical Analysis** of {symbol} + • **Trading Recommendations** (Buy/Hold/Sell) + • **Sharia Compliance** assessment + • **Risk Analysis** and market insights + + What would you like to know about {symbol}? + """ + st.chat_message("assistant").write(welcome_msg) + + user_input = st.chat_input("Ask me anything about this stock...") + + if user_input: + st.session_state.chat_history.append({'role': 'user', 'content': user_input}) + + with st.spinner("Analyzing..."): + ai_response = self.generate_ai_response(user_input, symbol) + + st.session_state.chat_history.append({'role': 'assistant', 'content': ai_response}) + st.rerun() + + st.subheader("🚀 Quick Actions") + col1, col2, col3, col4 = st.columns(4) + + with col1: + if st.button("📊 Get Analysis"): + self.add_analysis_to_chat(symbol) + st.rerun() + + with col2: + if st.button("💰 Trading Rec"): + self.add_trading_to_chat(symbol) + st.rerun() + + with col3: + if st.button("☪️ Sharia Check"): + self.add_sharia_to_chat(symbol) + st.rerun() + + with col4: + if st.button("🎯 Price Target"): + self.add_target_to_chat(symbol) + st.rerun() + + def generate_ai_response(self, user_input: str, symbol: str) -> str: + try: + from openai import OpenAI + client = OpenAI(api_key=os.getenv('OPENAI_API_KEY')) + + # Check if user is asking about Sharia compliance + sharia_keywords = ['sharia', 'halal', 'haram', 'islamic', 'muslim', 'compliant', 'permissible', 'forbidden'] + is_sharia_query = any(keyword in user_input.lower() for keyword in sharia_keywords) + + stock_data = st.session_state.stock_data.get(symbol, {}) + analysis = stock_data.get('analysis', {}) + trading_decision = stock_data.get('trading_decision', {}) + stock_info = stock_data.get('stock_info', {}) + country = st.session_state.selected_country + + # Format price with proper currency + current_price = analysis.get('current_price', 0) + formatted_price = stock_fetcher.format_price_with_currency(current_price, country) + + # Base context without Sharia info + context = f""" + You are analyzing {symbol} ({stock_info.get('company_name', 'N/A')}). + + Current Price: {formatted_price} + Return: {analysis.get('total_return_pct', 0):.2f}% + Recommendation: {trading_decision.get('recommendation', 'N/A')} + Sector: {stock_info.get('sector', 'N/A')} + + User Question: {user_input} + + Provide helpful analysis based on the available data. + """ + + # Add Sharia context only if user asks about it + if is_sharia_query: + # Load Sharia compliance if not already loaded + if symbol not in st.session_state.stock_data or 'sharia_compliance' not in st.session_state.stock_data[symbol]: + with st.spinner("Loading Sharia compliance analysis..."): + self.load_stock_analysis(symbol) + + sharia_compliance = st.session_state.stock_data.get(symbol, {}).get('sharia_compliance', {}) + context += f""" + + SHARIA COMPLIANCE ANALYSIS: + Ruling: {sharia_compliance.get('ruling', 'N/A')} + Confidence: {sharia_compliance.get('confidence', 0)*100:.0f}% + Reasoning: {sharia_compliance.get('reasoning', 'N/A')} + + Focus your response on Islamic finance principles and Sharia compliance. + """ + + response = client.chat.completions.create( + model="gpt-4o-mini", + messages=[ + {"role": "system", "content": "You are a financial advisor and Islamic finance expert."}, + {"role": "user", "content": context} + ], + temperature=0.7, + max_tokens=400 + ) + + return response.choices[0].message.content + + except Exception as e: + return f"Sorry, I'm having trouble right now. Error: {str(e)}" + + def add_analysis_to_chat(self, symbol: str): + stock_data = st.session_state.stock_data.get(symbol, {}) + analysis = stock_data.get('analysis', {}) + + if analysis: + summary = stock_analyzer.get_analysis_summary(analysis) + st.session_state.chat_history.append({ + 'role': 'assistant', + 'content': f"📊 **Analysis Summary for {symbol}:**\n\n{summary}" + }) + + def add_trading_to_chat(self, symbol: str): + stock_data = st.session_state.stock_data.get(symbol, {}) + trading_decision = stock_data.get('trading_decision', {}) + stock_info = stock_data.get('stock_info', {}) + country = st.session_state.selected_country + + if trading_decision: + rec = trading_decision.get('recommendation', 'HOLD') + conf = trading_decision.get('confidence', 0) + + # Handle confidence as percentage if it's already 0-100, or as decimal if 0-1 + if conf <= 1.0: + conf_pct = conf * 100 + else: + conf_pct = conf + + reason = trading_decision.get('reasoning', 'No reasoning available') + price_target = trading_decision.get('price_target') + stop_loss = trading_decision.get('stop_loss') + time_horizon = trading_decision.get('time_horizon', 'medium') + risk_level = trading_decision.get('risk_level', 'medium') + + # Clean reasoning - remove JSON artifacts + if reason.startswith('```json') or reason.startswith('{'): + # Extract readable content from malformed JSON + if 'reasoning' in reason: + try: + import re + reasoning_match = re.search(r'"reasoning"\s*:\s*"([^"]+)"', reason) + if reasoning_match: + reason = reasoning_match.group(1) + else: + reason = "Technical analysis suggests this recommendation based on current market conditions." + except: + reason = "Technical analysis suggests this recommendation based on current market conditions." + + # Format the message professionally + message_parts = [ + f"💰 **Trading Recommendation: {rec}**", + f"📊 **Confidence Level:** {conf_pct:.0f}%", + f"⏱️ **Time Horizon:** {time_horizon.title()}-term", + f"⚠️ **Risk Level:** {risk_level.title()}", + "", + f"**Analysis:**", + reason + ] + + # Add price targets if available + if price_target: + formatted_target = stock_fetcher.format_price_with_currency(price_target, country) + message_parts.append(f"🎯 **Price Target:** {formatted_target}") + + if stop_loss: + formatted_stop = stock_fetcher.format_price_with_currency(stop_loss, country) + message_parts.append(f"🛡️ **Stop Loss:** {formatted_stop}") + + message_parts.append("") + message_parts.append("*This is not financial advice. Please do your own research and consult with a financial advisor.*") + + message = "\n".join(message_parts) + st.session_state.chat_history.append({'role': 'assistant', 'content': message}) + + def add_sharia_to_chat(self, symbol: str): + stock_data = st.session_state.stock_data.get(symbol, {}) + sharia_compliance = stock_data.get('sharia_compliance', {}) + + if sharia_compliance: + summary = sharia_checker.get_compliance_summary(sharia_compliance) + st.session_state.chat_history.append({ + 'role': 'assistant', + 'content': f"☪️ **Sharia Compliance:**\n\n{summary}" + }) + + def add_target_to_chat(self, symbol: str): + stock_data = st.session_state.stock_data.get(symbol, {}) + trading_decision = stock_data.get('trading_decision', {}) + analysis = stock_data.get('analysis', {}) + + current = analysis.get('current_price', 0) + target = trading_decision.get('price_target') + stop = trading_decision.get('stop_loss') + + message = f"🎯 **Current Price:** ${current:.2f}\n" + if target: + upside = ((target - current) / current) * 100 + message += f"**Target:** ${target:.2f} ({upside:+.1f}%)\n" + if stop: + downside = ((stop - current) / current) * 100 + message += f"**Stop Loss:** ${stop:.2f} ({downside:+.1f}%)" + + st.session_state.chat_history.append({'role': 'assistant', 'content': message}) + + def render_dashboard_page(self): + st.header("📊 Dashboard") + + if not st.session_state.selected_stock: + st.warning("⚠️ Please select a stock from the sidebar.") + return + + symbol = st.session_state.selected_stock + country = st.session_state.selected_country + + if symbol not in st.session_state.stock_data: + with st.spinner("Loading analysis..."): + self.load_stock_analysis(symbol) + + stock_data = st.session_state.stock_data.get(symbol, {}) + if not stock_data: + st.error("Failed to load data.") + return + + analysis = stock_data.get('analysis', {}) + trading_decision = stock_data.get('trading_decision', {}) + sharia_compliance = stock_data.get('sharia_compliance', {}) + data = stock_data.get('data') + + # KPIs at the top + col1, col2, col3, col4, col5 = st.columns(5) + + with col1: + current_price = data['Close'].iloc[-1] + formatted_price = stock_fetcher.format_price_with_currency(current_price, country) + st.metric("💰 Current Price", formatted_price) + + with col2: + total_return = analysis.get('total_return_pct', 0) + st.metric("Total Return", f"{total_return:.2f}%") + + with col3: + rec = trading_decision.get('recommendation', 'HOLD') + conf = trading_decision.get('confidence', 0) * 100 + st.metric("Recommendation", rec, f"{conf:.0f}% confidence") + + with col4: + ruling = sharia_compliance.get('ruling', 'UNCERTAIN') + sharia_conf = sharia_compliance.get('confidence', 0) * 100 + st.metric("Sharia Status", ruling, f"{sharia_conf:.0f}% confidence") + + with col5: + volatility = analysis.get('volatility_annualized', 0) + st.metric("Volatility", f"{volatility:.1f}%") + + st.divider() + + # Charts section + + # First row: Risk Analysis and Trading Signals + col1, col2 = st.columns(2) + + with col1: + risk_fig = chart_generator.create_risk_analysis_chart(analysis, symbol) + st.plotly_chart(risk_fig, use_container_width=True) + + with col2: + signals_fig = chart_generator.create_trading_signals_chart(data, analysis, trading_decision, symbol) + st.plotly_chart(signals_fig, use_container_width=True) + + # Second row: Price Chart (full width) + price_fig = chart_generator.create_price_chart(data, symbol, analysis) + st.plotly_chart(price_fig, use_container_width=True) + + + +def main(): + app = StockTradingApp() + app.run() + +if __name__ == "__main__": + main() diff --git a/week4/community-contributions/ai_stock_trading/requirements.txt b/week4/community-contributions/ai_stock_trading/requirements.txt index 3c05391..98321c1 100644 --- a/week4/community-contributions/ai_stock_trading/requirements.txt +++ b/week4/community-contributions/ai_stock_trading/requirements.txt @@ -2,7 +2,9 @@ yfinance>=0.2.10 openai>=1.0.0 pandas>=1.5.0 matplotlib>=3.5.0 -gradio>=4.0.0 +streamlit>=1.28.0 requests>=2.28.0 beautifulsoup4>=4.11.0 -numpy>=1.21.0 \ No newline at end of file +numpy>=1.21.0 +python-dotenv>=1.0.0 +plotly>=5.15.0 \ No newline at end of file diff --git a/week4/community-contributions/ai_stock_trading/stock_analysis_sharia_compliance.ipynb b/week4/community-contributions/ai_stock_trading/stock_analysis_sharia_compliance.ipynb index 3c7bfca..7fd7810 100644 --- a/week4/community-contributions/ai_stock_trading/stock_analysis_sharia_compliance.ipynb +++ b/week4/community-contributions/ai_stock_trading/stock_analysis_sharia_compliance.ipynb @@ -41,7 +41,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "metadata": {}, "outputs": [ { @@ -107,31 +107,31 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "✅ Successfully fetched 18 data points for ABUK.CA (1mo)\n", + "✅ Successfully fetched 17 data points for ABUK.CA (1mo)\n", "\n", "📊 Sample data for ABUK.CA:\n", - " Open High Low Close Volume \\\n", - "Date \n", - "2025-05-29 00:00:00+03:00 49.000000 49.270000 48.099998 48.320000 971406 \n", - "2025-06-01 00:00:00+03:00 48.320000 48.840000 48.189999 48.400002 583557 \n", - "2025-06-02 00:00:00+03:00 48.400002 49.450001 48.500000 49.000000 648049 \n", - "2025-06-03 00:00:00+03:00 49.000000 49.470001 49.029999 49.090000 379774 \n", - "2025-06-04 00:00:00+03:00 49.090000 49.889999 48.970001 49.889999 592659 \n", + " Open High Low Close \\\n", + "Date \n", + "2025-06-22 00:00:00+03:00 45.970001 47.000000 45.049999 46.840000 \n", + "2025-06-23 00:00:00+03:00 46.840000 47.099998 45.830002 46.410000 \n", + "2025-06-24 00:00:00+03:00 46.410000 47.950001 47.009998 47.889999 \n", + "2025-06-25 00:00:00+03:00 47.889999 48.990002 47.939999 48.889999 \n", + "2025-06-29 00:00:00+03:00 48.889999 50.869999 49.520000 50.389999 \n", "\n", - " Dividends Stock Splits Capital Gains \n", - "Date \n", - "2025-05-29 00:00:00+03:00 0.0 0.0 0.0 \n", - "2025-06-01 00:00:00+03:00 0.0 0.0 0.0 \n", - "2025-06-02 00:00:00+03:00 0.0 0.0 0.0 \n", - "2025-06-03 00:00:00+03:00 0.0 0.0 0.0 \n", - "2025-06-04 00:00:00+03:00 0.0 0.0 0.0 \n" + " Volume Dividends Stock Splits Capital Gains \n", + "Date \n", + "2025-06-22 00:00:00+03:00 408343 0.0 0.0 0.0 \n", + "2025-06-23 00:00:00+03:00 1425250 0.0 0.0 0.0 \n", + "2025-06-24 00:00:00+03:00 1184487 0.0 0.0 0.0 \n", + "2025-06-25 00:00:00+03:00 833208 0.0 0.0 0.0 \n", + "2025-06-29 00:00:00+03:00 994006 0.0 0.0 0.0 \n" ] } ], @@ -188,7 +188,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -197,14 +197,14 @@ "text": [ "\n", "📈 Analysis Summary:\n", - " start_price: 48.32\n", - " end_price: 50.39\n", - " total_return_%: 4.28\n", - " volatility_%: 33.04\n", - " avg_volume: 965145\n", - " max_price: 51.5\n", - " min_price: 45.01\n", - " price_range_%: 14.42\n" + " start_price: 46.84\n", + " end_price: 52.7\n", + " total_return_%: 12.51\n", + " volatility_%: 30.91\n", + " avg_volume: 1153685\n", + " max_price: 53.25\n", + " min_price: 45.05\n", + " price_range_%: 18.2\n" ] } ], @@ -291,7 +291,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 4, "metadata": { "scrolled": true }, @@ -308,19 +308,17 @@ "\n", "**Justification:**\n", "\n", - "1. **Price Movement**: The stock price has increased from $48.32 to $50.39 over the past month, representing a gain of 4.28%. This upward movement indicates positive momentum and investor interest.\n", + "1. **Price Movement**: The stock price has increased from $46.84 to $52.7 over the past month, representing a gain of 12.51%. This upward momentum indicates strong buying interest and positive market sentiment.\n", "\n", - "2. **Volatility**: The volatility of 33.04% is relatively high, which suggests that the stock may experience significant price fluctuations. While this can be a risk factor, it also indicates potential for higher returns, especially for investors who can tolerate short-term volatility.\n", + "2. **Volatility**: The volatility of 30.91% is relatively high, suggesting that while the stock can experience significant price swings, it also presents opportunities for substantial gains. For risk-tolerant investors, this volatility can be seen as a chance to capitalize on price movements.\n", "\n", - "3. **Average Volume**: The average trading volume of 965,145 shares suggests healthy liquidity in the stock. High trading volume often correlates with strong investor interest and can lead to more stable price movements.\n", + "3. **Average Volume**: The average volume of 1,153,685 shares traded indicates a healthy level of liquidity, allowing for easier entry and exit points for investors. High trading volume often correlates with strong investor interest and can support price stability.\n", "\n", - "4. **Price Range**: The price range of 14.42% indicates that the stock has experienced considerable price swings within the month. This can be viewed as a sign of volatility but also presents opportunities for traders to capitalize on price movements.\n", + "4. **Price Range**: The price range of 18.2% suggests that the stock has experienced considerable fluctuations within the month. However, the upward trend and the recent price increase indicate that the stock is currently on a bullish trajectory.\n", "\n", - "5. **Risk Factors**: While the volatility is a concern, the positive total return and upward price trend suggest that the stock is currently in a bullish phase. Investors should be aware of the potential for increased risk but can also benefit from the potential upside.\n", + "5. **Risk Factors**: While the high volatility presents risks, the recent positive performance and the total return of 12.51% over the month suggest that the stock is gaining traction. Investors should be aware of potential market corrections but can take advantage of the current upward trend.\n", "\n", - "6. **Technical Indicators**: If we consider typical technical analysis indicators, such as moving averages or RSI (Relative Strength Index), a further analysis would likely show that the stock is either approaching or is in a bullish trend, supporting the BUY recommendation.\n", - "\n", - "In conclusion, given the recent price appreciation, healthy trading volume, and the potential for further gains despite the volatility, I recommend a BUY for ABUK.CA. Investors should, however, monitor the stock closely due to its high volatility.\n" + "**Conclusion**: Given the strong price performance, reasonable trading volume, and potential for continued growth despite volatility, the recommendation is to BUY ABUK.CA. Investors should monitor the stock closely for any changes in market conditions or company fundamentals that may impact future performance.\n" ] } ], @@ -407,7 +405,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -420,7 +418,7 @@ "Sharia Assessment for ABUK.CA:\n", "Ruling: DOUBTFUL\n", "Confidence: 50%\n", - "Justification: The business description for ABUK.CA does not provide sufficient information regarding its specific activities, sector, or industry. Without clarity on whether the company engages in any HARAM activities or has excessive debt, it is difficult to make a definitive ruling. Given the lack of transparency, it is prudent to classify the company as DOUBTFUL.\n" + "Justification: The business description for ABUK.CA does not provide sufficient information about its specific activities or revenue sources. Without clarity on whether the company engages in any HARAM activities or has excessive debt, it is prudent to classify it as DOUBTFUL. Further investigation into the company's financials and business operations is necessary to make a definitive ruling.\n" ] } ], @@ -568,7 +566,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -581,7 +579,7 @@ }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABKUAAAJOCAYAAABm7rQwAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvc2/+5QAAAAlwSFlzAAAPYQAAD2EBqD+naQAA7h9JREFUeJzs3Xd4U2X7B/Bvkjbde7d0MgqFQsssG2RvVAQFWTL0FRUVXxEnvPBzoqLgAoECskWGKILMFplFWkahtHTSvXfTJjm/Pwqh6aItbU/H93Ndudozc+ckJ8m58zz3IxEEQQAREREREREREVEjkoodABERERERERERtT5MShERERERERERUaNjUoqIiIiIiIiIiBodk1JERERERERERNTomJQiIiIiIiIiIqJGx6QUERERERERERE1OialiIiIiIiIiIio0TEpRUREREREREREjY5JKSIiIiIiIiIianRMShEREdUTNzc3SCQSza05On36tNZjmDNnjtghNajW9niJiIiImhImpYiIqNEVFRVh7dq1GDp0KGxsbKCrqwszMzO4u7vDz88PL774In766SckJSVV2HbNmjVYvny55tYalE+clL1JpVKYmpqia9euWLx4McLCwsQOV1Rnz57FK6+8Ah8fH1hbW2teW927d8eiRYtw8uRJsUOsk6ysLK3Xvb+/v9ghaenatWuF1+b7779f7TbLly+v8nVtYGAAJycnDBs2DKtXr0ZOTk6l+5gzZ47WdlW9JwwZMkRrvfLHryb7SUxMRPv27bXW69atGzIyMmpyiCqIiorCBx98gIEDB8LBwQF6enowMjJChw4d8Nxzz2HHjh1QKBRVbl9SUgJra+sKx+7nn3+uUzxERERi0BE7ACIial0SEhIwfPhw3Lp1S2t+Tk4OcnJyEB0djYsXLwIAjIyM8Pzzz2utt2bNGsTExGimW0tiqiqCICA3NxfXr1/H9evX8eOPP+L777/HvHnz6rQ/uVwOOzs7zbSZmVl9hdqgEhISMHv2bBw/frzCspycHFy9ehVXr17F999/j08++QTvvPOOCFHWXVZWFlasWKGZHjx4cJNp1XXz5k1cv369wvwdO3Zg1apVddpnUVEREhISkJCQgJMnT2LNmjU4ffo02rVr97jh1klKSgqGDRuGiIgIzbxOnTrh+PHjsLS0rNW+iouLsWTJEvz4449Q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Q2FjYwMdHR0YGBjAw8MDkydPxtq1axEbG4s+ffrUOqY2bdrg5MmTOHPmDP7zn//A29sblpaWkMlkMDExgbe3NxYuXIhjx45h6dKl9XUoMHnyZPz9998YPHgwDA0NYWJign79+mHfvn14++236+1+AOC///0vvv32W/j4+NQ6cVdfdu7cqVXnaejQobC2tq5y/QkTJmglfENCQhAaGvrI+5FKpZrn7aWXXkJQUFCVx1MqlWLdunW4cOEC5s+fj44dO8LExAQ6OjqwsLBA79698c477+D27duYMWNGLR6tto8++gjvvPOO1rw///wTzz33XK1qfOnp6eH7779HWFgY3nvvPfTr1w92dnbQ1dWFgYEB2rZtiylTpmDr1q2aQrvlu+49+eST0NHRqfI+nnnmGa3pI0eOaLofExFR7fz7778QBAEdOnSAsbGx5nbmzBncvXsXAKBWq6FQKLB161YMHDgQQ4YMwcaNG3Hq1CmEhYWJ/AiaNokglKsgSURERERERETUCkkkEuzfv1/TEnj37t2YMWMGbt68WaGVq7GxMezt7fHRRx/h448/1mo9W1hYCENDQxw7dgwjRoxozIfQrFT9EwsRERERERERUSvm6+sLlUqFlJQUDBw4sNJ1+vfvD6VSibt376Jt27YAgDt37gAoHYCHqsaWUkRERERERETUauXl5SEiIgJAaRLqQbkBS0tLuLi44Pnnn8c///yDL7/8Er6+vkhLS8PJkyfh7e2NsWPHQq1Wo1evXjA2NsaaNWugVquxaNEimJqa4tixYyI/uqaNSSkiIiIiIiIiarVOnz5d6YAps2fPhr+/P0pKSrBq1Sps3boV8fHxsLKyQt++fbFixQp4e3sDABISEvDqq6/i2LFjMDIywpgxY/Dll1/C0tKysR9Os8KkFBERERERERERNTqOvkdERERERERERI2OSSkiIiIiIiIiImp0rWL0PaVSiatXr8LOzg5SKfNwRERERERERNQ41Go1kpOT4evrCx2dVpGGqbFWcTSuXr2K3r17ix0GEREREREREbVSly5dQq9evcQOo0lpFUkpOzs7AKUvAAcHB6jVaqSnp8PKyootp4geE88novrD84mo/vB8IqpfPKeI6i4xMRG9e/fW5CbooVaRlHrwpung4IA2bdpArVZDLpfD1taWb6hEj4nnE1H94flEVH94PhHVL55T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clREVF+afLouMTERM2fORMeOHfHaa69h5syZ2Llzp9hhETW6vVfuITItHwDQ290SQzrYiBwREVHzYWuij/7trAEAcRmF+Dc2S9yAiIjokQqLVViw9Qris0prRnVtY4avp/nwh1miFkT00ffKO336tNb0a6+9htdee02cYIiaiMJiFdYcv6OZXjq6I3/hJyKqpUk+Tgi8P1DEweB49HC1EDkiIiKqilotYMneYITEZQEAHM308fOsnjCQy6rfkIialSbfUoqIgC3no5GcowAAjPCy44UUEVEdjOpsBz2d0q8+f1xLRImKwzMTETVVq4+F4c/rSQAAI7kMG+f0gq1pxRHbiah5Y1KKqInLLijB96dKR9yTSoD/NtPivEREYjPR18XwTnYAgPT8YpyNSBM5IiIiqsyeoDh8f/ougNLvv+umd0cnB1ORoyKihsCkFFET98OZu8gpKi3s+FT3NuhgZyJyREREzdckH0fN/wevxosYCRERVebc3TS8+9vDEdqXT+yMoR1tRYyIiBpSk6spRUQPJWUXYfM/UQAAuUyKN0Z0EDkiIqKKwsLCHr3SY/D0rL8WokM8bWFmoIvswhIcC01GQbEShnJ+HSIiagpScxV4adsVKNUCAGBOPzfM6usmblBE1KDYUoqoCfvmRDgUytKaJzP7usLJ3EDkiIiImje5jhRjve0BAAXFKvwdmixyRERE9MDB4HhND4EnOtrig/FeIkdERA2NSSmiJioyNQ97guIAAMZ6Olg0tJ3IERERtQyTfJw0/x8MThAxEiIiKuuvG0ma/98f1wkyKUebJmrpmJQiaqK+PHYHqvtNlxcO8oClkVzkiIiIWobebpZwMCsdwSngTioy8otFjoiIiFJyinAlNhMA0MHOGB42xiJHRESNgUkpoibo2r0s/HE9EQBgbSzHvAHuIkdERNRySKUSTOxWWvBcqRY077dERCSeY6HJEEp/j8XozvbiBkNEjYZJKaIm6PO/HhYNfvWJ9jDSYxFeIqL6pNWFj6PwERGJ7ujNh133RnVhUoqotWBSiqiJORuehrMRaQAAZ0sDPNfbReSIiIhank4OJuhgV9o1JCgmE3EZBSJHRETUemUXlOD83XQAQBsLA3g5mIocERE1FialiJoQQRDw+dHbmuklIzwh1+FpSkRU3yQSiVZrqUMhLHhORCSWE7eTobxfS3V0Z3tI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HNc/TTxiYiQA4FybK03d6xMXYl4gQBO0evVqXX755YqJiZHFYtGnn3561sesWrVKffv2la+vr9q3b6+5c+eeVmbRokXq2rWrrFarunbtqsWLF9c6ppdeekl//OMftWzZMl177bUaMmSIrr32Wn3++ee6/vrr9dJLL9XlFB1qNX1vxIgRCgoKcly3WCz1agwAAKAp69O2pdqE+ulQ9nH9tDdTGfnFahXoa3ZYANCgDMNwJKU8PSzq0TrE3ICAJqawsFA9e/bUbbfdpmuuueas5ZOSknTJJZfojjvu0AcffKCffvpJU6dOVUREhOPxa9eu1cSJE/X3v/9dV111lRYvXqw//OEP+vHHHzVgwICztrFr1y7NnDnzjPfdeOONuuqqq+p2kifUKin17rvvOq7Pnz+/Xg0BAAA0dRaLReN7xurV7/fKbkjLfknVbUPizQ4LABrUwewiZReWSZK6RAfK38fT5IiApmXcuHEaN25crcvPnTtXbdu21ezZsyVJXbp00caNG/XCCy84klKzZ8/W6NGjNWPGDEnSjBkztGrVKs2ePVsfffTRWdvw8/NTdnb2Ge/Lzs6Wn59freOtrE4Tf48fP64hQ4bom2++qVdjAAAATV3VKXwpJkYCAM6x+WClqXttW5oYCQCpYhTUmDFjqhwbO3asNm7cqLKyshrLrFmzplZtDBs2TE888YRSUqp+t0lLS9NTTz2l4cOH1yv2Ou2+5+fnp23btsnLq96b9gEAADRp50UGqmt0kHak5mnroRwlZRYqPjzA7LAAoME41pOySL3ahpgaC+BO8vPzlZeX57httVpltVrPud60tDRFRkZWORYZGany8nJlZmYqOjq62jJpaWnV1nv06FFFRERIkp555hkNHjxYHTt21KhRoxQdHa3U1FR999138vb21v/+9796xV7nLRIGDRqk9evX16sxAACA5uDK3qdGSy1ltBSAJiQ157jSckskSee1aqEgX2+TIwLcR9euXRUcHOy4VLdGU338fu1vwzBOO36mMjWtGR4bG6sJEyboiy++ULdu3bRx40aNHz9eGzZs0LvvvqsNGzboyiuv1Pr169W1a9d6xV3nIU///Oc/NX78eEVFRenqq69WixYt6tUwAABAU3V5zxjN/GKXDENaknhE943qyEYxAJqEzck5jut9mbqHE3bv3u30NhISEpzehrPt2LFD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", + "image/png": "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1ADwXiVqGHivEtWN7IJiXInNBAA4WBiimUnN60ndvz+lUmmlPaV4HxPVHd5fOjj7Xmk5OTmIioqCg4ODtkMhIiIiIiLSqnM306BSl9SP8rGvWXkTIiJdolM9pebOnYvhw4fD1dUV8fHx+PDDDyGTyTBx4kQAQGJiIhITE8WeU8HBwVAoFHBxcYGlpaU2QyciIiIiIqpTp6Luij/fL3JORNSQ6VRSKjY2FhMnTkRqaipsbGzQo0cPnD17FjY2NgCAb7/9VqNoea9evQAAGzZswNSpU7URMhERERERUb04FVmSlJJKAC97JqWIqOHTqaTU5s2bK12/cOFCLFy4sH6CISIiIiIi0hHJ2QW4npQDAGjrZAFjA5mWIyIienw6XVOKiIiIiIiIgNORD6aO7+FhpcVIiIhqD5NSREREREREOu7+0D0A6N7SWouREBHVHialiIiIiIiIdJggCGJSSq4nRUfXZlqOiIiodjApRUREREREpMNup+YhPrMAANDZzRKG+qwnRUSNA5NSREREREREOkxj6J4Hh+4RUePBpBQREREREZEO00xKscg5ETUeTEoRERERERHpKJVawJmbJTPvmRnqoXVzcy1HRERUe5iUIiIiIiIi0lGh8VnIyCsGAAS0tIZMKtFyREREtYdJKSIiIiIiIh11KopD94io8WJSioiIiIiISEexyDkRNWZMShEREREREemgQqUK/91OAwA4mBvC3dpEyxEREdUuJqWIiIiIiIh00KXoDBQUqwGU9JKSSFhPiogaFyaliIiIiIiIdJDm0D3WkyKixkdP2wEQERERERFRWaWLnAe01L16UhEREfV2Li8vr3o7FxHVH/aUIiIiIiIi0jFZBcW4EpMBAGhlawo7M0PtBkREVAeYlCIiIiIiItIx526mQS2U/MxZ94iosWJSioiIiIiISMdo1pNiUoqIGicmpYiIiIiIiHTM/aSUVAJ0bWGp5WiIiOoGk1JEREREREQ6JDmrADeScwAA7ZwtYGaor+WIiIjqBpNSREREREREOqT0rHvddXDWPSKi2sKkFBERERERkQ45FZkq/hzgYaXFSIiI6haTUkRERERERDpCEASxnpShvhQdXZppOSIiorrDpBQREREREZGOuHU3FwmZBQCAzm6WMNSXaTkiIqK6w6QUERERERGRjjgV9WDoXncP1pMiosaNSSkiIiIi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p59+WgkJCXr99dddnPzsKEoBAAAAAAC4seLiYm3YsEGDBg1ytFmtVg0aNEhr1qyp8jFr1qyptL8kDRky5Kz7m8HH7ACuZrfbJUlpaWkmJ6m9sw3Nqw/BwcFuncMZGQzDUHZ2toqLi2WxWM47g7Ny1FR1OeBeeF84l91u17Fjx1RcXCyrtXbfqfCaoCru8r5wlxx15U3nqrvkQDl3eT28JYc3fQZ2lxw4zVWviae/HqfqEllZWQoLC3O0+/v7y9/fv9K+R48eVVlZmaKioiq1R0VFaefOnVX2n56eXuX+6enpzojvFA2uKHX48GFJUp8+fUxOAgAAAAAAGrpu3bpV2p42bZqefPJJc8K4WIMrSsXHx+unn35SVFRUrb+9g3fJyclRly5dtH37doWGhpodB8BZcK4CnoFzFfAMnKuA+ex2u/bv368uXbrIx+d0eea3o6QkqVmzZrLZbI6BNqccPnxY0dHRVfYfHR19XvubocEVpXx8fHTRRReZHQNuJDs7W5IUExNTacgkAPfCuQp4Bs5VwDNwrgLuoXXr1jXaz8/PT71799bSpUt13XXXSSovai1dulT33ntvlY/p16+fli5dqsmTJzvalixZon79+tU1ttM0uKIUAAAAAACAp5kyZYrGjx+vCy+8UH369NGMGTOUl5enCRMmSJLGjRunmJgYPfvss5KkSZMm6bLLLtOLL76oa665RvPnz9f69ev19ttvm/k0KqEoBQAAAAAA4OZuvPFGHTlyRE888YTS09PVq1cvLV682LGY+f79+ystU5SYmKh58+bpscce01//+ld17NhRixYtOmMNKzNRlEKD5+/vr2nTplU5bxeA++BcBTwD5yrgGThXAc907733nnW63vLly89o++Mf/6g//vGP9Zyq9iyGYRhmhwAAAAAAAEDDwuXnAAAAAAAA4HIUpQAAAAAAAOByFKUAAAAAAADgchSl4DLPPvusLrroIoWGhioyMlLXXXedUlJSKu1TWFioe+65R02bNlVISIhuuOEGHT582HH/pk2bNGrUKLVq1UqBgYHq3LmzXnnllUp9LF++XBaL5Yyf9PT0avMZhqEnnnhCzZs3V2BgoAYNGqRffvnljP2++OILXXzxxQoMDFTjxo113XXXVdvv8uXLde2116p58+YKDg5Wr169NHfu3LPuP3/+fFkslnP2C9QXTz9Xz9avxWLRunXrqu17+fLlSkhIkL+/vzp06KDZs2dXun/FihUaNmyYWrRoIYvFokWLFlXbH1CfOFfPfq6WlZXp8ccfV2xsrAIDA9W+fXs9/fTTYilVmKGhnqtpaWkaPXq0LrjgAlmtVk2ePPmMfWbPnn1GnwEBAdXmBeBdKErBZb7//nvdc889+vHHH7VkyRKVlJRo8ODBysvLc+xz//3363//+58WLlyo77//Xr/++qtGjBjhuH/Dhg2KjIzUhx9+qG3btunRRx/V1KlT9frrr59xvJSUFKWlpTl+IiMjq833j3/8Q6+++qpmzpyptWvXKjg4WEOGDFFhYaFjn08++URjx47VhAkTtGnTJq1atUqjR4+utt/Vq1erR48e+uSTT7R582ZNmDBB48aN0+eff37Gvnv37tVf/vIXDRgwoNo+gfrk6edqYmJipf7S0tJ02223KTY2VhdeeOFZ+01NTdU111yjyy+/XMnJyZo8ebJuu+02ff3114598vLy1LNnT73xxhs1/v8J1BfO1bOfq88//7z++c9/6vXXX9eOHTv0/PPP6x//+Idee+21Gv//BZyloZ6rRUVFioiI0GOPPaaePXuedb+wsLBKfe/bt6/avAC8jAGYJCMjw5BkfP/994ZhGEZmZqbh6+trLFy40LHPjh07DEnGmjVrztrP3XffbVx++eWO7e+++86QZJw4caLGWex2uxEdHW383//9n6MtMzPT8Pf3Nz766CPDMAyjpKTEiImJMd59990a93s2V199tTFhwoRKbaWlpUZiYqLx7rvvGuPHjzeuvfbaOh8HcAZPO1d/q7i42IiIiDCeeuqpavt+6KGHjK5du1Zqu/HGG40hQ4ZUub8k49NPP61xdqC+ca6ePlevueYa409/+lOlfUaMGGGMGTOmxs8BqC8N5Vyt6LLLLjMmTZp0RvusWbOMRo0a1bgfAN6HkVIwTVZWliSpSZMmksq/ASopKdGgQYMc+3Tq1EmtW7fWmjVrqu3nVB8V9erVS82bN9fvfvc7rVq1qtosqampSk9Pr3TsRo0a6eKLL3YcOykpSYcOHZLValV8fLyaN2+uoUOHauvWrTV/0tVkfuqppxQZGalbb731vPsD6pOnnau/9d///lfHjh3ThAkTqu17zZo1lfqVpCFDhlT7nAB3wrl6ut/ExEQtXbpUP//8s6TyqU8rV67U0KFDq+0bcIWGcq7WVG5urtq0aaNWrVrp2muv1bZt25zSLwDP4GN2ADRMdrtdkydP1iWXXKJu3bpJktLT0+Xn56fw8PBK+0ZFRZ11Lvzq1au1YMECffHFF4625s2ba+bMmbrwwgtVVFSkd999VwMHDtTatWuVkJBQZT+n+o+Kijrrsffs2SNJevLJJ/XSSy+pbdu2evHFFzVw4ED9/PPPVX4oqMrHH3+sdevW6a233nK0rVy5Uu+9956Sk5Nr1AfgKp54rv7We++9pyFDhqhly5bVPtf09PQq+83OzlZBQYECAwOrfTxgJs7VyufqI488ouzsbHXq1Ek2m01lZWX6+9//rjFjxlTbN1DfGtK5WhNxcXF6//331aNHD2VlZemFF15QYmKitm3b5pT+Abg/ilIwxT333KOtW7dq5cqVte5j69atuvbaazVt2jQNHjzY0R4XF6e4uDjHdmJionbv3q2XX35Zc+bM0dy5czVx4kTH/V999ZVsNts5j2e32yVJjz76qG644QZJ0qxZs9SyZUstXLhQEydOVNeuXR3z4AcMGKCvvvqqUh/fffedJkyYoHfeeUddu3aVJOXk5Gjs2LF655131KxZs1r+3wDqhyeeqxUdPHhQX3/9tT7++ONK7SEhIY7bN998s2bOnHm+TwtwK5yrlX388ceaO3eu5s2bp65duzrWnmrRooXGjx9/XtkAZ+Jcraxfv37q169fpcydO3fWW2+9paeffvq8sgHwTBSl4HL33nuvPv/8c61YsaLSNyDR0dEqLi5WZmZmpW+KDh8+rOjo6Ep9bN++XVdeeaXuuOMOPfbYY+c8Zp8+fRy//IcPH66LL77YcV9MTIzS0tIcx2revHmlY/fq1UuSHO1dunRx3O/v76927dpp//79kqQvv/xSJSUlknTGqIrvv/9ew4YN08svv6xx48Y52nfv3q29e/dq2LBhjrZTBTAfHx+lpKSoffv253yOgLN56rla0axZs9S0aVMNHz68UnvFUYlhYWGO51XxSken+g0LC2OUFNwa5+qZ5+qDDz6oRx55RDfddJMkqXv37tq3b5+effZZilIwTUM7V2vD19dX8fHx2rVrV637AOBZKErBZQzD0H333adPP/1Uy5cvV2xsbKX7e/fuLV9fXy1dutQxEiklJUX79++v9A3Ktm3bdMUVV2j8+PH6+9//XqNjJycnO37RhoaGKjQ0tNL9sbGxio6O1tKlSx2/gLOzs7V27Vrdddddjnz+/v5KSUlR//79JUklJSXau3ev2rRpI0mO//7W8uXL9fvf/17PP/+87rjjjkr3derUSVu2bKnU9thjjyknJ0evvPKKWrVqVaPnCDiLp5+rFZ/HrFmzNG7cOPn6+la6r0OHDmccu1+/fvryyy8rtS1ZsqTScwLcCefqab89V/Pz82W1Vl461WazOb70AVypoZ6rtVFWVqYtW7bo6quvdkp/ADyAiYuso4G56667jEaNGhnLly830tLSHD/5+fmOfe68806jdevWxrJly4z169cb/fr1M/r16+e4f8uWLUZERIRx8803V+ojIyPDsc/LL79sLFq0yPjll1+MLVu2GJMmTTKsVqvx7bffVpvvueeeM8LDw43PPvvM2Lx5s3HttdcasbGxRkFBgWOfSZMmGTExMcbXX39t7Ny507j11luNyMhI4/jx42ftd9myZUZQUJAxderUSpmPHTt21sdw9T2YyRvOVcMwjG+//daQZOzYsaNGz3vPnj1GUFCQ8eCDDxo7duww3njjDcNmsxmLFy927JOTk2Ns3LjR2LhxoyHJeOmll4yNGzca+/btq9ExAGfiXD37uTp+/HgjJibG+Pzzz43U1FTjP//5j9GsWTPjoYceqtExAGdqqOeqYRiO35m9e/c2Ro8ebWzcuNHYtm2b4/7p06cbX3/9tbF7925jw4YNxk033WQEBARU2geAd6MoBZeRVOXPrFmzHPsUFBQYd999t9G4cWMjKCjIuP766420tDTH/dOmTauyjzZt2jj2ef7554327dsbAQEBRpMmTYyBAwcay5YtO2c+u91uPP7440ZUVJTh7+9vXHnllUZKSkqlfYqLi40HHnjAiIyMNEJDQ41BgwYZW7durbbf8ePHV5n5sssuq/YxFKVgFm84Vw3DMEaNGmUkJiae13P/7rvvjF69ehl+fn5Gu3btKj3nU/dX9bzGjx9/XscBnIFz9eznanZ2tjFp0iSjdevWRkBAgNGuXTvj0UcfNYqKis7rOIAzNORz9VyZJ0+ebLRu3drw8/MzoqKijKuvvtpISko6r2MA8GwWwzAMJwy4AgAAAAAAAGrMeu5dAAAAAAAAAOeiKAUAAAAAAACXoygFAAAAAAAAl6MoBQAAAAAAAJejKAUAAAAAAACXoygFAAAAAAAAl6MoBQAAAAAAAJejKAUAAAAAAACXoygFAAAAAAAAl6MoBQAAGpTZs2fLYrE4fgICAtSiRQsNGTJEr776qnJycmrV7+rVq/Xkk08qMzPTuYEBAAC8FEUpAADQID311FOaM2eO/vnPf+q+++6TJE2ePFndu3fX5s2bz7u/1atXa/r06RSlAAAAasjH7AAAAABmGDp0qC688ELH9tSpU7Vs2TL9/ve/1/Dhw7Vjxw4FBgaamBAAAMC7MVIKAADgpCuuuEKPP/649u3bpw8//FCStHnzZt1yyy1q166dAgICFB0drT/96U86duyY43FPPvmkHnzwQUlSbGysY2rg3r17Hft8+OGH6t27twIDA9WkSRPddNNNOnDggEufHwAAgDuhKAUAAFDB2LFjJUnffPONJGnJkiXas2ePJkyYoNdee0033XST5s+fr6uvvlqGYUiSRowYoVGjRkmSXn75Zc2ZM0dz5sxRRESEJOnvf/+7xo0bp44dO+qll17S5MmTtXTpUl166aVM9wMAAA0W0/cAAAAqaNmypRo1aqTdu3dLku6++2498MADlfbp27evRo0apZUrV2rAgAHq0aOHEhIS9NFHH+m6665T27ZtHfvu27dP06ZN09/+9jf99a9/dbSPGDFC8fHxevPNNyu1AwAANBSMlAIAAPiNkJAQx1X4Kq4rVVhYqKNHj6pv376SpKSkpHP29Z///Ed2u10jR47U0aNHHT/R0dHq2LGjvvvuu/p5EgAAAG6OkVIAAAC/kZubq8jISEnS8ePHNX36dM2fP18ZGRmV9svKyjpnX7/88osMw1DHjh2rvN/X17fugQEAADwQRSkAAIAKDh48qKysLHXo0EGSNHLkSK1evVoPPvigevXqpZCQENntdl111VWy2+3n7M9ut8tiseirr76SzWY74/6QkBCnPwcAAABPQFEKAACggjlz5kiShgwZohMnTmjp0qWaPn26nnjiCcc+v/zyyxmPs1gsVfbXvn17GYah2NhYXXDBBfUTGgAAwAOxphQAAMBJy5Yt09NPP63Y2FiNGTPGMbLp1FX2TpkxY8YZjw0ODpakM66mN2LECNlsNk2fPv2MfgzD0LFjx5z3BAAAADwII6UAAECD9NVXX2nnzp0qLS3V4cOHtWzZMi1ZskRt2rTRf//7XwUEBCggIECXXnqp/vGPf6ikpEQxMTH65ptvlJqaekZ/vXv3liQ9+uijuummm+Tr66thw4apffv2+tvf/qapU6dq7969uu666xQaGqrU1FR9+umnuuOOO/SXv/zF1U8fAADAdBSlAABAg3RqOp6fn5+aNGmi7t27a8aMGZowYYJCQ0Md+82bN0/33Xef3njjDRmGocGDB+urr75SixYtKvV30UUX6emnn9bMmTO1ePFi2e12paamKjg4WI888oguuOACvfzyy5o+fbokqVWrVho8eLCGDx/uuicNAADgRizGb8eRAwAAAAAAAPWMNaUAAAAAAADgchSlAAAAAAAA4HIUpQAAAAAAAOByFKUAAAAAAADgchSlAAAAAAAA4HIUpQAAAAAAAOByFKUAAAAAAADgchSlAAAAAAAA4HIUpQAAAAAAAOByFKUAAAAAAADgchSlAAAAAAAA4HIUpQAAAAAAAOByFKUAAAAAAADgcv8PRt05QdKqU10AAAAASUVORK5CYII=", "text/plain": [ "
" ] @@ -686,7 +684,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -873,7 +871,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -883,8 +881,8 @@ "🚀 Launching Stock Analysis & Sharia Compliance Interface...\n", "📝 Make sure you have set your OPENAI_API_KEY environment variable\n", "🌐 The interface will open in your browser\n", - "* Running on local URL: http://0.0.0.0:7861\n", - "* Running on public URL: https://83c8badbf7f5d179dd.gradio.live\n", + "* Running on local URL: http://0.0.0.0:7860\n", + "* Running on public URL: https://ebf42ba14d2f6c267b.gradio.live\n", "\n", "This share link expires in 1 week. For free permanent hosting and GPU upgrades, run `gradio deploy` from the terminal in the working directory to deploy to Hugging Face Spaces (https://huggingface.co/spaces)\n" ] @@ -892,7 +890,7 @@ { "data": { "text/html": [ - "
" + "
" ], "text/plain": [ "" @@ -900,102 +898,6 @@ }, "metadata": {}, "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "🔄 Analyzing AAPL...\n", - "📈 Fetching 1mo data...\n", - "✅ Successfully fetched 22 data points for AAPL (1mo)\n", - "📈 Fetching 1y data...\n", - "✅ Successfully fetched 250 data points for AAPL (1y)\n", - "📈 Fetching 5y data...\n", - "✅ Successfully fetched 1256 data points for AAPL (5y)\n", - "✅ Successfully fetched 22 data points for AAPL (1mo)\n", - "🤖 Getting AI trade advice...\n", - "☪️ Assessing Sharia compliance...\n", - "📊 Creating price chart...\n", - "✅ Analysis complete for AAPL\n", - "🔄 Analyzing ABUK...\n", - "📈 Fetching 1mo data...\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "HTTP Error 404: \n", - "$ABUK: possibly delisted; no price data found (period=1mo) (Yahoo error = \"No data found, symbol may be delisted\")\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "❌ Error fetching data for ABUK: No data found for symbol: ABUK\n", - "📈 Fetching 1y data...\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "$ABUK: possibly delisted; no price data found (period=1y) (Yahoo error = \"No data found, symbol may be delisted\")\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "❌ Error fetching data for ABUK: No data found for symbol: ABUK\n", - "📈 Fetching 5y data...\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "$ABUK: possibly delisted; no price data found (period=5y) (Yahoo error = \"No data found, symbol may be delisted\")\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "❌ Error fetching data for ABUK: No data found for symbol: ABUK\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "$ABUK: possibly delisted; no price data found (period=1mo) (Yahoo error = \"No data found, symbol may be delisted\")\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "❌ Error fetching data for ABUK: No data found for symbol: ABUK\n", - "🤖 Getting AI trade advice...\n", - "☪️ Assessing Sharia compliance...\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "HTTP Error 404: \n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "📊 Creating price chart...\n", - "✅ Analysis complete for ABUK\n" - ] } ], "source": [ @@ -1098,7 +1000,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.12" + "version": "3.10.18" } }, "nbformat": 4, diff --git a/week4/community-contributions/ai_stock_trading/tools/__init__.py b/week4/community-contributions/ai_stock_trading/tools/__init__.py new file mode 100644 index 0000000..eee1806 --- /dev/null +++ b/week4/community-contributions/ai_stock_trading/tools/__init__.py @@ -0,0 +1,28 @@ +""" +AI Stock Trading Tools + +This package contains all the core tools for the AI Stock Trading platform: +- fetching: Stock data fetching and market data +- analysis: Technical analysis and stock metrics +- trading_decisions: AI-powered trading recommendations +- sharia_compliance: Islamic finance compliance checking +- charting: Interactive charts and visualizations +""" + +__version__ = "1.0.0" +__author__ = "AI Stock Trading Platform" + +# Import main classes and functions for easy access +from .fetching import StockDataFetcher, stock_fetcher, fetch_stock_data, get_available_stocks +from .analysis import StockAnalyzer, stock_analyzer, analyze_stock +from .trading_decisions import TradingDecisionEngine, trading_engine, get_trading_recommendation +from .sharia_compliance import ShariaComplianceChecker, sharia_checker, check_sharia_compliance +from .charting import StockChartGenerator, chart_generator, create_price_chart + +__all__ = [ + 'StockDataFetcher', 'stock_fetcher', 'fetch_stock_data', 'get_available_stocks', + 'StockAnalyzer', 'stock_analyzer', 'analyze_stock', + 'TradingDecisionEngine', 'trading_engine', 'get_trading_recommendation', + 'ShariaComplianceChecker', 'sharia_checker', 'check_sharia_compliance', + 'StockChartGenerator', 'chart_generator', 'create_price_chart' +] diff --git a/week4/community-contributions/ai_stock_trading/tools/analysis.py b/week4/community-contributions/ai_stock_trading/tools/analysis.py new file mode 100644 index 0000000..9ab856e --- /dev/null +++ b/week4/community-contributions/ai_stock_trading/tools/analysis.py @@ -0,0 +1,316 @@ +""" +Stock Analysis Module + +This module provides enhanced technical and fundamental analysis capabilities +for stock data with advanced metrics and indicators. +""" + +import pandas as pd +import numpy as np +from typing import Dict, List, Optional, Tuple, Union, Any +import warnings + +warnings.filterwarnings('ignore') + +class StockAnalyzer: + """Enhanced stock analyzer with comprehensive technical indicators""" + + def __init__(self): + pass + + def analyze_stock(self, data: pd.DataFrame) -> Dict: + """ + Comprehensive stock analysis with enhanced metrics + + Args: + data: DataFrame with OHLCV stock data + + Returns: + Dictionary with analysis results + """ + if data.empty: + return {'error': 'No data provided for analysis'} + + try: + analysis = {} + + # Basic price metrics + analysis.update(self._calculate_price_metrics(data)) + + # Technical indicators + analysis.update(self._calculate_technical_indicators(data)) + + # Volatility analysis + analysis.update(self._calculate_volatility_metrics(data)) + + # Volume analysis + analysis.update(self._calculate_volume_metrics(data)) + + # Trend analysis + analysis.update(self._calculate_trend_metrics(data)) + + # Risk metrics + analysis.update(self._calculate_risk_metrics(data)) + + # Performance metrics + analysis.update(self._calculate_performance_metrics(data)) + + return analysis + + except Exception as e: + return {'error': f'Analysis failed: {str(e)}'} + + def _calculate_price_metrics(self, data: pd.DataFrame) -> Dict: + """Calculate basic price metrics""" + close_prices = data['Close'] + + return { + 'current_price': float(close_prices.iloc[-1]), + 'start_price': float(close_prices.iloc[0]), + 'max_price': float(close_prices.max()), + 'min_price': float(close_prices.min()), + 'price_range_pct': float(((close_prices.max() - close_prices.min()) / close_prices.min()) * 100), + 'total_return_pct': float(((close_prices.iloc[-1] - close_prices.iloc[0]) / close_prices.iloc[0]) * 100) + } + + def _calculate_technical_indicators(self, data: pd.DataFrame) -> Dict: + """Calculate technical indicators""" + close_prices = data['Close'] + high_prices = data['High'] + low_prices = data['Low'] + + indicators = {} + + # Moving averages + if len(data) >= 20: + sma_20 = close_prices.rolling(window=20).mean() + indicators['sma_20'] = float(sma_20.iloc[-1]) + indicators['price_vs_sma_20'] = float(((close_prices.iloc[-1] - sma_20.iloc[-1]) / sma_20.iloc[-1]) * 100) + + if len(data) >= 50: + sma_50 = close_prices.rolling(window=50).mean() + indicators['sma_50'] = float(sma_50.iloc[-1]) + indicators['price_vs_sma_50'] = float(((close_prices.iloc[-1] - sma_50.iloc[-1]) / sma_50.iloc[-1]) * 100) + + # Exponential Moving Average + if len(data) >= 12: + ema_12 = close_prices.ewm(span=12).mean() + indicators['ema_12'] = float(ema_12.iloc[-1]) + + # RSI (Relative Strength Index) + if len(data) >= 14: + rsi = self._calculate_rsi(pd.Series(close_prices), 14) + indicators['rsi'] = float(rsi.iloc[-1]) + indicators['rsi_signal'] = self._interpret_rsi(float(rsi.iloc[-1])) + + # MACD + if len(data) >= 26: + macd_line, signal_line, histogram = self._calculate_macd(pd.Series(close_prices)) + indicators['macd'] = float(macd_line.iloc[-1]) + indicators['macd_signal'] = float(signal_line.iloc[-1]) + indicators['macd_histogram'] = float(histogram.iloc[-1]) + indicators['macd_trend'] = 'bullish' if float(histogram.iloc[-1]) > 0 else 'bearish' + + # Bollinger Bands + if len(data) >= 20: + bb_upper, bb_middle, bb_lower = self._calculate_bollinger_bands(pd.Series(close_prices), 20, 2) + indicators['bb_upper'] = float(bb_upper.iloc[-1]) + indicators['bb_middle'] = float(bb_middle.iloc[-1]) + indicators['bb_lower'] = float(bb_lower.iloc[-1]) + indicators['bb_position'] = self._interpret_bollinger_position(float(close_prices.iloc[-1]), float(bb_upper.iloc[-1]), float(bb_lower.iloc[-1])) + + return indicators + + def _calculate_volatility_metrics(self, data: pd.DataFrame) -> Dict: + """Calculate volatility metrics""" + close_prices = data['Close'] + daily_returns = close_prices.pct_change().dropna() + + return { + 'volatility_daily': float(daily_returns.std() * 100), + 'volatility_annualized': float(daily_returns.std() * np.sqrt(252) * 100), + 'avg_daily_return': float(daily_returns.mean() * 100), + 'max_daily_gain': float(daily_returns.max() * 100), + 'max_daily_loss': float(daily_returns.min() * 100) + } + + def _calculate_volume_metrics(self, data: pd.DataFrame) -> Dict: + """Calculate volume metrics""" + volume = data['Volume'] + + metrics: Dict[str, Union[float, str]] = { + 'avg_volume': float(volume.mean()), + 'current_volume': float(volume.iloc[-1]), + 'max_volume': float(volume.max()), + 'min_volume': float(volume.min()) + } + + # Volume trend + if len(volume) >= 10: + recent_avg = volume.tail(10).mean() + overall_avg = volume.mean() + if recent_avg > overall_avg: + metrics['volume_trend'] = 'increasing' + else: + metrics['volume_trend'] = 'decreasing' + metrics['volume_vs_avg'] = float(((recent_avg - overall_avg) / overall_avg) * 100) + + return metrics + + def _calculate_trend_metrics(self, data: pd.DataFrame) -> Dict: + """Calculate trend analysis metrics""" + close_prices = data['Close'] + + # Linear regression for trend + x = np.arange(len(close_prices)) + slope, intercept = np.polyfit(x, close_prices, 1) + + # Trend strength + correlation = np.corrcoef(x, close_prices)[0, 1] + + return { + 'trend_slope': float(slope), + 'trend_direction': 'upward' if slope > 0 else 'downward', + 'trend_strength': float(abs(correlation)), + 'trend_angle': float(np.degrees(np.arctan(slope))), + 'r_squared': float(correlation ** 2) + } + + def _calculate_risk_metrics(self, data: pd.DataFrame) -> Dict: + """Calculate risk metrics""" + close_prices = data['Close'] + daily_returns = close_prices.pct_change().dropna() + + # Value at Risk (VaR) + var_95 = np.percentile(daily_returns, 5) + var_99 = np.percentile(daily_returns, 1) + + # Maximum Drawdown + cumulative_returns = (1 + daily_returns).cumprod() + running_max = cumulative_returns.expanding().max() + drawdown = (cumulative_returns - running_max) / running_max + max_drawdown = drawdown.min() + + # Sharpe Ratio (assuming risk-free rate of 2%) + risk_free_rate = 0.02 / 252 # Daily risk-free rate + excess_returns = daily_returns - risk_free_rate + sharpe_ratio = excess_returns.mean() / daily_returns.std() if daily_returns.std() != 0 else 0 + + return { + 'var_95': float(var_95 * 100), + 'var_99': float(var_99 * 100), + 'max_drawdown': float(max_drawdown * 100), + 'sharpe_ratio': float(sharpe_ratio * np.sqrt(252)), # Annualized + 'downside_deviation': float(daily_returns[daily_returns < 0].std() * 100) + } + + def _calculate_performance_metrics(self, data: pd.DataFrame) -> Dict: + """Calculate performance metrics""" + close_prices = data['Close'] + + # Different period returns + periods = { + '1_week': min(5, len(close_prices) - 1), + '1_month': min(22, len(close_prices) - 1), + '3_months': min(66, len(close_prices) - 1), + '6_months': min(132, len(close_prices) - 1) + } + + performance = {} + current_price = close_prices.iloc[-1] + + for period_name, days_back in periods.items(): + if days_back > 0: + past_price = close_prices.iloc[-(days_back + 1)] + return_pct = ((current_price - past_price) / past_price) * 100 + performance[f'return_{period_name}'] = float(return_pct) + + return performance + + def _calculate_rsi(self, prices: pd.Series, period: int = 14) -> pd.Series: + """Calculate Relative Strength Index""" + delta = prices.diff() + gain = (delta.where(delta > 0, 0)).rolling(window=period).mean() + loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean() + rs = gain / loss + rsi = 100 - (100 / (1 + rs)) + return rsi + + def _interpret_rsi(self, rsi_value: float) -> str: + """Interpret RSI value""" + if rsi_value >= 70: + return 'overbought' + elif rsi_value <= 30: + return 'oversold' + else: + return 'neutral' + + def _calculate_macd(self, prices: pd.Series, fast: int = 12, slow: int = 26, signal: int = 9) -> Tuple[pd.Series, pd.Series, pd.Series]: + """Calculate MACD indicator""" + ema_fast = prices.ewm(span=fast).mean() + ema_slow = prices.ewm(span=slow).mean() + macd_line = ema_fast - ema_slow + signal_line = macd_line.ewm(span=signal).mean() + histogram = macd_line - signal_line + return macd_line, signal_line, histogram + + def _calculate_bollinger_bands(self, prices: pd.Series, period: int = 20, std_dev: int = 2) -> Tuple[pd.Series, pd.Series, pd.Series]: + """Calculate Bollinger Bands""" + sma = prices.rolling(window=period).mean() + std = prices.rolling(window=period).std() + upper_band = sma + (std * std_dev) + lower_band = sma - (std * std_dev) + return upper_band, sma, lower_band + + def _interpret_bollinger_position(self, current_price: float, upper_band: float, lower_band: float) -> str: + """Interpret position relative to Bollinger Bands""" + if current_price > upper_band: + return 'above_upper_band' + elif current_price < lower_band: + return 'below_lower_band' + else: + return 'within_bands' + + def get_analysis_summary(self, analysis: Dict) -> str: + """Generate a human-readable analysis summary""" + if 'error' in analysis: + return f"Analysis Error: {analysis['error']}" + + summary = [] + + # Price summary + current_price = analysis.get('current_price', 0) + total_return = analysis.get('total_return_pct', 0) + summary.append(f"Current Price: ${current_price:.2f}") + summary.append(f"Total Return: {total_return:.2f}%") + + # Trend + trend_direction = analysis.get('trend_direction', 'unknown') + trend_strength = analysis.get('trend_strength', 0) + summary.append(f"Trend: {trend_direction.title()} (Strength: {trend_strength:.2f})") + + # Technical indicators + if 'rsi' in analysis: + rsi = analysis['rsi'] + rsi_signal = analysis['rsi_signal'] + summary.append(f"RSI: {rsi:.1f} ({rsi_signal})") + + if 'macd_trend' in analysis: + macd_trend = analysis['macd_trend'] + summary.append(f"MACD: {macd_trend}") + + # Risk + volatility = analysis.get('volatility_annualized', 0) + max_drawdown = analysis.get('max_drawdown', 0) + summary.append(f"Volatility: {volatility:.1f}% (Annual)") + summary.append(f"Max Drawdown: {max_drawdown:.1f}%") + + return "\n".join(summary) + +# Global instance for easy import +stock_analyzer = StockAnalyzer() + +# Convenience function +def analyze_stock(data: pd.DataFrame) -> Dict: + """Convenience function to analyze stock data""" + return stock_analyzer.analyze_stock(data) diff --git a/week4/community-contributions/ai_stock_trading/tools/charting.py b/week4/community-contributions/ai_stock_trading/tools/charting.py new file mode 100644 index 0000000..e10384e --- /dev/null +++ b/week4/community-contributions/ai_stock_trading/tools/charting.py @@ -0,0 +1,483 @@ +""" +Charting Module + +This module provides comprehensive charting and visualization capabilities +for stock analysis with interactive dashboards using Plotly. +""" + +import pandas as pd +import numpy as np +import plotly.graph_objects as go +import plotly.express as px +from plotly.subplots import make_subplots +import streamlit as st +from typing import Dict, List, Optional, Tuple +import warnings + +warnings.filterwarnings('ignore') + +class StockChartGenerator: + """Enhanced stock chart generator with interactive dashboards""" + + def __init__(self): + self.color_scheme = { + 'primary': '#1f77b4', + 'secondary': '#ff7f0e', + 'success': '#2ca02c', + 'danger': '#d62728', + 'warning': '#ff7f0e', + 'info': '#17a2b8', + 'background': '#f8f9fa' + } + + def create_price_chart(self, data: pd.DataFrame, symbol: str, analysis: Dict = None) -> go.Figure: + """ + Create comprehensive price chart with technical indicators + + Args: + data: Stock price data + symbol: Stock symbol + analysis: Technical analysis results + + Returns: + Plotly figure object + """ + if data.empty: + return self._create_empty_chart("No data available") + + # Create subplots + fig = make_subplots( + rows=3, cols=1, + shared_xaxes=True, + vertical_spacing=0.05, + subplot_titles=(f'{symbol} Price Chart', 'Volume', 'Technical Indicators'), + row_heights=[0.6, 0.2, 0.2] + ) + + # Main price chart (candlestick) + fig.add_trace( + go.Candlestick( + x=data.index, + open=data['Open'], + high=data['High'], + low=data['Low'], + close=data['Close'], + name='Price', + increasing_line_color=self.color_scheme['success'], + decreasing_line_color=self.color_scheme['danger'] + ), + row=1, col=1 + ) + + # Add moving averages if available + if 'SMA_20' in data.columns: + fig.add_trace( + go.Scatter( + x=data.index, + y=data['SMA_20'], + mode='lines', + name='SMA 20', + line=dict(color=self.color_scheme['primary'], width=1) + ), + row=1, col=1 + ) + + if 'SMA_50' in data.columns: + fig.add_trace( + go.Scatter( + x=data.index, + y=data['SMA_50'], + mode='lines', + name='SMA 50', + line=dict(color=self.color_scheme['secondary'], width=1) + ), + row=1, col=1 + ) + + # Volume chart + colors = ['red' if close < open else 'green' for close, open in zip(data['Close'], data['Open'])] + fig.add_trace( + go.Bar( + x=data.index, + y=data['Volume'], + name='Volume', + marker_color=colors, + opacity=0.7 + ), + row=2, col=1 + ) + + # Technical indicators (RSI if available in analysis) + if analysis and 'rsi' in analysis: + # Create RSI line (simplified - would need full RSI calculation for time series) + rsi_value = analysis['rsi'] + rsi_line = [rsi_value] * len(data) + + fig.add_trace( + go.Scatter( + x=data.index, + y=rsi_line, + mode='lines', + name=f'RSI ({rsi_value:.1f})', + line=dict(color=self.color_scheme['info'], width=2) + ), + row=3, col=1 + ) + + # Add RSI reference lines + fig.add_hline(y=70, line_dash="dash", line_color="red", opacity=0.5, row=3, col=1) + fig.add_hline(y=30, line_dash="dash", line_color="green", opacity=0.5, row=3, col=1) + + # Update layout + fig.update_layout( + title=f'{symbol} Stock Analysis Dashboard', + xaxis_title='Date', + yaxis_title='Price ($)', + template='plotly_white', + height=800, + showlegend=True, + hovermode='x unified' + ) + + # Remove rangeslider for cleaner look + fig.update_layout(xaxis_rangeslider_visible=False) + + return fig + + def create_performance_chart(self, data: pd.DataFrame, symbol: str, analysis: Dict) -> go.Figure: + """ + Create performance analysis chart + + Args: + data: Stock price data + symbol: Stock symbol + analysis: Analysis results with performance metrics + + Returns: + Plotly figure object + """ + if data.empty: + return self._create_empty_chart("No data available for performance analysis") + + # Calculate cumulative returns + daily_returns = data['Close'].pct_change().fillna(0) + cumulative_returns = (1 + daily_returns).cumprod() - 1 + + fig = go.Figure() + + # Cumulative returns line + fig.add_trace( + go.Scatter( + x=data.index, + y=cumulative_returns * 100, + mode='lines', + name='Cumulative Returns (%)', + line=dict(color=self.color_scheme['primary'], width=2), + fill='tonexty', + fillcolor='rgba(31, 119, 180, 0.1)' + ) + ) + + # Add benchmark line (0% return) + fig.add_hline(y=0, line_dash="dash", line_color="gray", opacity=0.5) + + # Add performance annotations + if analysis: + total_return = analysis.get('total_return_pct', 0) + fig.add_annotation( + x=data.index[-1], + y=total_return, + text=f"Total Return: {total_return:.1f}%", + showarrow=True, + arrowhead=2, + arrowcolor=self.color_scheme['primary'], + bgcolor="white", + bordercolor=self.color_scheme['primary'] + ) + + fig.update_layout( + title=f'{symbol} Performance Analysis', + xaxis_title='Date', + yaxis_title='Cumulative Returns (%)', + template='plotly_white', + height=500, + hovermode='x' + ) + + return fig + + def create_risk_analysis_chart(self, analysis: Dict, symbol: str) -> go.Figure: + """ + Create risk analysis visualization + + Args: + analysis: Analysis results with risk metrics + symbol: Stock symbol + + Returns: + Plotly figure object + """ + if not analysis or 'error' in analysis: + return self._create_empty_chart("No risk data available") + + # Prepare risk metrics + risk_metrics = { + 'Volatility (Annual)': analysis.get('volatility_annualized', 0), + 'Max Drawdown': abs(analysis.get('max_drawdown', 0)), + 'VaR 95%': abs(analysis.get('var_95', 0)), + 'VaR 99%': abs(analysis.get('var_99', 0)) + } + + # Create radar chart for risk metrics + categories = list(risk_metrics.keys()) + values = list(risk_metrics.values()) + + fig = go.Figure() + + fig.add_trace(go.Scatterpolar( + r=values, + theta=categories, + fill='toself', + name=f'{symbol} Risk Profile', + line_color=self.color_scheme['danger'], + fillcolor='rgba(214, 39, 40, 0.1)' + )) + + fig.update_layout( + polar=dict( + radialaxis=dict( + visible=True, + range=[0, max(values) * 1.2] if values else [0, 100] + ) + ), + title=f'{symbol} Risk Analysis Chart', + template='plotly_white', + height=500 + ) + + return fig + + def create_comparison_chart(self, data_dict: Dict[str, pd.DataFrame], symbols: List[str]) -> go.Figure: + """ + Create comparison chart for multiple stocks + + Args: + data_dict: Dictionary of stock data {symbol: dataframe} + symbols: List of stock symbols to compare + + Returns: + Plotly figure object + """ + fig = go.Figure() + + colors = [self.color_scheme['primary'], self.color_scheme['secondary'], + self.color_scheme['success'], self.color_scheme['danger']] + + for i, symbol in enumerate(symbols): + if symbol in data_dict and not data_dict[symbol].empty: + data = data_dict[symbol] + # Normalize prices to start at 100 for comparison + normalized_prices = (data['Close'] / data['Close'].iloc[0]) * 100 + + fig.add_trace( + go.Scatter( + x=data.index, + y=normalized_prices, + mode='lines', + name=symbol, + line=dict(color=colors[i % len(colors)], width=2) + ) + ) + + fig.update_layout( + title='Stock Price Comparison (Normalized to 100)', + xaxis_title='Date', + yaxis_title='Normalized Price', + template='plotly_white', + height=600, + hovermode='x unified' + ) + + return fig + + def create_sector_analysis_chart(self, sector_data: Dict) -> go.Figure: + """ + Create sector analysis visualization + + Args: + sector_data: Dictionary with sector analysis data + + Returns: + Plotly figure object + """ + # This would typically show sector performance, P/E ratios, etc. + # For now, create a placeholder + fig = go.Figure() + + fig.add_annotation( + x=0.5, y=0.5, + text="Sector Analysis
Coming Soon", + showarrow=False, + font=dict(size=20), + xref="paper", yref="paper" + ) + + fig.update_layout( + title='Sector Analysis Dashboard', + template='plotly_white', + height=400, + showticklabels=False + ) + + return fig + + def create_trading_signals_chart(self, data: pd.DataFrame, analysis: Dict, trading_decision: Dict, symbol: str) -> go.Figure: + """ + Create trading signals visualization + + Args: + data: Stock price data + analysis: Technical analysis results + trading_decision: Trading recommendation + symbol: Stock symbol + + Returns: + Plotly figure object + """ + if data.empty: + return self._create_empty_chart("No data available for trading signals") + + fig = go.Figure() + + # Price line + fig.add_trace( + go.Scatter( + x=data.index, + y=data['Close'], + mode='lines', + name='Price', + line=dict(color=self.color_scheme['primary'], width=2) + ) + ) + + # Add trading signal + recommendation = trading_decision.get('recommendation', 'HOLD') + current_price = data['Close'].iloc[-1] + + signal_color = { + 'BUY': self.color_scheme['success'], + 'SELL': self.color_scheme['danger'], + 'HOLD': self.color_scheme['warning'] + }.get(recommendation, self.color_scheme['info']) + + fig.add_trace( + go.Scatter( + x=[data.index[-1]], + y=[current_price], + mode='markers', + name=f'{recommendation} Signal', + marker=dict( + color=signal_color, + size=15, + symbol='triangle-up' if recommendation == 'BUY' else + 'triangle-down' if recommendation == 'SELL' else 'circle' + ) + ) + ) + + # Add price target if available + price_target = trading_decision.get('price_target') + if price_target: + fig.add_hline( + y=price_target, + line_dash="dash", + line_color=self.color_scheme['success'], + annotation_text=f"Target: ${price_target:.2f}" + ) + + # Add stop loss if available + stop_loss = trading_decision.get('stop_loss') + if stop_loss: + fig.add_hline( + y=stop_loss, + line_dash="dash", + line_color=self.color_scheme['danger'], + annotation_text=f"Stop Loss: ${stop_loss:.2f}" + ) + + fig.update_layout( + title=f'{symbol} Trading Signals', + xaxis_title='Date', + yaxis_title='Price ($)', + template='plotly_white', + height=500, + hovermode='x' + ) + + return fig + + def create_dashboard_summary(self, symbol: str, analysis: Dict, trading_decision: Dict, sharia_compliance: Dict) -> Dict: + """ + Create summary metrics for dashboard display + + Args: + symbol: Stock symbol + analysis: Technical analysis results + trading_decision: Trading recommendation + sharia_compliance: Sharia compliance results + + Returns: + Dictionary with summary metrics + """ + summary = { + 'symbol': symbol, + 'current_price': analysis.get('current_price', 0), + 'total_return': analysis.get('total_return_pct', 0), + 'volatility': analysis.get('volatility_annualized', 0), + 'trading_recommendation': trading_decision.get('recommendation', 'HOLD'), + 'trading_confidence': trading_decision.get('confidence', 0) * 100, + 'sharia_ruling': sharia_compliance.get('ruling', 'UNCERTAIN'), + 'sharia_confidence': sharia_compliance.get('confidence', 0) * 100, + 'risk_level': trading_decision.get('risk_level', 'medium'), + 'trend_direction': analysis.get('trend_direction', 'unknown'), + 'rsi': analysis.get('rsi', 50), + 'max_drawdown': analysis.get('max_drawdown', 0) + } + + return summary + + def _create_empty_chart(self, message: str) -> go.Figure: + """Create an empty chart with a message""" + fig = go.Figure() + + fig.add_annotation( + x=0.5, y=0.5, + text=message, + showarrow=False, + font=dict(size=16), + xref="paper", yref="paper" + ) + + fig.update_layout( + template='plotly_white', + height=400, + showticklabels=False + ) + + return fig + +# Global instance for easy import +chart_generator = StockChartGenerator() + +# Convenience functions +def create_price_chart(data: pd.DataFrame, symbol: str, analysis: Dict = None) -> go.Figure: + """Convenience function to create price chart""" + return chart_generator.create_price_chart(data, symbol, analysis) + +def create_performance_chart(data: pd.DataFrame, symbol: str, analysis: Dict) -> go.Figure: + """Convenience function to create performance chart""" + return chart_generator.create_performance_chart(data, symbol, analysis) + +def create_trading_signals_chart(data: pd.DataFrame, analysis: Dict, trading_decision: Dict, symbol: str) -> go.Figure: + """Convenience function to create trading signals chart""" + return chart_generator.create_trading_signals_chart(data, analysis, trading_decision, symbol) diff --git a/week4/community-contributions/ai_stock_trading/tools/fetching.py b/week4/community-contributions/ai_stock_trading/tools/fetching.py new file mode 100644 index 0000000..5966e8e --- /dev/null +++ b/week4/community-contributions/ai_stock_trading/tools/fetching.py @@ -0,0 +1,384 @@ +""" +Stock Data Fetching Module + +This module handles fetching stock data from various sources including yfinance +and provides enhanced data retrieval capabilities for different markets. +""" + +import yfinance as yf +import pandas as pd +import numpy as np +import requests +from typing import Dict, List, Optional, Tuple +import warnings + +warnings.filterwarnings('ignore') + +class StockDataFetcher: + """Enhanced stock data fetcher with multi-market support""" + + # Stock symbols for different markets + STOCK_SYMBOLS = { + 'USA': { + # Technology + 'Apple Inc.': 'AAPL', + 'Microsoft Corporation': 'MSFT', + 'NVIDIA Corporation': 'NVDA', + 'Alphabet Inc. (Class A)': 'GOOGL', + 'Alphabet Inc. (Class C)': 'GOOG', + 'Meta Platforms Inc.': 'META', + 'Tesla Inc.': 'TSLA', + 'Amazon.com Inc.': 'AMZN', + 'Netflix Inc.': 'NFLX', + 'Adobe Inc.': 'ADBE', + 'Salesforce Inc.': 'CRM', + 'Oracle Corporation': 'ORCL', + 'Cisco Systems Inc.': 'CSCO', + 'Intel Corporation': 'INTC', + 'Advanced Micro Devices': 'AMD', + 'Qualcomm Inc.': 'QCOM', + 'Texas Instruments': 'TXN', + 'Broadcom Inc.': 'AVGO', + 'ServiceNow Inc.': 'NOW', + 'Palantir Technologies': 'PLTR', + + # Financial Services + 'JPMorgan Chase & Co.': 'JPM', + 'Bank of America Corp': 'BAC', + 'Wells Fargo & Company': 'WFC', + 'Goldman Sachs Group': 'GS', + 'Morgan Stanley': 'MS', + 'Citigroup Inc.': 'C', + 'American Express Company': 'AXP', + 'Berkshire Hathaway Inc.': 'BRK.B', + 'BlackRock Inc.': 'BLK', + 'Charles Schwab Corporation': 'SCHW', + 'Visa Inc.': 'V', + 'Mastercard Inc.': 'MA', + + # Healthcare & Pharmaceuticals + 'Johnson & Johnson': 'JNJ', + 'UnitedHealth Group': 'UNH', + 'Pfizer Inc.': 'PFE', + 'AbbVie Inc.': 'ABBV', + 'Merck & Co Inc.': 'MRK', + 'Eli Lilly and Company': 'LLY', + 'Abbott Laboratories': 'ABT', + 'Thermo Fisher Scientific': 'TMO', + 'Danaher Corporation': 'DHR', + 'Gilead Sciences Inc.': 'GILD', + + # Consumer & Retail + 'Walmart Inc.': 'WMT', + 'Procter & Gamble Co': 'PG', + 'Coca-Cola Company': 'KO', + 'PepsiCo Inc.': 'PEP', + 'Home Depot Inc.': 'HD', + 'McDonald\'s Corporation': 'MCD', + 'Nike Inc.': 'NKE', + 'Costco Wholesale Corp': 'COST', + 'TJX Companies Inc.': 'TJX', + 'Lowe\'s Companies Inc.': 'LOW', + + # Industrial & Energy + 'Exxon Mobil Corporation': 'XOM', + 'Chevron Corporation': 'CVX', + 'ConocoPhillips': 'COP', + 'Caterpillar Inc.': 'CAT', + 'Boeing Company': 'BA', + 'General Electric': 'GE', + 'Honeywell International': 'HON', + 'Deere & Company': 'DE', + 'Union Pacific Corporation': 'UNP', + 'Lockheed Martin Corp': 'LMT', + + # Communication & Media + 'AT&T Inc.': 'T', + 'Verizon Communications': 'VZ', + 'T-Mobile US Inc.': 'TMUS', + 'Comcast Corporation': 'CMCSA', + 'Walt Disney Company': 'DIS' + }, + 'Egypt': { + # Banking & Financial Services + 'Commercial International Bank': 'COMI.CA', + 'QNB Alahli Bank': 'QNBE.CA', + 'Housing and Development Bank': 'HDBK.CA', + 'Abu Dhabi Islamic Bank Egypt': 'ADIB.CA', + 'Egyptian Gulf Bank': 'EGBE.CA', + + # Real Estate & Construction + 'Talaat Moustafa Group Holding': 'TMGH.CA', + 'Palm Hills Developments': 'PHDC.CA', + 'Orascom Construction': 'ORAS.CA', + 'Orascom Development Holding': 'ORHD.CA', + 'Six of October Development': 'SCTS.CA', + 'Heliopolis Housing': 'HELI.CA', + 'Rooya Group': 'RMDA.CA', + + # Industrial & Manufacturing + 'Eastern Company': 'EAST.CA', + 'El Sewedy Electric Company': 'SWDY.CA', + 'Ezz Steel': 'ESRS.CA', + 'Iron and Steel Company': 'IRON.CA', + 'Alexandria Containers': 'ALCN.CA', + 'Sidi Kerir Petrochemicals': 'SKPC.CA', + + # Chemicals & Fertilizers + 'Abu Qir Fertilizers and Chemical Industries': 'ABUK.CA', + 'Egyptian Chemical Industries (Kima)': 'KIMA.CA', + 'Misr Fertilizers Production': 'MFPC.CA', + + # Telecommunications & Technology + 'Telecom Egypt': 'ETEL.CA', + 'Raya Holding': 'RAYA.CA', + 'E-Finance for Digital Payments': 'EFIH.CA', + 'Fawry for Banking Technology': 'FWRY.CA', + + # Food & Beverages + 'Juhayna Food Industries': 'JUFO.CA', + 'Edita Food Industries': 'EFID.CA', + 'Cairo Poultry Company': 'POUL.CA', + 'Upper Egypt Flour Mills': 'UEFM.CA', + 'Ismailia Misr Poultry': 'ISPH.CA', + + # Healthcare & Pharmaceuticals + 'Cleopatra Hospital Group': 'CLHO.CA', + 'Cairo Pharmaceuticals': 'PHAR.CA', + + # Energy & Utilities + 'Egyptian Natural Gas Company': 'EGAS.CA', + 'Suez Cement Company': 'SCEM.CA', + 'Arabian Cement Company': 'ARCC.CA', + + # Investment & Holding Companies + 'Egyptian Financial Group-Hermes': 'HRHO.CA', + 'Citadel Capital': 'CCAP.CA', + 'Beltone Financial Holding': 'BTFH.CA' + } + } + + # Currency mapping for different markets + MARKET_CURRENCIES = { + 'USA': 'USD', + 'Egypt': 'EGP' + } + + def __init__(self): + self.cache = {} + + def get_available_stocks(self, country: str) -> Dict[str, str]: + """Get available stocks for a specific country""" + return self.STOCK_SYMBOLS.get(country, {}) + + def get_market_currency(self, country: str) -> str: + """Get the currency for a specific market""" + return self.MARKET_CURRENCIES.get(country, 'USD') + + def format_price_with_currency(self, price: float, country: str) -> str: + """Format price with appropriate currency symbol""" + currency = self.get_market_currency(country) + if currency == 'EGP': + return f"{price:.2f} EGP" + elif currency == 'USD': + return f"${price:.2f}" + else: + return f"{price:.2f} {currency}" + + def fetch_stock_data(self, symbol: str, period: str = "1y", interval: str = "1d") -> pd.DataFrame: + """ + Fetch historical stock data with enhanced error handling + + Args: + symbol: Stock symbol (e.g., 'AAPL', 'COMI.CA') + period: Time period ('1d', '5d', '1mo', '3mo', '6mo', '1y', '2y', '5y', '10y', 'ytd', 'max') + interval: Data interval ('1m', '2m', '5m', '15m', '30m', '60m', '90m', '1h', '1d', '5d', '1wk', '1mo', '3mo') + + Returns: + DataFrame with OHLCV data + """ + cache_key = f"{symbol}_{period}_{interval}" + + # Check cache first + if cache_key in self.cache: + return self.cache[cache_key] + + try: + # Create ticker object + ticker = yf.Ticker(symbol) + + # Fetch historical data + data = ticker.history(period=period, interval=interval) + + if data.empty: + print(f"⚠️ No data found for {symbol}") + return pd.DataFrame() + + # Clean and enhance data + data = self._clean_data(data) + + # Cache the result + self.cache[cache_key] = data + + print(f"✅ Successfully fetched {len(data)} data points for {symbol} ({period})") + return data + + except Exception as e: + print(f"❌ Error fetching data for {symbol}: {str(e)}") + return pd.DataFrame() + + def get_stock_info(self, symbol: str, country: Optional[str] = None) -> Dict: + """ + Get comprehensive stock information + + Args: + symbol: Stock symbol + country: Market country (USA, Egypt) for currency handling + + Returns: + Dictionary with stock information + """ + try: + ticker = yf.Ticker(symbol) + info = ticker.info + + # Detect country if not provided + if country is None: + country = self._detect_country_from_symbol(symbol) + + # Get market currency + market_currency = self.get_market_currency(country) + + # Extract key information + stock_info = { + 'symbol': symbol, + 'company_name': info.get('longName', 'N/A'), + 'sector': info.get('sector', 'N/A'), + 'industry': info.get('industry', 'N/A'), + 'market_cap': info.get('marketCap', 0), + 'pe_ratio': info.get('trailingPE', 0), + 'dividend_yield': info.get('dividendYield', 0), + 'beta': info.get('beta', 0), + 'fifty_two_week_high': info.get('fiftyTwoWeekHigh', 0), + 'fifty_two_week_low': info.get('fiftyTwoWeekLow', 0), + 'current_price': info.get('currentPrice', 0), + 'currency': market_currency, # Use detected market currency + 'exchange': info.get('exchange', 'N/A'), + 'country': country, + 'market_country': country # Add explicit market country + } + + return stock_info + + except Exception as e: + print(f"❌ Error fetching info for {symbol}: {str(e)}") + return {'symbol': symbol, 'error': str(e)} + + def _detect_country_from_symbol(self, symbol: str) -> str: + """ + Detect country from stock symbol + + Args: + symbol: Stock symbol + + Returns: + Country name (USA or Egypt) + """ + # Check if symbol exists in any country's stock list + for country, stocks in self.STOCK_SYMBOLS.items(): + if symbol in stocks.values(): + return country + + # Default to USA if not found + return 'USA' + + def fetch_multiple_periods(self, symbol: str) -> Dict[str, pd.DataFrame]: + """ + Fetch data for multiple time periods + + Args: + symbol: Stock symbol + + Returns: + Dictionary with DataFrames for different periods + """ + periods = ['1mo', '1y', '5y'] + data = {} + + for period in periods: + df = self.fetch_stock_data(symbol, period) + if not df.empty: + data[period] = df + + return data + + def _clean_data(self, data: pd.DataFrame) -> pd.DataFrame: + """ + Clean and enhance the stock data + + Args: + data: Raw stock data DataFrame + + Returns: + Cleaned DataFrame + """ + # Remove rows with all NaN values + data = data.dropna(how='all') + + # Forward fill missing values + data = data.fillna(method='ffill') + + # Add technical indicators + if len(data) > 0: + # Simple moving averages + if len(data) >= 20: + data['SMA_20'] = data['Close'].rolling(window=20).mean() + if len(data) >= 50: + data['SMA_50'] = data['Close'].rolling(window=50).mean() + + # Daily returns + data['Daily_Return'] = data['Close'].pct_change() + + # Price change from previous day + data['Price_Change'] = data['Close'].diff() + data['Price_Change_Pct'] = (data['Price_Change'] / data['Close'].shift(1)) * 100 + + return data + + def get_real_time_price(self, symbol: str) -> Optional[float]: + """ + Get real-time stock price + + Args: + symbol: Stock symbol + + Returns: + Current stock price or None if error + """ + try: + ticker = yf.Ticker(symbol) + data = ticker.history(period="1d", interval="1m") + + if not data.empty: + return float(data['Close'].iloc[-1]) + return None + + except Exception as e: + print(f"❌ Error fetching real-time price for {symbol}: {str(e)}") + return None + +# Global instance for easy import +stock_fetcher = StockDataFetcher() + +# Convenience functions +def fetch_stock_data(symbol: str, period: str = "1y", interval: str = "1d") -> pd.DataFrame: + """Convenience function to fetch stock data""" + return stock_fetcher.fetch_stock_data(symbol, period, interval) + +def get_available_stocks(country: str) -> Dict[str, str]: + """Convenience function to get available stocks""" + return stock_fetcher.get_available_stocks(country) + +def get_stock_info(symbol: str) -> Dict: + """Convenience function to get stock info""" + return stock_fetcher.get_stock_info(symbol) diff --git a/week4/community-contributions/ai_stock_trading/tools/sharia_compliance.py b/week4/community-contributions/ai_stock_trading/tools/sharia_compliance.py new file mode 100644 index 0000000..f0f3119 --- /dev/null +++ b/week4/community-contributions/ai_stock_trading/tools/sharia_compliance.py @@ -0,0 +1,591 @@ +""" +Sharia Compliance Module + +This module provides comprehensive Islamic finance compliance checking +for stocks and investments according to Islamic principles. +""" + +import os +import json +import requests +from typing import Dict, List, Optional, Tuple +import pandas as pd +from openai import OpenAI +from dotenv import load_dotenv +from bs4 import BeautifulSoup +import time +import re + +# Load environment variables +load_dotenv() + +class ShariaComplianceChecker: + """Enhanced Sharia compliance checker for Islamic investing""" + + def __init__(self): + self.client = OpenAI(api_key=os.getenv('OPENAI_API_KEY')) + + # Sharia compliance criteria weights + self.criteria_weights = { + 'business_activity': 0.40, # Most important + 'financial_ratios': 0.30, + 'debt_levels': 0.20, + 'revenue_sources': 0.10 + } + + # Prohibited business activities (comprehensive list) + self.prohibited_activities = { + # Core prohibitions + 'alcohol', 'alcoholic_beverages', 'wine', 'beer', 'spirits', 'liquor', + 'gambling', 'casino', 'lottery', 'betting', 'gaming', 'poker', + 'tobacco', 'cigarettes', 'smoking', 'nicotine', + 'pork', 'pig_farming', 'swine', 'ham', 'bacon', + 'adult_entertainment', 'pornography', 'strip_clubs', 'escort_services', + + # Financial prohibitions + 'conventional_banking', 'interest_based_finance', 'usury', 'riba', + 'conventional_insurance', 'life_insurance', 'derivatives_trading', + 'forex_trading', 'currency_speculation', 'margin_trading', + 'short_selling', 'day_trading', 'high_frequency_trading', + + # Weapons and defense + 'weapons', 'arms_manufacturing', 'defense_contractors', 'military_equipment', + 'ammunition', 'explosives', 'nuclear_weapons', + + # Other prohibitions + 'nightclubs', 'bars', 'entertainment_venues', 'music_industry', + 'film_industry', 'media_entertainment', 'advertising_haram_products' + } + + # Sharia-compliant sectors (generally accepted) + self.compliant_sectors = { + 'technology', 'healthcare', 'pharmaceuticals', 'telecommunications', + 'utilities', 'real_estate', 'construction', 'manufacturing', + 'retail', 'food_beverages', 'transportation', 'energy_renewable' + } + + # Questionable sectors (need detailed analysis) + self.questionable_sectors = { + 'financial_services', 'media', 'hotels', 'airlines', + 'oil_gas', 'mining', 'chemicals', 'entertainment', + 'restaurants', 'hospitality', 'advertising' + } + + # AAOIFI and DSN Sharia standards + self.sharia_standards = { + 'max_debt_to_assets': 0.33, # 33% maximum debt-to-assets ratio + 'max_interest_income': 0.05, # 5% maximum interest income + 'max_non_compliant_income': 0.05, # 5% maximum non-compliant income + 'min_tangible_assets': 0.20 # 20% minimum tangible assets + } + + def _search_company_business_activities(self, company_name: str, symbol: str) -> Dict: + """ + Search web for company's business activities to verify Sharia compliance + + Args: + company_name: Company name + symbol: Stock symbol + + Returns: + Dictionary with business activity information + """ + try: + # Search query for company business activities + search_queries = [ + f"{company_name} business activities products services", + f"{company_name} {symbol} what does company do", + f"{company_name} revenue sources business model" + ] + + business_info = { + 'activities': [], + 'products': [], + 'services': [], + 'revenue_sources': [], + 'prohibited_found': [], + 'confidence': 0.5 + } + + for query in search_queries[:1]: # Limit to 1 search to avoid rate limits + try: + # Simple web search simulation (in production, use proper search API) + search_url = f"https://www.google.com/search?q={query.replace(' ', '+')}" + headers = { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' + } + + # For now, return basic analysis based on company name and sector + # In production, implement actual web scraping with proper rate limiting + business_info['confidence'] = 0.6 + break + + except Exception as e: + print(f"Web search error: {e}") + continue + + return business_info + + except Exception as e: + print(f"Error in business activity search: {e}") + return {'activities': [], 'prohibited_found': [], 'confidence': 0.3} + + def _estimate_debt_ratio(self, stock_info: Dict) -> float: + """ + Estimate debt-to-assets ratio based on available information + + Args: + stock_info: Stock information dictionary + + Returns: + Estimated debt-to-assets ratio + """ + try: + # In production, this would fetch actual balance sheet data + # For now, estimate based on sector and other indicators + sector = stock_info.get('sector', '').lower() + industry = stock_info.get('industry', '').lower() + + # High debt sectors + if any(x in sector or x in industry for x in ['utility', 'telecom', 'airline', 'real estate']): + return 0.45 # Typically higher debt + + # Medium debt sectors + elif any(x in sector or x in industry for x in ['manufacturing', 'retail', 'energy']): + return 0.25 + + # Low debt sectors + elif any(x in sector or x in industry for x in ['technology', 'healthcare', 'software']): + return 0.15 + + # Financial sector (different calculation) + elif 'financial' in sector or 'bank' in sector: + return 0.8 # Banks have high leverage by nature + + # Default estimate + return 0.3 + + except Exception: + return 0.3 # Conservative default + + def _check_business_activity(self, stock_info: Dict) -> float: + """ + Check if the company's primary business activity is Sharia-compliant + + Returns: + Score from 0.0 (non-compliant) to 1.0 (fully compliant) + """ + sector = stock_info.get('sector', '').lower() + industry = stock_info.get('industry', '').lower() + company_name = stock_info.get('company_name', '').lower() + + # Check for explicitly prohibited activities + for prohibited in self.prohibited_activities: + if (prohibited.replace('_', ' ') in sector or + prohibited.replace('_', ' ') in industry or + prohibited.replace('_', ' ') in company_name): + return 0.0 + + # Check for compliant sectors + for compliant in self.compliant_sectors: + if (compliant.replace('_', ' ') in sector or + compliant.replace('_', ' ') in industry): + return 1.0 + + # Check for questionable sectors + for questionable in self.questionable_sectors: + if (questionable.replace('_', ' ') in sector or + questionable.replace('_', ' ') in industry): + return 0.5 + + # Default for unknown sectors + return 0.7 + + def check_sharia_compliance(self, symbol: str, stock_info: Dict, analysis: Dict) -> Dict: + """ + Comprehensive Sharia compliance check + + Args: + symbol: Stock symbol + stock_info: Stock information + analysis: Technical analysis results + + Returns: + Dictionary with compliance assessment + """ + try: + # Business activity screening + business_score = self._check_business_activity(stock_info) + + # Financial ratios screening + financial_score = self._check_financial_ratios(stock_info, analysis) + + # Debt levels screening + debt_score = self._check_debt_levels(stock_info) + + # Revenue sources screening + revenue_score = self._check_revenue_sources(stock_info) + + # Calculate weighted compliance score + total_score = ( + business_score * self.criteria_weights['business_activity'] + + financial_score * self.criteria_weights['financial_ratios'] + + debt_score * self.criteria_weights['debt_levels'] + + revenue_score * self.criteria_weights['revenue_sources'] + ) + + # Get AI-powered detailed analysis + ai_analysis = self._get_ai_sharia_analysis(symbol, stock_info) + + # Determine final ruling + ruling = self._determine_ruling(total_score, ai_analysis) + + return { + 'symbol': symbol, + 'ruling': ruling['status'], + 'confidence': ruling['confidence'], + 'compliance_score': total_score, + 'detailed_scores': { + 'business_activity': business_score, + 'financial_ratios': financial_score, + 'debt_levels': debt_score, + 'revenue_sources': revenue_score + }, + 'reasoning': ruling['reasoning'], + 'key_concerns': ruling.get('concerns', []), + 'recommendations': ruling.get('recommendations', []), + 'ai_analysis': ai_analysis.get('analysis', ''), + 'scholar_consultation_advised': ruling.get('scholar_consultation', False), + 'alternative_suggestions': ruling.get('alternatives', []) + } + + except Exception as e: + return { + 'symbol': symbol, + 'ruling': 'UNCERTAIN', + 'confidence': 0.0, + 'reasoning': f'Error in Sharia compliance analysis: {str(e)}', + 'error': str(e) + } + + def _check_business_activity(self, stock_info: Dict) -> float: + """ + Check if the company's primary business activity is Sharia-compliant + + Returns: + Score from 0.0 (non-compliant) to 1.0 (fully compliant) + """ + sector = stock_info.get('sector', '').lower() + industry = stock_info.get('industry', '').lower() + company_name = stock_info.get('company_name', '').lower() + + # Check for explicitly prohibited activities + for prohibited in self.prohibited_activities: + if (prohibited.replace('_', ' ') in sector or + prohibited.replace('_', ' ') in industry or + prohibited.replace('_', ' ') in company_name): + return 0.0 + + # Check for compliant sectors + for compliant in self.compliant_sectors: + if (compliant.replace('_', ' ') in sector or + compliant.replace('_', ' ') in industry): + return 1.0 + + # Check for questionable sectors + for questionable in self.questionable_sectors: + if (questionable.replace('_', ' ') in sector or + questionable.replace('_', ' ') in industry): + return 0.5 + + # Default for unknown sectors + return 0.7 + + def _check_financial_ratios(self, stock_info: Dict, analysis: Dict) -> float: + """ + Check financial ratios according to AAOIFI and DSN Sharia standards + + AAOIFI/DSN Sharia screening ratios: + - Debt/Total Assets < 33% + - Interest Income/Total Revenue < 5% + - Non-compliant Income/Total Revenue < 5% + - Tangible Assets/Total Assets > 20% + + Returns: + Score from 0.0 to 1.0 + """ + score = 1.0 + penalties = [] + + try: + # Get financial metrics (these would come from detailed financial data) + market_cap = stock_info.get('market_cap', 0) + pe_ratio = stock_info.get('pe_ratio', 0) + + # Debt-to-Assets ratio check + # Note: In production, fetch actual balance sheet data + debt_to_assets = self._estimate_debt_ratio(stock_info) + if debt_to_assets > self.sharia_standards['max_debt_to_assets']: + penalty = min(0.5, (debt_to_assets - self.sharia_standards['max_debt_to_assets']) * 2) + score -= penalty + penalties.append(f"High debt ratio: {debt_to_assets:.1%} > {self.sharia_standards['max_debt_to_assets']:.1%}") + + # Interest income check (for financial companies) + sector = stock_info.get('sector', '').lower() + if 'financial' in sector or 'bank' in sector: + # Financial companies likely have significant interest income + score -= 0.3 + penalties.append("Financial sector - likely high interest income") + + # Industry-specific checks + industry = stock_info.get('industry', '').lower() + if any(prohibited in industry for prohibited in ['insurance', 'casino', 'alcohol', 'tobacco']): + score = 0.0 + penalties.append(f"Prohibited industry: {industry}") + + return max(0.0, score) + + except Exception as e: + print(f"Error in financial ratio analysis: {e}") + return 0.5 # Default moderate score if analysis fails + # For now, we'll use available basic metrics and estimate + + # PE ratio check (very high PE might indicate speculation) + pe_ratio = stock_info.get('pe_ratio', 0) + if pe_ratio > 50: + score -= 0.2 + elif pe_ratio > 30: + score -= 0.1 + + # Beta check (high beta indicates high speculation/volatility) + beta = stock_info.get('beta', 1.0) + if beta > 2.0: + score -= 0.3 + elif beta > 1.5: + score -= 0.1 + + # Volatility check from analysis + volatility = analysis.get('volatility_annualized', 0) + if volatility > 60: + score -= 0.2 + elif volatility > 40: + score -= 0.1 + + return max(0.0, score) + + def _check_debt_levels(self, stock_info: Dict) -> float: + """ + Check debt levels according to Sharia standards + + Returns: + Score from 0.0 to 1.0 + """ + # Note: In a real implementation, you would fetch debt-to-assets ratio + # For now, we'll use sector-based estimation + + sector = stock_info.get('sector', '').lower() + + # Sectors typically with high debt + high_debt_sectors = ['utilities', 'real estate', 'telecommunications'] + medium_debt_sectors = ['manufacturing', 'transportation', 'energy'] + low_debt_sectors = ['technology', 'healthcare', 'retail'] + + if any(s in sector for s in high_debt_sectors): + return 0.6 # Assume higher debt but may still be acceptable + elif any(s in sector for s in medium_debt_sectors): + return 0.8 + elif any(s in sector for s in low_debt_sectors): + return 1.0 + else: + return 0.7 # Default assumption + + def _check_revenue_sources(self, stock_info: Dict) -> float: + """ + Check revenue sources for non-compliant income + + Returns: + Score from 0.0 to 1.0 + """ + sector = stock_info.get('sector', '').lower() + industry = stock_info.get('industry', '').lower() + + # Industries with potential non-compliant revenue + if 'financial' in sector or 'bank' in industry: + return 0.3 # Banks typically have significant interest income + elif 'insurance' in industry: + return 0.2 + elif 'hotel' in industry or 'entertainment' in industry: + return 0.6 # May have some non-compliant revenue sources + else: + return 0.9 # Assume mostly compliant revenue + + def _get_ai_sharia_analysis(self, symbol: str, stock_info: Dict) -> Dict: + """ + Get AI-powered detailed Sharia compliance analysis + + Args: + symbol: Stock symbol + stock_info: Stock information + + Returns: + Dictionary with AI analysis + """ + try: + prompt = f""" + As an Islamic finance expert, analyze the Sharia compliance of {symbol}. + + Company Information: + - Name: {stock_info.get('company_name', 'N/A')} + - Sector: {stock_info.get('sector', 'N/A')} + - Industry: {stock_info.get('industry', 'N/A')} + - Country: {stock_info.get('country', 'N/A')} + + Please analyze according to Islamic finance principles and provide: + 1. Primary business activity assessment + 2. Potential Sharia compliance concerns + 3. Revenue source analysis + 4. Debt and interest exposure concerns + 5. Overall compliance recommendation + 6. Specific areas requiring scholar consultation + 7. Alternative Sharia-compliant investment suggestions + + Format your response as JSON: + {{ + "compliance_status": "HALAL/HARAM/DOUBTFUL", + "confidence": 85, + "analysis": "Detailed analysis...", + "concerns": ["concern1", "concern2"], + "recommendations": ["rec1", "rec2"], + "scholar_consultation": true/false, + "alternatives": ["alt1", "alt2"] + }} + """ + + response = self.client.chat.completions.create( + model="gpt-4o-mini", + messages=[ + {"role": "system", "content": "You are an expert in Islamic finance and Sharia compliance for investments."}, + {"role": "user", "content": prompt} + ], + temperature=0.2, + max_tokens=1000 + ) + + ai_response = response.choices[0].message.content + + try: + if ai_response: + return json.loads(ai_response) + else: + return {'analysis': 'No AI response received', 'error': 'Empty response'} + except json.JSONDecodeError: + return {'analysis': ai_response, 'parsed_fallback': True} + + except Exception as e: + return {'analysis': f'AI analysis unavailable: {str(e)}', 'error': str(e)} + + def _determine_ruling(self, compliance_score: float, ai_analysis: Dict) -> Dict: + """ + Determine final Sharia compliance ruling + + Args: + compliance_score: Calculated compliance score + ai_analysis: AI analysis results + + Returns: + Dictionary with final ruling + """ + # Get AI recommendation if available + ai_status = ai_analysis.get('compliance_status', 'DOUBTFUL') + ai_confidence = ai_analysis.get('confidence', 50) / 100 + + # Combine algorithmic score with AI analysis + if compliance_score >= 0.8 and ai_status == 'HALAL': + status = 'HALAL' + confidence = min(0.9, (compliance_score + ai_confidence) / 2) + reasoning = "Company appears to be Sharia-compliant based on business activities and financial structure." + elif compliance_score <= 0.3 or ai_status == 'HARAM': + status = 'HARAM' + confidence = max(0.7, (1 - compliance_score + ai_confidence) / 2) + reasoning = "Company has significant Sharia compliance issues and should be avoided." + else: + status = 'DOUBTFUL' + confidence = 0.6 + reasoning = "Company has mixed compliance indicators. Consultation with Islamic scholars recommended." + + return { + 'status': status, + 'confidence': confidence, + 'reasoning': reasoning, + 'concerns': ai_analysis.get('concerns', []), + 'recommendations': ai_analysis.get('recommendations', []), + 'scholar_consultation': ai_analysis.get('scholar_consultation', status == 'DOUBTFUL'), + 'alternatives': ai_analysis.get('alternatives', []) + } + + def get_compliance_summary(self, compliance_result: Dict) -> str: + """Generate a human-readable compliance summary""" + if 'error' in compliance_result: + return f"Compliance Analysis Error: {compliance_result['error']}" + + symbol = compliance_result.get('symbol', 'Unknown') + ruling = compliance_result.get('ruling', 'UNCERTAIN') + confidence = compliance_result.get('confidence', 0) * 100 + + summary = [f"Sharia Compliance Analysis for {symbol}"] + summary.append(f"Ruling: {ruling} (Confidence: {confidence:.0f}%)") + + if ruling == 'HALAL': + summary.append("✅ This investment appears to be permissible under Islamic law.") + elif ruling == 'HARAM': + summary.append("❌ This investment should be avoided due to Sharia non-compliance.") + else: + summary.append("⚠️ This investment requires further investigation and scholar consultation.") + + # Add key concerns if any + concerns = compliance_result.get('key_concerns', []) + if concerns: + summary.append(f"Key Concerns: {', '.join(concerns)}") + + # Add recommendations + recommendations = compliance_result.get('recommendations', []) + if recommendations: + summary.append(f"Recommendations: {', '.join(recommendations[:2])}") + + return "\n".join(summary) + + def get_sharia_alternatives(self, sector: str, country: str = 'USA') -> List[str]: + """ + Get Sharia-compliant alternatives in the same sector + + Args: + sector: Company sector + country: Market country + + Returns: + List of alternative stock symbols + """ + # This would typically connect to a Sharia-compliant stock database + # For now, return some common Sharia-compliant stocks by sector + + alternatives = { + 'technology': ['AAPL', 'MSFT', 'GOOGL', 'META'], + 'healthcare': ['JNJ', 'PFE', 'UNH', 'ABBV'], + 'consumer': ['PG', 'KO', 'PEP', 'WMT'], + 'industrial': ['BA', 'CAT', 'GE', 'MMM'] + } + + sector_lower = sector.lower() + for key, stocks in alternatives.items(): + if key in sector_lower: + return stocks[:3] # Return top 3 alternatives + + return [] + +# Global instance for easy import +sharia_checker = ShariaComplianceChecker() + +# Convenience function +def check_sharia_compliance(symbol: str, stock_info: Dict, analysis: Dict) -> Dict: + """Convenience function to check Sharia compliance""" + return sharia_checker.check_sharia_compliance(symbol, stock_info, analysis) diff --git a/week4/community-contributions/ai_stock_trading/tools/trading_decisions.py b/week4/community-contributions/ai_stock_trading/tools/trading_decisions.py new file mode 100644 index 0000000..05b4255 --- /dev/null +++ b/week4/community-contributions/ai_stock_trading/tools/trading_decisions.py @@ -0,0 +1,491 @@ +""" +Trading Decisions Module + +This module provides AI-powered trading recommendations using OpenAI +and advanced algorithmic decision-making based on technical analysis. +""" + +import os +import json +from typing import Dict, List, Optional, Tuple +import pandas as pd +import numpy as np +from openai import OpenAI +from dotenv import load_dotenv + +# Load environment variables +load_dotenv() + +class TradingDecisionEngine: + """Enhanced trading decision engine with AI and algorithmic analysis""" + + def __init__(self): + self.client = OpenAI(api_key=os.getenv('OPENAI_API_KEY')) + + # Trading signal weights + self.signal_weights = { + 'trend': 0.25, + 'momentum': 0.20, + 'volume': 0.15, + 'volatility': 0.15, + 'technical': 0.25 + } + + def get_trading_recommendation(self, symbol: str, analysis: Dict, stock_info: Dict) -> Dict: + """ + Get comprehensive trading recommendation + + Args: + symbol: Stock symbol + analysis: Technical analysis results + stock_info: Stock information + + Returns: + Dictionary with trading recommendation + """ + try: + # Get algorithmic score + algo_decision = self._get_algorithmic_decision(analysis) + + # Get AI-powered recommendation + ai_decision = self._get_ai_recommendation(symbol, analysis, stock_info) + + # Combine decisions + final_decision = self._combine_decisions(algo_decision, ai_decision) + + return { + 'symbol': symbol, + 'recommendation': final_decision['action'], + 'confidence': final_decision['confidence'], + 'price_target': final_decision.get('price_target'), + 'stop_loss': final_decision.get('stop_loss'), + 'reasoning': final_decision['reasoning'], + 'algorithmic_score': algo_decision['score'], + 'ai_recommendation': ai_decision['recommendation'], + 'risk_level': self._assess_risk_level(analysis), + 'time_horizon': final_decision.get('time_horizon', 'medium'), + 'key_factors': final_decision.get('key_factors', []) + } + + except Exception as e: + return { + 'symbol': symbol, + 'recommendation': 'HOLD', + 'confidence': 0.5, + 'reasoning': f'Error in analysis: {str(e)}', + 'error': str(e) + } + + def _get_algorithmic_decision(self, analysis: Dict) -> Dict: + """ + Generate algorithmic trading decision based on technical indicators + + Args: + analysis: Technical analysis results + + Returns: + Dictionary with algorithmic decision + """ + signals = {} + + # Trend signals + trend_score = self._calculate_trend_signal(analysis) + signals['trend'] = trend_score + + # Momentum signals + momentum_score = self._calculate_momentum_signal(analysis) + signals['momentum'] = momentum_score + + # Volume signals + volume_score = self._calculate_volume_signal(analysis) + signals['volume'] = volume_score + + # Volatility signals + volatility_score = self._calculate_volatility_signal(analysis) + signals['volatility'] = volatility_score + + # Technical indicator signals + technical_score = self._calculate_technical_signal(analysis) + signals['technical'] = technical_score + + # Calculate weighted score + total_score = sum(signals[key] * self.signal_weights[key] for key in signals) + + # Determine action + if total_score >= 0.6: + action = 'BUY' + elif total_score <= -0.6: + action = 'SELL' + else: + action = 'HOLD' + + return { + 'action': action, + 'score': total_score, + 'signals': signals, + 'confidence': min(abs(total_score), 1.0) + } + + def _calculate_trend_signal(self, analysis: Dict) -> float: + """Calculate trend-based signal (-1 to 1)""" + score = 0.0 + + # Trend direction and strength + if analysis.get('trend_direction') == 'upward': + score += 0.5 + elif analysis.get('trend_direction') == 'downward': + score -= 0.5 + + # Trend strength + trend_strength = analysis.get('trend_strength', 0) + score *= trend_strength + + # Moving average signals + if 'price_vs_sma_20' in analysis: + sma_20_signal = analysis['price_vs_sma_20'] + if sma_20_signal > 2: + score += 0.2 + elif sma_20_signal < -2: + score -= 0.2 + + if 'price_vs_sma_50' in analysis: + sma_50_signal = analysis['price_vs_sma_50'] + if sma_50_signal > 2: + score += 0.3 + elif sma_50_signal < -2: + score -= 0.3 + + return max(-1.0, min(1.0, score)) + + def _calculate_momentum_signal(self, analysis: Dict) -> float: + """Calculate momentum-based signal (-1 to 1)""" + score = 0.0 + + # RSI signal + if 'rsi' in analysis: + rsi = analysis['rsi'] + if rsi < 30: + score += 0.4 # Oversold - potential buy + elif rsi > 70: + score -= 0.4 # Overbought - potential sell + + # MACD signal + if 'macd_trend' in analysis: + if analysis['macd_trend'] == 'bullish': + score += 0.3 + else: + score -= 0.3 + + # Recent performance + if 'return_1_week' in analysis: + weekly_return = analysis['return_1_week'] + if weekly_return > 5: + score += 0.2 + elif weekly_return < -5: + score -= 0.2 + + return max(-1.0, min(1.0, score)) + + def _calculate_volume_signal(self, analysis: Dict) -> float: + """Calculate volume-based signal (-1 to 1)""" + score = 0.0 + + # Volume trend + if analysis.get('volume_trend') == 'increasing': + score += 0.3 + elif analysis.get('volume_trend') == 'decreasing': + score -= 0.2 + + # Volume vs average + if 'volume_vs_avg' in analysis: + vol_vs_avg = analysis['volume_vs_avg'] + if vol_vs_avg > 20: + score += 0.2 + elif vol_vs_avg < -20: + score -= 0.1 + + return max(-1.0, min(1.0, score)) + + def _calculate_volatility_signal(self, analysis: Dict) -> float: + """Calculate volatility-based signal (-1 to 1)""" + score = 0.0 + + # High volatility can be both opportunity and risk + volatility = analysis.get('volatility_annualized', 0) + + if volatility > 50: + score -= 0.3 # High risk + elif volatility < 15: + score += 0.2 # Low risk + + # Max drawdown consideration + max_drawdown = analysis.get('max_drawdown', 0) + if abs(max_drawdown) > 20: + score -= 0.2 + + return max(-1.0, min(1.0, score)) + + def _calculate_technical_signal(self, analysis: Dict) -> float: + """Calculate technical indicator signal (-1 to 1)""" + score = 0.0 + + # Bollinger Bands + if 'bb_position' in analysis: + bb_pos = analysis['bb_position'] + if bb_pos == 'below_lower_band': + score += 0.3 # Potential buy + elif bb_pos == 'above_upper_band': + score -= 0.3 # Potential sell + + # Sharpe ratio + sharpe = analysis.get('sharpe_ratio', 0) + if sharpe > 1: + score += 0.2 + elif sharpe < 0: + score -= 0.2 + + return max(-1.0, min(1.0, score)) + + def _get_ai_recommendation(self, symbol: str, analysis: Dict, stock_info: Dict) -> Dict: + """ + Get AI-powered trading recommendation using OpenAI + + Args: + symbol: Stock symbol + analysis: Technical analysis results + stock_info: Stock information + + Returns: + Dictionary with AI recommendation + """ + try: + # Prepare analysis data for AI + analysis_summary = self._prepare_analysis_for_ai(analysis, stock_info) + + prompt = f""" + You are a senior financial analyst with 15+ years of experience providing institutional-grade trading recommendations. + Analyze {symbol} and provide a professional trading recommendation. + + Company Information: + - Name: {stock_info.get('company_name', 'N/A')} + - Sector: {stock_info.get('sector', 'N/A')} + - Market Cap: ${stock_info.get('market_cap', 0):,} + + Technical Analysis Data: + {analysis_summary} + + REQUIREMENTS: + 1. Provide BUY/HOLD/SELL recommendation based on technical analysis + 2. Set realistic confidence level (60-95% range) + 3. Calculate logical price targets using support/resistance levels + 4. Set appropriate stop-loss levels (5-15% below entry for long positions) + 5. Consider risk-reward ratios (minimum 1:2 ratio preferred) + 6. Provide clear, actionable reasoning without jargon + 7. Consider market conditions and sector trends + + TRADING STANDARDS: + - BUY: Strong upward momentum, good risk/reward, clear catalysts + - HOLD: Consolidation phase, mixed signals, or fair value + - SELL: Downward trend, poor fundamentals, or overvalued + + Return ONLY valid JSON: + {{ + "recommendation": "BUY/HOLD/SELL", + "confidence": 85, + "price_target": 150.00, + "stop_loss": 120.00, + "time_horizon": "short/medium/long", + "reasoning": "Professional analysis explaining the recommendation with specific technical factors", + "key_factors": ["specific technical indicator", "market condition", "risk factor"], + "risk_assessment": "low/medium/high" + }} + """ + + response = self.client.chat.completions.create( + model="gpt-4o-mini", + messages=[ + {"role": "system", "content": "You are an expert financial analyst providing professional trading recommendations."}, + {"role": "user", "content": prompt} + ], + temperature=0.3, + max_tokens=1000 + ) + + # Parse AI response + ai_response = response.choices[0].message.content + + if ai_response: + try: + # Clean the response - extract JSON + json_start = ai_response.find('{') + json_end = ai_response.rfind('}') + 1 + + if json_start != -1 and json_end != -1: + json_str = ai_response[json_start:json_end] + ai_recommendation = json.loads(json_str) + + # Validate and clean the response + return { + 'recommendation': ai_recommendation.get('recommendation', 'HOLD'), + 'confidence': ai_recommendation.get('confidence', 50), + 'price_target': ai_recommendation.get('price_target'), + 'stop_loss': ai_recommendation.get('stop_loss'), + 'time_horizon': ai_recommendation.get('time_horizon', 'medium'), + 'reasoning': ai_recommendation.get('reasoning', 'AI analysis completed'), + 'key_factors': ai_recommendation.get('key_factors', []), + 'risk_assessment': ai_recommendation.get('risk_assessment', 'medium') + } + else: + # No JSON found, use fallback + return self._parse_ai_response_fallback(ai_response) + + except json.JSONDecodeError: + # Fallback parsing + return self._parse_ai_response_fallback(ai_response) + else: + return self._parse_ai_response_fallback('No response received') + + except Exception as e: + return { + 'recommendation': 'HOLD', + 'confidence': 50, + 'reasoning': f'AI analysis unavailable: {str(e)}', + 'error': str(e) + } + + def _prepare_analysis_for_ai(self, analysis: Dict, stock_info: Dict) -> str: + """Prepare analysis summary for AI consumption""" + summary_parts = [] + + # Price metrics + current_price = analysis.get('current_price', 0) + total_return = analysis.get('total_return_pct', 0) + summary_parts.append(f"Current Price: ${current_price:.2f}") + summary_parts.append(f"Total Return: {total_return:.2f}%") + + # Trend analysis + trend_dir = analysis.get('trend_direction', 'unknown') + trend_strength = analysis.get('trend_strength', 0) + summary_parts.append(f"Trend: {trend_dir} (strength: {trend_strength:.2f})") + + # Technical indicators + if 'rsi' in analysis: + rsi = analysis['rsi'] + rsi_signal = analysis.get('rsi_signal', 'neutral') + summary_parts.append(f"RSI: {rsi:.1f} ({rsi_signal})") + + if 'macd_trend' in analysis: + summary_parts.append(f"MACD: {analysis['macd_trend']}") + + # Risk metrics + volatility = analysis.get('volatility_annualized', 0) + max_drawdown = analysis.get('max_drawdown', 0) + summary_parts.append(f"Volatility: {volatility:.1f}% (annual)") + summary_parts.append(f"Max Drawdown: {max_drawdown:.1f}%") + + # Performance + if 'return_1_month' in analysis: + monthly_return = analysis['return_1_month'] + summary_parts.append(f"1-Month Return: {monthly_return:.2f}%") + + return "\n".join(summary_parts) + + def _parse_ai_response_fallback(self, response: str) -> Dict: + """Fallback parser for AI response if JSON parsing fails""" + # Simple keyword-based parsing + recommendation = 'HOLD' + confidence = 50 + + response_lower = response.lower() + + if 'buy' in response_lower and 'sell' not in response_lower: + recommendation = 'BUY' + confidence = 70 + elif 'sell' in response_lower: + recommendation = 'SELL' + confidence = 70 + + return { + 'recommendation': recommendation, + 'confidence': confidence, + 'reasoning': response, + 'parsed_fallback': True + } + + def _combine_decisions(self, algo_decision: Dict, ai_decision: Dict) -> Dict: + """Combine algorithmic and AI decisions""" + # Weight the decisions (60% algorithmic, 40% AI) + algo_weight = 0.6 + ai_weight = 0.4 + + # Map recommendations to scores + rec_scores = {'BUY': 1, 'HOLD': 0, 'SELL': -1} + + algo_score = rec_scores.get(algo_decision['action'], 0) + ai_score = rec_scores.get(ai_decision.get('recommendation', 'HOLD'), 0) + + # Calculate combined score + combined_score = (algo_score * algo_weight) + (ai_score * ai_weight) + + # Determine final recommendation + if combined_score >= 0.3: + final_action = 'BUY' + elif combined_score <= -0.3: + final_action = 'SELL' + else: + final_action = 'HOLD' + + # Calculate confidence + algo_confidence = algo_decision.get('confidence', 0.5) + ai_confidence = ai_decision.get('confidence', 50) / 100 + combined_confidence = (algo_confidence * algo_weight) + (ai_confidence * ai_weight) + + return { + 'action': final_action, + 'confidence': combined_confidence, + 'combined_score': combined_score, + 'reasoning': ai_decision.get('reasoning', 'Combined algorithmic and AI analysis'), + 'price_target': ai_decision.get('price_target'), + 'stop_loss': ai_decision.get('stop_loss'), + 'time_horizon': ai_decision.get('time_horizon', 'medium'), + 'key_factors': ai_decision.get('key_factors', []) + } + + def _assess_risk_level(self, analysis: Dict) -> str: + """Assess overall risk level""" + risk_score = 0 + + # Volatility risk + volatility = analysis.get('volatility_annualized', 0) + if volatility > 40: + risk_score += 2 + elif volatility > 25: + risk_score += 1 + + # Drawdown risk + max_drawdown = abs(analysis.get('max_drawdown', 0)) + if max_drawdown > 30: + risk_score += 2 + elif max_drawdown > 15: + risk_score += 1 + + # Sharpe ratio + sharpe = analysis.get('sharpe_ratio', 0) + if sharpe < 0: + risk_score += 1 + + # Determine risk level + if risk_score >= 4: + return 'high' + elif risk_score >= 2: + return 'medium' + else: + return 'low' + +# Global instance for easy import +trading_engine = TradingDecisionEngine() + +# Convenience function +def get_trading_recommendation(symbol: str, analysis: Dict, stock_info: Dict) -> Dict: + """Convenience function to get trading recommendation""" + return trading_engine.get_trading_recommendation(symbol, analysis, stock_info)