Beancount 및 Fava를 사용한 스크립팅 가능한 워크플로우
Beancount (plain-text 복식 부기 회계 도구) 및 Fava (웹 인터페이스)는 확장 가능하고 스크립팅 가능합니다. 이를 통해 Python 스크립트를 작성하여 재무 작업을 자동화하고, 사용자 정의 보고서를 생성하고, 알림을 설정할 수 있습니다. 한 사용자의 말에 따르면 "데이터를 편리한 형식으로 가지고 있고, 원하는 대로 자동화할 수 있다는 점이 마음에 듭니다. 디스크에 있는 파일과 같은 API가 없으며, 통합하기 쉽습니다." 이 가이드에서는 초보자에게 적합한 자동화부터 고급 Fava 플러그인까지 스크립팅 가능한 워크플로우를 만드는 방법을 안내합니다.
시작하기: Python 스크립트로 Beancount 실행하기
)
특정 작업을 시작하기 전에 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 Query Language (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의 Query 시스템을 사용하여 데이터를 집계합니다. (내부적으로는
bean-query명령이 수행하는 것과 유사하지만 여기서는 스크립트에서 사용하고 있습니다.) 실제로 Beancount 작성자는 파일을 로드하고 Python API를 통해 직접run_query()를 호출하여 루프에서 외부 명령을 호출할 필요가 없다고 언급합니다. -
프로젝트 구조 설정: 원장과 함께 스크립트를 구성합니다. 일반적인 레이아웃은 임포터 (외부 데이터를 가져오고 파싱), 보고서 또는 쿼리 (분석 스크립트) 및 문서 (다운로드한 명세서를 저장)를 위한 디렉토리를 갖는 것입니다. 예를 들어 한 사용자는 다음을 유지합니다.
importers/– 사용자 정의 Python 가져오기 스크립트 (테스트 포함),queries/– 보고서를 생성하는 스크립트 (python3 queries/...를 통해 실행 가능),documents/– 계정별로 구성된 다운로드된 은행 CSV/PDF.
이 설정을 사용하면 스크립트를 수동으로 실행하거나 (예: python3 queries/cash_flow.py) cron 또는 작업 실행기를 통해 스크립트를 예약하여 워크플로우를 자동화할 수 있습니다.
조정 작업 자동화
조정은 원장이 외부 기록 (은행 명세서, 신용 카드 보고서 등)과 일치하는지 확인하는 것을 의미합니다. Beancount의 plain-text 원장 및 Python API를 통해 이 프로세스의 상당 부분을 자동화할 수 있습니다.
거래 가져오기 및 매칭 (초급)
초보자의 경우 Beancount의 임포터 플러그인을 사용하는 것이 좋습니다. 주어진 형식 (CSV, OFX, PDF 등)을 파싱하고 거래를 생성하기 위해 Beancount의 임포터 프로토콜을 따르는 작은 Python 클래스를 작성합니다. 그런 다 음 bean-extract 명령 또는 스크립트를 사용하여 이러한 임포터를 적용합니다.
- 은행의 CSV 형식에 대한 임포터 (예:
identify(),extract()와 같은 메서드가 있는 Python 클래스)를 작성합니다. Beancount의 설명서는 가이드 및 예제를 제공합니다. - 스크립트 또는 Makefile (예:
justfile예제)에서bean-extract를 사용하여 새 명세서를 파싱합니다. 예를 들어 한 워크플로우는~/Downloads의 모든 파일에서bean-extract를 실행하고 임시 파일에 거래를 출력합니다. - 임시 파일에서 거래를 수동으로 검토하고 기본 원장에 복사한 다음
bean-check를 실행하여 잔액이 조정되었는지 확인합니다.
이 프로세스에는 여전히 검토 단계가 포함되지만 항목 파싱 및 형식 지정에 대한 대부분의 힘든 작업이 자동화됩니다. 임포터 스크립트는 카테고리를 자동 할당하고 불일치를 잡기 위해 잔액 어설션 (예상 잔액에 대한 설명)을 설정할 수도 있습니다. 예를 들어 가져온 후 2025-04-30 balance Assets:Bank:Checking 1234.56 USD와 같은 줄이 있을 수 있으며 이는 마감 잔액을 어설션합니다. bean-check를 실행하면 Beancount는 이러한 모든 잔액 어설션이 올바른지 확인하고 거래가 누락되거나 중복된 경우 오류를 플래그합니다. 이것은 모범 사례입니다. 각 명세서 기간에 대한 잔액 어설션을 자동 생성하여 컴퓨터가 조정되지 않은 차이점을 찾아내도록 합니다.
사용자 정의 조정 스크립트 (중급)
더 많은 제어를 위해 은행의 거래 목록 (CSV 또는 API를 통해)을 원장 항목과 비교하는 사용자 정의 Python 스크립트를 작성할 수 있습니다.
- 외부 데이터 읽기: Python의
csv모듈 (또는 Pandas)을 사용하여 은행의 CSV 파일을 파싱합니다. 데이터를 날짜, 금액 및 설명이 포함된 거래 목록으로 정규화합니다. - 원장 거래 로드: 앞에서와 같이
loader.load_file을 사용하여 모든 원장 항목을 가져옵니다. 이 목록을 관심 계정 (예: 당좌 예금 계정) 및 명세서의 날짜 범위로 필터링합니다. - 비교 및 불일치 찾기:
- 각 외부 거래에 대해 원장에 동일한 항목이 있는지 확인합니다 (날짜 및 금액, 아마도 설명으로 일치). 찾을 수 없으면 "새로움"으로 표시하고 검토할 수 있도록 Beancount 형식 거래로 출력합니다.
- 반대로 해당 계정에 외부 소스에 나타나지 않는 원장 항목을 식별합니다. 이는 데이터 입력 오류 또는 은행에서 정리되지 않은 거래일 수 있습니다.
- 결과 출력: 보고서를 인쇄하거나 누락된 거래가 포함된 새
.beancount스니펫을 만듭니다.
예를 들어 **reconcile.py**라는 커뮤니티 스크립트는 정확히 이 작업을 수행합니다. Beancount 파일과 입력 CSV가 주어지면 가져와야 하는 새 거래 목록과 입력에 없는 기존 원장 게시 (잠재적으로 잘못된 분류의 신호)를 인쇄합니다. 이러한 스크립트를 사용하면 월별 조정은 스크립트를 실행한 다음 제안된 거래를 원장에 추가하는 것만큼 간단할 수 있습니다. 한 Beancount 사용자는 _"매달 모든 계정에 대해 조정 프로세스를 수행합니다."_라고 언급하고 Python 코드 모음을 늘려 데이터를 가져오고 조정하는 데 있어 대부분의 수동 작업을 제거합니다.
팁: 조정하는 동안 정확성을 위해 Beancount의 도구를 활용하십시오.
- 계정 잔액에 대한 자동 검사를 수행하기 위해 언급된 잔액 어설션을 사용합니다.
- 원하는 경우 사소한 반올림 차이에 대한 균형 조정 항목을 자동 삽입할 수 있는
pad지시문을 사용합니다 (주의해서 사용하십시오). - 임포터 또는 조정 논리에 대한 단위 테스트를 작성합니다 (Beancount는 테스트 도우미를 제공합니다). 예를 들어 한 워크플로우는 샘플 CSV를 가져와 예상 거래로 실패하는 테스트를 작성한 다음 모든 테스트가 통과될 때까지 임포터를 구현하는 것을 포함했습니다. 이렇게 하면 가져오기 스크립트가 다양한 경우에 대해 올바르게 작동합니다.
사용자 정의 보고서 및 요약 생성
Fava는 많은 표준 보고서 (손익 계산서, 대차 대조표 등)를 제공하지만 스크립트를 사용하여 사용자 정의 보고서를 만들 수 있습니다. 이것은 간단한 콘솔 출력에서 풍부한 형식 파일 또는 차트에 이르기까지 다양합니다.
보고서를 위한 데이터 쿼리 (초급)
기본 수준에서는 Beancount Query Language (BQL)를 사용하여 요약 데이터를 가져와 인쇄하거나 저장할 수 있습니다. 예를 들어:
-
현금 흐름 요약: 쿼리를 사용하여 순 현금 흐름을 계산합니다. "현금 흐름"은 일정 기간 동안 특정 계정의 잔액 변화로 정의될 수 있습니다. BQL을 사용하여 다음과 같이 할 수 있습니다.
SELECT year, month, sum(amount)
WHERE account LIKE 'Income:%' OR account LIKE 'Expenses:%'
GROUP BY year, month이렇게 하면 모든 수입 및 지출 게시물이 월별로 정산됩니다. 이것을
bean-queryCLI 또는 Python API (query.Query(앞에서와 같이))를 통해 실행한 다음 결과를 형식화할 수 있습니다. -
카테고리별 지출 보고서: 카테고리별 총 지출을 쿼리합니다.
SELECT account, round(sum(position), 2)
WHERE account ~ 'Expenses'
GROUP BY account
ORDER BY sum(position) ASC이렇게 하면 카테고리별 지출 표가 생성됩니다. 스크립트에서 여러 쿼리를 실행하고 결과를 텍스트, CSV 또는 추가 처리를 위해 JSON으로 출력할 수 있습니다.
한 사용자는 **Fava 또는 스크립트를 사용하여 재무 데이터를 분석하는 것이 "사소하다"**는 것을 발견하고, Python 스크립트 하나를 사용하여 Query Language를 통해 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 Notebook과 통합할 수도 있지만 이는 자동화보다 탐색에 더 적합합니다.