Claude Code Plugins

Community-maintained marketplace

Feedback

financial-analysis

@keith-mvs/ordinis
1
0

Comprehensive financial statement analysis including ratio calculation, trend analysis, and peer comparison. Evaluates liquidity, profitability, efficiency, and leverage metrics. Requires numpy>=1.24.0, pandas>=2.0.0, matplotlib>=3.7.0. Use when analyzing company fundamentals, comparing financial performance, or conducting equity research.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name financial-analysis
description Comprehensive financial statement analysis including ratio calculation, trend analysis, and peer comparison. Evaluates liquidity, profitability, efficiency, and leverage metrics. Requires numpy>=1.24.0, pandas>=2.0.0, matplotlib>=3.7.0. Use when analyzing company fundamentals, comparing financial performance, or conducting equity research.

Financial Analysis and Modeling Skill

Purpose

Generate sophisticated financial models and analyses directly in Excel with comprehensive audit trails, validation logic, and professional formatting. This skill enables creation of production-ready financial models with full transparency, reproducibility, and enterprise-grade quality controls.

Core Principles

1. Audit Trail Requirements

All formulas visible and documented, dedicated assumptions sheet with sources/dates, model version and modification log, clear data flow from inputs to outputs, change tracking with rationale, embedded validation checks with pass/fail indicators.

2. Model Architecture

Structure models for clarity, maintainability, and audit-readiness:

Standard Model Structure:
├── Cover Sheet (Model metadata, purpose, version)
├── Executive Summary (Key outputs and insights)
├── Assumptions (All inputs, sources, dates, sensitivity flags)
├── Input Data (Raw data with source documentation)
├── Calculations (Core model logic, clearly sectioned)
├── Outputs (Results, dashboards, charts)
├── Validation (Internal checks, reconciliations, error tests)
└── Documentation (Methodology, formulas explained, changelog)

3. Professional Standards

Consistent calculation methods, color-code hard-coded values, use named ranges for key cells, implement IFERROR/IFNA for robustness, build modular reusable blocks, support multiple scenarios (base/upside/downside).

Excel Implementation Guidelines

Python Library Requirements

# Primary libraries for Excel manipulation
import openpyxl
from openpyxl.styles import Font, PatternFill, Border, Side, Alignment, NumberFormat
from openpyxl.utils import get_column_letter
from openpyxl.worksheet.datavalidation import DataValidation
from openpyxl.chart import LineChart, BarChart, Reference

# For advanced calculations
import pandas as pd
import numpy as np
from datetime import datetime, date

Standard Color Coding Scheme

COLORS = {
    'input': 'FFFF00',        # Yellow - User inputs/assumptions
    'calculation': 'E0E0E0',  # Light gray - Formulas
    'output': '90EE90',       # Light green - Key results
    'validation': 'FFB6C1',   # Light pink - Check cells
    'header': '4472C4',       # Blue - Section headers
    'hardcoded': 'FFA500',    # Orange - Hard-coded constants
    'error': 'FF0000',        # Red - Error conditions
    'pass': '00FF00',         # Green - Validation passed
}

Model Metadata Template

Always include on the Cover Sheet:

def create_cover_sheet(ws, model_details):
    """Create cover sheet. model_details dict: title, purpose, version, author, created_date, modified_date, reviewer, assumptions_source."""
    ws['A1'] = model_details['title']
    ws['A1'].font = Font(size=18, bold=True)

    ws['A3'] = "Model Purpose:"
    ws['B3'] = model_details['purpose']

    ws['A4'] = "Version:"
    ws['B4'] = model_details['version']

    ws['A5'] = "Author:"
    ws['B5'] = model_details['author']

    ws['A6'] = "Created Date:"
    ws['B6'] = model_details['created_date']

    ws['A7'] = "Last Modified:"
    ws['B7'] = model_details['modified_date']

    ws['A8'] = "Reviewed By:"
    ws['B8'] = model_details.get('reviewer', 'Pending Review')

    ws['A10'] = "Assumptions Source:"
    ws['B10'] = model_details['assumptions_source']

    # Add audit note
    ws['A12'] = "Audit Trail:"
    ws['B12'] = "All assumptions, calculations, and validations are documented within this model."

Assumptions Sheet Best Practices

The Assumptions sheet is the foundation of model credibility:

def create_assumptions_sheet(ws, assumptions_data):
    """Create assumptions sheet. assumptions_data: list of dicts with category, parameter, value, unit, source, date, sensitivity, notes."""
    headers = ['Category', 'Parameter', 'Value', 'Unit', 'Source',
               'Date', 'Sensitivity', 'Notes']

    # Create header row with formatting
    for col_num, header in enumerate(headers, 1):
        cell = ws.cell(row=1, column=col_num)
        cell.value = header
        cell.font = Font(bold=True, color='FFFFFF')
        cell.fill = PatternFill(start_color='4472C4', end_color='4472C4', fill_type='solid')
        cell.alignment = Alignment(horizontal='center')

    # Add assumptions with color coding
    for row_num, assumption in enumerate(assumptions_data, 2):
        ws.cell(row=row_num, column=1, value=assumption['category'])
        ws.cell(row=row_num, column=2, value=assumption['parameter'])

        # Value cell - marked as input
        value_cell = ws.cell(row=row_num, column=3, value=assumption['value'])
        value_cell.fill = PatternFill(start_color='FFFF00', end_color='FFFF00', fill_type='solid')

        ws.cell(row=row_num, column=4, value=assumption['unit'])
        ws.cell(row=row_num, column=5, value=assumption['source'])
        ws.cell(row=row_num, column=6, value=assumption['date'])

        # Sensitivity indicator
        sensitivity_cell = ws.cell(row=row_num, column=7, value=assumption['sensitivity'])
        if assumption['sensitivity'] == 'High':
            sensitivity_cell.fill = PatternFill(start_color='FF6B6B', end_color='FF6B6B', fill_type='solid')

        ws.cell(row=row_num, column=8, value=assumption['notes'])

    # Add named ranges for key assumptions
    for row_num, assumption in enumerate(assumptions_data, 2):
        param_name = assumption['parameter'].replace(' ', '_').replace('%', 'pct')
        ws.define_name(param_name, f"Assumptions!${get_column_letter(3)}${row_num}")

Validation Sheet Requirements

Every model must include comprehensive validation checks:

def create_validation_sheet(ws):
    """Create validation with automated checks: balance, reconciliation, logical, completeness, formula, sensitivity."""
    headers = ['Check ID', 'Check Description', 'Expected Result',
               'Actual Result', 'Status', 'Tolerance', 'Notes']

    for col_num, header in enumerate(headers, 1):
        cell = ws.cell(row=1, column=col_num)
        cell.value = header
        cell.font = Font(bold=True, color='FFFFFF')
        cell.fill = PatternFill(start_color='4472C4', end_color='4472C4', fill_type='solid')

    # Example validation check row
    ws['A2'] = 'CHK-001'
    ws['B2'] = 'Balance Sheet Balance: Total Assets = Total Liabilities + Equity'
    ws['C2'] = '=Calculations!TotalAssets'  # Reference to expected
    ws['D2'] = '=Calculations!TotalLiabilitiesEquity'  # Reference to actual

    # Status formula with color coding
    ws['E2'] = '=IF(ABS(C2-D2)<=F2, "PASS", "FAIL")'

    # Conditional formatting for status
    ws['E2'].style = 'Good' if ws['E2'].value == 'PASS' else 'Bad'

    ws['F2'] = 0.01  # Tolerance threshold
    ws['G2'] = 'Critical balance check for accounting integrity'

Advanced Formula Patterns

Time Series Calculations

def create_projection_formulas(ws, start_row, periods):
    """
    Create time-series projection formulas with growth rates.

    Pattern: Next Period = Previous Period * (1 + Growth Rate)
    Includes error handling and circular reference prevention.
    """
    for period in range(periods):
        row = start_row + period
        if period == 0:
            # First period uses base assumption
            ws[f'C{row}'] = f'=Assumptions!Base_Value'
        else:
            # Subsequent periods use growth formula
            ws[f'C{row}'] = f'=IFERROR(C{row-1}*(1+Assumptions!Growth_Rate), C{row-1})'

NPV and IRR Calculations

def create_npv_irr_section(ws, cash_flow_range, discount_rate_cell):
    """
    Create NPV and IRR calculations with proper documentation.

    Args:
        cash_flow_range: Range of cash flow cells (e.g., 'C10:C20')
        discount_rate_cell: Cell reference for discount rate
    """
    ws['B25'] = 'Net Present Value (NPV):'
    ws['C25'] = f'=NPV({discount_rate_cell}, {cash_flow_range})'
    ws['C25'].number_format = '$#,##0'
    ws['D25'] = 'Discount rate from Assumptions sheet'

    ws['B26'] = 'Internal Rate of Return (IRR):'
    ws['C26'] = f'=IRR({cash_flow_range})'
    ws['C26'].number_format = '0.00%'
    ws['D26'] = 'Iterative calculation'

    # Color code as output
    ws['C25'].fill = PatternFill(start_color='90EE90', end_color='90EE90', fill_type='solid')
    ws['C26'].fill = PatternFill(start_color='90EE90', end_color='90EE90', fill_type='solid')

Scenario Analysis Structure

def create_scenario_section(ws, base_case_range):
    """
    Create scenario analysis with base, upside, and downside cases.
    """
    scenarios = ['Base Case', 'Upside (+20%)', 'Downside (-20%)']

    ws['A1'] = 'Scenario Analysis'
    ws['A1'].font = Font(size=14, bold=True)

    for col, scenario in enumerate(scenarios, 2):
        ws.cell(row=2, column=col, value=scenario)
        ws.cell(row=2, column=col).font = Font(bold=True)

    # Link calculations with scenario multipliers
    ws['B3'] = f'={base_case_range}'
    ws['C3'] = f'={base_case_range}*1.2'
    ws['D3'] = f'={base_case_range}*0.8'

Data Visualization Standards

def create_professional_chart(ws, data_range, chart_title, chart_type='line'):
    """
    Create professional chart with proper formatting.

    Args:
        ws: worksheet object
        data_range: Range containing data for chart
        chart_title: Descriptive chart title
        chart_type: 'line', 'bar', or 'column'
    """
    if chart_type == 'line':
        chart = LineChart()
    else:
        chart = BarChart()

    chart.title = chart_title
    chart.style = 10  # Professional style
    chart.y_axis.title = 'Value ($)'
    chart.x_axis.title = 'Period'

    # Add data
    data = Reference(ws, min_col=2, min_row=1, max_row=20, max_col=4)
    cats = Reference(ws, min_col=1, min_row=2, max_row=20)
    chart.add_data(data, titles_from_data=True)
    chart.set_categories(cats)

    # Place chart
    ws.add_chart(chart, 'F2')

Common Financial Model Types

DCF Model: Revenue projections, operating expenses, working capital, CapEx schedule, FCF calculation, terminal value, WACC, NPV/sensitivity | Three-Statement Model: Income statement, balance sheet, cash flow statement with automatic balancing, period analysis, ratios | Budget vs Actual: Budget assumptions, actual results, variance calculations ($ and %), commentary, rolling forecasts, YTD projections | ROI Model: Initial investment, projected returns, cost of capital, ROI/IRR/payback, sensitivity, breakeven | Scenario Analysis: Multiple scenarios, key variables, data tables, tornado charts, Monte Carlo simulation, risk-adjusted returns

Workflow Process

Requirements: Define purpose, identify users/sophistication, determine scope (horizon/detail/frequency), list assumptions/sources, establish validation criteria | Design: Sketch flow, define sheets, establish naming, design inputs, plan validation | Foundation: Create cover (metadata/version), build assumptions (documented inputs), setup validation framework, create documentation | Implementation: Start simple, test incrementally, add complexity, implement error handling, document formulas | Validation: Run checks, stress test, reconcile totals, cross-check outputs, peer review | Finishing: Format consistently, create executive summary, add charts, write documentation, lock structure

Best Practices for Production Models

Formula Hygiene

  • Never hide rows or columns with formulas
  • Avoid merged cells in calculation areas
  • Keep formulas short and readable (break complex calculations into steps)
  • Use consistent reference styles (prefer absolute references for assumptions)
  • Avoid volatile functions (NOW, TODAY, RAND) in large models

Error Prevention

  • Always use IFERROR to prevent #DIV/0, #N/A, #VALUE errors
  • Implement input validation (Data Validation dropdowns, ranges)
  • Add warning flags for unusual results
  • Create boundary checks (negative values where impossible)
  • Test with edge cases (zero values, very large numbers)

Performance Optimization

  • Minimize array formulas in large datasets
  • Use manual calculation mode for very large models
  • Replace complex formulas with helper columns
  • Avoid entire column references (A:A)
  • Turn off automatic chart updates during data entry

Audit Trail Documentation

Every change should be logged:

def create_change_log(ws):
    """Create a change log sheet for model modifications."""
    headers = ['Version', 'Date', 'Author', 'Section Modified',
               'Change Description', 'Rationale', 'Reviewed By']

    for col, header in enumerate(headers, 1):
        cell = ws.cell(row=1, column=col)
        cell.value = header
        cell.font = Font(bold=True)
        cell.fill = PatternFill(start_color='4472C4',
                                end_color='4472C4', fill_type='solid')

Example: Creating a Complete DCF Model

from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Alignment
from datetime import datetime

def create_dcf_model(company_name, projection_years=5):
    """Create complete DCF valuation model. Returns saved Excel workbook path."""
    wb = Workbook()
    wb.remove(wb.active)

    # 1. Cover Sheet: Title, purpose, version, created date, status
    cover = wb.create_sheet('Cover')
    cover['A1'] = f'{company_name} - DCF Valuation Model'
    cover['A1'].font = Font(size=18, bold=True)
    # ... metadata cells

    # 2. Assumptions Sheet: Revenue (Base, Growth %), Margins (EBITDA %), Cost of Capital (WACC, Terminal Growth)
    assumptions = wb.create_sheet('Assumptions')
    # Color-code inputs (yellow fill), add sources in column C
    # Define named ranges: BaseRevenue, RevenueGrowth, EBITDAMargin, WACC, TerminalGrowth

    # 3. Projections Sheet: Revenue, EBITDA, Free Cash Flow formulas
    projections = wb.create_sheet('Projections')
    # Revenue: =BaseRevenue*(1+RevenueGrowth)^year
    # EBITDA: =Revenue*EBITDAMargin
    # FCF: =EBITDA*0.7 (simplified)

    # 4. Valuation Sheet: PV calculations, Terminal Value, Enterprise Value
    valuation = wb.create_sheet('Valuation')
    # PV = FCF/(1+WACC)^year
    # Terminal Value = Final FCF*(1+g)/(WACC-g)
    # EV = Sum of PVs + PV of Terminal Value

    # 5. Validation Sheet: VAL-001 (all inputs populated), VAL-002 (growth <50%), VAL-003 (terminal growth < WACC)
    validation = wb.create_sheet('Validation')
    # Use IF formulas for PASS/FAIL status

    # 6. Documentation Sheet: Methodology, key formulas, changelog
    docs = wb.create_sheet('Documentation')

    wb.save(f'/mnt/user-data/outputs/{company_name.replace(" ", "_")}_DCF_Model.xlsx')
    return filename

Quality Checklist

Structure: Cover sheet (metadata), assumptions (sources/dates), input/calculation/output separation, validation sheet, documentation | Formulas: Reference assumptions (no hard-coding), IFERROR wrapping, named ranges, auditable, no unintentional circular refs | Formatting: Color coding, professional fonts, clear headers, number formatting, charts | Validation: All checks pass/noted, balance checks, sense checks, sensitivity analysis, peer review | Audit Trail: Documented assumptions/sources, change log, version number, methodology explained, review sign-off

Advanced Topics

Scenario Management with Data Tables

Use Excel's Data Table feature for sophisticated scenario analysis:

def create_sensitivity_table(ws, output_cell, variable_cells):
    """Create two-way data table. variable_cells: dict with 'row_variable' and 'col_variable' cell refs."""
    # Create table structure
    ws['A1'] = 'Sensitivity Analysis'
    ws['B1'] = output_cell

    # Column headers (first variable values)
    for i, val in enumerate([-20, -10, 0, 10, 20], 2):
        ws.cell(row=1, column=i, value=f'{val}%')

    # Row headers (second variable values)
    for i, val in enumerate([-20, -10, 0, 10, 20], 2):
        ws.cell(row=i, column=1, value=f'{val}%')

    # Excel data table will populate the interior cells automatically
    # User must manually: Select range → Data → What-If Analysis → Data Table

Monte Carlo Simulation Integration

For risk analysis, integrate with Python's statistical libraries:

import numpy as np
from scipy import stats

def monte_carlo_simulation(base_value, volatility, simulations=10000):
    """Run Monte Carlo for uncertain inputs. Returns array of simulated values."""
    np.random.seed(42)  # For reproducibility
    std_dev = base_value * volatility
    simulated_values = np.random.normal(base_value, std_dev, simulations)

    # Calculate statistics
    results = {
        'mean': np.mean(simulated_values),
        'median': np.median(simulated_values),
        'std': np.std(simulated_values),
        'p10': np.percentile(simulated_values, 10),
        'p90': np.percentile(simulated_values, 90),
    }

    return simulated_values, results

VBA for Advanced Automation

For models requiring user forms or custom functions:

Function PV_Custom(rate As Double, nper As Integer, cashFlows As Range) As Double
    'Custom present value function with detailed audit trail
    Dim i As Integer
    Dim pv_sum As Double

    pv_sum = 0
    For i = 1 To nper
        pv_sum = pv_sum + cashFlows.Cells(i) / ((1 + rate) ^ i)
    Next i

    PV_Custom = pv_sum

    'Log calculation for audit trail
    ThisWorkbook.Sheets("Audit").Range("A1").Value = _
        "PV calculated: " & Format(Now, "yyyy-mm-dd hh:mm:ss")
End Function

Integration with External Tools

Power BI for Dashboard Creation

Export key model outputs to Power BI for executive dashboards:

# Export summary data for Power BI consumption
def export_for_powerbi(workbook, output_path):
    """
    Export model outputs in Power BI friendly format.

    Creates a structured table with:
    - Metric name
    - Value
    - Unit
    - Scenario
    - Timestamp
    """
    import pandas as pd

    # Extract key metrics from model
    # (Implementation would read from Excel and create structured DataFrame)
    pass

Python Analytics Integration

Link Excel models with Python for advanced analytics:

# Read Excel model and run advanced analytics
def analyze_model_outputs(excel_path):
    """
    Read Excel model outputs and perform statistical analysis.

    Can perform:
    - Regression analysis
    - Time series forecasting
    - Correlation analysis
    - Risk metrics calculation
    """
    import pandas as pd

    # Read outputs
    df = pd.read_excel(excel_path, sheet_name='Outputs')

    # Perform analysis
    # (Implementation would include statistical tests, visualizations)
    pass

Critical Reminders

Audit trail is non-negotiable (every number traceable), assumptions drive everything (document sources), validate ruthlessly (build error checks), format for clarity (color coding matters), document methodology (others must understand), test extensively (edge cases and stress scenarios), maintain version control, professional presentation (reflects credibility).

Common Pitfalls

Avoid: circular references without purpose, hard-coded values in formulas, missing error handling (#DIV/0, #N/A), inconsistent time periods, hidden rows with calculations, entire column references (A:A), missing documentation, no validation checks, overly complex nested formulas, unprotected formulas.