Excel Author
Создавайте проверяемые книги Excel «вслепую» с помощью openpyxl — соглашения о цветах ячеек (синий/чёрный/зелёный), формулы вместо жёстко заданных значений, именованные диапазоны, проверки балансов, таблицы чувствительности. Используется для финансовых моделей, аудиторских отчётов, сверок.
Метаданные навыка
| Источник | Опционально — установка: vibeos skills install official/finance/excel-author |
| Путь | optional-skills/finance/excel-author |
| Версия | 1.0.0 |
| Автор | Anthropic (адаптировано Nous Research) |
| Лицензия | Apache-2.0 |
| Платформы | linux, macos, windows |
| Теги | excel, openpyxl, finance, spreadsheet, modeling |
| Связанные навыки | pptx-author, dcf-model, comps-analysis, lbo-model, 3-statement-model |
Справочник: полный SKILL.md
Ниже приведено полное описание навыка, которое VibeOS загружает при его активации. Агент видит эти инструкции, когда навык активен.
excel-author
Создайте файл .xlsx на диске с помощью openpyxl. Следуйте приведённым ниже банковским соглашениям, чтобы модель была проверяемой, гибкой и доступной для рецензирования кем-то, кроме её создателя.
Адаптировано из навыков xlsx-author и audit-xls от Anthropic в репозитории anthropics/financial-services. Ветки, специфичные для MCP / Office-JS / Cowork, удалены — этот навык предполагает работу «вслепую» на Python.
Контракт на вывод
- Записывать в
./out/<name>.xlsx. Создавать./out/, если он не существует. - Возвращать относительный путь в итоговом сообщении, чтобы последующие инструменты могли его подхватить.
- Одна логическая модель на файл. Не добавлять данные в существующую книгу, если это не указано явно.
Настройка
pip install "openpyxl>=3.0"
Основные соглашения (обязательны к исполнению)
Цвет ячеек: синий / чёрный / зелёный
- Синий (
Font(color="0000FF")) — жёстко заданные входные данные, введённые человеком. Драйверы выручки, параметры WACC, терминальный рост, рыночные данные. - Чёрный (по умолчанию) — формула. Каждая производная ячейка содержит «живую» формулу Excel.
- Зелёный (
Font(color="006100")) — ссылка на другой лист или внешний файл.
Рецензент может быстро просмотреть лист и сразу увидеть, что является допущением, а что — расчётным значением.
Формулы вместо жёстко заданных значений
Каждая расчётная ячейка ДОЛЖНА быть строкой формулы, а не числом, вычисленным в Python и вставленным как значение.
# НЕПРАВИЛЬНО — скрытая ошибка
ws["D20"] = revenue_prior_year * (1 + growth)
# ПРАВИЛЬНО — изменяется при изменении допущения пользователем
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")
# затем в другом месте:
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("Источник: 10-K FY2024, стр.47, строка выручки", "analyst")
Формат: Источник: [Система/Документ], [Дата], [Ссылка], [URL если применимо].
Никогда не откладывайте указание источника. Никогда не пишите TODO: добавить источник.
Шаблон: типичная финансовая модель
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()
# --- Вкладка входных данных ---
inp = wb.active
inp.title = "Inputs"
inp["A1"] = "РЫНОЧНЫЕ ДАННЫЕ И КЛЮЧЕВЫЕ ВХОДНЫЕ ПАРАМЕТРЫ"
inp["A1"].font = HEADER_FONT
inp["A1"].fill = HEADER_FILL
inp.merge_cells("A1:C1")
inp["B3"] = "Выручка FY2024"
inp["C3"] = 1_250_000_000
inp["C3"].font = BLUE
inp["C3"].comment = Comment("Источник: 10-K FY2024 стр.47", "model")
inp["B4"] = "Темп роста"
inp["C4"] = 0.12
inp["C4"].font = BLUE
# --- Вкладка расчётов ---
calc = wb.create_sheet("DCF")
calc["B2"] = "Прогнозная выручка"
calc["C2"] = "=Inputs!C3*(1+Inputs!C4)" # формула, чёрный
# --- Вкладка проверок ---
chk = wb.create_sheet("Checks")
chk["A2"] = "Баланс сходится"
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"] = "ПРОГНОЗ ДВИЖЕНИЯ ДЕНЕЖНЫХ СРЕДСТВ"
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 (строки) x терминальный рост (столбцы)
wacc_axis = [0.08, 0.085, 0.09, 0.095, 0.10] # центральная строка = базовые 9.0%
term_axis = [0.02, 0.025, 0.03, 0.035, 0.04] # центральный столбец = базовые 3.0%
start_row = 40
ws.cell(row=start_row, column=1).value = "Расчётная цена акции ($)"
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
# Формула полного пересчёта DCF (упрощена для иллюстрации).
# В реальной модели ссылается на полный блок прогнозов.
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"
)
# Выделение центральной ячейки (базовый сценарий)
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 «вслепую»
libreoffice --headless --calc --convert-to xlsx ./out/model.xlsx --outdir ./out/
Или используйте вспомогательный скрипт пересчёта на Python (см. scripts/recalc.py в этом навыке).
Планирование макета модели
Перед написанием любой формулы:
- Определите ВСЕ позиции строк разделов
- Напишите ВСЕ заголовки и метки
- Напишите ВСЕ разделители разделов и пустые строки
- ЗАТЕМ пишите формулы, используя зафиксированные позиции строк
Это предотвращает каскадное нарушение формул, когда вставка строки заголовка после написания формул сдвигает все последующие ссылки.
Пошаговая проверка с пользователем
Для больших моделей (DCF, трёхотчётные модели, LBO) останавливайтесь и показывайте пользователю промежуточные артефакты перед продолжением. Обнаружение неверного допущения по марже до того, как вы построили последующие таблицы чувствительности, экономит час.
Схема контрольных точек:
- После блока Inputs → показать исходные данные, подтвердить перед прогнозированием
- После прогнозов выручки → подтвердить верхнюю строку + рост
- После построения FCF → подтвердить полный график
- После WACC → подтвердить входные данные
- После оценки → подтвердить мост собственного капитала
- ЗАТЕМ строить таблицы чувствительности
Когда НЕ использовать этот навык
- Пользователи работают в «живом» сеансе Excel с доступным MCP Office — управляйте их «живой» книгой.
- Чистый экспорт табличных данных без формул — проще использовать
csvилиpandas.to_excel. - Панели мониторинга / диаграммы с высокой интерактивностью — используйте настоящий BI-инструмент.
Атрибуция
Соглашения (синий/чёрный/зелёный, формулы вместо жёстко заданных значений, именованные диапазоны, правила чувствительности) адаптированы из набора плагинов Claude for Financial Services от Anthropic, лицензия Apache-2.0. Оригинал: https://github.com/anthropics/financial-services/tree/main/plugins/vertical-plugins/financial-analysis/skills/xlsx-author