{"product_id":"claude-skills-cho-tai-chinh-dashboard-portfolio-phan-tich","title":"Claude Skills cho Tài chính — Dashboard, portfolio, phân tích","description":"\n\u003cp\u003ePhân tích tài chính truyền thống đòi hỏi chuyên gia với Excel phức tạp, Python scripts tùy chỉnh, và nhiều giờ làm việc thủ công. \u003cstrong\u003eClaude kết hợp với financial libraries\u003c\/strong\u003e thay đổi hoàn toàn điều này — từ việc giải thích dữ liệu đến tự động tạo báo cáo chuyên sâu.\u003c\/p\u003e\n\n\u003ch2\u003eSetup môi trường\u003c\/h2\u003e\n\n\u003cpre\u003e\u003ccode\u003epip install anthropic pandas numpy yfinance matplotlib plotly openpyxl\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eModule 1: Portfolio Analyzer\u003c\/h2\u003e\n\n\u003cpre\u003e\u003ccode\u003eimport anthropic\nimport json\nimport yfinance as yf\nimport pandas as pd\nimport numpy as np\nfrom datetime import datetime, timedelta\n\nclient = anthropic.Anthropic()\n\nclass PortfolioAnalyzer:\n    def __init__(self):\n        self.client = anthropic.Anthropic()\n\n    def analyze_portfolio(self, holdings: dict) -\u0026gt; dict:\n        \"\"\"\n        holdings = {\n            \"AAPL\": {\"shares\": 100, \"avg_cost\": 150.0},\n            \"MSFT\": {\"shares\": 50, \"avg_cost\": 280.0},\n            \"GOOGL\": {\"shares\": 20, \"avg_cost\": 2800.0}\n        }\n        \"\"\"\n        # Fetch market data\n        market_data = self._fetch_market_data(list(holdings.keys()))\n\n        # Calculate portfolio metrics\n        portfolio_metrics = self._calculate_metrics(holdings, market_data)\n\n        # Claude phân tích và đưa ra insights\n        analysis = self._ai_analysis(portfolio_metrics)\n\n        return {\n            \"metrics\": portfolio_metrics,\n            \"analysis\": analysis,\n            \"recommendations\": self._generate_recommendations(portfolio_metrics, analysis)\n        }\n\n    def _fetch_market_data(self, symbols: list) -\u0026gt; dict:\n        data = {}\n        end_date = datetime.now()\n        start_date = end_date - timedelta(days=365)\n\n        for symbol in symbols:\n            try:\n                ticker = yf.Ticker(symbol)\n                hist = ticker.history(start=start_date, end=end_date)\n                info = ticker.info\n\n                data[symbol] = {\n                    \"current_price\": hist['Close'].iloc[-1] if not hist.empty else 0,\n                    \"price_52w_high\": hist['Close'].max() if not hist.empty else 0,\n                    \"price_52w_low\": hist['Close'].min() if not hist.empty else 0,\n                    \"ytd_return\": self._calculate_ytd_return(hist),\n                    \"volatility\": hist['Close'].pct_change().std() * np.sqrt(252) * 100 if not hist.empty else 0,\n                    \"pe_ratio\": info.get('trailingPE', 'N\/A'),\n                    \"sector\": info.get('sector', 'Unknown'),\n                    \"prices_30d\": hist['Close'].tail(30).tolist() if not hist.empty else []\n                }\n            except Exception as e:\n                data[symbol] = {\"error\": str(e), \"current_price\": 0}\n\n        return data\n\n    def _calculate_ytd_return(self, hist: pd.DataFrame) -\u0026gt; float:\n        if hist.empty:\n            return 0\n        year_start = hist[hist.index.year == datetime.now().year]\n        if year_start.empty:\n            return 0\n        first_price = year_start['Close'].iloc[0]\n        last_price = hist['Close'].iloc[-1]\n        return ((last_price - first_price) \/ first_price) * 100\n\n    def _calculate_metrics(self, holdings: dict, market_data: dict) -\u0026gt; dict:\n        total_cost = 0\n        total_value = 0\n        positions = []\n\n        for symbol, holding in holdings.items():\n            mdata = market_data.get(symbol, {})\n            shares = holding[\"shares\"]\n            avg_cost = holding[\"avg_cost\"]\n            current_price = mdata.get(\"current_price\", 0)\n\n            cost_basis = shares * avg_cost\n            market_value = shares * current_price\n            gain_loss = market_value - cost_basis\n            gain_loss_pct = ((current_price - avg_cost) \/ avg_cost * 100) if avg_cost \u0026gt; 0 else 0\n\n            total_cost += cost_basis\n            total_value += market_value\n\n            positions.append({\n                \"symbol\": symbol,\n                \"shares\": shares,\n                \"avg_cost\": avg_cost,\n                \"current_price\": current_price,\n                \"market_value\": market_value,\n                \"cost_basis\": cost_basis,\n                \"gain_loss\": gain_loss,\n                \"gain_loss_pct\": round(gain_loss_pct, 2),\n                \"weight\": 0,  # Will calculate after totals\n                \"sector\": mdata.get(\"sector\", \"Unknown\"),\n                \"pe_ratio\": mdata.get(\"pe_ratio\", \"N\/A\"),\n                \"ytd_return\": mdata.get(\"ytd_return\", 0),\n                \"volatility\": mdata.get(\"volatility\", 0)\n            })\n\n        # Calculate weights\n        for pos in positions:\n            pos[\"weight\"] = (pos[\"market_value\"] \/ total_value * 100) if total_value \u0026gt; 0 else 0\n\n        # Portfolio-level metrics\n        portfolio_return = ((total_value - total_cost) \/ total_cost * 100) if total_cost \u0026gt; 0 else 0\n\n        # Sector allocation\n        sector_allocation = {}\n        for pos in positions:\n            sector = pos[\"sector\"]\n            sector_allocation[sector] = sector_allocation.get(sector, 0) + pos[\"weight\"]\n\n        return {\n            \"total_cost\": total_cost,\n            \"total_value\": total_value,\n            \"total_gain_loss\": total_value - total_cost,\n            \"portfolio_return_pct\": round(portfolio_return, 2),\n            \"positions\": positions,\n            \"sector_allocation\": sector_allocation,\n            \"num_positions\": len(positions),\n            \"largest_position\": max(positions, key=lambda x: x[\"weight\"])[\"symbol\"] if positions else None\n        }\n\n    def _ai_analysis(self, metrics: dict) -\u0026gt; str:\n        positions_summary = \"\n\".join([\n            f\"- {p['symbol']}: {p['weight']:.1f}% weight, {p['gain_loss_pct']:+.1f}% return, volatility {p['volatility']:.1f}%\"\n            for p in metrics[\"positions\"]\n        ])\n\n        response = self.client.messages.create(\n            model=\"claude-opus-4-5\",\n            max_tokens=2000,\n            system=\"You are a senior portfolio manager and financial analyst. Provide clear, actionable analysis.\",\n            messages=[{\n                \"role\": \"user\",\n                \"content\": f\"\"\"Analyze this investment portfolio:\n\nTotal Value: ${metrics['total_value']:,.2f}\nTotal Return: {metrics['portfolio_return_pct']:+.2f}%\nNumber of Positions: {metrics['num_positions']}\n\nPositions:\n{positions_summary}\n\nSector Allocation:\n{json.dumps(metrics['sector_allocation'], indent=2)}\n\nProvide analysis on:\n1. Portfolio diversification (concentrated? well-diversified?)\n2. Risk assessment (high volatility positions, sector concentration)\n3. Performance highlights (winners and laggards)\n4. Key risks to watch\n5. Overall portfolio health score (1-10) with brief explanation\"\"\"\n            }]\n        )\n        return response.content[0].text\n\n    def _generate_recommendations(self, metrics: dict, analysis: str) -\u0026gt; list:\n        response = self.client.messages.create(\n            model=\"claude-haiku-4-5\",\n            max_tokens=1000,\n            messages=[{\n                \"role\": \"user\",\n                \"content\": f\"\"\"Based on this portfolio analysis, provide 3-5 specific, actionable recommendations.\n\nAnalysis:\n{analysis}\n\nPortfolio Stats:\n- Total Return: {metrics['portfolio_return_pct']:+.2f}%\n- Positions: {metrics['num_positions']}\n- Sectors: {list(metrics['sector_allocation'].keys())}\n\nFormat each recommendation as:\nACTION: [BUY\/SELL\/HOLD\/REBALANCE]\nTICKER: [if applicable]\nRATIONALE: [1-2 sentences]\nPRIORITY: [HIGH\/MEDIUM\/LOW]\"\"\"\n            }]\n        )\n        return response.content[0].text.strip().split(\"\n\n\")\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eModule 2: Financial Dashboard Generator\u003c\/h2\u003e\n\n\u003cpre\u003e\u003ccode\u003eimport plotly.graph_objects as go\nfrom plotly.subplots import make_subplots\n\ndef create_financial_dashboard(portfolio_data: dict, output_html: str):\n    \"\"\"Tạo interactive HTML dashboard với Plotly\"\"\"\n\n    positions = portfolio_data[\"metrics\"][\"positions\"]\n    sector_alloc = portfolio_data[\"metrics\"][\"sector_allocation\"]\n\n    fig = make_subplots(\n        rows=2, cols=2,\n        subplot_titles=[\n            \"Portfolio Composition\",\n            \"Sector Allocation\",\n            \"Gain\/Loss by Position\",\n            \"Risk vs Return\"\n        ],\n        specs=[\n            [{\"type\": \"pie\"}, {\"type\": \"pie\"}],\n            [{\"type\": \"bar\"}, {\"type\": \"scatter\"}]\n        ]\n    )\n\n    # 1. Portfolio composition (by market value)\n    fig.add_trace(\n        go.Pie(\n            labels=[p[\"symbol\"] for p in positions],\n            values=[p[\"market_value\"] for p in positions],\n            name=\"Portfolio\"\n        ),\n        row=1, col=1\n    )\n\n    # 2. Sector allocation\n    fig.add_trace(\n        go.Pie(\n            labels=list(sector_alloc.keys()),\n            values=list(sector_alloc.values()),\n            name=\"Sectors\"\n        ),\n        row=1, col=2\n    )\n\n    # 3. Gain\/Loss bar chart\n    colors = ['green' if p[\"gain_loss\"] \u0026gt;= 0 else 'red' for p in positions]\n    fig.add_trace(\n        go.Bar(\n            x=[p[\"symbol\"] for p in positions],\n            y=[p[\"gain_loss\"] for p in positions],\n            marker_color=colors,\n            name=\"Gain\/Loss\"\n        ),\n        row=2, col=1\n    )\n\n    # 4. Risk vs Return scatter\n    fig.add_trace(\n        go.Scatter(\n            x=[p[\"volatility\"] for p in positions],\n            y=[p[\"gain_loss_pct\"] for p in positions],\n            mode='markers+text',\n            text=[p[\"symbol\"] for p in positions],\n            textposition=\"top center\",\n            marker=dict(\n                size=[p[\"weight\"] * 2 for p in positions],  # Size by weight\n                color=[p[\"gain_loss\"] for p in positions],\n                colorscale='RdYlGn',\n                showscale=True\n            ),\n            name=\"Risk\/Return\"\n        ),\n        row=2, col=2\n    )\n\n    fig.update_layout(\n        title=f\"Portfolio Dashboard — Total Value: ${portfolio_data['metrics']['total_value']:,.2f}\",\n        height=800,\n        showlegend=False\n    )\n\n    fig.write_html(output_html)\n    print(f\"Dashboard saved to: {output_html}\")\n    return output_html\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eModule 3: Financial Modeling với Claude\u003c\/h2\u003e\n\n\u003cpre\u003e\u003ccode\u003edef run_dcf_analysis(company_data: dict) -\u0026gt; dict:\n    \"\"\"Discounted Cash Flow analysis với Claude\"\"\"\n\n    response = client.messages.create(\n        model=\"claude-opus-4-5\",\n        max_tokens=3000,\n        system=\"You are a CFA-level financial analyst expert in DCF valuation.\",\n        messages=[{\n            \"role\": \"user\",\n            \"content\": f\"\"\"Perform a DCF (Discounted Cash Flow) analysis for:\n\nCompany: {company_data.get('name')}\nIndustry: {company_data.get('industry')}\nCurrent Revenue: ${company_data.get('revenue', 0):,.0f}\nRevenue Growth (3-year avg): {company_data.get('revenue_growth', 0):.1f}%\nOperating Margin: {company_data.get('operating_margin', 0):.1f}%\nCurrent P\/E: {company_data.get('pe_ratio', 'N\/A')}\nShares Outstanding: {company_data.get('shares', 0):,.0f}\n\nProvide:\n1. 5-year revenue and FCF projections (base\/bull\/bear scenarios)\n2. Discount rate (WACC) estimate with reasoning\n3. Terminal value calculation\n4. Intrinsic value per share (all 3 scenarios)\n5. Margin of safety at current price: ${company_data.get('current_price', 0):.2f}\n6. Investment verdict: UNDERVALUED \/ FAIRLY VALUED \/ OVERVALUED\n\nFormat key numbers clearly.\"\"\"\n        }]\n    )\n    return {\"analysis\": response.content[0].text}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eTích hợp đầy đủ: Monthly Report Generator\u003c\/h2\u003e\n\n\u003cpre\u003e\u003ccode\u003edef generate_monthly_report(portfolio: dict, month: str) -\u0026gt; str:\n    \"\"\"Tạo báo cáo tháng đầy đủ: phân tích + Excel + Dashboard\"\"\"\n\n    analyzer = PortfolioAnalyzer()\n\n    # 1. Phân tích portfolio\n    print(\"Analyzing portfolio...\")\n    analysis_result = analyzer.analyze_portfolio(portfolio)\n\n    # 2. Tạo Excel report\n    import openpyxl\n    wb = openpyxl.Workbook()\n    ws = wb.active\n    ws.title = f\"Portfolio {month}\"\n\n    headers = [\"Symbol\", \"Shares\", \"Avg Cost\", \"Current Price\",\n               \"Market Value\", \"Gain\/Loss\", \"Return%\", \"Weight%\", \"Sector\"]\n    for col, h in enumerate(headers, 1):\n        ws.cell(row=1, column=col, value=h)\n\n    for row, pos in enumerate(analysis_result[\"metrics\"][\"positions\"], 2):\n        ws.cell(row=row, column=1, value=pos[\"symbol\"])\n        ws.cell(row=row, column=2, value=pos[\"shares\"])\n        ws.cell(row=row, column=3, value=pos[\"avg_cost\"])\n        ws.cell(row=row, column=4, value=pos[\"current_price\"])\n        ws.cell(row=row, column=5, value=pos[\"market_value\"])\n        ws.cell(row=row, column=6, value=pos[\"gain_loss\"])\n        ws.cell(row=row, column=7, value=pos[\"gain_loss_pct\"])\n        ws.cell(row=row, column=8, value=round(pos[\"weight\"], 2))\n        ws.cell(row=row, column=9, value=pos[\"sector\"])\n\n    excel_path = f\"\/tmp\/portfolio_{month}.xlsx\"\n    wb.save(excel_path)\n\n    # 3. Tạo HTML dashboard\n    dashboard_path = f\"\/tmp\/dashboard_{month}.html\"\n    create_financial_dashboard(analysis_result, dashboard_path)\n\n    # 4. AI Summary\n    summary_response = client.messages.create(\n        model=\"claude-haiku-4-5\",\n        max_tokens=500,\n        messages=[{\n            \"role\": \"user\",\n            \"content\": f\"\"\"Write a brief monthly portfolio summary for {month}:\n\nPerformance: {analysis_result['metrics']['portfolio_return_pct']:+.2f}%\nTotal Value: ${analysis_result['metrics']['total_value']:,.2f}\n\nAnalysis highlights:\n{analysis_result['analysis'][:500]}\n\nWrite 3-4 sentences suitable for an executive briefing.\"\"\"\n        }]\n    )\n\n    return {\n        \"excel\": excel_path,\n        \"dashboard\": dashboard_path,\n        \"summary\": summary_response.content[0].text,\n        \"recommendations\": analysis_result[\"recommendations\"]\n    }\n\n# Chạy report\nholdings = {\n    \"AAPL\": {\"shares\": 100, \"avg_cost\": 150.0},\n    \"MSFT\": {\"shares\": 50, \"avg_cost\": 280.0},\n    \"VNM.VN\": {\"shares\": 1000, \"avg_cost\": 75.0}\n}\nreport = generate_monthly_report(holdings, \"2025-03\")\nprint(f\"Report generated: {report['summary']}\")\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eTổng kết\u003c\/h2\u003e\n\n\u003cp\u003eVới Claude + Python financial libraries, bạn có thể xây dựng công cụ phân tích tài chính mạnh mẽ:\u003c\/p\u003e\n\n\u003cul\u003e\n  \u003cli\u003e\n\u003cstrong\u003ePortfolio Analyzer\u003c\/strong\u003e — metrics tự động + AI insights\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eDashboard Generator\u003c\/strong\u003e — interactive charts với Plotly\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eDCF Modeling\u003c\/strong\u003e — valuation analysis với Claude làm financial analyst\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eMonthly Reports\u003c\/strong\u003e — Excel + dashboard + executive summary tự động\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cp\u003eKhám phá tiếp: \u003ca href=\"\/collections\/nang-cao\"\u003eTạo Custom Skills cho Claude\u003c\/a\u003e để đóng gói các tools này thành skills tái sử dụng.\u003c\/p\u003e\n\n\u003chr\u003e\n\u003ch3\u003eBài viết liên quan\u003c\/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"\/products\/claude-skills-t%E1%BA%A1o-excel-powerpoint-pdf-t%E1%BB%B1-d%E1%BB%99ng\"\u003eClaude Skills — Tạo Excel, PowerPoint, PDF tự động\u003c\/a\u003e\u003c\/li\u003e\n\u003cli\u003e\u003ca href=\"\/products\/chuy%E1%BB%83n-t%E1%BB%AB-openai-agents-sdk-sang-claude-h%C6%B0%E1%BB%9Bng-d%E1%BA%ABn-migration-chi-ti%E1%BA%BFt\"\u003eChuyển từ OpenAI Agents SDK sang Claude — Hướng dẫn migration chi tiết\u003c\/a\u003e\u003c\/li\u003e\n\u003cli\u003e\u003ca href=\"\/products\/computer-use-demo-claude-di%E1%BB%81u-khi%E1%BB%83n-may-tinh-c%E1%BB%A7a-b%E1%BA%A1n\"\u003eComputer Use Demo — Claude điều khiển máy tính của bạn\u003c\/a\u003e\u003c\/li\u003e\n\u003cli\u003e\u003ca href=\"\/products\/claude-cho-data-vi%E1%BA%BFt-database-queries-t%E1%BB%AB-ngon-ng%E1%BB%AF-t%E1%BB%B1-nhien\"\u003eClaude cho Data: Viết database queries từ ngôn ngữ tự nhiên\u003c\/a\u003e\u003c\/li\u003e\n\u003cli\u003e\u003ca href=\"\/products\/claude-cho-engineering-standup-va-bao-cao-ti%E1%BA%BFn-d%E1%BB%99\"\u003eClaude cho Engineering: Standup và báo cáo tiến độ\u003c\/a\u003e\u003c\/li\u003e\n\u003c\/ul\u003e","brand":"Minh Tuấn","offers":[{"title":"Default Title","offer_id":47721898574036,"sku":null,"price":0.0,"currency_code":"VND","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0821\/0264\/9044\/files\/claude-skills-cho-tai-chinh-dashboard-portfolio-phan-tich_7c012432-3c01-4314-9739-c80214e2a750.jpg?v=1774521771","url":"https:\/\/claude.vn\/products\/claude-skills-cho-tai-chinh-dashboard-portfolio-phan-tich","provider":"CLAUDE.VN","version":"1.0","type":"link"}