microsft income statement bridge chart for current year

Calling: load - metrics=["total_revenue", "cost_of_revenue", "gross_profit", "research_and_development", "selling_general_and_administrative", "operating_expenses", "operating_income", "net_income"], start_date="2024-01-01", tickers=["MSFT"], end_date="2026-06-12" DataFrame 224 OK msft_fundamentals (11 rows)

Calling: compute - dataframe_ids=[224], code="df = df_224\nannual_df = df[df['period_type'] == 'annual'].sort_values('date')\nquarterly_df = df[df['period_type'] == 'quarterly'].sort_values('date')\nprint(\"Annual:\\n\", annual_df[['date', 'total_revenue', 'operating_income', 'net_income']])\nprint(\"Quarterly:\\n\", quarterly_df[['date', 'total_revenue', 'operating_income', 'net_income']])\nresult = annual_df\n" DataFrame 225 OK result_225 (17 rows)

Calling: compute - code="df = df_224.sort_values(['period_type', 'date'])\nresult = df\n", dataframe_ids=[224] DataFrame 226 OK result_226 (11 rows)

Calling: compute - code="df = df_224.sort_values('date')\nresult = df\nprint(df[['date', 'period_type', 'total_revenue']])\n", dataframe_ids=[224] DataFrame 227 OK result_227 (23 rows)

Calling: compute - dataframe_ids=[224], code="print(df_224.to_string())\nresult = df_224\n" DataFrame 228 OK result_228 (23 rows)

Calling: compute - dataframe_ids=[224], code="import pandas as pd\npd.set_option('display.max_rows', 100)\npd.set_option('display.max_columns', 20)\nprint(df_224.sort_values(['period_type', 'date']).to_string())\nresult = df_224\n" DataFrame 229 OK result_229 (23 rows)

Calling: compute - dataframe_ids=[224], code="import pandas as pd\ndf = df_224\ndates = df.sort_values('date')[['date', 'period_type']].drop_duplicates()\nresult = dates\n" DataFrame 230 OK result_230 (11 rows)

Calling: compute - dataframe_ids=[230], code="result = df_230.tail(2)\n" DataFrame 231 OK result_231 (2 rows)

Calling: compute - code="import pandas as pd\ndf = df_224\n\n# Let's check what rows we have for quarterly\nq_df = df[df['period_type'] == 'quarterly'].copy()\nq_df['date'] = pd.to_datetime(q_df['date'])\nq_df = q_df.sort_values('date')\n\n# Let's print out the quarters to verify\nprint(q_df[['date', 'total_revenue', 'cost_of_revenue', 'gross_profit', 'research_and_development', 'selling_general_and_administrative', 'operating_income', 'net_income']])\n\n# Let's calculate TTM ended March 31, 2026\nttm_dates = ['2025-06-30', '2025-09-30', '2025-12-31', '2026-03-31']\nttm_df = q_df[q_df['date'].isin(ttm_dates)]\nprint(f\"Number of quarters for TTM: {len(ttm_df)}\")\n\n# Let's calculate 9M ended March 31, 2026 (FY2026 Q1-Q3)\nfy26_9m_dates = ['2025-09-30', '2025-12-31', '2026-03-31']\nfy26_9m_df = q_df[q_df['date'].isin(fy26_9m_dates)]\n\n# Let's calculate 9M ended March 31, 2025 (FY2025 Q1-Q3)\nfy25_9m_dates = ['2024-09-30', '2024-12-31', '2025-03-31']\nfy25_9m_df = q_df[q_df['date'].isin(fy25_9m_dates)]\n\n# Create a summary of these\nsummary = pd.DataFrame()\nsummary['Metric'] = ['total_revenue', 'cost_of_revenue', 'gross_profit', 'research_and_development', 'selling_general_and_administrative', 'operating_income', 'net_income']\n\n# Compute sums\nsummary['TTM_March_2026'] = [ttm_df[m].sum() for m in summary['Metric']]\nsummary['9M_FY2026'] = [fy26_9m_df[m].sum() for m in summary['Metric']]\nsummary['9M_FY2025'] = [fy25_9m_df[m].sum() for m in summary['Metric']]\n\n# Also get FY2025 (Full Year) from annual rows\nfy25_annual = df[(df['period_type'] == 'annual') & (df['date'] == '2025-06-30')]\nif not fy25_annual.empty:\n summary['FY2025_Annual'] = [fy25_annual[m].values[0] for m in summary['Metric']]\nelse:\n summary['FY2025_Annual'] = 0\n\nresult = summary\n", dataframe_ids=[224] DataFrame 232 OK result_232 (20 rows)

Calling: compute - dataframe_ids=[232], code="print(df_232.to_string())\nresult = df_232\n" Error: Python error: ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/dist-packages/pandas/io/parsers/c_parser_wrapper.py", line 215, in read chunks = self._reader.read_low_memory(nrows) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "pandas/_libs/parsers.pyx", line 832, in pandas._libs.parsers.TextReader.read_low_memory File "pandas/_libs/parsers.pyx", line 897, in pandas._libs.parsers.TextReader._read_rows File "pandas/_libs/parsers.pyx", line 868, in pandas._libs.parsers.TextReader._tokenize_rows File "pandas/_libs/parsers.pyx", line 885, in pandas._libs.parsers.TextReader._check_tokenize_status File "pandas/_libs/parsers.pyx", line 2084, in pandas._libs.parsers.raise_parser_error pandas.errors.ParserError: Error tokenizing data. C error: Expected 1 fields in line 14, saw 5

Calling: compute - code="import pandas as pd\ndf = df_224.copy()\ndf['date'] = pd.to_datetime(df['date'])\n\nq_df = df[df['period_type'] == 'quarterly'].sort_values('date')\n\n# Periods\nttm_dates = ['2025-06-30', '2025-09-30', '2025-12-31', '2026-03-31']\nfy26_9m_dates = ['2025-09-30', '2025-12-31', '2026-03-31']\nfy25_9m_dates = ['2024-09-30', '2024-12-31', '2025-03-31']\n\n# Dataframes\nttm_q = q_df[q_df['date'].isin(pd.to_datetime(ttm_dates))]\nfy26_9m_q = q_df[q_df['date'].isin(pd.to_datetime(fy26_9m_dates))]\nfy25_9m_q = q_df[q_df['date'].isin(pd.to_datetime(fy25_9m_dates))]\n\nmetrics = ['total_revenue', 'cost_of_revenue', 'gross_profit', 'research_and_development', 'selling_general_and_administrative', 'operating_expenses', 'operating_income', 'net_income']\n\nsummary = pd.DataFrame({'Metric': metrics})\nsummary['TTM_March_2026'] = summary['Metric'].apply(lambda m: ttm_q[m].sum())\nsummary['9M_FY2026'] = summary['Metric'].apply(lambda m: fy26_9m_q[m].sum())\nsummary['9M_FY2025'] = summary['Metric'].apply(lambda m: fy25_9m_q[m].sum())\n\nfy25_annual = df[(df['period_type'] == 'annual') & (df['date'] == '2025-06-30')]\nif not fy25_annual.empty:\n summary['FY2025_Annual'] = summary['Metric'].apply(lambda m: fy25_annual[m].values[0])\nelse:\n summary['FY2025_Annual'] = 0.0\n\nresult = summary\n", dataframe_ids=[224] DataFrame 233 OK result_233 (8 rows)

Calling: compute - code="import pandas as pd\n\n# Let's create the Revenue to Net Income Bridge for 9M FY26 (in Millions)\nbridge_9m = pd.DataFrame([\n {\"Item\": \"Total Revenue\", \"Value\": 241832.0, \"Type\": \"Starting\"},\n {\"Item\": \"Cost of Revenue\", \"Value\": -76849.0, \"Type\": \"Expense\"},\n {\"Item\": \"Gross Profit\", \"Value\": 164983.0, \"Type\": \"Subtotal\"},\n {\"Item\": \"Research & Development (R&D)\", \"Value\": -25565.0, \"Type\": \"Expense\"},\n {\"Item\": \"Selling, General & Administrative\", \"Value\": -5669.0, \"Type\": \"Expense\"},\n {\"Item\": \"Other Operating Expenses\", \"Value\": -19115.0, \"Type\": \"Expense\"},\n {\"Item\": \"Operating Income\", \"Value\": 114634.0, \"Type\": \"Subtotal\"},\n {\"Item\": \"Interest, Taxes & Non-Operating (Net)\", \"Value\": -16651.0, \"Type\": \"Expense\"},\n {\"Item\": \"Net Income\", \"Value\": 97983.0, \"Type\": \"Final\"}\n])\n\n# Let's create the Operating Income YoY Bridge (9M FY25 to 9M FY26)\nyoy_bridge = pd.DataFrame([\n {\"Driver\": \"Operating Income (9M FY25)\", \"Impact\": 94205.0, \"Type\": \"Starting\"},\n {\"Driver\": \"Revenue Growth Impact\", \"Impact\": 36549.0, \"Type\": \"Positive\"},\n {\"Driver\": \"Cost of Revenue Increase\", \"Impact\": -13032.0, \"Type\": \"Negative\"},\n {\"Driver\": \"R&D Expense Increase\", \"Impact\": -1906.0, \"Type\": \"Negative\"},\n {\"Driver\": \"SG&A Expense Increase\", \"Impact\": -439.0, \"Type\": \"Negative\"},\n {\"Driver\": \"Other OpEx Increase\", \"Impact\": -743.0, \"Type\": \"Negative\"}, # (19115 - 18372) = 743\n {\"Driver\": \"Operating Income (9M FY26)\", \"Impact\": 114634.0, \"Type\": \"Final\"}\n])\n\n# Save these to display\n# We will return the first one as result, we can create another dataframe for the second one\nresult = bridge_9m\n", dataframe_ids=[233] DataFrame 234 OK result_234 (9 rows)

Calling: compute - dataframe_ids=[233], code="import pandas as pd\nyoy_bridge = pd.DataFrame([\n {\"Driver\": \"Operating Income (9M FY25)\", \"Impact\": 94205.0, \"Type\": \"Starting\"},\n {\"Driver\": \"Revenue Growth Impact\", \"Impact\": 36549.0, \"Type\": \"Positive\"},\n {\"Driver\": \"Cost of Revenue Increase\", \"Impact\": -13032.0, \"Type\": \"Negative\"},\n {\"Driver\": \"R&D Expense Increase\", \"Impact\": -1906.0, \"Type\": \"Negative\"},\n {\"Driver\": \"SG&A Expense Increase\", \"Impact\": -439.0, \"Type\": \"Negative\"},\n {\"Driver\": \"Other OpEx Increase\", \"Impact\": -743.0, \"Type\": \"Negative\"},\n {\"Driver\": \"Operating Income (9M FY26)\", \"Impact\": 114634.0, \"Type\": \"Final\"}\n])\nresult = yoy_bridge\n" DataFrame 235 OK result_235 (7 rows)

Calling: show - dataframe_id=234 Blob 98 DataFrame 234 OK result_234 (9 rows)

Calling: show - dataframe_id=235 Blob 99 DataFrame 235 OK result_235 (7 rows)

Calling: show_chart - title="Microsoft Operating Income YoY Bridge (9M FY25 to 9M FY26)", dataframe_id=235, x="Driver", chart_type="bar", series=["Impact"] Blob 100 DataFrame 235 OK result_235 (7 rows)

Presented below are the income statement bridges for Microsoft Corp. (MSFT) for the current fiscal year (FY26), based on the latest available data for the nine months (9M) ended March 31, 2026 (since the full fiscal year ending June 30, 2026, is not yet fully reported).

Two perspectives of the bridge are provided: 1. Revenue to Net Income Bridge: Showing the step-down from total sales to bottom-line profitability. 2. Year-over-Year Operating Income Bridge: Explaining the drivers of the operating profit expansion from 9M FY25 to 9M FY26.

Microsoft Revenue to Net Income Bridge (9M FY26)

This table outlines how Microsoft's top-line revenue bridges down to net income through each major expense line item for the nine months ended March 31, 2026.

MSFT Operating Income YoY Bridge (9M FY25 to 9M FY26)

This bridge details the individual drivers behind the $20.43 Billion increase in operating income year-over-year. Positive figures indicate profit drivers (revenue increases), while negative figures represent drag factors (higher operating expenses).

Note: All figures are in Millions of USD ($M).

New