Скриптуемые Рабочие П роцессы с Beancount и Fava
Beancount (инструмент бухгалтерского учета в виде обычного текста с двойной записью) и Fava (его веб-интерфейс) обладают высокой расширяемостью и возможностью написания скриптов. Их конструкция позволяет автоматизировать финансовые задачи, создавать собственные отчеты и настраивать оповещения, написав скрипты на Python. По словам одного из пользователей: "Мне очень нравится, что мои данные представлены в таком удобном формате, и мне нравится, что я могу автоматизировать все, что угодно. Нет API лучше, чем файл на вашем диске; его легко интегрировать." Это руководство проведет вас через создание скриптуемых рабочих процессов — от простой автоматизации для начинающих до продвинутых плагинов Fava.
Начало работы: Запуск Beancount как скрипта Python
Прежде чем углубляться в конкретные задачи, убедитесь, что у вас установлен Beancount (например, через pip install beancount). Поскольку Beancount написан на Python, вы можете использовать его как библиотеку в своих собственных скриптах. Общий подход заключается в следующем:
-
Загрузите свою бухгалтерскую книгу Beancount: Используйте загрузчик Beancount для разбора файла
.beancountв объекты Python. Например:from beancount import loader
entries, errors, options_map = loader.load_file("myledger.beancount")
if errors:
print("Errors:", errors)Это даст вам список
entries(транзакции, балансы и т. д.) иoptions_mapс метаданными. Все ваши счета, транзакции и балансы теперь доступны в коде. -
Используйте язык запросов Beancount (BQL): Вместо ручной итерации вы можете выполнять SQL-подобные запросы к данным. Например, чтобы получить общую сумму расходов по месяцам, вы можете использовать API запросов:
from beancount.query import query
q = query.Query(entries, options_map)
result = q.query("SELECT month, sum(position) WHERE account ~ 'Expenses' GROUP BY month")
print(result)Здесь используется система запросов Beancount для агрегирования данных. (По сути, это похоже на то, что делает команда
bean-query, но здесь вы используете ее в скрипте.) Фактически, автор Beancount отмечает, что вы можете загрузить файл и вызватьrun_query()непосредственно через API Python, избегая необходимости вызывать внешние команды в цикле. -
Настройте структуру проекта: Организуйте свои скрипты вместе с вашей бухгалтерской книгой. Распространенная структура - это наличие каталогов для импортеров (для получения/разбора внешних данных), отчетов или запросов (для скриптов анализа) и документов (для хранения загруженных выписок). Например, один пользователь хранит:
importers/- пользовательские скрипты импорта Python (с тестами),queries/- скрипты для создания отчетов (запускаемые черезpython3 queries/...),documents/- загруженные банковские CSV/PDF, организованные по счетам.
С помощью этой настройки вы можете запускать скрипты вручную (например, python3 queries/cash_flow.py) или планировать их (через cron или task runner) для автоматизации рабочего процесса.
Автоматизация задач сверки
Сверка означает, что ваша бухгалтерская книга соответствует внешним записям (банковским выпискам, отчетам по кредитным картам и т. д.). Простой текстовый формат Beancount и API Python позволяют автоматизировать большую часть этого процесса.
Импорт и сопоставление транзакций (для начинающих)
Начинающим рекомендуется использовать плагины импорта Beancount. Вы пишете небольшой класс Python, следующий протоколу импорта Beancount, для разбора заданного формата (CSV, OFX, PDF и т. д.) и создания транзакций. Затем используйте команду bean-extract или скрипт для применения этих импортеров:
- Напишит е импортер (класс Python с методами, такими как
identify(),extract()) для формата CSV вашего банка. Документация Beancount предоставляет руководство и примеры. - Используйте
bean-extractв скрипте или Makefile (как в примереjustfile) для разбора новых выписок. Например, один рабочий процесс запускаетbean-extractдля всех файлов в~/Downloadsи выводит транзакции во временный файл. - Вручную просмотрите и скопируйте транзакции из временного файла в свою основную бухгалтерскую книгу, затем запустите
bean-check, чтобы убедиться, что балансы согласованы.
Хотя этот процесс по-прежнему включает этап проверки, большая часть рутинной работы по разбору и форматированию записей автоматизирована. Скрипты импорта также могут автоматически назначать категории и даже устанавливать утверждения баланса (заявления об ожидаемых остатках) для выявления расхождений. Например, после импорта у вас может быть строка, подобная 2025-04-30 balance Assets:Bank:Checking 1234.56 USD, которая подтверждает конечное сальдо. Когда вы запускаете bean-check, Beancount проверит, что все эти утверждения баланса верны, и со общит о любых ошибках, если транзакции отсутствуют или дублируются. Это лучшая практика: автоматически генерируйте утверждения баланса для каждого периода выписки, чтобы компьютер мог обнаружить несогласованные различия за вас.
Пользовательские скрипты сверки (средний уровень)
Для большего контроля вы можете написать собственный скрипт Python для сравнения списка транзакций банка (CSV или через API) с записями вашей бухгалтерской книги:
- Прочитайте внешние данные: Разберите CSV-файл банка с помощью модуля
csvPython (или Pandas). Нормализуйте данные в список транзакций, например, каждая с датой, суммой и описанием. - Загрузите транзакции бухгалтерской книги: Используйте
loader.load_file, как показано ранее, чтобы получить все записи бухгалтерской книги. Отфильтруйте этот спи сок по интересующему вас счету (например, вашему расчетному счету) и, возможно, по диапазону дат выписки. - Сравните и найдите несоответствия:
- Для каждой внешней транзакции проверьте, существует ли идентичная запись в бухгалтерской книге (сопоставьте по дате и сумме, возможно, по описанию). Если не найдено, пометьте ее как "новую" и, возможно, выведите ее как транзакцию в формате Beancount для вашего рассмотрения.
- И наоборот, определите любые записи бухгалтерской книги на этом счете, которые не отображаются во внешнем источнике - это могут быть ошибки ввода данных или транзакции, которые еще не прошли через банк.
- Выведите результаты: Распечатайте отчет или создайте новый фрагмент
.beancountс отсутствующими транзакциями.
В качестве примера, скрипт сообщества под названием reconcile.py делает именно это: учитывая файл Beancount и входной CSV, он печатает список новых транзакций, которые следует импортировать, а также любые существующие проводки бухгалтерской книги, которых нет во входных данных (потенциально признак неправильной классификации). С помощью такого скрипта ежемесячная сверка может быть такой же простой, как запуск скрипта, а затем добавление предлагаемых транзакций в вашу бухгалтерскую книгу. Один из пользователей Beancount отмечает, что они "проводят процесс сверки по всем счетам каждый месяц" и используют растущую коллекцию кода Python для устранения большей части ручной работы по импорту и согласованию данных.
Совет: Во время сверки используйте инструменты Beancount для обеспечения точности:
- Используйте утверждения баланса, как упоминалось, для автоматической проверки остатков на счетах.
- Используйте директиву
pad, если хотите, которая может автоматически вставлять балансирующие записи для незначительных различий в округлении (используйте с осторожностью). - Напишите модульные тесты для своей логики импортера или сверки (Beancount предоставляет вспомогательные средства для тестирования). Например, один рабочий процесс включал в себя взятие образца CSV, написание непроходящих тестов с ожидаемыми транзакциями, а затем реализацию импортера до тех пор, пока все тесты не пройдут. Это гарантирует правильную работу вашего скрипта импорта в различных случаях.
Создание пользовательских отчетов и сводок
Хотя Fava предоставляет множество стандартных отчетов (отчет о прибылях и убытках, баланс и т. д.), вы можете создавать пользовательские отчеты с помощью скриптов. Они могут варьироваться от простых консольных выводов до файлов или графиков в формате rich.
Запрос данных для отчетов (для начинающих)
На базовом уровне вы можете использовать язык запросов Beancount (BQL) для получения сводных данных и их печати или сохранения. Например:
-
Сводка движения денежных средств: Используйте запрос для вычисления чистого движения денежных средств. "Движение денежных средств" можно определить как изменение остатка на определенных счетах за период. С помощью BQL вы можете сделать следующее:
SELECT year, month, sum(amount)
WHERE account LIKE 'Income:%' OR account LIKE 'Expenses:%'
GROUP BY year, monthЭто позволит получить чистую сумму всех доходов и расходов по месяцам. Вы можете запустить это через CLI
bean-queryили через API Python (query.Query, как показано ранее), а затем отформатировать результат. -
Отчет о расходах по категориям: Запросите общую сумму расходов по категориям:
SELECT account, round(sum(position), 2)
WHERE account ~ 'Expenses'
GROUP BY account
ORDER BY sum(position) ASCЭто даст таблицу расходов по категориям. Вы можете запускать несколько запросов в скрипте и выводить результаты в виде текста, CSV или даже JSON для дальнейше й обработки.
Один пользователь обнаружил, что "тривиально" анализировать финансовые данные с помощью Fava или скриптов, сославшись на то, что они используют один скрипт Python для извлечения данных из Beancount через язык запросов, а затем помещают их в Pandas DataFrame для подготовки пользовательского отчета. Например, вы можете получить ежемесячные итоги с помощью запроса, а затем использовать Pandas/Matplotlib для построения графика движения денежных средств во времени. Сочетание BQL и библиотек науки о данных позволяет создавать отчеты, выходящие за рамки того, что Fava предлагает по умолчанию.
Расширенная отчетность (графики, производительность и т. д.)
Для более продвинутых потребностей ваши скрипты могут вычислять такие показатели, как доходность инвестиций, или с оздавать визуальные выходные данные:
-
Доходность инвестиций (IRR/XIRR): Поскольку ваша бухгалтерская книга содержит все денежные потоки (покупки, продажи, дивиденды), вы можете рассчитать ставки доходности портфеля. Например, вы можете написать скрипт, который фильтрует транзакции ваших инвестиционных счетов, а затем вычисляет внутреннюю норму доходности. Существуют библиотеки (или формулы) для вычисления IRR на основе данных о денежных потоках. Некоторые разработанные сообществом расширения Fava (например, PortfolioSummary или fava_investor) делают именно это, вычисляя IRR и другие показатели для инвестиционных портфелей. В качестве скрипта вы можете использовать функцию IRR (из NumPy или свою собственную) для серии взносов/снятий средств плюс итоговую стоимость.
-
Многопериодные или пользовательские показатели: Хотите отчет о вашем уровне сбережений (отношении сбережений к доходу) за каждый месяц? Скрипт Python может загрузить бухгалтерскую книгу, суммировать все счета доходов и все счета расходов, а затем вычислить сбережения = доход - расходы и процент. Это может вывести красивую таблицу или даже сгенерировать отчет HTML/Markdown для ваших записей.
-
Визуализация: Вы можете создавать графики вне Fava. Например, используйте
matplotlibилиaltairв скрипте для создания графика собственного капитала с течением времени, используя данные бухгалтерской книги. Поскольку в бухгалтерской книге есть все исторические остатки (или вы можете накапливать их, перебирая записи), вы можете создавать графики временных рядов. Сохраните эти графики как изображения или интерактивный HTML. (Если вы предпочитаете визуальные элементы в приложении, см. раздел расширений Fava ниже для добавления графиков внутри Fava.)
Параметры вывода: Решите, как доставить отчет:
- Для разового анализа может быть достаточно печати на экране или сохранения в файл CSV/Excel.
- Для информационных панелей рассмотрите возможность создания HTML-файла с данными (возможно, с использованием библиотеки шаблонов, такой как Jinja2, или даже просто записи Markdown), который вы можете открыть в браузере.
- Вы также можете интегрироваться с Jupyter Notebooks для интерактивной среды отчетности, хотя это больше подходит для исследования, чем для автоматизации.
Запуск оповещений из вашей бухгалтерской книги
Еще одно мощное использование скриптуемых рабочих процессов - это настройка оповещений на основе условий в ваших финансовых данных. Поскольку ваша бухгалтерская книга регулярно обновляется (и может включать элементы, датированные будущим, такие как предстоящие счета или бюджеты), вы можете сканировать ее с помощью скрипта и получать уведомления о важных событиях.
Предупреждения о низком остатке на счете
Чтобы избежать овердрафтов или поддерживать минимальный остаток, вам может потребоваться оповещение, если какой-либо счет (например, расчетный или сберегательный) опускается ниже порогового значения. Вот как вы можете это реализовать:
-
Определите текущие остатки: После загрузки
entriesчерез загрузчик рассчитайте последний остаток на интересующих счетах. Вы можете сделать это, агрегируя проводки или используя запрос. Например, используйте запрос BQL для остатка на определенном счете:SELECT sum(position) WHERE account = 'Assets:Bank:Checking'Это вернет текущий остаток на этом счете (сумму всех его проводок). В качестве альтернативы используйте внутренние функции Beancount для создания баланса. Например:
from beancount.core import realization
tree = realization.realize(entries, options_map)
acct = realization.get_or_create(tree, "Assets:Bank:Checking")
balance = acct.balance # an Inventory of commoditiesЗатем извлеките числовое значение (например,
balance.get_currency_units('USD')может дать Decimal). Однако использование запроса проще в большинстве случаев. -
Проверьте пороговое значение: Сравните остаток с вашим предопределенным лимитом. Если ниже, запустите оповещение.
-
Запустите уведомление: Это может быть так же просто, как вывод предупреждения в консоль, но для реальных оповещений вы можете отправить электронное письмо или push-уведомление. Вы можете интегрироваться с электронной почтой (через
smtplib) или службой, такой как IFTTT, или API веб-перехватчика Slack для отправки оповещения. Например:if balance < 1000:
send_email("Low balance alert", f"Account XYZ balance is {balance}")(Реализуйте
send_emailс данными вашего почтового сервера.)
Запуская этот скрипт ежедневно (с помощью cron job или Windows Task Scheduler), вы будете получать упреждающие предупреждения. Поскольку он использует бухгалтерскую книгу, он может учитывать все транзакции, включая те, которые вы только что добавили.