毎年2〜3月になると、確定申告の季節が来る。
給与所得だけであれば年末調整で終わる話だが、投資口座を複数持っていると話はまったく変わる。FXだけで20業者、株式は13社、仮想通貨は7プラットフォーム、クラウドファンディングは6社——これが私の2025年分申告の全体像だ。
厄介なのは金額の多寡ではなく、税区分がバラバラだという点にある。FXは「先物取引に係る雑所得等(申告分離課税)」、株式や外国債券は「上場株式等の譲渡所得・配当所得(申告分離課税)」、仮想通貨や外貨預金の為替差益・クラウドファンディング収入は「雑所得(総合課税)」——同じ「投資の利益」でも、税法上はまったく別物として扱われる。
今年は「これを毎年ちゃんとやり続けるためのしくみを作ろう」と決意し、Python 20本のスクリプトとAIを組み合わせたプロジェクトを立ち上げた。その全記録を、同じような複数口座投資家の参考になればと思いまとめる。
今年の申告対象——規模感
まず今年の申告対象を整理すると次のようになる(金額は非公開)。
| 区分 | 税区分 | 対象 |
|---|---|---|
| FX・CFD | 申告分離課税(先物取引) | 20業者 |
| 株式・投資信託 | 申告分離課税(特定口座) | 13社 |
| 外国債券 | 申告分離課税 + 外国税額控除 | 1社 |
| 仮想通貨 | 総合課税(雑所得) | 7プラットフォーム |
| クラウドファンディング | 総合課税(雑所得) | 6社 |
| 外貨預金 為替差益 | 総合課税(雑所得) | 5銀行 |
| iDeCo | 小規模企業共済等掛金控除 | |
| 生命保険料控除 | 所得控除 | マイナポータル連携 |
| 医療費控除 | 所得控除 | マイナポータル連携 |
| 住宅ローン控除 | 税額控除 | 申告不要(後述) |
これだけの口座を持っていると、「口座ごとに集計する」という発想ではいつまでたっても終わらない。できるところまでAIで自動化を試みた。
自動化の試み——3つの原則
ChatGPTと相談しながら自動化を進めたところ、結果として、主に3つのルールで整理することとなった。途中で何度も方針変更したので、来年は最初からこの方針で進めようと思う。
ルール1: 税区分ベースで処理する
FXの損益と、外貨預金の為替差益は、似ているようで税法上の区分が異なる。FXは申告分離課税(20.315%)、外貨預金の為替差益は総合課税(累進税率)だ。これを混在させると申告が誤る。フォルダ構成から処理ロジックまで、すべて税区分を基準にした。
ルール2: 特定口座の年間取引報告書は集計しない
特定口座の年間取引報告書は業者ごとにフォーマットが異なるうえ、項目が多いので、AI任せ(LLM)で集計するとミスが多すぎた。各業者が発行する「年間損益報告書」の値をそのまま手入力するか、入手できるならXML形式の年間取引報告書を使う方が正確かつ効率的だ。
ルール3: 税額断定はしない
このプロジェクトはあくまで「e-Taxへの入力値を整理するための補助ツール」であり、最終的な税額計算はe-Tax(国税庁の確定申告書等作成コーナー)に委ねる。税額の断定はせず、参考値を出力するに留める。
フォルダ設計
データは次の3層で整理した。
年度ごとに 2025_tax_return/、2026_tax_return/ とフォルダを切り、同じ構成を毎年使い回す。スクリプト側も環境変数 TAX_YEAR で年度を切り替えられる設計にした。
Pythonスクリプト20本の役割分担
処理の種類に応じてスクリプトを4種類に分類した。
1. 抽出系——PDFをテキスト化する
FXの年間損益報告書はほぼPDFで届く。export_fx_pdf_to_text.py でテキスト化し、そのテキストをNotebookLMに読み込ませて数値を抽出する「半自動フロー」を採用した。株式の報告書も同様に export_stocks_pdf_to_text.py でテキスト化する。
2. 計算系——税法に沿ったロジックを実装する
calculate_crypto_gain.py: 仮想通貨の損益を総平均法で計算。複数のプラットフォーム・複数の通貨を横断して取得単価を管理する。calculate_forex_gain.py: 外貨預金の為替差益を計算。「いつ、いくらでドルを受け取り、いつ円転したか」を銀行CSVから読み取る。calculate_jtg_deemed_foreign_tax.py: 外国債の「みなし外国税額控除」の計算補助。ブラジル国債は、現地では非課税でも租税条約により20%が課税済みとみなされる——この特殊な制度を扱うための専用スクリプト。
3. XML生成・修正系——e-Taxとの格闘
株式の特定口座年間取引報告書は、e-Tax共通様式(TEG204形式)のXMLで提出できる。証券会社から公式XMLを入手できない場合は create_teg204_xml.py でXMLを生成し、fix_teg204_xml_format.py で形式を修正する方法をとったが途中で断念(詳細は後述)。
4. 集計系——全税目を一覧で出力する
aggregate_all_2025.py: 全税目の最終サマリを出力する。実行すると給与・株式・FX・雑所得・控除の一覧が表示され、e-Taxへの入力前の最終確認に使う。
e-Taxとの格闘実録
特定口座年間取引報告書のXML化(※一番苦労しましたが、結局断念)
e-Taxに読み込ませるべくPDFの特定口座年間取引報告書をXMLに変換したところ、e-Taxから拒否された。原因を調べたが、e-Tax XMLの仕様はドキュメントが少なく、エラーコードだけが手がかりでは修正しきれなかった。
その他のe-Taxへの入力でハマったポイントは2つ。
住宅ローン控除——「申告不要」と判明
「住宅を持っているから住宅ローン控除を申告しなければ」と当初は考えていた。ところが、昭和54年建築の物件は住宅ローン減税の対象外であることが判明。「やらなくていいことを確認する」のも立派な作業だ、と改めて感じた。
外国税額控除の入力
※みなし外国税額控除の入力は非常に特殊なので読み飛ばしてOK
- 外貨建て入力が必要: 相手国での課税標準は円だけでなく外貨(USD)でも入力が求められる。
- 調整国外所得金額が0だと控除額も0になる: この項目を入力するまで「外国税額控除 0円」と表示され続けた。
AIの使い方——NotebookLMとCursor
NotebookLM: PDFから数値を抽出する
XML形式以外は自分でPDF等からデータ化(テキスト化)し、NotebookLMに読み込ませ、「年間損益合計はいくらか」というように自然言語で問い合わせる流れにした。
各税区分ごとに専用のプロンプトテンプレートを用意した(例: analysis/fx/fx_notebooklm_prompt_template.txt)。ひな形に証券会社名や年度を埋めるだけで毎年使い回せる。
Cursor(AI IDE): コードとドキュメントをペアプロ
このプロジェクトのスクリプト20本とドキュメント群は、ほぼすべてCursor(AIが統合されたコードエディタ)との対話で作成した。e-TaxのXML仕様を貼り付けて「この仕様に合わせた修正スクリプトを書いて」と指示したり、「みなし外国税額控除の控除額が0になる原因を調べて」と相談したりした。
AIが一番役に立ったのは「知らない税制上の知識を即座に調べられる点」だ。みなし外国税額控除や外国税額控除限度額の計算方法など、通常は税理士に聞くような内容も含め、対話しながら理解を深めることができた。
マイナポータル連携との使い分け
生命保険料控除と医療費控除はマイナポータル連携を使った。e-Taxにマイナンバーカードでログインすると、保険会社・医療機関のデータが自動で取り込まれる。これらはスクリプトを使わず、連携で完結させた。
まとめ
このプロジェクトを通じて感じたのは、「完全自動化は目標ではない」ということだ。
20業者のFX報告書から人手で数値を転記する作業は残るし、e-Taxへの最終入力も人間がやる。最終的に目指したのは次の2点だけだ。
- 転記ミスをゼロにする(CSVに保存してスクリプトが集計するため、手計算の桁ミスがない)
- 何がどこにあるか一目でわかる(税区分別のフォルダ構成と、各フォルダのREADMEで証憑と申告値が紐づく)
確定申告は毎年やってくる。今年の経験とコードを来年も使い回せる形で整理したことで、来年の自分がだいぶ楽になるはずだ。
同じように複数の投資口座を持ち、確定申告に頭を抱えている方の参考になれば幸いだ。
