{ "cells": [ { "cell_type": "code", "execution_count": 1, "id": "0aab70ec", "metadata": {}, "outputs": [], "source": [ "import json\n", "import plotly.graph_objects as go\n", "import plotly.express as px\n", "from plotly.subplots import make_subplots\n", "import pandas as pd\n", "import re\n", "from datetime import datetime\n", "from textstat import flesch_reading_ease\n", "import numpy as np" ] }, { "cell_type": "code", "execution_count": 2, "id": "47f14ad4", "metadata": {}, "outputs": [], "source": [ "class InvestmentDashboard:\n", " def __init__(self, json_data=None, json_file_path=None):\n", " \"\"\"\n", " Initialize the dashboard with JSON data\n", " Args:\n", " json_data: Dictionary containing investment data\n", " json_file_path: Path to JSON file containing investment data\n", " \"\"\"\n", " if json_file_path:\n", " with open(json_file_path, 'r') as f:\n", " self.data = json.load(f)\n", " elif json_data:\n", " self.data = json_data\n", " else:\n", " raise ValueError(\"Either json_data or json_file_path must be provided\")\n", " \n", " self.analysis = self._analyze_data()\n", " \n", " def _analyze_data(self):\n", " \"\"\"Analyze the JSON data to extract key metrics and insights\"\"\"\n", " analysis = {}\n", " \n", " for date, data in self.data.items():\n", " company = data.get('company_of_interest', 'Unknown')\n", " \n", " # Extract technical indicators from market report\n", " analysis[date] = {\n", " 'company': company,\n", " 'trade_date': data.get('trade_date'),\n", " 'technical_indicators': self._extract_technical_indicators(data.get('market_report', '')),\n", " 'sentiment_metrics': self._extract_sentiment_metrics(data.get('sentiment_report', '')),\n", " 'fundamental_metrics': self._extract_fundamental_metrics(data.get('fundamentals_report', '')),\n", " 'final_decisions': self._extract_decisions(data),\n", " 'risk_assessment': self._analyze_risk_debate(data.get('risk_debate_state', {})),\n", " 'news_sentiment': self._analyze_news_sentiment(data.get('news_report', ''))\n", " }\n", " \n", " return analysis\n", " \n", " def _extract_technical_indicators(self, market_report):\n", " \"\"\"Extract technical indicators from market report\"\"\"\n", " indicators = {}\n", " \n", " # Price information\n", " price_match = re.search(r'closing price.*?\\$?([\\d,]+\\.?\\d*)', market_report, re.IGNORECASE)\n", " if price_match:\n", " indicators['closing_price'] = float(price_match.group(1).replace(',', ''))\n", " \n", " # Moving averages\n", " sma_50_match = re.search(r'50-SMA.*?\\$?([\\d,]+\\.?\\d*)', market_report, re.IGNORECASE)\n", " if sma_50_match:\n", " indicators['sma_50'] = float(sma_50_match.group(1).replace(',', ''))\n", " \n", " sma_200_match = re.search(r'200-SMA.*?\\$?([\\d,]+\\.?\\d*)', market_report, re.IGNORECASE)\n", " if sma_200_match:\n", " indicators['sma_200'] = float(sma_200_match.group(1).replace(',', ''))\n", " \n", " ema_10_match = re.search(r'10-EMA.*?\\$?([\\d,]+\\.?\\d*)', market_report, re.IGNORECASE)\n", " if ema_10_match:\n", " indicators['ema_10'] = float(ema_10_match.group(1).replace(',', ''))\n", " \n", " # MACD\n", " macd_match = re.search(r'MACD.*?([\\d.]+)', market_report, re.IGNORECASE)\n", " if macd_match:\n", " indicators['macd'] = float(macd_match.group(1))\n", " \n", " # RSI\n", " rsi_match = re.search(r'RSI.*?([\\d.]+)', market_report, re.IGNORECASE)\n", " if rsi_match:\n", " indicators['rsi'] = float(rsi_match.group(1))\n", " \n", " # ATR\n", " atr_match = re.search(r'ATR.*?([\\d.]+)', market_report, re.IGNORECASE)\n", " if atr_match:\n", " indicators['atr'] = float(atr_match.group(1))\n", " \n", " return indicators\n", " \n", " def _extract_sentiment_metrics(self, sentiment_report):\n", " \"\"\"Extract sentiment metrics from sentiment report\"\"\"\n", " metrics = {}\n", " \n", " # Reddit mentions\n", " mentions_match = re.search(r'(\\d+)\\s+mentions', sentiment_report, re.IGNORECASE)\n", " if mentions_match:\n", " metrics['reddit_mentions'] = int(mentions_match.group(1))\n", " \n", " # Sentiment score\n", " sentiment_match = re.search(r'sentiment score.*?(\\d+\\.?\\d*)%?', sentiment_report, re.IGNORECASE)\n", " if sentiment_match:\n", " metrics['sentiment_score'] = float(sentiment_match.group(1))\n", " \n", " # Rule of 40 score\n", " rule40_match = re.search(r'Rule of 40.*?(\\d+)%', sentiment_report, re.IGNORECASE)\n", " if rule40_match:\n", " metrics['rule_of_40'] = int(rule40_match.group(1))\n", " \n", " # Stock price from sentiment\n", " price_match = re.search(r'current price.*?\\$?([\\d,]+\\.?\\d*)', sentiment_report, re.IGNORECASE)\n", " if price_match:\n", " metrics['current_price'] = float(price_match.group(1).replace(',', ''))\n", " \n", " return metrics\n", " \n", " def _extract_fundamental_metrics(self, fundamentals_report):\n", " \"\"\"Extract fundamental metrics from fundamentals report\"\"\"\n", " metrics = {}\n", " \n", " # Revenue\n", " revenue_match = re.search(r'revenue.*?\\$?([\\d,]+\\.?\\d*)\\s*(billion|million)', fundamentals_report, re.IGNORECASE)\n", " if revenue_match:\n", " value = float(revenue_match.group(1).replace(',', ''))\n", " unit = revenue_match.group(2).lower()\n", " if unit == 'billion':\n", " value *= 1000\n", " metrics['revenue_millions'] = value\n", " \n", " # Revenue growth\n", " revenue_growth_match = re.search(r'(\\d+)%.*?year-over-year', fundamentals_report, re.IGNORECASE)\n", " if revenue_growth_match:\n", " metrics['revenue_growth'] = int(revenue_growth_match.group(1))\n", " \n", " # Net income\n", " net_income_match = re.search(r'net income.*?\\$?([\\d,]+\\.?\\d*)\\s*million', fundamentals_report, re.IGNORECASE)\n", " if net_income_match:\n", " metrics['net_income_millions'] = float(net_income_match.group(1).replace(',', ''))\n", " \n", " # Market cap\n", " market_cap_match = re.search(r'market capitalization.*?\\$?([\\d,]+\\.?\\d*)\\s*(billion|trillion)', fundamentals_report, re.IGNORECASE)\n", " if market_cap_match:\n", " value = float(market_cap_match.group(1).replace(',', ''))\n", " unit = market_cap_match.group(2).lower()\n", " if unit == 'trillion':\n", " value *= 1000\n", " metrics['market_cap_billions'] = value\n", " \n", " return metrics\n", " \n", " def _extract_decisions(self, data):\n", " \"\"\"Extract investment decisions from various reports\"\"\"\n", " decisions = {}\n", " \n", " # Extract final decisions from each report\n", " for report_type in ['market_report', 'sentiment_report', 'fundamentals_report']:\n", " report = data.get(report_type, '')\n", " decision_match = re.search(r'FINAL TRANSACTION PROPOSAL:\\s*\\*?\\*?([A-Z]+)', report, re.IGNORECASE)\n", " if decision_match:\n", " decisions[report_type] = decision_match.group(1).upper()\n", " \n", " # Final trade decision\n", " final_decision = data.get('final_trade_decision', '')\n", " if 'BUY' in final_decision.upper():\n", " decisions['final_decision'] = 'BUY'\n", " elif 'SELL' in final_decision.upper():\n", " decisions['final_decision'] = 'SELL'\n", " elif 'HOLD' in final_decision.upper():\n", " decisions['final_decision'] = 'HOLD'\n", " \n", " return decisions\n", " \n", " def _analyze_risk_debate(self, risk_debate):\n", " \"\"\"Analyze risk debate to extract risk assessment\"\"\"\n", " if not risk_debate:\n", " return {}\n", " \n", " risk_analysis = {}\n", " \n", " # Analyze judge decision\n", " judge_decision = risk_debate.get('judge_decision', '')\n", " if 'BUY' in judge_decision.upper():\n", " risk_analysis['risk_adjusted_decision'] = 'BUY'\n", " elif 'SELL' in judge_decision.upper():\n", " risk_analysis['risk_adjusted_decision'] = 'SELL'\n", " elif 'HOLD' in judge_decision.upper():\n", " risk_analysis['risk_adjusted_decision'] = 'HOLD'\n", " \n", " # Extract position sizing\n", " position_match = re.search(r'(\\d+\\.?\\d*)%.*?portfolio', judge_decision, re.IGNORECASE)\n", " if position_match:\n", " risk_analysis['recommended_position_size'] = float(position_match.group(1))\n", " \n", " # Extract stop loss\n", " stop_loss_match = re.search(r'(\\d+)%.*?stop', judge_decision, re.IGNORECASE)\n", " if stop_loss_match:\n", " risk_analysis['stop_loss_percent'] = int(stop_loss_match.group(1))\n", " \n", " return risk_analysis\n", " \n", " def _analyze_news_sentiment(self, news_report):\n", " \"\"\"Analyze news report for sentiment indicators\"\"\"\n", " sentiment = {}\n", " \n", " # Count positive/negative words\n", " positive_words = ['growth', 'increase', 'strong', 'positive', 'bullish', 'surge', 'rise', 'improvement']\n", " negative_words = ['decline', 'fall', 'weak', 'negative', 'bearish', 'drop', 'concern', 'risk']\n", " \n", " news_lower = news_report.lower()\n", " positive_count = sum(news_lower.count(word) for word in positive_words)\n", " negative_count = sum(news_lower.count(word) for word in negative_words)\n", " \n", " if positive_count + negative_count > 0:\n", " sentiment['news_sentiment_score'] = (positive_count - negative_count) / (positive_count + negative_count) * 100\n", " else:\n", " sentiment['news_sentiment_score'] = 0\n", " \n", " return sentiment\n", " \n", " def create_dashboard(self):\n", " \"\"\"Create the main dashboard with multiple visualizations\"\"\"\n", " fig = make_subplots(\n", " rows=4, cols=2,\n", " subplot_titles=(\n", " 'Technical Indicators Overview', 'Investment Decisions Summary',\n", " 'Sentiment Analysis', 'Fundamental Metrics',\n", " 'Risk Assessment', 'Price vs Moving Averages',\n", " 'Decision Consensus', 'Key Performance Metrics'\n", " ),\n", " specs=[[{\"secondary_y\": True}, {\"type\": \"pie\"}],\n", " [{\"type\": \"bar\"}, {\"type\": \"bar\"}],\n", " [{\"type\": \"indicator\"}, {\"type\": \"scatter\"}],\n", " [{\"type\": \"bar\"}, {\"type\": \"table\"}]],\n", " vertical_spacing=0.12,\n", " horizontal_spacing=0.1\n", " )\n", " \n", " # Extract data for visualizations\n", " dates = list(self.analysis.keys())\n", " latest_date = dates[0] if dates else None\n", " \n", " if not latest_date:\n", " return fig\n", " \n", " latest_data = self.analysis[latest_date]\n", " \n", " # 1. Technical Indicators Radar Chart (converted to bar for simplicity)\n", " tech_indicators = latest_data['technical_indicators']\n", " if tech_indicators:\n", " # RSI and normalized values for comparison\n", " indicators = []\n", " values = []\n", " \n", " if 'rsi' in tech_indicators:\n", " indicators.append('RSI')\n", " values.append(tech_indicators['rsi'])\n", " \n", " if 'macd' in tech_indicators:\n", " indicators.append('MACD')\n", " values.append(tech_indicators['macd'] * 10) # Scale for visibility\n", " \n", " if 'atr' in tech_indicators:\n", " indicators.append('ATR')\n", " values.append(tech_indicators['atr'] * 10) # Scale for visibility\n", " \n", " if indicators:\n", " fig.add_trace(\n", " go.Bar(x=indicators, y=values, name=\"Technical Indicators\", \n", " marker_color=['#FF6B6B', '#4ECDC4', '#45B7D1']),\n", " row=1, col=1\n", " )\n", " \n", " # 2. Investment Decisions Pie Chart\n", " decisions = latest_data['final_decisions']\n", " decision_counts = {}\n", " for decision in decisions.values():\n", " decision_counts[decision] = decision_counts.get(decision, 0) + 1\n", " \n", " if decision_counts:\n", " fig.add_trace(\n", " go.Pie(labels=list(decision_counts.keys()), \n", " values=list(decision_counts.values()),\n", " hole=0.4,\n", " marker_colors=['#FF6B6B', '#4ECDC4', '#45B7D1']),\n", " row=1, col=2\n", " )\n", " \n", " # 3. Sentiment Analysis\n", " sentiment_data = latest_data['sentiment_metrics']\n", " if sentiment_data:\n", " sentiment_labels = []\n", " sentiment_values = []\n", " \n", " if 'reddit_mentions' in sentiment_data:\n", " sentiment_labels.append('Reddit Mentions')\n", " sentiment_values.append(sentiment_data['reddit_mentions'])\n", " \n", " if 'sentiment_score' in sentiment_data:\n", " sentiment_labels.append('Sentiment Score')\n", " sentiment_values.append(sentiment_data['sentiment_score'])\n", " \n", " if sentiment_labels:\n", " fig.add_trace(\n", " go.Bar(x=sentiment_labels, y=sentiment_values, \n", " name=\"Sentiment Metrics\",\n", " marker_color='#FFA726'),\n", " row=2, col=1\n", " )\n", " \n", " # 4. Fundamental Metrics\n", " fundamental_data = latest_data['fundamental_metrics']\n", " if fundamental_data:\n", " fund_labels = []\n", " fund_values = []\n", " \n", " if 'revenue_growth' in fundamental_data:\n", " fund_labels.append('Revenue Growth %')\n", " fund_values.append(fundamental_data['revenue_growth'])\n", " \n", " if 'revenue_millions' in fundamental_data:\n", " fund_labels.append('Revenue (M)')\n", " fund_values.append(fundamental_data['revenue_millions'])\n", " \n", " if fund_labels:\n", " fig.add_trace(\n", " go.Bar(x=fund_labels, y=fund_values, \n", " name=\"Fundamental Metrics\",\n", " marker_color='#66BB6A'),\n", " row=2, col=2\n", " )\n", " \n", " # 5. Risk Assessment Gauge\n", " risk_data = latest_data['risk_assessment']\n", " risk_score = 50 # Default neutral\n", " \n", " if 'recommended_position_size' in risk_data:\n", " # Convert position size to risk score (higher position = higher confidence = lower risk)\n", " position_size = risk_data['recommended_position_size']\n", " risk_score = max(0, min(100, 100 - (position_size * 10)))\n", " \n", " fig.add_trace(\n", " go.Indicator(\n", " mode=\"gauge+number+delta\",\n", " value=risk_score,\n", " title={'text': \"Risk Level\"},\n", " gauge={\n", " 'axis': {'range': [0, 100]},\n", " 'bar': {'color': \"#FF6B6B\"},\n", " 'steps': [\n", " {'range': [0, 30], 'color': \"#4ECDC4\"},\n", " {'range': [30, 70], 'color': \"#FFA726\"},\n", " {'range': [70, 100], 'color': \"#FF6B6B\"}\n", " ],\n", " 'threshold': {\n", " 'line': {'color': \"red\", 'width': 4},\n", " 'thickness': 0.75,\n", " 'value': 80\n", " }\n", " }\n", " ),\n", " row=3, col=1\n", " )\n", " \n", " # 6. Price vs Moving Averages\n", " if 'closing_price' in tech_indicators:\n", " price_data = {\n", " 'Current Price': tech_indicators.get('closing_price', 0),\n", " '50-SMA': tech_indicators.get('sma_50', 0),\n", " '200-SMA': tech_indicators.get('sma_200', 0),\n", " '10-EMA': tech_indicators.get('ema_10', 0)\n", " }\n", " \n", " # Filter out zero values\n", " price_data = {k: v for k, v in price_data.items() if v > 0}\n", " \n", " if price_data:\n", " fig.add_trace(\n", " go.Scatter(x=list(price_data.keys()), \n", " y=list(price_data.values()),\n", " mode='lines+markers',\n", " name=\"Price vs MA\",\n", " line=dict(color='#9C27B0', width=3),\n", " marker=dict(size=8)),\n", " row=3, col=2\n", " )\n", " \n", " # 7. Decision Consensus\n", " all_decisions = list(decisions.values())\n", " buy_count = all_decisions.count('BUY')\n", " hold_count = all_decisions.count('HOLD')\n", " sell_count = all_decisions.count('SELL')\n", " \n", " fig.add_trace(\n", " go.Bar(x=['BUY', 'HOLD', 'SELL'], \n", " y=[buy_count, hold_count, sell_count],\n", " name=\"Decision Consensus\",\n", " marker_color=['#4ECDC4', '#FFA726', '#FF6B6B']),\n", " row=4, col=1\n", " )\n", " \n", " # 8. Key Performance Metrics Table\n", " kpi_data = []\n", " \n", " # Compile KPI data\n", " if 'closing_price' in tech_indicators:\n", " kpi_data.append(['Current Price', f\"${tech_indicators['closing_price']:.2f}\"])\n", " if 'revenue_growth' in fundamental_data:\n", " kpi_data.append(['Revenue Growth', f\"{fundamental_data['revenue_growth']}%\"])\n", " if 'rule_of_40' in sentiment_data:\n", " kpi_data.append(['Rule of 40', f\"{sentiment_data['rule_of_40']}%\"])\n", " if 'rsi' in tech_indicators:\n", " kpi_data.append(['RSI', f\"{tech_indicators['rsi']:.2f}\"])\n", " \n", " if kpi_data:\n", " fig.add_trace(\n", " go.Table(\n", " header=dict(values=['Metric', 'Value'],\n", " fill_color='#E3F2FD',\n", " align='left',\n", " font=dict(size=12, color='#1976D2')),\n", " cells=dict(values=[[row[0] for row in kpi_data], \n", " [row[1] for row in kpi_data]],\n", " fill_color='#F8F9FA',\n", " align='left',\n", " font=dict(size=11))\n", " ),\n", " row=4, col=2\n", " )\n", " \n", " # Update layout\n", " fig.update_layout(\n", " title=f\"Investment Analysis Dashboard - {latest_data['company']} ({latest_date})\",\n", " title_font_size=24,\n", " title_x=0.5,\n", " height=1200,\n", " showlegend=False,\n", " plot_bgcolor='white',\n", " paper_bgcolor='#F8F9FA',\n", " font=dict(family=\"Arial, sans-serif\", size=10)\n", " )\n", " \n", " # Update all axes\n", " fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor='#E0E0E0')\n", " fig.update_yaxes(showgrid=True, gridwidth=1, gridcolor='#E0E0E0')\n", " \n", " return fig\n", " \n", " def create_summary_report(self):\n", " \"\"\"Create a summary report of the analysis\"\"\"\n", " report = {}\n", " \n", " for date, analysis in self.analysis.items():\n", " company = analysis['company']\n", " decisions = analysis['final_decisions']\n", " \n", " # Get most common decision\n", " decision_list = list(decisions.values())\n", " final_recommendation = max(set(decision_list), key=decision_list.count) if decision_list else \"UNKNOWN\"\n", " \n", " # Risk assessment\n", " risk_data = analysis['risk_assessment']\n", " position_size = risk_data.get('recommended_position_size', 'Not specified')\n", " stop_loss = risk_data.get('stop_loss_percent', 'Not specified')\n", " \n", " # Key metrics\n", " tech_indicators = analysis['technical_indicators']\n", " fundamental_metrics = analysis['fundamental_metrics']\n", " \n", " report[date] = {\n", " 'company': company,\n", " 'final_recommendation': final_recommendation,\n", " 'current_price': tech_indicators.get('closing_price', 'N/A'),\n", " 'rsi': tech_indicators.get('rsi', 'N/A'),\n", " 'revenue_growth': fundamental_metrics.get('revenue_growth', 'N/A'),\n", " 'position_size': position_size,\n", " 'stop_loss': stop_loss\n", " }\n", " \n", " return report" ] }, { "cell_type": "code", "execution_count": 3, "id": "ff0c9dd5", "metadata": {}, "outputs": [], "source": [ "\n", "# Example usage and demo\n", "def demo_dashboard():\n", " \"\"\"Demo function to show how to use the dashboard\"\"\"\n", " \n", " # Sample JSON data structure (you can replace this with actual data)\n", " sample_data = {\n", " \"2025-08-01\": {\n", " \"company_of_interest\": \"PLTR\",\n", " \"trade_date\": \"2025-08-01\",\n", " \"market_report\": \"The closing price on August 1, 2025, is $158.35. 50-SMA: $139.85, 200-SMA: $96.60, 10-EMA: $155.04, MACD: 5.46, RSI: 58.63, ATR: 5.41 FINAL TRANSACTION PROPOSAL: BUY\",\n", " \"sentiment_report\": \"PLTR received 70 mentions on Reddit with a sentiment score of 58%. Rule of 40 score of 81%. Current price $160.66. FINAL TRANSACTION PROPOSAL: BUY\",\n", " \"fundamentals_report\": \"Q2 2025 Revenue: $1 billion, 48% year-over-year growth. Net Income: $327 million, 144% increase. Market Capitalization: $360 billion. FINAL TRANSACTION PROPOSAL: HOLD\",\n", " \"final_trade_decision\": \"BUY with 2.5% starter position, 12% stop-loss\",\n", " \"risk_debate_state\": {\n", " \"judge_decision\": \"BUY with 2.5% of portfolio at ~$160. Stop-loss at 12% below entry.\"\n", " },\n", " \"news_report\": \"Global M&A activity shows strong growth. Palantir wins $10 billion U.S. Army contract showing positive momentum.\"\n", " }\n", " }\n", " \n", " # Create dashboard\n", " dashboard = InvestmentDashboard(json_data=sample_data)\n", " \n", " # Generate the dashboard\n", " fig = dashboard.create_dashboard()\n", " fig.show()\n", " \n", " # Get summary report\n", " summary = dashboard.create_summary_report()\n", " print(\"Summary Report:\")\n", " print(json.dumps(summary, indent=2))\n", " \n", " return dashboard" ] }, { "cell_type": "code", "execution_count": 4, "id": "f540c44b", "metadata": {}, "outputs": [ { "data": { "application/vnd.plotly.v1+json": { "config": { "plotlyServerURL": "https://plot.ly" }, "data": [ { "marker": { "color": [ "#FF6B6B", "#4ECDC4", "#45B7D1" ] }, "name": "Technical Indicators", "type": "bar", "x": [ "RSI", "MACD", "ATR" ], "xaxis": "x", "y": [ 58.63, 54.6, 54.1 ], "yaxis": "y" }, { "domain": { "x": [ 0.52, 0.94 ], "y": [ 0.84, 1 ] }, "hole": 0.4, "labels": [ "BUY", "HOLD" ], "marker": { "colors": [ "#FF6B6B", "#4ECDC4", "#45B7D1" ] }, "type": "pie", "values": [ 3, 1 ] }, { "marker": { "color": "#FFA726" }, "name": "Sentiment Metrics", "type": "bar", "x": [ "Reddit Mentions", "Sentiment Score" ], "xaxis": "x2", "y": [ 70, 58 ], "yaxis": "y3" }, { "marker": { "color": "#66BB6A" }, "name": "Fundamental Metrics", "type": "bar", "x": [ "Revenue Growth %", "Revenue (M)" ], "xaxis": "x3", "y": [ 48, 1000 ], "yaxis": "y4" }, { "domain": { "x": [ 0, 0.42 ], "y": [ 0.28, 0.44000000000000006 ] }, "gauge": { "axis": { "range": [ 0, 100 ] }, "bar": { "color": "#FF6B6B" }, "steps": [ { "color": "#4ECDC4", "range": [ 0, 30 ] }, { "color": "#FFA726", "range": [ 30, 70 ] }, { "color": "#FF6B6B", "range": [ 70, 100 ] } ], "threshold": { "line": { "color": "red", "width": 4 }, "thickness": 0.75, "value": 80 } }, "mode": "gauge+number+delta", "title": { "text": "Risk Level" }, "type": "indicator", "value": 75 }, { "line": { "color": "#9C27B0", "width": 3 }, "marker": { "size": 8 }, "mode": "lines+markers", "name": "Price vs MA", "type": "scatter", "x": [ "Current Price", "50-SMA", "200-SMA", "10-EMA" ], "xaxis": "x4", "y": [ 1, 139.85, 96.6, 155.04 ], "yaxis": "y5" }, { "marker": { "color": [ "#4ECDC4", "#FFA726", "#FF6B6B" ] }, "name": "Decision Consensus", "type": "bar", "x": [ "BUY", "HOLD", "SELL" ], "xaxis": "x5", "y": [ 3, 1, 0 ], "yaxis": "y6" }, { "cells": { "align": "left", "fill": { "color": "#F8F9FA" }, "font": { "size": 11 }, "values": [ [ "Current Price", "Revenue Growth", "Rule of 40", "RSI" ], [ "$1.00", "48%", "81%", "58.63" ] ] }, "domain": { "x": [ 0.52, 0.94 ], "y": [ 0, 0.16 ] }, "header": { "align": "left", "fill": { "color": "#E3F2FD" }, "font": { "color": "#1976D2", "size": 12 }, "values": [ "Metric", "Value" ] }, "type": "table" } ], "layout": { "annotations": [ { "font": { "size": 16 }, "showarrow": false, "text": "Technical Indicators Overview", "x": 0.21, "xanchor": "center", "xref": "paper", "y": 1, "yanchor": "bottom", "yref": "paper" }, { "font": { "size": 16 }, "showarrow": false, "text": "Investment Decisions Summary", "x": 0.73, "xanchor": "center", "xref": "paper", "y": 1, "yanchor": "bottom", "yref": "paper" }, { "font": { "size": 16 }, "showarrow": false, "text": "Sentiment Analysis", "x": 0.21, "xanchor": "center", "xref": "paper", "y": 0.7200000000000001, "yanchor": "bottom", "yref": "paper" }, { "font": { "size": 16 }, "showarrow": false, "text": "Fundamental Metrics", "x": 0.73, "xanchor": "center", "xref": "paper", "y": 0.7200000000000001, "yanchor": "bottom", "yref": "paper" }, { "font": { "size": 16 }, "showarrow": false, "text": "Risk Assessment", "x": 0.21, "xanchor": "center", "xref": "paper", "y": 0.44000000000000006, "yanchor": "bottom", "yref": "paper" }, { "font": { "size": 16 }, "showarrow": false, "text": "Price vs Moving Averages", "x": 0.73, "xanchor": "center", "xref": "paper", "y": 0.44000000000000006, "yanchor": "bottom", "yref": "paper" }, { "font": { "size": 16 }, "showarrow": false, "text": "Decision Consensus", "x": 0.21, "xanchor": "center", "xref": "paper", "y": 0.16, "yanchor": "bottom", "yref": "paper" }, { "font": { "size": 16 }, "showarrow": false, "text": "Key Performance Metrics", "x": 0.73, "xanchor": "center", "xref": "paper", "y": 0.16, "yanchor": "bottom", "yref": "paper" } ], "font": { "family": "Arial, sans-serif", "size": 10 }, "height": 1200, "paper_bgcolor": "#F8F9FA", "plot_bgcolor": "white", "showlegend": false, "template": { "data": { "bar": [ { "error_x": { "color": "#2a3f5f" }, "error_y": { "color": "#2a3f5f" }, "marker": { "line": { "color": "#E5ECF6", "width": 0.5 }, "pattern": { "fillmode": "overlay", "size": 10, "solidity": 0.2 } }, "type": "bar" } ], "barpolar": [ { "marker": { "line": { "color": "#E5ECF6", "width": 0.5 }, "pattern": { "fillmode": "overlay", "size": 10, "solidity": 0.2 } }, "type": "barpolar" } ], "carpet": [ { "aaxis": { "endlinecolor": "#2a3f5f", "gridcolor": "white", "linecolor": "white", "minorgridcolor": "white", "startlinecolor": "#2a3f5f" }, "baxis": { "endlinecolor": "#2a3f5f", "gridcolor": "white", "linecolor": "white", "minorgridcolor": "white", "startlinecolor": "#2a3f5f" }, "type": "carpet" } ], "choropleth": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "choropleth" } ], "contour": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "contour" } ], "contourcarpet": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "contourcarpet" } ], "heatmap": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "heatmap" } ], "histogram": [ { "marker": { "pattern": { "fillmode": "overlay", "size": 10, "solidity": 0.2 } }, "type": "histogram" } ], "histogram2d": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "histogram2d" } ], "histogram2dcontour": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "histogram2dcontour" } ], "mesh3d": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "mesh3d" } ], "parcoords": [ { "line": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "parcoords" } ], "pie": [ { "automargin": true, "type": "pie" } ], "scatter": [ { "fillpattern": { "fillmode": "overlay", "size": 10, "solidity": 0.2 }, "type": "scatter" } ], "scatter3d": [ { "line": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatter3d" } ], "scattercarpet": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattercarpet" } ], "scattergeo": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattergeo" } ], "scattergl": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattergl" } ], "scattermap": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattermap" } ], "scattermapbox": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattermapbox" } ], "scatterpolar": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterpolar" } ], "scatterpolargl": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterpolargl" } ], "scatterternary": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterternary" } ], "surface": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "surface" } ], "table": [ { "cells": { "fill": { "color": "#EBF0F8" }, "line": { "color": "white" } }, "header": { "fill": { "color": "#C8D4E3" }, "line": { "color": "white" } }, "type": "table" } ] }, "layout": { "annotationdefaults": { "arrowcolor": "#2a3f5f", "arrowhead": 0, "arrowwidth": 1 }, "autotypenumbers": "strict", "coloraxis": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "colorscale": { "diverging": [ [ 0, "#8e0152" ], [ 0.1, "#c51b7d" ], [ 0.2, "#de77ae" ], [ 0.3, "#f1b6da" ], [ 0.4, "#fde0ef" ], [ 0.5, "#f7f7f7" ], [ 0.6, "#e6f5d0" ], [ 0.7, "#b8e186" ], [ 0.8, "#7fbc41" ], [ 0.9, "#4d9221" ], [ 1, "#276419" ] ], "sequential": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "sequentialminus": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ] }, "colorway": [ "#636efa", "#EF553B", "#00cc96", "#ab63fa", "#FFA15A", "#19d3f3", "#FF6692", "#B6E880", "#FF97FF", "#FECB52" ], "font": { "color": "#2a3f5f" }, "geo": { "bgcolor": "white", "lakecolor": "white", "landcolor": "#E5ECF6", "showlakes": true, "showland": true, "subunitcolor": "white" }, "hoverlabel": { "align": "left" }, "hovermode": "closest", "mapbox": { "style": "light" }, "paper_bgcolor": "white", "plot_bgcolor": "#E5ECF6", "polar": { "angularaxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" }, "bgcolor": "#E5ECF6", "radialaxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" } }, "scene": { "xaxis": { "backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white" }, "yaxis": { "backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white" }, "zaxis": { "backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white" } }, "shapedefaults": { "line": { "color": "#2a3f5f" } }, "ternary": { "aaxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" }, "baxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" }, "bgcolor": "#E5ECF6", "caxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" } }, "title": { "x": 0.05 }, "xaxis": { "automargin": true, "gridcolor": "white", "linecolor": "white", "ticks": "", "title": { "standoff": 15 }, "zerolinecolor": "white", "zerolinewidth": 2 }, "yaxis": { "automargin": true, "gridcolor": "white", "linecolor": "white", "ticks": "", "title": { "standoff": 15 }, "zerolinecolor": "white", "zerolinewidth": 2 } } }, "title": { "font": { "size": 24 }, "text": "Investment Analysis Dashboard - PLTR (2025-08-01)", "x": 0.5 }, "xaxis": { "anchor": "y", "domain": [ 0, 0.42 ], "gridcolor": "#E0E0E0", "gridwidth": 1, "showgrid": true }, "xaxis2": { "anchor": "y3", "domain": [ 0, 0.42 ], "gridcolor": "#E0E0E0", "gridwidth": 1, "showgrid": true }, "xaxis3": { "anchor": "y4", "domain": [ 0.52, 0.94 ], "gridcolor": "#E0E0E0", "gridwidth": 1, "showgrid": true }, "xaxis4": { "anchor": "y5", "domain": [ 0.52, 0.94 ], "gridcolor": "#E0E0E0", "gridwidth": 1, "showgrid": true }, "xaxis5": { "anchor": "y6", "domain": [ 0, 0.42 ], "gridcolor": "#E0E0E0", "gridwidth": 1, "showgrid": true }, "yaxis": { "anchor": "x", "domain": [ 0.84, 1 ], "gridcolor": "#E0E0E0", "gridwidth": 1, "showgrid": true }, "yaxis2": { "anchor": "x", "gridcolor": "#E0E0E0", "gridwidth": 1, "overlaying": "y", "showgrid": true, "side": "right" }, "yaxis3": { "anchor": "x2", "domain": [ 0.56, 0.7200000000000001 ], "gridcolor": "#E0E0E0", "gridwidth": 1, "showgrid": true }, "yaxis4": { "anchor": "x3", "domain": [ 0.56, 0.7200000000000001 ], "gridcolor": "#E0E0E0", "gridwidth": 1, "showgrid": true }, "yaxis5": { "anchor": "x4", "domain": [ 0.28, 0.44000000000000006 ], "gridcolor": "#E0E0E0", "gridwidth": 1, "showgrid": true }, "yaxis6": { "anchor": "x5", "domain": [ 0, 0.16 ], "gridcolor": "#E0E0E0", "gridwidth": 1, "showgrid": true } } } }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Summary Report:\n", "{\n", " \"2025-08-01\": {\n", " \"company\": \"PLTR\",\n", " \"final_recommendation\": \"BUY\",\n", " \"current_price\": 1.0,\n", " \"rsi\": 58.63,\n", " \"revenue_growth\": 48,\n", " \"position_size\": 2.5,\n", " \"stop_loss\": 5\n", " }\n", "}\n" ] }, { "data": { "text/plain": [ "<__main__.InvestmentDashboard at 0x7f5fd4fac920>" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Run demo\n", "demo_dashboard()" ] }, { "cell_type": "code", "execution_count": null, "id": "35f59ac0", "metadata": {}, "outputs": [], "source": [ "dashboard = InvestmentDashboard(json_file_path=\"path/to/your/file.json\")\n", "fig = dashboard.create_dashboard()\n", "fig.show()\n", "summary = dashboard.create_summary_report()\n", "\n", "\n" ] } ], "metadata": { "kernelspec": { "display_name": "Trading Agents", "language": "python", "name": "trading_agents" }, "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.12.3" } }, "nbformat": 4, "nbformat_minor": 5 }