takutakahashi.dev

MoneyForward と自作ソフトウェアを用いた家計管理

我が家では、家計の管理に MoneyForward を活用しています。プレミアム会員です。

前提

まず前提として、我が家は夫婦二人暮らしで共働きです。
仕組みとしては、毎月家計に一定額を収めるシステムを採用しています。
家計支払い用に家族カードを奥さんに渡してあります。できる限り家計の支払いは家族カードで行います。
また、MoneyForward を利用して毎月の収支や資産総額の推移を可視化できるようにしています。
支出が多かったときは、食費に使いすぎたね、など振り返りを実施します。

家計と個人のお金のやり取りが頻繁に発生する

我が家では、家計借金制度を導入しています。
これは、「ほしいものがあったらカジュアルに家計から借金して購入しても構わない」という制度です。
理由は様々ありますが、要約すると以下のようになります。

  • お金がないことによる機会損失を減らす
  • 複数回払いによるクレジットカードの金利など、無駄な出費をなくす
  • 数十万のオーダーで一時的に残高が減っても問題ない程度には蓄えがある

そのため、家計から個人用にお金を使う、家計にお金を追加で入れる、といったオペレーションが頻繁に発生します。

月ごとに厳密に締めたい

我が家では、毎月のキャッシュフローを重視しています。
主に出費の把握と毎月の資産推移の安定化を目的としています。
また、月始めには、先月の収支を夫婦で軽く確認します。
そのときまでに先月の収支を確定させたい、という意味合いもあります。

そのため、「月終わりは大きい買い物をカード決済しない」などの行動を取ります。
カードの明細が降りてくるのが遅いため、収支が確定する時期が遅れてしまうためです。

大型出費は年間を通して管理したい

家具を買った、結婚式に出席した、など、大型出費が発生することは往々にしてあります。
その出費は月々の出費に混ぜず、年間でいくらまで、というふうに管理をする必要があります。
月々の収支はあくまでその月内で消費が完結するものに閉じるほうが望ましいです。


Money Forward 要件

上記の前提を踏まえ、要件を定義します。
以下の要件を満たせるように MoneyForward の使い方を工夫します。

1. 家計に対する個人のお金のやり取りを記録できるようにする

家計からいくら借金しているのか、家計の費用をいくら建て替えているのかを把握できるようにします。
ただし、お金の動きが記録されていないと予期せぬ踏み倒しが発生する可能性があるため、
これを MoneyForward で記録し管理します。

2. 建て替えや借金が貯金成績に反映されないようにする

毎月の貯金目標を設定し、目標よりも多かったり少なかったりしたら何が原因か分析を行っています。
この際、家計とのお金のやり取りが成績に反映されないように工夫する必要があります。
例えば、10万円借金したので収支マイナス10万円、みたいなことが起こらないようにする必要があります。

3. お金の流れはできる限り発生した月を正確に記録する

例えば、8月に家計の物品4000円を建て替え、9月に家計から徴収したとすると、
本来8月に引かれるはずだった4000円が9月に引かれることになってしまいます。
これを防ぐために、8月の出費は8月に計上されるようにする必要があります。

4. 投資信託の時価総額の増減が貯金成績に反映されないようにする

投資信託の時価総額(基準価額)は大きく増減を繰り返します。
その差分が目標に反映されると、「貯金が多かったけど投信の値上がりを引くと実質マイナス」みたいなことが起こります。
また、投資成績はあまり目に入れたくないため、どうにかして隠蔽します。

5. 大型出費は月々の収支に反映されないようにする

大型出費を、登録されるがまま任せておくと、
月々の収支がめちゃくちゃになります。
仮に引っ越しをしたとして、その月収支が20万円マイナス、みたいなことになってしまいます。
これを防ぎます。

解決法

それぞれの要件を解決する方法を紹介します。

(要件1,2,3) 個人用と家計用の現金財布を作成する

財布

具体的には、「自分」「奥さん」「家計」の3つの財布を作成します。
そして、家計の資産を管理するグループに上記の財布を追加します。
財布の中身の規約は以下の通りです。

  • 個人財布
    • 残高がプラス = 家計に借金がある
    • 残高がマイナス = 家計からお金をもらえる
  • 家計財布
    • 物理財布の残高 (共有財布に何枚お札が入っているか)

上記の画像は、現在の財布の残高の様子です。
僕は家計から14万円借金をしており、奥さんは1200円家計の費用を建て替えています。
賞与を見込んで色々買い物をしたため、借金がかさんでいます。

そして、お金のやり取りに以下のルールを設定します。

  • 家計からお金を借りる時
    1. 家計の物理財布から借りたい額を抜く(または口座から引き落とす)
    2. MoneyForward で「家計」→ 「個人」へと振替入金を設定する
    3. 「家計」の額が減り、「個人」の額が増える = 収支がゼロに合う
  • 家計の費用を建て替える時
    1. 自分の物理財布からお金を支払う
    2. MoneyForward で「個人」からの出費を入力する
    3. 「個人」の額が減り、出費が正常に記録される
  • 建て替えや借金を後日精算するとき
    1. 家計の物理財布からお金を出し入れする
    2. 物理財布からお金を操作した場合は、「家計財布」 → 「個人」の振替を設定する
    3. 「家計」の額が増え、「個人」の額が減る = 収支がゼロに合う

上記の例を見るとわかるのですが、家計への借金は個人財布から見るとプラスに計上され、
家計代金の建て替えはマイナスに計上されます。
こうすることで、MoneyForward 全体で見ると、資産額が建て替え等を行っていない場合と一致するようになります。
例えば、家計口座から10000円借金するとして、
家計口座から10000円の引き落としを行ったら家計の残高はマイナス10000円になりますが、
個人財布に10000円がプラスされるのでプラマイゼロになります。

また、建て替えを行った際は、出費が発生したタイミングで家計簿に記録するため、
要件3のような時系列のズレが発生しなくなります。

建て替えてる様子

(要件4) 投資積立額という財布を用意する

財布  投資積立の額を隠蔽するためには、「投資積立額」という財布を用意します。
画像の、一番下の現金管理の部分です。
積立を口座引落しに設定している場合、MoneyForward に引き落としの記録が残ります。
その記録を「引き落とし口座」→「投資積立額」へと振替設定するだけです。

こうすることで、「現金をいくら積立に使ったか」が正確に記録されます。
あとは、積立の証券口座を資産総額のグループから外せば、増減は隠蔽されます。

(要件5) 特別出費という財布を用意して、年末に満額出費にする

「特別出費」という財布を用意します。

そして、特別出費が発生したタイミングで、家計簿に記録された出費を、「特別出費」に入金する形で振替設定します。
そうすると、その出費が月々の出費から消え、「特別出費」の残高が増えます。
資産全体に影響を与えず、特別出費を時系列に合わせて記録することができます。
年末に予算を「特別出費」の財布から出費として記録すれば、年間の収支も一致します。


収支入力にソフトウェアを導入する

MoneyForward は自分のアカウントで運用していますが、
借金や建て替えを記録するために、奥さんにも収支を登録してもらう必要があります。
これに対し、以下の問題が生じます。

  1. アカウントを共有するのはあまり望ましくない
  2. 収支の登録方法がトリッキーであるため、登録間違いが発生する可能性がある

以上の理由から、MoneyForward に収支を登録するための Web アプリを構築しました。

小さいことをうまくやるソフトウェアを作成

再利用可能な状態にするために、2つのソフトウェアを作成しました。

1. MoneyForward に入出金データを入れる CLI ツール

automf という名前を付けています。

https://github.com/takutakahashi/automf

MoneyForward にデータを入れるツールです。
CLI として実装し、コンテナにまとめてあります。

以下のように実行すると、
指定した財布から支出するというデータが入ります。

python3 ./mf.py add \
  --group "group" \
  --add_type expense \
  --member "財布名" \
  --item "食費" \
  --amount "100" \
  --comment "アイスを買った"

他にも、リロードボタンを叩いたり資産合計を抽出したり色々と便利なタスクを作成しています。
内部は、愚直に selenium で Web を叩いてます。

2. 任意のコンテナを Web API 化するツール

container-api-gateway という名前を付けています。

https://github.com/takutakahashi/container-api-gateway

HTTP リクエストのパラメータをコンテナ起動時のコマンドライン引数にパースし、
コンテナ終了時の標準出力をレスポンスとして返すツールです。
Backend として Kubernetes に対応しています。

これで、以下のように config を書くと、/add という API を生やすことができます。

baseURL: "https://www.takutakahashi.dev/assets"
host: "0.0.0.0"
healthcheckPath: /health
endpoints:
 - path: /add
   method: POST
   async: true
   env:
   - MF_ID
   - MF_PASSWORD
   params:
   - name: member
     description: 建て替えした人
     choice:
       - name: ぼく
       - name: 奥さん
   - name: item
     description: 種類
     choice:
       - name: 外食
         value: 食費/外食
       - name: 食費
         value: 食費/食費
       - name: 日用品
         value: 日用品/日用品
       - name: 光熱費
         value: 光熱費/光熱費
       - name: その他
         value: その他/生活費
   - name: amount
     type: number
     description: 金額
   - name: comment
     type: string
     description: コメント
     optional: true
   containers:
   - name: main
     image: docker.io/takutakahashi/automf
     command:
      - python3
      - ./mf.py
      - add
      - --group
      - "家計"
      - --add_type
      - expense
      - --member
      - "{{ .member }}"
      - --item
      - "{{ .item }}"
      - --amount
      - "{{ .amount }}"
      - --comment
      - "{{ .comment }}"

params にパラメータを定義すると、containers の引数として利用することができます。

API ができたのでそれを叩くフロントエンドが必要になるのですが、
なんと container-api-gateway は form を自動で生成する機能があります。
以下のディレクティブを追加すると、同一パスの GET でフォームにアクセスできるようになります。

   form: true

デフォルトのフォームは web1.0 みたいな見た目なのですが、
テンプレートを当てることで装飾することができます。

   template_url: https://www.takutakahashi.dev/assets/form.html

最終的に、以下のようなフォームが作成できます。
テンプレートのデザインは奥さんに作ってもらいました。

フォーム

日常的にこのフォームを利用して収支の登録をしています。

構成

以下に全体の構成を示します。

構成

やっていることはこれだけです。

  1. container-api-gateway がリクエストを受け、Job を発行する
  2. Job が MoneyForward にデータを挿入する

配信周りはすべて Kubernetes に依存しています。
Ingress の公開には pagekite-proxy というものを使っています。詳しくはこちら。

Global IP のない環境から k8s Ingress を使う

まとめ

MoneyForward 内での工夫と、外部ソフトを利用した工夫を紹介しました。
結構トリッキーなことをしていますが、運用が軌道に乗れば、
たまに振替設定を行うだけでほぼ何も意識せずに自動でフローが回ります。
家計の財布管理に困っている人がいたら真似してみてください。