Перейти к основному содержимому

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)"

Допускаются только следующие жёстко заданные числа:

  1. Исходные исторические данные (фактическая выручка, отчётная EBITDA и т.д.)
  2. Ключевые допущения, которые пользователь может изменять (темпы роста, параметры WACC, терминальный g)
  3. Текущие рыночные данные (цена акции, сумма долга) — с комментарием к ячейке с указанием источника и даты

Если вы ловите себя на том, что вычисляете значение в 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 в этом навыке).

Планирование макета модели​

Перед написанием любой формулы:

  1. Определите ВСЕ позиции строк разделов
  2. Напишите ВСЕ заголовки и метки
  3. Напишите ВСЕ разделители разделов и пустые строки
  4. ЗАТЕМ пишите формулы, используя зафиксированные позиции строк

Это предотвращает каскадное нарушение формул, когда вставка строки заголовка после написания формул сдвигает все последующие ссылки.

Пошаговая проверка с пользователем​

Для больших моделей (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