diff --git a/week4/community-contributions/ai_stock_trading/README.md b/week4/community-contributions/ai_stock_trading/README.md new file mode 100644 index 0000000..3a56e71 --- /dev/null +++ b/week4/community-contributions/ai_stock_trading/README.md @@ -0,0 +1,249 @@ +# šŸ“ˆ Stock Analysis & Sharia Compliance Tool + +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. + +![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) + +## 🌟 Features + +### šŸ“Š **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 + +### šŸ¤– **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 + +### ā˜Ŗļø **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 + +### šŸ“ˆ **Interactive Visualizations** +- 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 + +## šŸš€ Quick Start + +### Prerequisites + +Ensure you have Python 3.8+ installed on your system. + +### Installation + +1. **Clone or download this project** +```bash +git clone +cd ai_stock_trading +``` + +2. **Install dependencies** +```bash +pip install -r requirements.txt +``` + +3. **Set up OpenAI API Key** +```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" +``` + +### Running the Application + +1. **Open the Jupyter notebook** +```bash +jupyter notebook stock_analysis_sharia_compliance.ipynb +``` + +2. **Run all cells** to initialize the functions + +3. **Launch the interface** by running the final cell + +4. **Access the web interface** at `http://localhost:7860` + +## šŸ“– 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 + +### 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 | + +## šŸ› ļø Technical Implementation + +### Core Components + +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 + +2. **Analysis Tool** (`summarize`) + - Calculates financial metrics + - Annualized volatility calculation + - Price performance analysis + +3. **Trade Decision Tool** (`get_trade_advice`) + - OpenAI GPT-4o-mini integration + - Multi-period analysis prompts + - Structured recommendation format + +4. **Sharia Compliance Tool** (`assess_sharia`) + - Company profile extraction + - Islamic finance criteria evaluation + - Confidence scoring system + +5. **Charting Tool** (`plot_price`) + - Matplotlib-based visualizations + - Price and volume charts + - Professional styling + +### AI Prompts + +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 + +## šŸ“Š Sample Analysis Output + +### Trade Recommendation Example +``` +RECOMMENDATION: BUY + +Based on the analysis of AAPL: +• 1Y return of +15.2% shows strong performance +• Volatility of 24.3% indicates manageable risk +• Recent 1M return of +5.8% shows positive momentum +• Strong volume indicates healthy trading activity + +Key factors supporting BUY decision: +- Consistent positive returns across timeframes +- Volatility within acceptable range for tech stocks +- Strong market position and fundamentals +``` + +### Sharia Assessment Example +```json +{ + "ruling": "HALAL", + "confidence": 85, + "justification": "Apple Inc. primarily operates in technology hardware and software, which are permissible under Islamic law. The company's main revenue sources (iPhone, Mac, services) do not involve prohibited activities such as gambling, alcohol, or interest-based banking." +} +``` + +## āš ļø Important Disclaimers + +### Financial Disclaimer +- **This tool is for educational purposes only** +- **Not professional financial advice** +- **Past performance does not guarantee future results** +- **Consult qualified financial advisors before making investment decisions** + +### Sharia Compliance Disclaimer +- **Consult qualified Islamic scholars for authoritative rulings** +- **AI assessments are preliminary and may have limitations** +- **Consider multiple sources for Sharia compliance verification** +- **Individual scholarly interpretations may vary** + +### Technical Limitations +- **Data accuracy depends on yfinance API availability** +- **OpenAI API calls consume credits/tokens** +- **Network connectivity required for real-time data** +- **Analysis speed depends on API response times** + +## šŸ”§ Customization + +### Adding New Analysis Periods +```python +periods = ["1mo", "3mo", "6mo", "1y", "2y", "5y"] # Modify as needed +``` + +### Modifying Sharia Criteria +```python +# Update the Sharia assessment prompt with additional criteria +prompt = f""" +Additional criteria: +- Debt-to-market cap ratio analysis +- Revenue source breakdown +- ESG factors consideration +""" +``` + +### Styling the Interface +```python +demo = create_interface() +demo.launch(theme="huggingface") # Try different themes +``` + +## šŸ“š Dependencies + +- **yfinance**: Real-time financial data +- **openai**: AI-powered analysis +- **pandas**: Data manipulation +- **matplotlib**: Chart generation +- **gradio**: Web interface +- **requests**: HTTP requests +- **beautifulsoup4**: Web scraping +- **numpy**: Numerical computations + +## šŸ¤ Contributing + +Contributions are welcome! Please feel free to submit issues, feature requests, or pull requests. + +### Areas for Enhancement +- Additional technical indicators +- More sophisticated Sharia screening +- Portfolio analysis features +- Historical backtesting +- Mobile-responsive design + +## šŸ“„ License + +This project is for educational purposes. Please ensure compliance with: +- OpenAI API usage terms +- Yahoo Finance data usage policies +- Local financial regulations +- Islamic finance guidelines + +## šŸ™ Acknowledgments + +- **yfinance** for providing free financial data API +- **OpenAI** for GPT-4o-mini language model +- **Gradio** for the intuitive web interface framework +- **Islamic finance scholars** for Sharia compliance frameworks + +--- + +**Made with ā¤ļø for the Muslim tech community and ethical investing enthusiasts** + +*"And Allah knows best" - ŁˆŁŽŲ§Ł„Ł„ŁŽŁ‘Ł‡Ł Ų£ŁŽŲ¹Ł’Ł„ŁŽŁ…Ł* \ No newline at end of file diff --git a/week4/community-contributions/ai_stock_trading/requirements.txt b/week4/community-contributions/ai_stock_trading/requirements.txt new file mode 100644 index 0000000..3c05391 --- /dev/null +++ b/week4/community-contributions/ai_stock_trading/requirements.txt @@ -0,0 +1,8 @@ +yfinance>=0.2.10 +openai>=1.0.0 +pandas>=1.5.0 +matplotlib>=3.5.0 +gradio>=4.0.0 +requests>=2.28.0 +beautifulsoup4>=4.11.0 +numpy>=1.21.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 new file mode 100644 index 0000000..3c7bfca --- /dev/null +++ b/week4/community-contributions/ai_stock_trading/stock_analysis_sharia_compliance.ipynb @@ -0,0 +1,1106 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "vscode": { + "languageId": "raw" + } + }, + "source": [ + "# Stock Analysis & Sharia Compliance Chat Interface\n", + "\n", + "This notebook implements a comprehensive Gradio-based chat interface for stock analysis and Islamic Sharia compliance checks. It provides:\n", + "\n", + "- **Real-time Stock Data Fetching** using yfinance\n", + "- **Technical Analysis** with multiple time periods\n", + "- **AI-Powered Trade Recommendations** using OpenAI GPT-4o-mini\n", + "- **Sharia Compliance Assessment** for Islamic investing\n", + "- **Interactive Charts** and user-friendly interface\n", + "\n", + "## Features\n", + "1. Multi-period stock analysis (1 month, 1 year, 5 years)\n", + "2. Automated trade advice (BUY/HOLD/SELL) with justification\n", + "3. Sharia compliance ruling with confidence scores\n", + "4. Interactive price charts\n", + "5. Clean Gradio chat interface\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "vscode": { + "languageId": "raw" + } + }, + "source": [ + "## 1. Imports\n", + "\n", + "First, let's import all necessary libraries and set up our environment.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "āœ… OpenAI API key loaded successfully\n", + "šŸš€ All libraries imported successfully!\n" + ] + } + ], + "source": [ + "# Core imports\n", + "import os\n", + "import json\n", + "import warnings\n", + "from dotenv import load_dotenv\n", + "\n", + "warnings.filterwarnings('ignore')\n", + "\n", + "# Data and analysis\n", + "import yfinance as yf\n", + "import pandas as pd\n", + "import numpy as np\n", + "\n", + "# Visualization\n", + "import matplotlib.pyplot as plt\n", + "import matplotlib.dates as mdates\n", + "\n", + "# Web scraping for company info\n", + "import requests\n", + "from bs4 import BeautifulSoup\n", + "\n", + "# AI and interface\n", + "import openai\n", + "import gradio as gr\n", + "\n", + "# Load OpenAI API key from environment\n", + "load_dotenv(override=True)\n", + "openai.api_key = os.getenv('OPENAI_API_KEY')\n", + "\n", + "if not openai.api_key:\n", + " print(\"āš ļø Warning: OPENAI_API_KEY not found in environment variables\")\n", + " print(\"Please set your OpenAI API key: export OPENAI_API_KEY='your-key-here'\")\n", + "else:\n", + " print(\"āœ… OpenAI API key loaded successfully\")\n", + "\n", + "print(\"šŸš€ All libraries imported successfully!\")\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "vscode": { + "languageId": "raw" + } + }, + "source": [ + "## 2. Data Fetching Tool\n", + "\n", + "This function fetches historical stock data using yfinance for any given symbol, period, and interval.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "āœ… Successfully fetched 18 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", + "\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" + ] + } + ], + "source": [ + "def fetch_history(symbol, period=\"1mo\", interval=\"1d\"):\n", + " \"\"\"\n", + " Fetch historical stock data using yfinance\n", + " \n", + " Args:\n", + " symbol (str): Stock ticker symbol (e.g., 'AAPL', 'MSFT')\n", + " period (str): Time period ('1d', '5d', '1mo', '3mo', '6mo', '1y', '2y', '5y', '10y', 'ytd', 'max')\n", + " interval (str): Data interval ('1m', '2m', '5m', '15m', '30m', '60m', '90m', '1h', '1d', '5d', '1wk', '1mo', '3mo')\n", + " \n", + " Returns:\n", + " pandas.DataFrame: Historical stock data with OHLCV columns\n", + " \"\"\"\n", + " try:\n", + " # Create ticker object\n", + " ticker = yf.Ticker(symbol)\n", + " \n", + " # Fetch historical data\n", + " df = ticker.history(period=period, interval=interval)\n", + " \n", + " if df.empty:\n", + " raise ValueError(f\"No data found for symbol: {symbol}\")\n", + " \n", + " print(f\"āœ… Successfully fetched {len(df)} data points for {symbol} ({period})\")\n", + " return df\n", + " \n", + " except Exception as e:\n", + " print(f\"āŒ Error fetching data for {symbol}: {str(e)}\")\n", + " return pd.DataFrame()\n", + "\n", + "# Test the function\n", + "test_symbol = \"ABUK.CA\"\n", + "test_data = fetch_history(test_symbol, \"1mo\", \"1d\")\n", + "if not test_data.empty:\n", + " print(f\"\\nšŸ“Š Sample data for {test_symbol}:\")\n", + " print(test_data.head())\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "vscode": { + "languageId": "raw" + } + }, + "source": [ + "## 3. Analysis Tool\n", + "\n", + "This function analyzes the fetched data and computes key financial metrics.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "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" + ] + } + ], + "source": [ + "def summarize(df):\n", + " \"\"\"\n", + " Analyze DataFrame and return key financial metrics\n", + " \n", + " Args:\n", + " df (pandas.DataFrame): Historical stock data with OHLCV columns\n", + " \n", + " Returns:\n", + " dict: Summary metrics including returns, volatility, and volume\n", + " \"\"\"\n", + " if df.empty:\n", + " return {\n", + " \"start_price\": 0,\n", + " \"end_price\": 0,\n", + " \"total_return_%\": 0,\n", + " \"volatility_%\": 0,\n", + " \"avg_volume\": 0,\n", + " \"max_price\": 0,\n", + " \"min_price\": 0,\n", + " \"price_range_%\": 0\n", + " }\n", + " \n", + " try:\n", + " # Basic price metrics\n", + " start_price = float(df['Close'].iloc[0])\n", + " end_price = float(df['Close'].iloc[-1])\n", + " max_price = float(df['High'].max())\n", + " min_price = float(df['Low'].min())\n", + " \n", + " # Calculate returns\n", + " total_return = ((end_price - start_price) / start_price) * 100\n", + " \n", + " # Calculate volatility (annualized)\n", + " daily_returns = df['Close'].pct_change().dropna()\n", + " volatility = daily_returns.std() * np.sqrt(252) * 100 # Annualized\n", + " \n", + " # Volume metrics\n", + " avg_volume = float(df['Volume'].mean())\n", + " \n", + " # Price range\n", + " price_range = ((max_price - min_price) / min_price) * 100\n", + " \n", + " summary = {\n", + " \"start_price\": round(start_price, 2),\n", + " \"end_price\": round(end_price, 2),\n", + " \"total_return_%\": round(total_return, 2),\n", + " \"volatility_%\": round(volatility, 2),\n", + " \"avg_volume\": int(avg_volume),\n", + " \"max_price\": round(max_price, 2),\n", + " \"min_price\": round(min_price, 2),\n", + " \"price_range_%\": round(price_range, 2)\n", + " }\n", + " \n", + " return summary\n", + " \n", + " except Exception as e:\n", + " print(f\"āŒ Error in analysis: {str(e)}\")\n", + " return {\"error\": str(e)}\n", + "\n", + "# Test the analysis function\n", + "if not test_data.empty:\n", + " test_summary = summarize(test_data)\n", + " print(\"\\nšŸ“ˆ Analysis Summary:\")\n", + " for key, value in test_summary.items():\n", + " print(f\" {key}: {value}\")\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "vscode": { + "languageId": "raw" + } + }, + "source": [ + "## 4. Trade Decision Tool\n", + "\n", + "This function uses OpenAI GPT-4o-mini to provide intelligent trade recommendations based on multi-period analysis.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "šŸ¤– Getting AI trade advice...\n", + "\n", + "Trade Advice for ABUK.CA:\n", + "RECOMMENDATION: BUY\n", + "\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", + "\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", + "\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", + "\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", + "\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", + "\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" + ] + } + ], + "source": [ + "def get_trade_advice(symbol, summaries):\n", + " \"\"\"\n", + " Get AI-powered trade advice using OpenAI GPT-4o-mini\n", + " \n", + " Args:\n", + " symbol (str): Stock ticker symbol\n", + " summaries (dict): Dictionary containing summaries for different periods\n", + " \n", + " Returns:\n", + " str: Trade advice from AI assistant\n", + " \"\"\"\n", + " if not openai.api_key:\n", + " return \"āŒ OpenAI API key not configured. Please set OPENAI_API_KEY environment variable.\"\n", + " \n", + " try:\n", + " # Build multi-period summary text\n", + " summary_text = f\"Stock Analysis for {symbol}:\\n\\n\"\n", + " \n", + " for period, data in summaries.items():\n", + " if \"error\" not in data:\n", + " summary_text += f\"{period.upper()} ANALYSIS:\\n\"\n", + " summary_text += f\" • Price: ${data['start_price']} → ${data['end_price']}\\n\"\n", + " summary_text += f\" • Total Return: {data['total_return_%']}%\\n\"\n", + " summary_text += f\" • Volatility: {data['volatility_%']}%\\n\"\n", + " summary_text += f\" • Average Volume: {data['avg_volume']:,}\\n\"\n", + " summary_text += f\" • Price Range: {data['price_range_%']}%\\n\\n\"\n", + " \n", + " # Create the prompt\n", + " prompt = f\"\"\"As a professional financial analyst, analyze the following stock data and provide a clear BUY/HOLD/SELL recommendation.\n", + "\n", + "{summary_text}\n", + "\n", + "Instructions:\n", + "1. Start your response with a clear decision: \"RECOMMENDATION: BUY/HOLD/SELL\"\n", + "2. Provide specific numerical justification based on the data\n", + "3. Consider multiple timeframes and risk factors\n", + "4. Keep your analysis concise but thorough\n", + "5. Include key metrics that support your decision\n", + "\n", + "Should I BUY/HOLD/SELL this stock? Justify with numbers.\"\"\"\n", + "\n", + " # Call OpenAI API\n", + " response = openai.chat.completions.create(\n", + " model=\"gpt-4o-mini\",\n", + " messages=[\n", + " {\"role\": \"system\", \"content\": \"You are a professional financial analyst providing stock trading advice based on technical analysis.\"},\n", + " {\"role\": \"user\", \"content\": prompt}\n", + " ],\n", + " max_tokens=500,\n", + " temperature=0.3\n", + " )\n", + " \n", + " advice = response.choices[0].message.content.strip()\n", + " return advice\n", + " \n", + " except Exception as e:\n", + " return f\"āŒ Error getting trade advice: {str(e)}\"\n", + "\n", + "# Test with dummy data\n", + "if not test_data.empty:\n", + " test_summaries = {\"1mo\": test_summary}\n", + " print(\"\\nšŸ¤– Getting AI trade advice...\")\n", + " test_advice = get_trade_advice(test_symbol, test_summaries)\n", + " print(f\"\\nTrade Advice for {test_symbol}:\")\n", + " print(test_advice)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "vscode": { + "languageId": "raw" + } + }, + "source": [ + "## 5. Sharia Compliance Tool\n", + "\n", + "This tool assesses whether a stock is compliant with Islamic Sharia principles by analyzing the company's business activities.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "ā˜Ŗļø Testing Sharia compliance assessment...\n", + "\n", + "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" + ] + } + ], + "source": [ + "def get_company_profile(symbol):\n", + " \"\"\"\n", + " Fetch company information from the internet\n", + " \n", + " Args:\n", + " symbol (str): Stock ticker symbol\n", + " \n", + " Returns:\n", + " str: Company description and business activities\n", + " \"\"\"\n", + " try:\n", + " # Use yfinance to get company info\n", + " ticker = yf.Ticker(symbol)\n", + " info = ticker.info\n", + " \n", + " company_info = \"\"\n", + " if 'longBusinessSummary' in info:\n", + " company_info = info['longBusinessSummary']\n", + " elif 'description' in info:\n", + " company_info = info['description']\n", + " else:\n", + " # Fallback: try to get basic info\n", + " company_info = f\"Company: {info.get('longName', symbol)}, \"\n", + " company_info += f\"Sector: {info.get('sector', 'Unknown')}, \"\n", + " company_info += f\"Industry: {info.get('industry', 'Unknown')}\"\n", + " \n", + " return company_info\n", + " \n", + " except Exception as e:\n", + " return f\"Unable to fetch company information for {symbol}: {str(e)}\"\n", + "\n", + "def assess_sharia(symbol):\n", + " \"\"\"\n", + " Assess Sharia compliance using AI analysis of company activities\n", + " \n", + " Args:\n", + " symbol (str): Stock ticker symbol\n", + " \n", + " Returns:\n", + " dict: Sharia ruling with confidence score and justification\n", + " \"\"\"\n", + " if not openai.api_key:\n", + " return {\n", + " \"ruling\": \"UNKNOWN\",\n", + " \"confidence\": 0,\n", + " \"justification\": \"OpenAI API key not configured\"\n", + " }\n", + " \n", + " try:\n", + " # Get company profile\n", + " company_profile = get_company_profile(symbol)\n", + " \n", + " # Create Sharia compliance prompt\n", + " prompt = f\"\"\"As an Islamic finance scholar, analyze the following company's business activities and determine if it is HALAL (permissible) or HARAM (forbidden) according to Islamic Sharia principles.\n", + "\n", + "Company: {symbol}\n", + "Business Description: {company_profile}\n", + "\n", + "Islamic Sharia Compliance Criteria:\n", + "- HARAM: Alcohol, gambling, adult entertainment, tobacco, conventional banking with interest (riba), insurance, pork products\n", + "- HARAM: Companies with >33% revenue from prohibited activities\n", + "- HARAM: Companies with excessive debt (debt-to-market cap >33%)\n", + "- HALAL: Technology, healthcare, retail (halal products), renewable energy, telecommunications\n", + "\n", + "Provide your assessment in the following format:\n", + "RULING: [HALAL/HARAM/DOUBTFUL]\n", + "CONFIDENCE: [0-100]\n", + "JUSTIFICATION: [Brief explanation of the ruling based on business activities]\n", + "\n", + "Be conservative in your assessment - when in doubt, classify as DOUBTFUL.\"\"\"\n", + "\n", + " # Call OpenAI API\n", + " response = openai.chat.completions.create(\n", + " model=\"gpt-4o-mini\",\n", + " messages=[\n", + " {\"role\": \"system\", \"content\": \"You are an Islamic finance scholar specializing in Sharia compliance assessment for investments.\"},\n", + " {\"role\": \"user\", \"content\": prompt}\n", + " ],\n", + " max_tokens=300,\n", + " temperature=0.2\n", + " )\n", + " \n", + " response_text = response.choices[0].message.content.strip()\n", + " \n", + " # Parse the response\n", + " ruling = \"UNKNOWN\"\n", + " confidence = 0\n", + " justification = response_text\n", + " \n", + " # Extract ruling\n", + " if \"RULING:\" in response_text:\n", + " ruling_line = [line for line in response_text.split('\\n') if 'RULING:' in line][0]\n", + " ruling = ruling_line.split('RULING:')[1].strip()\n", + " \n", + " # Extract confidence\n", + " if \"CONFIDENCE:\" in response_text:\n", + " confidence_line = [line for line in response_text.split('\\n') if 'CONFIDENCE:' in line][0]\n", + " try:\n", + " confidence = int(''.join(filter(str.isdigit, confidence_line)))\n", + " except:\n", + " confidence = 50\n", + " \n", + " # Extract justification\n", + " if \"JUSTIFICATION:\" in response_text:\n", + " justification = response_text.split('JUSTIFICATION:')[1].strip()\n", + " \n", + " return {\n", + " \"ruling\": ruling,\n", + " \"confidence\": confidence,\n", + " \"justification\": justification\n", + " }\n", + " \n", + " except Exception as e:\n", + " return {\n", + " \"ruling\": \"ERROR\",\n", + " \"confidence\": 0,\n", + " \"justification\": f\"Error assessing Sharia compliance: {str(e)}\"\n", + " }\n", + "\n", + "# Test Sharia assessment\n", + "print(\"\\nā˜Ŗļø Testing Sharia compliance assessment...\")\n", + "test_sharia = assess_sharia(test_symbol)\n", + "print(f\"\\nSharia Assessment for {test_symbol}:\")\n", + "print(f\"Ruling: {test_sharia['ruling']}\")\n", + "print(f\"Confidence: {test_sharia['confidence']}%\")\n", + "print(f\"Justification: {test_sharia['justification']}\")\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "vscode": { + "languageId": "raw" + } + }, + "source": [ + "## 6. Charting Tool\n", + "\n", + "This function creates interactive price charts using Matplotlib for visualization in the Gradio interface.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "šŸ“Š Creating test chart...\n" + ] + }, + { + "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/GKXDENaknhE943qyEYxAJqEzck5jut9mbqHE3bv3u30NhISEpzehrPt2LFDsbGxjtsNMUpKkqKiok4b8ZSRkSEvLy+FhYXVWOb3o6cqu/baa/Xpp59q8eLFio6O1q233qqnn35aHTp0aJC4pXqOlDp8+LBuu+02BQcHKzAwUEFBQY5LcHBwgwUHAADgjqKD/TQgPlSStD+zUNuO5JocEQA0jMpJqd5M3QPq5Pf5k4ZKSg0aNEgrVqyocuzrr79Wv3795O3tXWOZwYMHV1vvhx9+qNTUVL322muKjY3Vs88+q06dOmnkyJH64IMPVFxcfM6x13mk1DXXXMN/+gAAAM7iyl6xWre/YpeaJYkpbJkOwO1lF5UrObtIkhQX5q+wFg3zgxpAVQUFBdq7d6/jdlJSkhITExUaGqq2bdtqxowZOnLkiN5//31J0pQpU/Tqq69q+vTpuuOOO7R27Vq98847VXbVu//++zV8+HDNmjVL48eP15IlS/TNN9/oxx9/rDGWoKAgTZkyRVOmTNHOnTv1zjvv6MMPP9TNN9+se++9V9dff71uv/129e/fv17nWuek1Pz58+vVEAAAQHMyrnu0/t+SX1Vqs+uzrSn66yVd5OnBP/YAuK/taQWO633imLoHOMvGjRs1cuRIx+3p06dLkm655RbNnz9fqampSk5OdtwfHx+v5cuXa9q0aXrttdcUExOjV155Rddcc42jzODBg7VgwQI99thjevzxx9WhQwctXLhQAwYMqHVcXbp00QsvvKBZs2Zp2bJlmjdvnubNm6c333xT3bp10y+//FLnc611Uur48eP69NNPdfDgQbVq1UqXX365YxV2AAAAVBXs760LEyL09Y50ZeSXaO2+LA09L9zssACg3ranFDqu92E9KcBpLrzwQsdC5WdypsFCI0aM0ObNm2usd8KECZowYcK5hidPT09dccUVGjBggP7xj39o9uzZ+vXXX+tVV62SUikpKRo+fLiSkpIcT0xwcLC++OILDRw4sF4No26cvXBcU1g0DgAAV3Nl71h9vSNdUsWC5ySlALir3ONlSsquWD8mOsRX0cG+JkcEwAw2m01Lly7Vu+++qy+//FLl5eXq0aOHJk2aVK/6arXQ+WOPPaYjR47oscce07JlyzR79mz5+Pjo7rvvrlejAAAAzcH/dW6lFtaK/wF+uT1NxWU2kyMCgPpJrLTAOaOkgObn119/1Z///GfFxMRowoQJ+uGHHzR58mRt2LBBiYmJ+tOf/lSvems1UmrFihX661//qscff1ySNG7cOHXo0EFXXHGF0tPTa9xCEAAAoLny9fbUxd2j9Mmmw8ovKdd3uzJ0yfnRZocFAHW2+VCO4zpJKaB5yMvL03/+8x/NmzdPmzZtkiQNHz5ckyZN0oQJE+Tre+4jJms1UiotLU3Dhw+vcuzkHMf09PRzDuKkmTNnymKx6IEHHnAcKygo0L333qvWrVvLz89PXbp00Zw5cxqsTQAAAGe6sles4/qSxCMmRgIA9VNUYtPutHxJUliAj9qG+pkcEYDGEBUVpXvuuUcpKSl65JFHtGfPHn3//fe68cYbGyQhJdVypJTNZpOfX9U3npMBlJeXN0ggGzZs0JtvvqkePXpUOT5t2jR9//33+uCDD9SuXTt9/fXXmjp1qmJiYjR+/PgGaRsAAMBZBnUIU0SgVUfzS/T9rqPKLSpTsL+32WEBQK1tPZwjm71ibeHebUNksbCTKNAcXHzxxZo0aZLGjRsnD49ajWmqs1rvvrd79255eZ0qbrNVrImwa9eu08r26dOnTkEUFBTohhtu0FtvvaWnn366yn1r167VLbfcogsvvFCSdOedd+qNN97Qxo0bSUoBAACX5+lh0eU9YjTvpySV2uz6YnuqrrugrdlhAUCtbU4+5rjeu22IeYEAaFT/+9//nN5GrZNSt9566xmP33TTTY7rhmHIYrE4Ela1dc899+jSSy/VRRdddFpSaujQoVq6dKluv/12xcTEaOXKldqzZ49efvnlOrUBAABglit7VySlJGlJYgpJKQBuo6Tcpu0puZKkFlZPdYxoYXJEAJqSWiWl3n33XacFsGDBAm3evFkbNmw44/2vvPKK7rjjDrVu3VpeXl7y8PDQ22+/raFDh1ZbZ0lJiUpKShy38/Mr5j/b7XbHxTAM2e32hj0ZJzIMw6n1u9NzAdfijv0JcKZzeb8+2Y/sdnu1Q6Sr62vO/pwws+2m8P7SLTpQ7cL8dSCrSOuSspRyrEhR9dhO3azn2h3/xnw+wVW52/v19sO5KiuveFy3qABJRrX10N+aLzNf1+7AnWN3tlolpW655RanNH7o0CHdf//9+vrrr6tdJOuVV17RunXrtHTpUsXFxWn16tWaOnWqoqOjddFFF53xMTNnztSTTz552vGsrCz5+PjIbrcrNzdXhmE4bV5kQ8vJyXFq/RkZGU6tH02XO/YnwJnO5f3aMAwVFRU5Rh6fSXXv187+nDCz7abyGXXRecF6O6tIhiF9tGaPbugbVec6zHqu3fFvzOcTXJW7vV+v23eqrvNaeio3N7fOn1Fo+sx8XbuDrKwss0NwWbWevucMmzZtUkZGhvr27es4ZrPZtHr1ar366qvKzc3VX//6Vy1evFiXXnqpJKlHjx5KTEzUCy+8UG1SasaMGZo+fbrj9pEjR9S1a1eFhYWpVatWstvtslgsioiIcJsvKc7u5K1atXJq/Wi63LE/Ac50Lu/XJ/tTUFBQtf2puvfrxvgyaFbbTeUz6vrBAXp7Xaok6bt9+Zo2rsdZHnE6s55rd/wb8/kEV+VO79flNrt2ph+QJPn5eKpb6xAFBwfX+TMKTZ+Zr2t3UFpaanYILsvUpNSoUaO0bdu2Ksduu+02de7cWQ8//LBsNpvKyspOe9Pz9PSscfib1WqV1Wp13M7Ly5MkeXh4OOqyWCxVbrs6Z+9w4S7PA1yTu/UnwJnO5f36ZB/y8PCotp7q+llj7IRkVttN5b2lQ6tA9WwdrK2Hc/VrSp72ZxaqY6vAOtVh1nPtrn9jPp/gitzp/XpXeoGKyyrWC+7ZOlheJ/pTXT+j0PSZ+bp2B+4cu7OZmpQKDAxU9+7dqxwLCAhQWFiY4/iIESP04IMPys/PT3FxcVq1apXef/99vfjii2aEDAAAUG/je8Vq6+GKBYM/3ZKiv4xNMDkiAKjeFnbdA+BkLp+uW7Bggfr3768bbrhBXbt21XPPPadnnnlGU6ZMMTs0AACAOrmsZ7Q8TvwzecnWI42yMCwA1IfdMLQlOUeS5O1lUfeYYHMDAtAkmTpS6kxWrlxZ5XZUVJRTd/8DAABoLK0CfTWkY7h++C1Th7KPa3NyjvrGtTQ7LAA4zd70AuUXl0uSzo8JkY+Xh4pMjglA0+PyI6UAAACakvG9Yh3XlyQeMTESAKje5kpT9/rEhZgXCIAmjaQUAABAIxrbLVJWr4qvYMt+SVWZrfrNWwDADEalqXueHhb1aB1iajwAmi6SUgAAAI0o0NdbF3WJlCRlFZbqx72ZJkcEAFUlZx9XVmHFFvadowPl7+NpckQAmiqSUgAAAI1sfK8Yx/UlW5jCB8C1VJm615Z17wA4D0kpAACARnZhQisF+3lLkr7eka6i0nKTIwKAU/ak5zuu92TqHgAnIikFAADQyHy8PHTJ+VGSpKJSm1bsSDc5IgCoYLMbOpBVKEkKa+GjEH9vkyMC0JSRlAIAADBB1V34UkyMBABOOXzsuMrKDUlS+/AAk6MB0NSRlAIAADDBBe1CFR3sK0laveeosk8sKgwAZkrKLHRcj48gKQXAuUhKAQAAmMDDw6IrelYseF5uN7RsW6rJEQGAtD+zwHG9Q0QLEyMB0ByQlAIAADBJlSl87MIHwAXsP1qRlPL0sKhtqL/J0QBo6khKAQAAmKRLdKA6RVaMRNh48JgOZReZHBGA5qyo1Ka03BJJUptQP3l78nMRgHPxLgMAAGASi8VSZbTU0q0seA7APAcqrSfFIucAGgNJKQAAABOdXFdKkpYkHpFhGCZGA6A523f01HpS7VlPCkAjICkFAABgojah/uoX11KStCe9QLvS8k2OCEBzVWXnvXCSUgCcj6QUAACAycb3PjWF79NEFjwH0PgMw9D+E0mpAKunWgX6mBwRgOaApBQAAIDJLj0/Wl4eFknSZ4kpstuZwgegcWUWlKqguFySFB8eIIvFYnJEAJoDklIAAAAmCw3w0fBOEZKklNxibTiQbXJEAJqb/ZmsJwWg8ZGUAgAAcAHje51a8PzTRHbhA9C49h+ttPMeSSkAjcTL7AAAAAAgje4aKX8fTxWV2rR8W6qevKKbfLz4/yGAxlElKRUW0KB17969u0Hr+72EhASn1g/AefimAwAA4AL8fbw0pmukJCn3eJlW7TlqckQAmosym12HsoskSVFBVvlbPU2OCEBzQVIKAADARbALHwAzJGcXqfzEBgvxTN0D0IhISgEAALiIoR3DFRpQsQ37NzvSlV9cZnJEAJqDpMpT98IbduoeANSEpBQAAICL8Pb00GU9oiVJJeV2ff1ruskRAWgO9meyyDkAc5CUAgAAcCHjezGFD0Dj2p9ZIEny9rSodUs/k6MB0JyQlAIAAHAhfdqGqE1oxY/Cn/ZmKiO/2OSIADRl+cVlyswvlSTFhQXI08NickQAmhOSUgAAAC7EYrFofM+K0VJ2Q1r2S6rJEQFoyqpM3WM9KQCNzMvsAAAAAFDVlb1j9Or3eyVJnyam6LYh8SZHZI7du3fX+7GGYSgnJ0c5OTmyWKof+ZGQkFDvNoCmYP9R1pMCYB5GSgEAALiYjq0C1TU6SJK09VCOkiqNZACAhlR55734CEZKAWhcJKUAAABc0JW9YxzXlyammBgJgKbKMAxH0jvYz1uh/t4mRwSguSEpBQAA4IIu7xmjk7POliQekWEY5gYEoMlJzS3W8TKbJKl9RECNU10BwBlISgEAALig6GA/DYgPlVSxEPG2I7kmRwSgqam8yHk8i5wDMAFJKQAAABd1Za9Yx/UlTOED0MAqr1fHIucAzEBSCgAAwEWN6x4tH8+Kr2ufbU2RnSl8ABrQvhOLnFssUnyYv8nRAKjs9ddfV3x8vHx9fdW3b1/98MMP1Za99dZbZbFYTrt069bNUWb+/PlnLFNcXNwYp1MtklIAAAAuKtjfWxcmREiSMvJLtCs13+SIADQVJeU2HTlWJEmKDfGT1dvT5IgAnLRw4UI98MADevTRR7VlyxYNGzZM48aNU3Jy8hnLv/zyy0pNTXVcDh06pNDQUF177bVVygUFBVUpl5qaKl9f38Y4pWqRlAIAAHBhV/Y+NYXv56QsEyMB0JQczCzSycGX7SNYTwpwJS+++KImTZqkyZMnq0uXLpo9e7batGmjOXPmnLF8cHCwoqKiHJeNGzfq2LFjuu2226qUs1gsVcpFRUU1xunUiKQUAACAC/u/zq0UaPWSJG0+mKMym93kiAA0BSxyDrim0tJSbdq0SWPGjKlyfMyYMVqzZk2t6njnnXd00UUXKS4ursrxgoICxcXFqXXr1rrsssu0ZcuWBou7vkhKAQAAuDBfb0+N7V7xn8zjZTb9cphd+ACcu/1HKy1yHs4i50BjyM/PV15enuNSUlJyWpnMzEzZbDZFRkZWOR4ZGam0tLSztpGamqovvvhCkydPrnK8c+fOmj9/vpYuXaqPPvpIvr6+GjJkiH777bdzO6lzRFIKAADAxVXehW/dfqbwATh3SZkFkioS39Eh5q4pAzQXXbt2VXBwsOMyc+bMastaLJYqtw3DOO3YmcyfP18hISG68sorqxwfOHCgbrzxRvXs2VPDhg3Txx9/rE6dOulf//pXvc6loXiZ2joAAADOalCHMEUEWqVCadvhXBWV2ORvZVFiAPVzrKhUx4rKJEntwv3lUYsfugDO3Y4dOxQbe+ofTVar9bQy4eHh8vT0PG1UVEZGxmmjp37PMAzNmzdPN910k3x8fGos6+Hhof79+zNSCgAAADXz9LDo8h4xkqRyu6FNB7NNjgiAO6s6dY/1pIDGEhgYqKCgIMflTEkpHx8f9e3bVytWrKhyfMWKFRo8eHCN9a9atUp79+7VpEmTzhqLYRhKTExUdHR03U6igZGUAgAAcANX9o5xXP85iaQUgPpLqrTIefsI1pMCXM306dP19ttva968edq5c6emTZum5ORkTZkyRZI0Y8YM3Xzzzac97p133tGAAQPUvXv30+578skn9dVXX2n//v1KTEzUpEmTlJiY6KjTLEzfAwAAcAPnxwYrKsiqtLwS7UrP17GiMrX09zY7LABuaN/RAsd1RkoBrmfixInKysrSU089pdTUVHXv3l3Lly937KaXmpqq5OTkKo/Jzc3VokWL9PLLL5+xzpycHN15551KS0tTcHCwevfurdWrV+uCCy5w+vnUhKQUAACAG7BYLLqgfZiWJqZIhrQ+KUtju0WZHRYAN2OzGzqYVSRJCgvwUZAfyW3AFU2dOlVTp049433z588/7VhwcLCKioqqre+ll17SSy+91FDhNRim7wEAALiJgfFhjus/72cKH4C6O5JzXKXldklS+whGSQEwF0kpAAAAN9EqyKr4E1NtkrOLlJp73OSIALibyoucx5OUAmAyklIAAABuZEB8qOP6OkZLAaij/Zmn1pPqwCLnAExGUgoAAMCN9I8PlcVScf3npCwZhmFuQADcysmd9zw9LGob6m9yNACaO5JSAAAAbiTYz1tdooMkSZn5pdpfaWt3AKhJUalNqTnFkqQ2oX7y9uTnIABz8S4EAADgZga2P7Xg+br9WSZGAsCdHKiUxD65Ph0AmImkFAAAgJvp3TZE3p4Vc/g2Hjgmm50pfADObv9R1pMC4FpISgEAALgZP29P9WwTIknKLy7XjtQ8cwMC4Bb2VxkpRVIKgPlISgEAALihyrvw/cwUPgBnYRiGIykVYPVUq0AfkyMCAJJSAAAAbun82BD5Wz0lSVuSc1RSbjM5IgCu7FD2cRUUl0uqWE/KcnIbTwAwEUkpAAAAN+TlaVG/uIrRUiXldiUeyjE3IAAubcuhY47r7VlPCoCLICkFAADgpqpO4cs2MRIArm5Lco7jOjvvAXAVJKUAAADcVKfIFgoN8JYk/ZqSp4KScpMjAuCqKo+mbE9SCoCLICkFAADgpiwWiy6ID5Mk2eyGNhw4dpZHAGiOSspt2pFSsUtnVJBVAVYvkyMCgAokpQAAANwYu/ABOJsdKXkqtdklSfHhrCcFwHWQlAIAAHBjrVv6KSbEV5K0N6NAmQUlJkcEwNVUmboXwdQ9AK6DpBQAAIAbs1gsGtA+zHH75yQWPAdQVeVFztl5D4ArYTIx4EJ2797t1PoTEhKcWj8AwBwD4kO1ePMRSRVT+C7pHiWLxWJyVABcxcmRUt6eFrVu6WduMABQCSOlAAAA3Fx4C6s6tqoY/ZCSU6wjOcdNjgiAq8gqKFFydpEkKS4sQJ4eJKwBuA6SUgAAAE1A5Sl86/YzhQ9AhSrrSYWznhQA10JSCgAAoAno366lYwTE+qQsGYZhckQAXEHlpFQ8i5wDcDEkpQAAAJqAFlYvdYsJkiRlF5bpt/QCkyMC4Aqq7rzHIucAXAtJKQAAgCZiQPtQx/V17MIHNHt2u6HEEzvvRQRaFervbW5AAPA7JKUAAACaiF5tQmT1qvh6t/FgtsptTOEDmrP9mQXKLymXVPH+wK6cAFwNSSkAAIAmwurlqd5tQyRJRSU2bU/JNTcgAKbacmKUlCTHewMAuBKSUgAAAE1I1V34skyMBIDZtlRaT6pXmxDT4gCA6niZHQAAAAAaTtfoILXw9VJBcbm2HsrRrrR8dY4KNDsst7N7926n1p+QkODU+gFJjvWkLBapR+sQHTlAohqAa2GkFAAAQBPi6WHRBe1aSpLKbIZe+Gq33ly9X8eKSk2ODEBjKiot1+70fElSQmSgWlgZjwDA9ZCUAgAAaGLG94pVfHiA4/b6pGw9tni7vtiWpjKb3cTIADSWbYdzZbNXbHbA1D0AroqkFAAAQBMTYPXSXy/prFsGx6mFb8XoiJJyuxZtPqwnl/6q7Sl5JkcIwNkSWU8KgBtgDCcA07BeBwA4j8Vi0bDzItS3bag+TTys73cflWFIaXklmr1ij3q3DdHE/m0U3sJqdqgAnKByUqp325bmBQIANWCkFAAAQBPmb/XUHwfE6f9d1lXnRbZwHN+SnKPHP92upVtTmNIHNEFbTixyHuDjqY6tWtRcGABMwkgp4HcYvQMAaIrahPrrobEJ+jkpWx9vPKy842Uqsxlampiin/Zm6rr+bdSpkyGLxWJ2qADOUVpusdLyiiVV7Lrn6UG/BuCaGCkFAADQTFgsFg1sH6ZnruquMd0iHT9UswpK9dr3+3Truxu0/2iByVECOFeJh445rvduG2JeIABwFiSlAAAAmhk/b0/9oV8b/e3yruoSHeg4vmrPUY2dvVqzvtylwpJyEyMEcC5OTt2TWOQcgGtj+h4AAEAzFRPip+mjO2lzco4WbkjWoXypzGZozsp9Wrz5iB69tIsu6xFtdpjNCssIoCFsqbzzHiOlALgwRkoBAAA0YxaLRX3jWurvV3bXvSM7ysez4uthWl6x/vTRFl3/1jodOXbc5CgB1JbNbmjb4VxJUmyIn1oF+pocEQBUj6QUAAAAZPXy1F/GJujracM1MiHCcXzd/mw9+fkOLVh/SEVlNhMjBFAbR3KO6/iJvsooKQCujqQUAAAAHNqFB+jd2y7QO7f0U9tQf0mS3W7om53pemzxNq3ZlyXDMEyOEkB1kjILHdd7s54UABdHUgoAAACnGdUlUl9PG64/j+4kb6+KXfryjpdr3o9Jeu6LXTqYVWRyhADOpPIOmuy8B8DVkZQCAADAGfl6e+pPo87T0+O7q29cS8fxfUcL9fdlO/TvdQdVwC59gEvZf2KklJeHRd1igk2OBgBq5lJJqZkzZ8piseiBBx5wHLNYLGe8PP/88+YFCgAA0IyEtbDq7gs7aProTooKtlYcNKRVu4/q0cXbtGrPUdmZ0geYrqjMptTcYklS15gg+Xp7mhwRANTMZZJSGzZs0JtvvqkePXpUOZ6amlrlMm/ePFksFl1zzTUmRQoAANA8dY0J0hOXd9e1/VrL6lXxNbKwxKZ/rz2op5ft1L5K04YANL4DRwulE/nhXqwnBcANuERSqqCgQDfccIPeeusttWzZssp9UVFRVS5LlizRyJEj1b59e5OiBQAAaL68PC0a2y1Kz1x1vga2D3UcT84q0szluzTvpyTlHS8zMUKg+aq8nhRJKQDuwMvsACTpnnvu0aWXXqqLLrpITz/9dLXl0tPTtWzZMr333ns11ldSUqKSkhLH7fz8fEmS3W53XAzDkN1ub5gTaATO3uXGnZ4LZzPzuXbHv/O59Cd3PF/gbM7ldX3yNWu32+Xhceb/G1X3um6M3dDMapu+fIpZz/WZ2g3289KkofEadl64Plp/SIePHZckrdmbpS3JOXpwTCe1ObF7X0O2W1u16U/Oars2XK1dNB5n/o33Z55KSvVsHXza37upfkbxujafmd9D3IE7x+5spielFixYoM2bN2vDhg1nLfvee+8pMDBQV199dY3lZs6cqSeffPK041lZWfLx8ZHdbldubq4Mw6jxS4orycnJcWr9GRkZTq3fnZj5XLvj3/lc+pM7ni9wNufyujYMQ0VFRTIMQxaL5YxlqntdO7s/mdk2ffkUs57rmtptZZX+NDRGaw/k6sud2Sout+t4qU3/3XBQtw+Idlq7Z1Ob/uSstmvD1dpF43Hm33j/0YpFzoN8PeVvK1BGRmGDte3Kn1G8rs1n5vcQd5CVlWV2CC7L1KTUoUOHdP/99+vrr7+Wr6/vWcvPmzdPN9xww1nLzpgxQ9OnT3fcPnLkiLp27aqwsDC1atVKdrtdFotFERERJKVOaNWqlVPrdydmPtfu+Hc+l/7kjucLnM25vK5P9qegoKBq+1N1r+vG+DJoVtv05VPMeq5r0+6lLUM0rHOMnl6+U8cKy7T76HHJx18h/j5Obbc6telPzmq7NlytXTQeZ/2Nj+aXqKDEJknq3balIiMjG7RtV/6M4nVtPjO/h7iD0tJSs0NwWaYmpTZt2qSMjAz17dvXccxms2n16tV69dVXVVJSIk/Pih0jfvjhB+3evVsLFy48a71Wq1VWq9VxOy8vT5Lk4eHheAO1WCxVbru6mv7D1xDc5XloDGY+1+76d65vf3LX8wVqci6v65OvWQ8Pj2rrqe517ez+ZGbb9OVTzHqua9tusL+PBncI17JfUmW3G1p/4JjGdotyers11VlTf3JW27Xhau2i8Tjrb5yUdWpUVO+2Lc/4t26qn1G8rs1n5vcQd1Cf2F9//XU9//zzSk1NVbdu3TR79mwNGzbsjGVXrlypkSNHnnZ8586d6ty5s+P2okWL9Pjjj2vfvn3q0KGDnnnmGV111VV1jq0hmfpXHTVqlLZt26bExETHpV+/frrhhhuUmJjoSEhJ0jvvvKO+ffuqZ8+eJkYMAACAmgzpEO64/tPezEZZZwSAlHT0VFKKRc4B97Zw4UI98MADevTRR7VlyxYNGzZM48aNU3Jyco2P2717t1JTUx2X8847z3Hf2rVrNXHiRN10003aunWrbrrpJv3hD3/Qzz//7OzTqZGpSanAwEB17969yiUgIEBhYWHq3r27o1xeXp7++9//avLkySZGCwAAgLNpFWTVeZEtJEkpOcU6kFVkckRA87CPpBTQZLz44ouaNGmSJk+erC5dumj27Nlq06aN5syZU+PjWrVqpaioKMel8kCf2bNna/To0ZoxY4Y6d+6sGTNmaNSoUZo9e7aTz6ZmbjH+bcGCBTIMQ9dff73ZoQAAAOAsBncIc1xfszfTxEiA5qHMZteh7IoEcFSQtVZruQFofPn5+crLy3NcSkpKTitTWlqqTZs2acyYMVWOjxkzRmvWrKmx/t69eys6OlqjRo3S999/X+W+tWvXnlbn2LFjz1qns7lcUmrlypWnZeruvPNOFRUVKTg42JygAAAAUGv924XKx6via+bPSdkqs7EVNuBMh48dV7m9YqpsfHgLk6MBUJ2uXbsqODjYcZk5c+ZpZTIzM2Wz2U7brCAyMlJpaWlnrDc6OlpvvvmmFi1apP/9739KSEjQqFGjtHr1akeZtLS0OtXZWExd6BwAAABNj6+3p/q2bam1+7NUVGpT4qEc9W8XanZYQJO172iB43r7iAATIwFQkx07dig2NtZxu/IGbb/3+8XjDcOodkH5hIQEJSQkOG4PGjRIhw4d0gsvvKDhw4fXq87G4nIjpQAAAOD+hpx3agrfT0zhA5wqKfPUelLtIxgpBbiqwMBABQUFOS5nSkqFh4fL09PztBFMGRkZp410qsnAgQP122+/OW5HRUWdc53OQFIKAAAADS4hMlBhARXr2vyakqdjRWUmRwQ0XftPLHLu7WlR65Z+JkcD4Fz4+Piob9++WrFiRZXjK1as0ODBg2tdz5YtWxQdHe24PWjQoNPq/Prrr+tUpzMwfQ8AAAANzmKxaHDHcH22NUWGIa3bl6Vx50eZHRbQ5OQXl+lofsViyW3DAuTpYe5UHADnbvr06brpppvUr18/DRo0SG+++aaSk5M1ZcoUSdKMGTN05MgRvf/++5IqdtZr166dunXrptLSUn3wwQdatGiRFi1a5Kjz/vvv1/DhwzVr1iyNHz9eS5Ys0TfffKMff/zRlHM8iaQUAAAAnGJwhzB9tjVFkvTTvqO6uHuk6WtXAE1N5al7HcJZTwpoCiZOnKisrCw99dRTSk1NVffu3bV8+XLFxcVJklJTU5WcnOwoX1paqr/85S86cuSI/Pz81K1bNy1btkyXXHKJo8zgwYO1YMECPfbYY3r88cfVoUMHLVy4UAMGDGj086uMpBQAAACcIiLQqk6RLbQnvUBpuSXan1moDqx3AzSok1P3JCmeRc6BJmPq1KmaOnXqGe+bP39+ldsPPfSQHnroobPWOWHCBE2YMKEhwmswrCkFAAAApxnSMdxxfc2+LBMjAZqm/ZUXOWekFAA3Q1IKAAAATtMvrqWsXhVfOdcnZavMZjc5IqBuCkrK9fAnv2jyexuUmnvc7HCqMAzDMX0vyM9boSc2FwAAd0FSCgAAAE5j9fZU33YtJUnHS23anHzM5IiA2sssKNH1b67Two2H9M3ODE35YLNKy10nsZqWV6zjpTZJUvuIANZsA+B2SEoBAADAqYZ0ODWF76e9TOGDe0jOKtKEOWu07Uiu49jWQzl6/qtdJkZVVZX1pJi6B8ANkZQCAACAU3WKbKGIQKskaUdqnrILS02OCKjZrym5umbuGh3IKpIkRQZZ5e1ZMQrprR+S9O3OdDPDc6i8nlQHFjkH4IZISgEAAMCpLBaLBncIq7hhSGv3M1oKrmvtvixd98Y6Hc0vkSR1bNVCi6cO0V8v6eIo8+f/blVKjvnrSzlGSlmkdmEkpQC4H5JSAAAAcLpBJ5NSktbszZRhGCZGA5zZF9tSdcu89covKZck9Wkbok+mDFJMiJ9uHdxOY7pGSpJyisp030dbVG7iwv2l5XYdOZEYiw32k6+3p2mxAEB9kZQCAACA04W3sKpzdKAkKT2vRPsqrYUDuIIP1h3U1P9sVumJRNP/dW6lDycPVIh/xY52FotFz0/oqdgQP0nSxoPH9OKKPabFeyCrSHZ7RXK3PVP3ALgpklIAAABoFFUXPM80MRLgFMMw9NKKPXrs0+06OYBvQt/WeuOmvvLzqTr6KNjfW//6Y295eVSsL/X6yn1atedoY4csSdp/tMBxvT2LnANwUySlAAAA0Cj6xIU4phhtOHBMpeXmTX0CJMlmN/Top9v18re/OY7dfWEHPT+hh7w9z/xTqU/blnro4gTH7ekLE5WeV+z0WH8vqdIi5/GMlALgpkhKAQAAoFFYvTzVv11LSVJxmU2bk4+ZHBGas+Iym+75cLP+83Oy49jjl3XVwxd3lsViqfGxk4e218iECElSVmGp7l+wRTZ7466Ttj+zYqSU1ctDMSemFAKAuyEpBQAAgEYzuCNT+GC+3ONlunneen35a5okydvTopev66VJQ+Nr9XgPD4v++YdeigrylSSt25+tVyqNtnK2Y0VlOlZYJkmKDw+Qx1mSaADgqkhKAQAAoNF0jAhQq0CrJGlnWr6yCkpMjgjNTUZesSa+sVbrk7IlSf4+nnrnlv4a3yu2TvWEBvjolet768TyUnrlu9+0ppESrUmV1pNi6h4Ad0ZSCgAAAI3GYrFoSMewihuGtGZflrkBoVnZf7RAV89Zo11p+ZIqEksf3TFQwztF1Ku+C+JDNX10J0mSYUj3L0xUZiMkWvdXWk+KRc4BuDMvswMAAABA8zKoQ7gWJ6Y4klKGYZx1DR/gXG09lKPb5m9QdmGpJKlXUJGmjW4t36J07d6dXu96L4oxtK21XTtS8qRC6dH5X2vaReepc+fODRX6afZV3nkvooXT2gEAZ2OkFAAAABpVaICPukYHSZKO5pc4plEBzrJ6z1Fd/9Y6R0Kqc1SgZozr4lgT6lxYLBZNHhqvID9vSdKOlDwt3552zvVWx2Y3dDCrSJIUFuCj4BPtAoA7IikFAACARueYwifpk02HTYwETd2SxCO6ff4GFZXaJFVMuVt41yCF+DdcMifIz1t3DouXLCfbTNGGA85JtqbkHFdpuV0S60kBcH8kpQAAANDoerdpKT9vT0nSsm2pKiwpNzkiNEXzfkzS/QsSVW43JEkXd4vS+7df4JTRRZ2jg3R5jxhJkt1u6E//2eIYmdWQqqwnRVIKgJsjKQUAAIBG5+Plof7xoZKkolKbvnDidCc0P4ZhaNaXu/TU5zscx/44oK1eu6GPfE8kQ53h8p7RSoiqWOMpLa9Yf/nvVtlPJMQayv7K60mFs54UAPdGUgoAAACmqDqF75CJkaApKbfZ9eAnv2jOyn2OY/ePOk/PXNldnh7OXVDfw2LRHcM6KNC3Yj+p73Zl6J0fkxq0jaQTI6U8PSyKC/Nv0LoBoLGRlAIAAIAp2ocHKCrYKklatz9bh7KLTI4I7u54qU13/XuTY50yi0X6+5XdNW10p0bb4THE31uThrV33J715S5tTj7WIHUXldmUklssSWrd0k/envycA+DevMwOAID5du/eXe/HGoahnJwc5eTkVPtlLyEhod71AwCaLovFosEdwrVhY8XIj082Hda00Z1MjgruKqeoVLfP36DNyTmSJB9PD82+rpcuOT+60WPpHhOkuy8M1JyV+1R+Yn2p5fcNU/A5Lq5+4GihdGI2YPtw1pMC4P5IrQMAAMA0gzqE6+SMqkWbDzf4+jtoHlJyjmvC3LWOhFSg1Uvv3X6BKQmpk/48upP6xbWUJB3JOa6HFm2VYZzb6zsps9J6UhGsJwXA/ZGUAgAAgGla+ntr2HkRkqTDx47r56RskyOCu/ktPV/XzFmjvRkVCZuIQKsW3DVQgzqEneWRzuXl6aFXru+tkBOjo776NV3vrTlwTnXuP3pq5714dt4D0ASQlAIAAICpJvRt7bj+XxY8Rx1sOnhME+auVeqJdZbahflr0ZTB6hYTbHJkFWJC/PTChJ6O288u36WDWfVbO80wDO0/sci5v9VTkYHWBokRAMxEUgoAAACmGt01UkEndiv7YluaCkrKTY4I7uDbnem64e11yj1eJkk6PzZYn9w9WG1dbEe6i7pGavLQeElSqc2uuav26XiZrc71ZBWWKr+4om+0Dw9otIXbAcCZSEoBAADAVL7enrqiV4wk6XiZTcu3pZocEVzdfzce0p3/3qTiMrskaWjHcH1050CFt3DN0UMPXdxZPduESJKO5pfovTUH6ry+1L6jp9aTig9nPSkATQNJKQAAAJhuQt82juufbDxsYiRwZYZhaM7KfXrwk19kO7Eo/uU9YzTv1v5qYXXdjcV9vDz06vW9FXhiRODGA8e0+rfMOtWRVGk9qfasJwWgiSApBQAAANP1bB2sjq0qRn+sP5CtA5mFZ3kEmhu73dDfP9+pWV/uchy7dXA7vTyxl3y8XP9nTZtQfz0/oYfj9kfrk3X4WO3Xl9pfqU/Eh5OUAtA0uP67NwAAAJo8i8WiaysteL5oM6OlcEppuV0PLEzUvJ+SHMceujhBf7u8qzw83GdtpYu7R+v/OlfsNlluMzR31T6V1GJ9qTKbXcknFkiPDLK69KgwAKgLklIAAABwCVf1jtXJ/MKiTYfrvOYOmqaCknJNem+Dlm5NkSR5elj0j2t6aOqFHd1yse9r+7VxLMaelluif69LPutr/fCx4yo/MV2R9aQANCUkpQAAAOASWgX5akSnilEkKbnF2pWWb3JEMFtWQYn++NY6/XBi/SWrl4feuLGv/tC/zVke6bq8PT00ZXgH+Xp7SpLW7c/Smn1ZNT5mf6VFzjuwnhSAJoSkFAAAAFzGtf1OJRt+2lu3haDRtBzKLtKEuWv1y+FcSVKQr5c+nDxAF3WNNDmyc9cqyKqbB8U5bn/4c7JSco5XW77KelIkpQA0ISSlAAAA4DJGdWmlEH9vSdKm5GMqqsV6O2h6dqTk6eo5a5R0IhkTFeSrT+4erH7tQk2OrOFcEB+q4SdGBpaW2zV31T6VltvPWHb/iZ33vD0tah3i32gxAoCzkZQCAACAy7B6eWp8zxhJUlm5oU1J2SZHhMa2bn+WJr6xVkfzSyRVTFdbNHWwOkUGmhxZw7v+gjZq3dJPkpSSU6yP1iefVqagpNzxXLQNC5CXp/utowUA1SEpBQAAAJcyoe+pKXw/nmWtHTQtX25P1c3z1iu/pFyS1LttiD6ZMlixIX4mR+Yc3p4eumtEB/l4Vfws++G3TK3bX/U1X3k9qfbhTN0D0LSQlAIAAIBL6R4bpIQTo2L2ZRQoLa/Y5IjQGD78+aCmfrjZMYVtZEKEPpw8QC0DfEyOzLmig31148BT60v9e+3BKq/5pKOn1pNqz3pSAJoYklIAAABwKRaLRdf2a+24vWYfC543ZYZh6OVvftOji7fLblQcu6ZPa715cz/5+3iZG1wjGdwhTIM7hkmSSsrtmrtqv8psFcm5fZUWOWekFICmhqQUAAAAXM74XrHy8KhYO2ft3izZDcPkiOAMNruhx5ds10vf7HEcu2tEe71wbQ95ezavnyo3DGir6BBfSdLh7CIt3HBIhmE4FnsP8vNWaBMfNQag+Wle7/QAAABwCxGBVp0fGyRJOlZUpp2p+SZHhIZWXGbTvf/ZrA/WnVrc+7FLu2jGuC6yWJrfYt5WL09NGd5B3icWMl+5+6g+/yVVx0srdqBsHxHQLJ8XAE0bSSkAAAC4pCEdwh3Xf9rLFL6mJK+4TLe+u15fbE+TJHl5WDR7Yi9NHtbe5MjMFdvST3+8oK3j9pLEFMf1eKbuAWiCSEoBAADAJfVoHaIWVk9J0pbkYyo6MWIE7i0jr1gT31indfuzJUn+Pp5659b+urJ3rMmRuYah54VrQPvQ0453ICkFoAkiKQUAAACX5OVp0YD2FYs/l9kMbTiQbXJEOFdJmYW6Zu4a7UzNkySFBvjoP3cM1IhOESZH5josFotuGhinyCBrpYNSO5JSAJogklIAAABwWUM6nprC9+NvTOFzZ9sO52rCnDU6lH1ckhQb4qf/ThmkXm1CzA3MBfl6e+quER3kdWJ9qXZh/vL19jQ5KgBoeCSlAAAA4LLahvqrdai/pIpRNqm5x02OCPXxw29Hdd2ba5VVWCpJ6hwVqP9NHawOES1Mjsx1tQ3117SLOmnYeeG6eVA7s8MBAKcgKQUAAACXNrRDmOP6T3uzTIwE9bF0a4pun79BhSfWBLugXagW3jVIkUG+Jkfm+hKiAnXL4HZqeyIxCwBNDUkpAAAAuLQB7UPl6VExjWntvizZ7IbJEaG23v0pSfd9tEVltoq/2ZiukXp/0gUK9vM2OTIAcG2vv/664uPj5evrq759++qHH36otuz//vc/jR49WhEREQoKCtKgQYP01VdfVSkzf/58WSyW0y7FxcXOPpUakZQCAACASwv09VaP1sGSpNzjZdpxYpFsuC7DMPSPL3fpyc92OI5df0FbvX5DH9ZGAoCzWLhwoR544AE9+uij2rJli4YNG6Zx48YpOTn5jOVXr16t0aNHa/ny5dq0aZNGjhypyy+/XFu2bKlSLigoSKmpqVUuvr7mjlr1MrV1AAAAoBaGdAzXluQcSdJPezN1fmywuQGhWuU2u/66eJs+3njYcey+/+uoaaM7yWKxmBgZALiHF198UZMmTdLkyZMlSbNnz9ZXX32lOXPmaObMmaeVnz17dpXbzz77rJYsWaLPPvtMvXv3dhy3WCyKiopyaux1xUgpAAAAuLzzY4MV6Fvx/9TE5BwVlpSbHBHO5HipTVM+2ORISFks0t/Hd9P0MQkkpAA0e/n5+crLy3NcSkpKTitTWlqqTZs2acyYMVWOjxkzRmvWrKlVO3a7Xfn5+QoNDa1yvKCgQHFxcWrdurUuu+yy00ZSmYGkFAAAAFyep4dFA9tXLHhebje0Pinb5IjwezlFpbrpnZ/1zc4MSZKPp4de+2Mf3cTOcQAgSeratauCg4MdlzONesrMzJTNZlNkZGSV45GRkUpLS6tVO//85z9VWFioP/zhD45jnTt31vz587V06VJ99NFH8vX11ZAhQ/Tbb7+d20mdI6bvAQAAwC0M6RimFTvSJUlr9mVqZOdWJkeEk1Jzj+vmd9brt4wCSVILq5fevLmvBncINzkyAHAdO3bsUGxsrOO21WqttuzvR5cahlGrEacfffSRnnjiCS1ZskStWp36nBw4cKAGDhzouD1kyBD16dNH//rXv/TKK6/U5TQaFEkpAAAAuIXWLf3VNsxfyVlFSsosUkrOccWE+JkdVrO3NyNfN7+zXim5FTs4hbewav5t/dWddb8AoIrAwEAFBQXVWCY8PFyenp6njYrKyMg4bfTU7y1cuFCTJk3Sf//7X1100UU1lvXw8FD//v1NHynF9D0AAAC4jSEdwhzXf9qXZWIkkKRNB49pwty1joRUXJi/Ft09iIQUANSTj4+P+vbtqxUrVlQ5vmLFCg0ePLjax3300Ue69dZb9Z///EeXXnrpWdsxDEOJiYmKjo4+55jPBUkpAAAAuI0B7cPk6VExfWHtvizZ7IbJETVf3+1K1w1vr1NOUZkkqXtskD6ZMlhxYQEmRwYA7m369Ol6++23NW/ePO3cuVPTpk1TcnKypkyZIkmaMWOGbr75Zkf5jz76SDfffLP++c9/auDAgUpLS1NaWppyc3MdZZ588kl99dVX2r9/vxITEzVp0iQlJiY66jQL0/cAAADgNlpYvdSrTYg2HTymvONl2p6Sq56tQ8wOq9lZtOmwHlr0iyMpOKRjmObe2FeBvt4mRwYA7m/ixInKysrSU089pdTUVHXv3l3Lly9XXFycJCk1NVXJycmO8m+88YbKy8t1zz336J577nEcv+WWWzR//nxJUk5Oju68806lpaUpODhYvXv31urVq3XBBRc06rn9HkkpAAAAuJUhHcO06eAxSdKavVkkpRqRYRh6c/V+zfxil+PYpT2i9eIfesrq5WliZADQtEydOlVTp049430nE00nrVy58qz1vfTSS3rppZcaILKGRVIKAAAAbqVbTLCC/LyVd7xMiYdyVFBSrhZWvtY6m91u6NnlO/X2j0mOY7cObqf/d1lXeXicfUcoAAB+j09vAAAAuBVPD4sGdQjTV9vTZLMb+nl/lkZ1qXlHooaWV1ymHSl52n4kV7vT8xUd7KdJQ+MV7Nc0p6+Vltv10Cdb9WliiuPYg2MTNPXCDrXaohwAgDMhKQUAAAC3M+REUkqq2IXP2Ukpm93Q/sxCbT+Sq+1HcnUwq6jK/ccKy/TMsh26b9R5at3S36mxNLbCknLd/eFmrd5zVJLkYZFmXn2+JvZva3JkAAB3R1IKAAAAbicmxE/x4f5KyixSclaRDh8ravBkUHZhqX49kqvtKXnakZqn46W2s5Qv08zlu3TniPZNZp2rrIIS3T5/g7YertjByerloVf/2EejuzbuyDQAQNNEUgoAAABuaXCHcCVlVuw+9NPeLE3sf25JqZJymzYkHdOqPRn65dedSskprrZsm1B/dY8NUveYYEUEWjVn5T4lZRaqpNyuf323V3/o11qju0S69dS2Q9lFumXeeu3PLJQkBfl66Z1b+6t/u1CTIwMANBUkpQAAAOCWBsSHaeGGQyq3G1q3P0sT+raWZx0X3D6YVahVe45q1e6jWrMvS8fLKkZDtfGompAKsHqqW0ywuscGq1t0kIL9q64d9dDFCXrnxyRtPHBMMqSPNxxWWm6JbhjQts4xuYKdqXm6Zd56ZeSXSJIig6x6//YBSogKNDkyAEBTQlIKAAAAbsnf6qlebUO08cAx5ReX65fDOerdtmWNjykpt2l3Wv6JtaHytCl375kLWqT24QHqHhus7jFBahceII8aRj15e3roruHtFR2cqs+2ViwGvnrPUWXkF2vqiI7yt3rW+zwb28/7szT5/Y3KLy6XJLWPCND7t1/Q5NbKAgCYj6QUAAAA3NaQjuEVo5MkrdmXdVpSyjAMpeYWO5JQe9LzVW43KpXwc1wLb2HViE4RujAhQjGWY2phrdtXZYvFovG9YhQZZNX8nw6o3G5oV2q+nl2+Q/eN6qRWQdZ6n2dj+erXNP3poy0qLbdLknq1CdG8W/srNMDH5MgAAE0RSSkAAAC4rW4xQQrx91ZOUZl+OZyr/OIyeXp4aEdKrjYfyNRvmck6Vlh2xsd6elg0IC5UIxIiNKJThLpEBcnjxFS73bvz6x3TwPZhigi06tXv9iq/uFxpeSV6ZvkOTb2wo0tPf/vPz8l67NNtOpmzuzAhQq/f0Ef+PvxkAAA4B58wAAAAcFseFosGtg/Tl9vTZLMbenb5LmUVlspeZTTUKWEBPureumJKXufoIPXq3tUpcXWIaKFHL+2iV779TSk5xSossenFFXt006A4De0Y7pQ268swDP3ru716ccUex7Gre8dq1oQe8vb0MDEyAEBTR1IKAAAAbm1Ix3B9uT1NknT0xMLcJ3l5WpQQFajuJxYpjwqyNtqOeOEtrJpxSRe9sWqfth/Jk81uaP5PB5SWW6wZ53VyjMoyk81u6MnPftX7aw86jt05vL0eubizS8QHAGjaSEoBAADArUUH+6pn62BtPZwrSYoKtqpbTJDig73Uu32UrN7mLTLu5+2pP/3fefp44yF9uzNDkvTl9jQd/GCTZl/Xy9SpcSXlNk1bmKjl29Icxx69pIvuGN7etJgAAM0LSSkAAAC4vTuHt9f+zEJFBFoV3sIqwzCUk5MjHy/zp595elh0/QVtFRXkq482HJLdbujrHem6du5avXNLf0UF+zZ6TPnFZbrz/U1auz9LkuTlYdHz1/bQVb1bN3osAIDmy/xPaQAAAOAcWb091SU6SOEtXHeHu5GdW+m+UefJ78TIrV9T8jT+tR+17cQIr8aSkV+siW+scySk/Lw99fYt/UhIAQAaHUkpAAAAoJF0jwnSjEs6q02onyQpPa9E176xRl9uT22U9g9kFmrCnLXakZonSWrp763/3DFAFya0apT2AQCojKQUAAAA0IhiQvz06dQh6hfXUpJUXGbXlA826/WVe2UYZ941sCEczCrShLlrlJxdJEmKDfHTJ3cPVu+2LZ3WJgAANSEpBQAAADSysBZWfXjHAF3dO9Zx7B9f7ta7Px1Qmc3e4O3tSMnTP77cpcyCUklSQmSgFt09WB0iWjR4WwAA1BZJKQAAAMAEVi9P/fMPPfXg2ATHsTX7svTiij0qKClvsHY2HMjWy9/+ppLyimRX/3Yt9fFdg0xZYB0AgMpISgEAAAAmsVgsumdkR71+Qx9ZT+wU+Ft6gZ5ZtlOpucfPuf5vd6brjdX7ZbNXTAsc3TVS/540QMH+3udcNwAA54qkFAAAAGCyS86P1sd3DVKQX0Wy6Gh+iZ5dvks7UvLqVZ9hGFq85Yg+Wn9IOrFM1bDzwjXnhj7yPbH7HwAAZiMpBQAAALiAnm1C9NilXdQm1F+SdLzUptnf/qaVu4/WqR6b3dD7aw9q2S+ndvS7rEe0bh4UJy9Pvv4DAFyHS30qzZw5UxaLRQ888ECV4zt37tQVV1yh4OBgBQYGauDAgUpOTjYnSAAAAMBJQgN89MjFCerZJkSSZLcb+mDdQS1Ynyx7LXbmK7PZ9frKffrht8yKAxbpjwPa6sresbJYLE6MHACAunOZpNSGDRv05ptvqkePHlWO79u3T0OHDlXnzp21cuVKbd26VY8//rh8fVmYEQAAAE2P1dtT94zsoLHdoxzHvtmZoX99+5uOl9mqfVxRiU0vrtijrYdyJEleHhbdNby9/q9zK2eHDABAvbhEUqqgoEA33HCD3nrrLbVs2bLKfY8++qguueQS/eMf/1Dv3r3Vvn17XXrppWrVig9XAAAANE0eFouu7dtatwyOk6dHxQinbUfy9NzyXcoqKDmt/LGiMs36cpd+Sy+QJPl6e+qBi85T/3ahjRo3AAB14WV2AJJ0zz336NJLL9VFF12kp59+2nHcbrdr2bJleuihhzR27Fht2bJF8fHxmjFjhq688spq6yspKVFJyakP6/z8fEd9Jy+GYchutzvtnBqaUYvh2ufCnZ4LZzPzuTar7XNp92SddrtdHh5nznM7o93a4HUNMzTV/mRm2/TlU9zxc8KsdmvTn5zVdm3Utt2hHcMVHmDVnNX7VFRi05Gc43p62U7dO7KD2ke0kCSl5hzX7G9/U3ZhmSQp0NdL94/qqLiwgNPqoz+d4ip/Y3dp25U/o3hdm8/M17U7cOfYnc30pNSCBQu0efNmbdiw4bT7MjIyVFBQoOeee05PP/20Zs2apS+//FJXX321vv/+e40YMeKMdc6cOVNPPvnkacezsrLk4+Mju92u3NxcGYZR45cUV5KTk+PU+jMyMpxavzsx87k2q+1zadcwDBUVFckwjGrXqnBGu7XB6xpmaKr9ycy26cunuOPnhFnt1qY/Oavt2qhLu1F+0r1DYzVvXaoyC8uUX1yu57/ao4m9Wik0wFvv/JyiotKKHzxhAV66Y2Csgj3LzlgX/ekUV/obu0PbrvwZxevafGa+rt1BVlaW2SG4LFOTUocOHdL999+vr7/++oxrRJ3MJo4fP17Tpk2TJPXq1Utr1qzR3Llzq01KzZgxQ9OnT3fcPnLkiLp27aqwsDC1atVKdrtdFotFERERJKVOYDrkKWY+12a1fS7tnuxPQUFB1fYnZ7RbG7yuYYam2p/MbJu+fIo7fk6Y1W5t+pOz2q6NurYbEiI9dllLzV21T7vSClRuN/Th5nR5eVpUbqsYodA21F/3jeqoYD/vOrfbHLna39jV23blzyhe1+Yz83XtDkpLS80OwWWZmpTatGmTMjIy1LdvX8cxm82m1atX69VXX1VhYaG8vLzUtWvXKo/r0qWLfvzxx2rrtVqtslqtjtt5eXmSJA8PD8cbqMViqXLb1Tl7txR3eR4ag5nPtVltn0u7J+v08PCoth5ntFsbvK5hhqban8xsm758ijt+TpjVbm36k7Paro36tNvC11sPXJSgD38+6Nhd72RCqnN0oO4Z2VF+3p71arc5csW/sSu37cqfUbyuzWfm69oduHPszmZqUmrUqFHatm1blWO33XabOnfurIcfflhWq1X9+/fX7t27q5TZs2eP4uLiGjNUAAAAwHRenhbdPChO0cG++njTYcmQ+rVrqUlD4+XtyY8eAIB7MTUpFRgYqO7du1c5FhAQoLCwMMfxBx98UBMnTtTw4cM1cuRIffnll/rss8+0cuVKEyIGAAAAzGWxWDSmW5S6xwYrp6hMXaIDG2WUAgAADc30hc7P5qqrrtLcuXM1c+ZM3XfffUpISNCiRYs0dOhQs0MDAAAATBMT4qeYED+zwwAAoN5cLil1phFQt99+u26//fbGDwYAAAAAAABOwcRzAAAAAAAANDqSUgAAAAAAAGh0JKUAAAAAAADQ6EhKAQAAAAAAoNGRlAIAAAAAAECjIykFAAAAAACARkdSCgAAAAAAAI2OpBQAAAAAAAAaHUkpAAAAAAAANDqSUgAAAAAAAGh0JKUAAAAAAADQ6EhKAQAAAAAAoNGRlAIAAAAAAECjIykFAAAAAACARkdSCgAAAAAAwIW8/vrrio+Pl6+vr/r27asffvihxvKrVq1S37595evrq/bt22vu3LmnlVm0aJG6du0qq9Wqrl27avHixc4Kv9ZISgEAAAAAALiIhQsX6oEHHtCjjz6qLVu2aNiwYRo3bpySk5PPWD4pKUmXXHKJhg0bpi1btuivf/2r7rvvPi1atMhRZu3atZo4caJuuukmbd26VTfddJP+8Ic/6Oeff26s0zojklIAAAAAAAAu4sUXX9SkSZM0efJkdenSRbNnz1abNm00Z86cM5afO3eu2rZtq9mzZ6tLly6aPHmybr/9dr3wwguOMrNnz9bo0aM1Y8YMde7cWTNmzNCoUaM0e/bsRjqrMyMpBQAAAAAA4AJKS0u1adMmjRkzpsrxMWPGaM2aNWd8zNq1a08rP3bsWG3cuFFlZWU1lqmuzsbiZWrrjcRut0uSUlNTHbezsrJUWloqDw/3yMtlZGQ4tf6AgACn1u9OzHyuzWr7XNo1DEN5eXkqLS2VxWJptHZrg9c1zNBU+5OZbdOXT3HHzwmz2q1Nf3JW27Xhau02R031b+ystl35M4rXtfnMfF27g5O5iNzcXAUFBTmOW61WWa3WKmUzMzNls9kUGRlZ5XhkZKTS0tLOWH9aWtoZy5eXlyszM1PR0dHVlqmuzsbSLJJS6enpkqQLLrjA5EgAAAAAAEBz1L179yq3//a3v+mJJ544Y9nfJ38Nw6jxnyxnKv/743WtszE0i6RU7969tX79ekVGRsrDw0P5+fnq2rWrduzYocDAQLPDA9wa/QloOPQnoOHQn4CGRZ8C6s9utys5OVldu3aVl9epNMzvR0lJUnh4uDw9PU8bwZSRkXHaSKeToqKizljey8tLYWFhNZaprs7G0iySUl5eXurfv7/jdl5eniQpNja2ytA5AHVHfwIaDv0JaDj0J6Bh0aeAc9O2bdtalfPx8VHfvn21YsUKXXXVVY7jK1as0Pjx48/4mEGDBumzzz6rcuzrr79Wv3795O3t7SizYsUKTZs2rUqZwYMH1/VUGlSzSEoBAAAAAAC4g+nTp+umm25Sv379NGjQIL355ptKTk7WlClTJEkzZszQkSNH9P7770uSpkyZoldffVXTp0/XHXfcobVr1+qdd97RRx995Kjz/vvv1/DhwzVr1iyNHz9eS5Ys0TfffKMff/zRlHM8iaQUAAAAAACAi5g4caKysrL01FNPKTU1Vd27d9fy5csVFxcnqWLh9OTkZEf5+Ph4LV++XNOmTdNrr72mmJgYvfLKK7rmmmscZQYPHqwFCxboscce0+OPP64OHTpo4cKFGjBgQKOfX2UW4+TqV81ISUmJZs6cqRkzZpxxDieA2qM/AQ2H/gQ0HPoT0LDoUwCcoVkmpQAAAAAAAGAuD7MDAAAAAAAAQPNDUgoAAAAAAACNjqQUAAAAAAAAGp3TklIzZ85U//79FRgYqFatWunKK6/U7t27q5QxDENPPPGEYmJi5OfnpwsvvFC//vqr4/7s7Gz96U9/UkJCgvz9/dW2bVvdd999ys3NrVJPu3btZLFYqlweeeSRs8a4bds2jRgxQn5+foqNjdVTTz2lyktsrVy58rR6LRaLdu3adc7nfqZ6LRaLnn/++bPGjeanKfQnqWKBzEcffVRxcXGyWq3q0KGD5s2bd9a6X3/9dcXHx8vX11d9+/bVDz/8UOX+J554Qp07d1ZAQIBatmypiy66SD///PNZ60Xz1Zz71OrVq3X55ZcrJiZGFotFn3766WllznbuQGX0p5r7E9/5UBfNuT/V5twru+uuu2SxWDR79uyzxgzAhRlOMnbsWOPdd981tm/fbiQmJhqXXnqp0bZtW6OgoMBR5rnnnjMCAwONRYsWGdu2bTMmTpxoREdHG3l5eYZhGMa2bduMq6++2li6dKmxd+9e49tvvzXOO+8845prrqnSVlxcnPHUU08Zqampjkt+fn6N8eXm5hqRkZHGddddZ2zbts1YtGiRERgYaLzwwguOMt9//70hydi9e3eVusvLy8/53CvXl5qaasybN8+wWCzGvn37av0co/loCv3JMAzjiiuuMAYMGGCsWLHCSEpKMn7++Wfjp59+qrHuBQsWGN7e3sZbb71l7Nixw7j//vuNgIAA4+DBg44yH374obFixQpj3759xvbt241JkyYZQUFBRkZGRq2eXzQ/zblPLV++3Hj00UeNRYsWGZKMxYsXn1bmbOcOVEZ/qrk/8Z0PddGc+1Ntzv2kxYsXGz179jRiYmKMl156qcZ6Abg2pyWlfi8jI8OQZKxatcowDMOw2+1GVFSU8dxzzznKFBcXG8HBwcbcuXOrrefjjz82fHx8jLKyMsexuLi4Or8Zvf7660ZwcLBRXFzsODZz5kwjJibGsNvthmGcSkodO3asTnX/3u/P/UzGjx9v/N///d85tYPmwx370xdffGEEBwcbWVlZdar7ggsuMKZMmVLlWOfOnY1HHnmk2sfk5uYakoxvvvmmTm2h+WpOfaqyM/2Iru+5AyfRn2rGdz7URXPtT4ZR/W+ow4cPG7Gxscb27dvrdQ4AXEujrSl1crhoaGioJCkpKUlpaWkaM2aMo4zVatWIESO0Zs2aGusJCgqSl5dXleOzZs1SWFiYevXqpWeeeUalpaU1xrN27VqNGDFCVqvVcWzs2LFKSUnRgQMHqpTt3bu3oqOjNWrUKH3//fe1Ot/fxyydOvffS09P17JlyzRp0qQ6143myR3709KlS9WvXz/94x//UGxsrDp16qS//OUvOn78eLX1lpaWatOmTVXOS5LGjBlT7XmVlpbqzTffVHBwsHr27Flj3MBJzaVP1UZ9zx04if5UPb7zoa6ac386028ou92um266SQ8++KC6detWp/oAuCavsxc5d4ZhaPr06Ro6dKi6d+8uSUpLS5MkRUZGVikbGRmpgwcPnrGerKws/f3vf9ddd91V5fj999+vPn36qGXLllq/fr1mzJihpKQkvf3229XGlJaWpnbt2p3W9sn74uPjFR0drTfffFN9+/ZVSUmJ/v3vf2vUqFFauXKlhg8fXu9z/7333ntPgYGBuvrqq2tVJ5o3d+1P+/fv148//ihfX18tXrxYmZmZmjp1qrKzs6tdYyAzM1M2m+2M53XynE/6/PPPdd1116moqEjR0dFasWKFwsPDq40ZOKk59anaqM+5AyfRn2rGdz7URXPuT9X9hpo1a5a8vLx033331aoeAG6gMYZjTZ061YiLizMOHTrkOPbTTz8ZkoyUlJQqZSdPnmyMHTv2tDpyc3ONAQMGGBdffLFRWlpaY3uffPKJIcnIzMw0DMMwunbtagQEBBgBAQHGxRdfbBiGYYwePdq48847qzzu8OHDhiRj7dq11dZ92WWXGZdffrlhGIaxevVqR70BAQHGBx98UKtz/72EhATj3nvvrfGcgJPctT+NHj3a8PX1NXJychxlFi1aZFgsFqOoqOiM/enIkSOGJGPNmjVV6n766aeNhISEKscKCgqM3377zVi7dq1x++23G+3atTPS09NrPDfAMJpXn/o9nWG6UV3PHaiM/rS4xnj5zoe6aM796UznvnHjRiMyMtI4cuSI4xjT9wD35/SRUn/605+0dOlSrV69Wq1bt3Ycj4qKklSRUY+OjnYcz8jIOC3zn5+fr4svvlgtWrTQ4sWL5e3tXWObAwcOlCTt3btXYWFhWr58ucrKyiRJfn5+jvZ/P9IiIyND0un/efh93R988IEkqV+/fkpMTHTc9/vHVXfulf3www/avXu3Fi5cWOM5AZJ796fo6GjFxsYqODjYUaZLly4yDEOHDx8+Y3+yWq3y9PQ8Y92/P6+AgAB17NhRHTt21MCBA3XeeefpnXfe0YwZM2o8PzRvza1P1UZdzh2ojP5UM77zoS6ac3+q7tx/+OEHZWRkqG3bto5jNptNf/7znzV79uzTlmAB4Cacle2y2+3GPffcY8TExBh79uw54/1RUVHGrFmzHMdKSkpOW6QvNzfXGDhwoDFixAijsLCwVm1/9tlnhqQqu3P93uuvv26EhIQYJSUljmPPPfdclUX6zuSaa64xRo4cWWP7Zzv3ym655Rajb9++NZYBmkJ/euONNww/P78qu7p8+umnhoeHh1FUVFRt3RdccIFx9913VznWpUuXGhc6NwzD6NChg/G3v/2txjJovppzn6pMNSx0frZzB06iP1U4U3+qjO98qI3m3J/Odu6ZmZnGtm3bqlxiYmKMhx9+2Ni1a1etzhGA63FaUuruu+82goODjZUrV1bZZrTyG9Fzzz1nBAcHG//73/+Mbdu2Gddff32V7Uzz8vKMAQMGGOeff76xd+/eKvWUl5cbhmEYa9asMV588UVjy5Ytxv79+42FCxcaMTExxhVXXFFjfDk5OUZkZKRx/fXXG9u2bTP+97//GUFBQVW2M33ppZeMxYsXG3v27DG2b99uPPLII4YkY9GiRed87oZR8WHh7+9vzJkzp07PLZqfptCf8vPzjdatWxsTJkwwfv31V2PVqlXGeeedZ0yePLnGuhcsWGB4e3sb77zzjrFjxw7jgQceMAICAowDBw4YhlExbW/GjBnG2rVrjQMHDhibNm0yJk2aZFitVmP79u31er7R9DXnPpWfn29s2bLF2LJliyHJEV/lHyFnO3egMvpTzf3JMPjOh9przv2ptr+hKmP6HuD+nJaUknTGy7vvvusoY7fbjb/97W9GVFSUYbVajeHDhxvbtm1z3P/9999XW09SUpJhGIaxadMmY8CAAUZwcLDh6+trJCQkGH/7299q9R+BX375xRg2bJhhtVqNqKgo44knnqgySmrWrFlGhw4dDF9fX6Nly5bG0KFDjWXLljXIuRvGqf8iVJ5vDZxJU+hPhmEYO3fuNC666CLDz8/PaN26tTF9+vRa/Qf6tddeM+Li4gwfHx+jT58+VbYGPn78uHHVVVcZMTExho+PjxEdHW1cccUVxvr1689aL5qv5tynqov7lltuqfW5A5XRn2ruT4bBdz7UXnPuT7X9DVUZSSnA/VkMwzBqN9EPAAAAAAAAaBgeZgcAAAAAAACA5oekFAAAAAAAABodSSkAAAAAAAA0OpJSAAAAAAAAaHQkpQAAAAAAANDoSEoBAAAAAACg0ZGUAgAAAAAAQKMjKQUAAAAAAIBGR1IKAAA0WfPnz5fFYnFcfH19FRUVpZEjR2rmzJnKyMioV707duzQE088oQMHDjRswAAAAM0ISSkAANDkvfvuu1q7dq1WrFih1157Tb169dKsWbPUpUsXffPNN3Wub8eOHXryySdJSgEAAJwDL7MDAAAAcLbu3burX79+jtvXXHONpk2bpqFDh+rqq6/Wb7/9psjISBMjBAAAaH4YKQUAAJqltm3b6p///Kfy8/P1xhtvSJI2btyo6667Tu3atZOfn5/atWun66+/XgcPHnQ8bv78+br22mslSSNHjnRMDZw/f76jzDfffKNRo0YpKChI/v7+GjJkiL799ttGPT8AAABXR1IKAAA0W5dccok8PT21evVqSdKBAweUkJCg2bNn66uvvtKsWbOUmpqq/v37KzMzU5J06aWX6tlnn5Ukvfbaa1q7dq3Wrl2rSy+9VJL0wQcfaMyYMQoKCtJ7772njz/+WKGhoRo7diyJKQAAgEoshmEYZgcBAADgDPPnz9dtt92mDRs2VJm+V1lUVJRCQ0O1Y8eO0+6z2WwqLi5WZGSknn32Wd13332SpE8++UTXXnutvv/+e1144YWO8kVFRWrTpo2GDBmipUuXOo7b7Xb16dNHVqtVP//8c8OeJAAAgJtipBQAAGjWKv9/rqCgQA8//LA6duwoLy8veXl5qUWLFiosLNTOnTvPWteaNWuUnZ2tW265ReXl5Y6L3W7XxRdfrA0bNqiwsNCZpwMAAOA2WOgcAAA0W4WFhcrKytL5558vSfrjH/+ob7/9Vo8//rj69++voKAgWSwWXXLJJTp+/PhZ60tPT5ckTZgwodoy2dnZCggIaJgTAAAAcGMkpQAAQLO1bNky2Ww2XXjhhcrNzdXnn3+uv/3tb3rkkUccZUpKSpSdnV2r+sLDwyVJ//rXvzRw4MAzlmGXPwAAgAokpQAAQLOUnJysv/zlLwoODtZdd90li8UiwzBktVqrlHv77bdls9mqHDtZ5vejp4YMGaKQkBDt2LFD9957r3NPAAAAwM2RlAIAAE3e9u3bHes7ZWRk6IcfftC7774rT09PLV68WBEREZKk4cOH6/nnn1d4eLjatWunVatW6Z133lFISEiV+rp37y5JevPNNxUYGChfX1/Fx8crLCxM//rXv3TLLbcoOztbEyZMUKtWrXT06FFt3bpVR48e1Zw5cxr79AEAAFwSSSkAANDk3XbbbZIkHx8fhYSEqEuXLnr44Yc1efJkR0JKkv7zn//o/vvv10MPPaTy8nINGTJEK1as0KWXXlqlvvj4eM2ePVsvv/yyLrzwQtlsNr377ru69dZbdeONN6pt27b6xz/+obvuukv5+flq1aqVevXqpVtvvbUxTxsAAMClWYzKW84AAAAAAAAAjcDD7AAAAAAAAADQ/JCUAgAAAAAAQKMjKQUAAAAAAIBGR1IKAAAAAAAAjY6kFAAAAAAAABodSSkAAAAAAAA0OpJSAAAAAAAAaHQkpQAAAAAAANDoSEoBAAAAAACg0ZGUAgAAAAAAQKMjKQUAAAAAAIBGR1IKAAAAAAAAje7/AwxqGfHJQ+v3AAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def plot_price(df, symbol):\n", + " \"\"\"\n", + " Create a price chart using Matplotlib\n", + " \n", + " Args:\n", + " df (pandas.DataFrame): Historical stock data\n", + " symbol (str): Stock ticker symbol\n", + " \n", + " Returns:\n", + " matplotlib.figure.Figure: Price chart figure\n", + " \"\"\"\n", + " if df.empty:\n", + " # Create empty figure with error message\n", + " fig, ax = plt.subplots(figsize=(12, 6))\n", + " ax.text(0.5, 0.5, f'No data available for {symbol}', \n", + " horizontalalignment='center', verticalalignment='center',\n", + " transform=ax.transAxes, fontsize=16)\n", + " ax.set_title(f'Stock Price Chart - {symbol}')\n", + " return fig\n", + " \n", + " try:\n", + " # Create figure and axis\n", + " fig, ax = plt.subplots(figsize=(12, 6))\n", + " \n", + " # Plot closing price\n", + " ax.plot(df.index, df['Close'], linewidth=2, label='Close Price', color='#1f77b4')\n", + " \n", + " # Add volume as secondary axis\n", + " ax2 = ax.twinx()\n", + " ax2.bar(df.index, df['Volume'], alpha=0.3, color='gray', label='Volume')\n", + " \n", + " # Formatting\n", + " ax.set_title(f'Stock Price Chart - {symbol}', fontsize=16, fontweight='bold')\n", + " ax.set_xlabel('Date', fontsize=12)\n", + " ax.set_ylabel('Price ($)', fontsize=12)\n", + " ax2.set_ylabel('Volume', fontsize=12)\n", + " \n", + " # Add grid\n", + " ax.grid(True, alpha=0.3)\n", + " \n", + " # Format dates on x-axis\n", + " ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))\n", + " ax.xaxis.set_major_locator(mdates.WeekdayLocator(interval=1))\n", + " plt.xticks(rotation=45)\n", + " \n", + " # Add legends\n", + " ax.legend(loc='upper left')\n", + " ax2.legend(loc='upper right')\n", + " \n", + " # Add price statistics\n", + " current_price = df['Close'].iloc[-1]\n", + " price_change = df['Close'].iloc[-1] - df['Close'].iloc[0]\n", + " price_change_pct = (price_change / df['Close'].iloc[0]) * 100\n", + " \n", + " stats_text = f'Current: ${current_price:.2f} | Change: ${price_change:.2f} ({price_change_pct:+.2f}%)'\n", + " ax.text(0.02, 0.98, stats_text, transform=ax.transAxes, \n", + " bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.8),\n", + " verticalalignment='top', fontsize=10)\n", + " \n", + " # Tight layout\n", + " plt.tight_layout()\n", + " \n", + " return fig\n", + " \n", + " except Exception as e:\n", + " # Create error figure\n", + " fig, ax = plt.subplots(figsize=(12, 6))\n", + " ax.text(0.5, 0.5, f'Error creating chart: {str(e)}', \n", + " horizontalalignment='center', verticalalignment='center',\n", + " transform=ax.transAxes, fontsize=16)\n", + " ax.set_title(f'Stock Price Chart - {symbol}')\n", + " return fig\n", + "\n", + "# Test the plotting function\n", + "if not test_data.empty:\n", + " print(\"\\nšŸ“Š Creating test chart...\")\n", + " test_fig = plot_price(test_data, test_symbol)\n", + " plt.show()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "vscode": { + "languageId": "raw" + } + }, + "source": [ + "## 7. Gradio Chat Interface\n", + "\n", + "This section creates the main Gradio interface with a two-column layout for stock analysis and Sharia compliance assessment.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "šŸš€ Creating Gradio interface...\n", + "āœ… Interface created successfully!\n", + "🌐 Launch the interface by running: demo.launch()\n" + ] + } + ], + "source": [ + "def analyze_stock(symbol):\n", + " \"\"\"\n", + " Main analysis function that combines all tools\n", + " \n", + " Args:\n", + " symbol (str): Stock ticker symbol\n", + " \n", + " Returns:\n", + " tuple: (trade_advice, sharia_dict, price_chart)\n", + " \"\"\"\n", + " if not symbol or not symbol.strip():\n", + " return (\"Please enter a valid stock symbol.\", {}, None)\n", + " \n", + " symbol = symbol.strip().upper()\n", + " \n", + " try:\n", + " # Update status\n", + " status_message = f\"šŸ”„ Analyzing {symbol}...\"\n", + " print(status_message)\n", + " \n", + " # Fetch data for multiple periods\n", + " periods = [\"1mo\", \"1y\", \"5y\"]\n", + " summaries = {}\n", + " \n", + " for period in periods:\n", + " print(f\"šŸ“ˆ Fetching {period} data...\")\n", + " df = fetch_history(symbol, period, \"1d\")\n", + " if not df.empty:\n", + " summaries[period] = summarize(df)\n", + " else:\n", + " summaries[period] = {\"error\": f\"No data for {period}\"}\n", + " \n", + " # Get 1-month data for chart\n", + " df_1mo = fetch_history(symbol, \"1mo\", \"1d\")\n", + " \n", + " # Get trade advice\n", + " print(\"šŸ¤– Getting AI trade advice...\")\n", + " trade_advice = get_trade_advice(symbol, summaries)\n", + " \n", + " # Get Sharia assessment\n", + " print(\"ā˜Ŗļø Assessing Sharia compliance...\")\n", + " sharia_assessment = assess_sharia(symbol)\n", + " \n", + " # Create price chart\n", + " print(\"šŸ“Š Creating price chart...\")\n", + " price_chart = plot_price(df_1mo, symbol)\n", + " \n", + " print(f\"āœ… Analysis complete for {symbol}\")\n", + " \n", + " return (trade_advice, sharia_assessment, price_chart)\n", + " \n", + " except Exception as e:\n", + " error_msg = f\"āŒ Error analyzing {symbol}: {str(e)}\"\n", + " print(error_msg)\n", + " return (error_msg, {\"error\": str(e)}, None)\n", + "\n", + "# Create Gradio Interface\n", + "def create_interface():\n", + " \"\"\"Create and return the Gradio interface\"\"\"\n", + " \n", + " with gr.Blocks(title=\"Stock Analysis & Sharia Compliance\", theme=gr.themes.Soft()) as interface:\n", + " \n", + " # Header\n", + " gr.Markdown(\"\"\"\n", + " # šŸ“ˆ Stock Analysis & Sharia Compliance Tool\n", + " \n", + " **Get comprehensive stock analysis with AI-powered trade recommendations and Islamic Sharia compliance assessment.**\n", + " \n", + " *Enter a stock ticker (e.g., AAPL, MSFT, GOOGL) and click Analyze to get started.*\n", + " \"\"\")\n", + " \n", + " with gr.Row():\n", + " # Left Column - Inputs and Results\n", + " with gr.Column(scale=1):\n", + " gr.Markdown(\"### šŸ“Š Stock Analysis\")\n", + " \n", + " # Input section\n", + " with gr.Group():\n", + " ticker_input = gr.Textbox(\n", + " label=\"Stock Ticker Symbol\",\n", + " placeholder=\"Enter ticker (e.g., AAPL, MSFT, GOOGL)\",\n", + " value=\"AAPL\"\n", + " )\n", + " analyze_button = gr.Button(\"šŸ” Analyze Stock\", variant=\"primary\", size=\"lg\")\n", + " \n", + " # Trade advice output\n", + " with gr.Group():\n", + " gr.Markdown(\"### šŸ¤– AI Trade Recommendation\")\n", + " trade_advice_output = gr.Textbox(\n", + " label=\"Trade Advice\",\n", + " lines=8,\n", + " placeholder=\"AI trade recommendation will appear here...\"\n", + " )\n", + " \n", + " # Sharia compliance output\n", + " with gr.Group():\n", + " gr.Markdown(\"### ā˜Ŗļø Sharia Compliance Assessment\")\n", + " sharia_output = gr.JSON(\n", + " label=\"Sharia Ruling\",\n", + " value={\"ruling\": \"Not analyzed\", \"confidence\": 0, \"justification\": \"Click Analyze to assess\"}\n", + " )\n", + " \n", + " # Right Column - Chart\n", + " with gr.Column(scale=1):\n", + " gr.Markdown(\"### šŸ“ˆ Price Chart (1 Month)\")\n", + " chart_output = gr.Plot(\n", + " label=\"Stock Price Chart\",\n", + " value=None\n", + " )\n", + " \n", + " # Examples section\n", + " with gr.Row():\n", + " gr.Markdown(\"\"\"\n", + " ### šŸ’” Example Tickers to Try:\n", + " - **AAPL** - Apple Inc. (Technology)\n", + " - **MSFT** - Microsoft Corporation (Technology) \n", + " - **BRK-B** - Berkshire Hathaway (Conglomerate)\n", + " - **JNJ** - Johnson & Johnson (Healthcare)\n", + " - **BAC** - Bank of America (Banking - may be Haram)\n", + " - **KO** - Coca-Cola (Beverages)\n", + " \n", + " *Note: Add \".CA\" suffix for Canadian stocks (e.g., \"SHOP.TO\" for Toronto Stock Exchange)*\n", + " \"\"\")\n", + " \n", + " # Wire up the interface\n", + " analyze_button.click(\n", + " fn=analyze_stock,\n", + " inputs=[ticker_input],\n", + " outputs=[trade_advice_output, sharia_output, chart_output],\n", + " show_progress=True\n", + " )\n", + " \n", + " # Add example buttons\n", + " with gr.Row():\n", + " example_buttons = [\n", + " gr.Button(\"šŸ“± AAPL\", size=\"sm\"),\n", + " gr.Button(\"šŸ’» MSFT\", size=\"sm\"),\n", + " gr.Button(\"šŸ¦ BAC\", size=\"sm\"),\n", + " gr.Button(\"🄤 KO\", size=\"sm\")\n", + " ]\n", + " \n", + " # Wire example buttons\n", + " for button, ticker in zip(example_buttons, [\"AAPL\", \"MSFT\", \"BAC\", \"KO\"]):\n", + " button.click(\n", + " fn=lambda t=ticker: t,\n", + " outputs=[ticker_input]\n", + " )\n", + " \n", + " return interface\n", + "\n", + "# Create the interface\n", + "print(\"šŸš€ Creating Gradio interface...\")\n", + "demo = create_interface()\n", + "\n", + "print(\"āœ… Interface created successfully!\")\n", + "print(\"🌐 Launch the interface by running: demo.launch()\")\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "vscode": { + "languageId": "raw" + } + }, + "source": [ + "## 8. Launch the Interface\n", + "\n", + "Run the cell below to launch the Gradio interface. It will open in your browser and provide an interactive chat interface for stock analysis.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "šŸš€ 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", + "\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" + ] + }, + { + "data": { + "text/html": [ + "
" + ], + "text/plain": [ + "" + ] + }, + "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": [ + "# Launch the Gradio interface\n", + "if __name__ == \"__main__\":\n", + " print(\"šŸš€ Launching Stock Analysis & Sharia Compliance Interface...\")\n", + " print(\"šŸ“ Make sure you have set your OPENAI_API_KEY environment variable\")\n", + " print(\"🌐 The interface will open in your browser\")\n", + " \n", + " # Launch with sharing enabled for easy access\n", + " demo.launch(\n", + " share=True, # Creates a public link for sharing\n", + " server_name=\"0.0.0.0\", # Allow external access\n", + " show_error=True, # Show detailed error messages\n", + " quiet=False # Show startup logs\n", + " )\n" + ] + }, + { + "cell_type": "raw", + "metadata": { + "vscode": { + "languageId": "raw" + } + }, + "source": [ + "## 9. Usage Instructions & Requirements\n", + "\n", + "### šŸ“‹ Prerequisites\n", + "\n", + "Before running this notebook, make sure you have the following installed:\n", + "\n", + "```bash\n", + "pip install yfinance openai pandas matplotlib gradio requests beautifulsoup4 numpy\n", + "```\n", + "\n", + "### šŸ”‘ API Key Setup\n", + "\n", + "Set your OpenAI API key as an environment variable:\n", + "\n", + "```bash\n", + "export OPENAI_API_KEY=\"your-api-key-here\"\n", + "```\n", + "\n", + "Or in Python:\n", + "```python\n", + "import os\n", + "os.environ[\"OPENAI_API_KEY\"] = \"your-api-key-here\"\n", + "```\n", + "\n", + "### šŸš€ How to Use\n", + "\n", + "1. **Run all cells** in this notebook to initialize all functions\n", + "2. **Launch the interface** by running the launch cell\n", + "3. **Enter a stock ticker** (e.g., AAPL, MSFT, GOOGL)\n", + "4. **Click \"Analyze Stock\"** to get:\n", + " - AI-powered trade recommendations (BUY/HOLD/SELL)\n", + " - Sharia compliance assessment\n", + " - Interactive price chart\n", + "\n", + "### šŸ“Š Features\n", + "\n", + "- **Multi-period Analysis**: 1 month, 1 year, and 5 year data analysis\n", + "- **AI Trade Advice**: GPT-4o-mini powered recommendations with numerical justification\n", + "- **Sharia Compliance**: Islamic finance assessment with confidence scores\n", + "- **Interactive Charts**: Real-time price charts with volume data\n", + "- **Example Tickers**: Quick-access buttons for popular stocks\n", + "\n", + "### āš ļø Disclaimers\n", + "\n", + "- **Not Financial Advice**: This tool is for educational purposes only\n", + "- **Sharia Assessments**: Consult qualified Islamic scholars for authoritative rulings\n", + "- **Data Accuracy**: Stock data depends on yfinance API availability\n", + "- **API Costs**: OpenAI API calls will consume your credits\n", + "\n", + "### šŸ› ļø Troubleshooting\n", + "\n", + "- **No data found**: Check if the ticker symbol is correct\n", + "- **API errors**: Verify your OpenAI API key is set correctly\n", + "- **Chart issues**: Ensure matplotlib backend supports interactive plotting\n", + "- **Slow performance**: API calls may take 10-30 seconds depending on network\n", + "\n", + "Enjoy analyzing stocks with AI-powered insights and Sharia compliance! šŸš€šŸ“ˆā˜Ŗļø\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.12" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +}