Excel Author
Создавайте проверяемые финансовые книги в headless-режиме через openpyxl.
Метаданные навыка
| Источник | Опциональный (устанавливается по запросу) — установите командой hermes skills install official/finance/excel-author |
| Путь | optional-skills/finance/excel-author |
| Версия | 1.0.0 |
| Автор | Anthropic (adapted by Nous Research) |
| Лицензия | Apache-2.0 |
| Платформы | linux, macos, windows |
| Теги | excel, openpyxl, finance, spreadsheet, modeling |
| Связанные навыки | xlsx, pptx-author, dcf-model, comps-analysis, lbo-model, 3-statement-model |
Справочник: полный SKILL.md
Ниже приведено полное определение навыка, которое Hermes Agent загружает при его активации. Именно этот текст агент видит как инструкцию в момент работы навыка.
excel-author
Создайте .xlsx-файл на диске с помощью openpyxl. Соблюдайте банковские соглашения, описанные ниже — модель должна поддаваться аудиту, оставаться гибкой при изменении допущений и читаться человеком, который её не строил.
Адаптировано из навыков xlsx-author и audit-xls Anthropic в репозитории anthropics/financial-services. Ветки MCP / Office-JS / Cowork убраны — навык рассчитан на headless Python.
Контракт на вывод
- Пишите в
./out/<name>.xlsx. Папку./out/создайте, если она не существует. - В финальном сообщении верните относительный путь к файлу — чтобы следующие инструменты могли его подхватить.
- Одна логическая модель — один файл. Не дописывайте в существующую книгу, если пользователь явно не попросил.
Установка
pip install "openpyxl>=3.0"
Базовые соглашения (обязательны)
Цвет ячеек: синий / чёрный / зелёный
- Синий (
Font(color="0000FF")) — захардкоженный ввод от человека: драйверы выручки, WACC, темп роста в терминальном периоде, рыночные данные. - Чёрный (по умолчанию) — формула. Любая производная ячейка содержит живую формулу Excel.
- Зелёный (
Font(color="006100")) — ссылка на другой лист или внешний файл.
Проверяющий сразу видит, что является допущением, а что — расчётом.
Формулы вместо захардкоженных значений
Каждая расчётная ячейка ОБЯЗАНА содержать строку-формулу — никаких чисел, вычисленных в Python и вставленных как значение.
# WRONG — silent bug waiting to happen
ws["D20"] = revenue_prior_year * (1 + growth)
# CORRECT — flexes when the user changes the assumption
ws["D20"] = "=D19*(1+$B$8)"
Захардкоженные числа допускаются только в следующих случаях:
- Исторические фактические данные (реальная выручка, отчётный EBITDA и т.д.)
- Драйверы допущений, которые пользователь должен менять (темпы роста, WACC, терминальный g)
- Текущие рыночные данные (цена акции, размер долга) — с комментарием к ячейке, фиксирующим источник и дату
Поймали себя на том, что вычисляете значение в Python и записываете результат — стоп.
Именованные диапазоны для межлистовых ссылок
Используйте именованные диапазоны для любой величины, на которую ссылаются с другого листа, из презентации или меморандума.
from openpyxl.workbook.defined_name import DefinedName
wb.defined_names["WACC"] = DefinedName("WACC", attr_text="Inputs!$C$8")
# then elsewhere:
calc["D30"] = "=D29/WACC"
Вкладка проверок баланса
Включите вкладку Checks, которая сводит всё воедино и показывает TRUE/FALSE:
- Баланс сходится (активы = обязательства + капитал)
- Денежный поток привязан к изменению кэша между периодами в балансе
- Сумма частей сходится с консолидированными итогами
- Нет посторонних захардкоженных значений внутри расчётных диапазонов
Пример:
checks = wb.create_sheet("Checks")
checks["A2"] = "BS balances"
checks["B2"] = "=IS!D20-IS!D21-IS!D22"
checks["C2"] = "=ABS(B2)<0.01" # TRUE/FALSE
Комментарии к каждой захардкоженной ячейке
Добавляйте комментарий в момент создания ячейки, не потом.
from openpyxl.comments import Comment
ws["C2"] = 1_250_000_000
ws["C2"].font = Font(color="0000FF")
ws["C2"].comment = Comment("Source: 10-K FY2024, p.47, revenue line", "analyst")
Формат: Source: [System/Document], [Date], [Reference], [URL if applicable].
Не откладывайте указание источника. Никаких TODO: add source.
Каркас: типовая финансовая модель
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
from openpyxl.comments import Comment
from openpyxl.utils import get_column_letter
from pathlib import Path
BLUE = Font(color="0000FF")
BLACK = Font(color="000000")
GREEN = Font(color="006100")
BOLD = Font(bold=True)
HEADER_FILL = PatternFill("solid", fgColor="1F4E79")
HEADER_FONT = Font(color="FFFFFF", bold=True)
wb = Workbook()
# --- Inputs tab ---
inp = wb.active
inp.title = "Inputs"
inp["A1"] = "MARKET DATA & KEY INPUTS"
inp["A1"].font = HEADER_FONT
inp["A1"].fill = HEADER_FILL
inp.merge_cells("A1:C1")
inp["B3"] = "Revenue FY2024"
inp["C3"] = 1_250_000_000
inp["C3"].font = BLUE
inp["C3"].comment = Comment("Source: 10-K FY2024 p.47", "model")
inp["B4"] = "Growth Rate"
inp["C4"] = 0.12
inp["C4"].font = BLUE
# --- Calc tab ---
calc = wb.create_sheet("DCF")
calc["B2"] = "Projected Revenue"
calc["C2"] = "=Inputs!C3*(1+Inputs!C4)" # formula, black
# --- Checks tab ---
chk = wb.create_sheet("Checks")
chk["A2"] = "BS balances"
chk["B2"] = "=ABS(BS!D20-BS!D21-BS!D22)<0.01"
Path("./out").mkdir(exist_ok=True)
wb.save("./out/model.xlsx")
Заголовки секций с объединёнными ячейками
Особенность openpyxl: при слиянии значение задаётся на верхней левой ячейке, а стиль применяется ко всему диапазону отдельно.
ws["A7"] = "CASH FLOW PROJECTION"
ws["A7"].font = HEADER_FONT
ws.merge_cells("A7:H7")
for col in range(1, 9): # A..H
ws.cell(row=7, column=col).fill = HEADER_FILL
Таблицы чувствительности
Строятся циклами — никаких захардкоженных формул на каждую ячейку. Правила:
- Нечётное количество строк/столбцов (5×5 или 7×7) — гарантирует истинную центральную ячейку.
- Центральная ячейка = базовый сценарий. Заголовок центральной строки/столбца должен совпадать с реальным WACC и терминальным g модели — тогда центральный результат даёт базовую подразумеваемую цену акции. Это и есть проверка на адекватность.
- Выделите центральную ячейку средне-синей заливкой (
"BDD7EE") и жирным шрифтом. - Каждая ячейка — полная формула пересчёта, без приближений.
# 5x5 WACC (rows) x terminal growth (cols) sensitivity
wacc_axis = [0.08, 0.085, 0.09, 0.095, 0.10] # center row = base 9.0%
term_axis = [0.02, 0.025, 0.03, 0.035, 0.04] # center col = base 3.0%
start_row = 40
ws.cell(row=start_row, column=1).value = "Implied Share Price ($)"
ws.cell(row=start_row, column=1).font = BOLD
for j, g in enumerate(term_axis):
ws.cell(row=start_row+1, column=2+j).value = g
ws.cell(row=start_row+1, column=2+j).font = BLUE
for i, w in enumerate(wacc_axis):
r = start_row + 2 + i
ws.cell(row=r, column=1).value = w
ws.cell(row=r, column=1).font = BLUE
for j, g in enumerate(term_axis):
c = 2 + j
# Full DCF recalc formula (simplified for illustration).
# In a real model this references the full projection block.
ws.cell(row=r, column=c).value = (
f"=SUMPRODUCT(FCF_range,1/(1+{w})^year_offset) + "
f"FCF_terminal*(1+{g})/({w}-{g})/(1+{w})^terminal_year"
)
# Highlight center cell (base case)
center = ws.cell(row=start_row+2+len(wacc_axis)//2,
column=2+len(term_axis)//2)
center.fill = PatternFill("solid", fgColor="BDD7EE")
center.font = BOLD
Пересчёт перед передачей
openpyxl записывает строки формул, но не вычисляет их. Excel пересчитает при открытии, однако downstream-потребители (скрипты автопроверки, CI) требуют готовых значений.
Перед передачей запустите LibreOffice или отдельный шаг пересчёта:
# LibreOffice headless recalc
libreoffice --headless --calc --convert-to xlsx ./out/model.xlsx --outdir ./out/
Либо воспользуйтесь вспомогательным Python-скриптом (см. scripts/recalc.py в этом навыке).
Планирование разметки модели
Прежде чем писать какую-либо формулу:
- Определите позиции строк ВСЕХ секций
- Запишите ВСЕ заголовки и метки
- Добавьте ВСЕ разделители секций и пустые строки
- ЗАТЕМ пишите формулы, используя зафиксированные позиции строк
Это предотвращает каскадное смещение ссылок, когда вставка строки заголовка после написанных формул сдвигает все нижние ссылки.
Пошаговая сверка с пользователем
Для крупных моделей (DCF, трёхотчётная, LBO) делайте паузы и показывайте промежуточные артефакты, не дожидаясь конца. Поймать неверное допущение по марже до того, как построены таблицы чувствительности, — экономит час работы.
Схема контрольных точек:
- После блока Inputs → покажите исходные данные, подтвердите перед проекциями
- После прогнозов выручки → подтвердите верхнюю строку и рост
- После расчёта FCF → подтвердите полный график
- После WACC → подтвердите допущения
- После оценки → подтвердите equity bridge
- ЗАТЕМ стройте таблицы чувствительности
Когда НЕ использовать этот навык
- Пользователь работает в живой сессии Excel с доступным Office MCP — управляйте его активной книгой напрямую.
- Нужен чистый экспорт таблицы без формул —
csvилиpandas.to_excelпроще. - Дашборды и графики с насыщенной интерактивностью — используйте полноценный BI-инструмент.
Авторство
Соглашения (синий/чёрный/зелёный, формулы вместо захардкоженных значений, именованные диапазоны, правила таблиц чувствительности) адаптированы из плагинного набора Anthropic «Claude for Financial Services», лицензия Apache-2.0. Оригинал: https://github.com/anthropics/financial-services/tree/main/plugins/vertical-plugins/financial-analysis/skills/xlsx-author