知人から依頼された「損益カレンダー」をWebアプリで作ってみた
株の取引をしていると、「今月はいくら勝ったんだっけ?」「先週の火曜、結構負けた気がするけど実際いくらだった?」みたいなことが気になります。
楽天証券にもポートフォリオ画面や実現損益の一覧はあります。
ただ、日ごとの損益をカレンダーでパッと見たい、というのはちょっと違う欲求だったりします。
もちろん、株の損益を管理できるアプリやサービスがすでにいくつもあるのは知っています(笑)。
そんな中、知人から「株の損益をカレンダーで見られるようなWebアプリって作れない?」という話がありました。
「それならちょっと作ってみようかな」と思ったのが今回のきっかけです。
ちょうどClaude Codeを使い始めたところだったので、今回はClaude Codeにも手伝ってもらいながら、実際にWebアプリとして形にしてみました。
今回はその開発過程を書いてみます。
作りたかったのは「損益カレンダー」
やりたいことはシンプルです。
- 楽天証券から取引履歴CSVをダウンロード
- そのCSVをWebアプリに読み込ませる
- 取引データから実現損益を計算
- 日別の損益をカレンダー形式で表示
- 月間・年間の合計も確認できる
「この日は勝った」「この日は結構負けた」というのが、カレンダーを見るだけでパッと分かれば十分。
あとは、自分の実際の取引履歴CSVを使えば、ちゃんと動くかどうかもすぐ確認できます。
ということで、まずは最低限の機能から作ってみることにしました。
空っぽのリポジトリから /init
GitHubに「trade-profit-calendar」というリポジトリを作って、あとはほぼ何もない状態でClaude Codeを起動しました。
そこでまず実行したのが、/initです。
/init
/initは、プロジェクトの構成を確認して、Claude Code向けの指示書となるCLAUDE.mdを作成するためのコマンドです。
ところが今回は、リポジトリの中身が.gitignoreしかありません。
さすがに読み取るものがないので、Claude Codeから「コードがまだありませんが、どうしますか?」と逆に聞かれました。
そこで、
- Next.jsの雛形をセットアップしてから
CLAUDE.mdを作る - 雛形は作らず、計画段階の内容だけ
CLAUDE.mdに書く
という選択肢から、「雛形もセットアップしてほしい」を選択。
その後も、パッケージマネージャーをどうするか、スタイリングにTailwind CSSを使うか、損益データをどこに保存するかなど、一つずつ質問されました。
まだ作り始めたばかりなので、データの保存方法については「未定・後で決める」としました。
最終的に、Next.js(App Router)+ TypeScript + Tailwind CSSの雛形ができ、その内容を踏まえたCLAUDE.mdも自動生成されました。
何もないところから始めても、要所要所で質問しながら土台を作ってくれるのは地味に助かります。
楽天証券のCSVを読み込んでみる
雛形ができたところで、いよいよ本題のCSV取り込み機能です。
楽天証券からダウンロードした実際の取引履歴CSVを使って、「これを読み込んで損益を表示できるようにしたい」とClaude Codeにお願いしました。
ここで少し注意したのが、今回使ったCSVが自分の実際の取引データだったことです。
当然ですが、実データにはそのまま公開したくない情報も含まれています。
Claude Codeからも、このファイルをリポジトリにコミットするかどうか確認があったので、実データは.gitignoreに追加してローカルだけで使用し、GitHubには架空の銘柄・数値で作った匿名のサンプルCSVを置く形にしました。
このあたりは、AIにコードを書いてもらう場合でも、データの扱いは自分でしっかり確認しておいた方がいいですね。
現物と信用で損益の計算方法が違う
CSVの中身を解析してもらうと、今回の取引履歴には現物取引と信用取引が混ざっていることが分かりました。
そして、ここが今回のアプリ作りで少し面白かったところです。
信用取引については、決済行の「受渡金額」の列に実現損益が入っている一方、現物取引には損益が直接書かれていません。
つまり、現物については買付と売付を突き合わせて、自分で損益を計算する必要があります。
今回は現物取引について、移動平均法で平均取得単価を計算し、売却したときに実現損益を計算する方式にしました。
このあたりは、実際の証券会社の計算結果と一致するのかを確認しながら作っていきます。
ひとまず画面ができた
CSVを解析して、損益計算のロジックを作り、カレンダー表示まで進めると、ひとまずこんな画面になりました。

利益は赤、損失は青で表示しています。
カレンダーを見るだけで、その日にどのくらい勝ったのか、負けたのかが分かります。
さらに、日付をクリックすると、その日の取引明細も確認できます。
画面上部には年間の合計損益と、その月の合計損益も表示。
前月・翌月への移動もできるようにしました。
ここまで作ってみた時点では、正直「思っていたよりだいぶ早くできたな」という感覚でした。
本当の勝負は「表示できてから」だった
ただ、損益計算アプリにとって一番大事なのは、画面が表示されることではありません。
数字が合っていることです。
ここからが今回、一番時間がかかったところでした。
実際に自分のスマホに入っている楽天証券のiSPEEDアプリの実現損益画面と見比べながら、同じ月の合計を確認してみました。
すると、
- iSPEED側:+142,235円
- 今回作ったアプリ側:+143,335円
と、1,100円だけズレていました。
金額だけ見れば小さな差ですが、損益を管理するアプリで「だいたい合ってます」はちょっと困ります。
ということで、原因を突き止めることにしました。
約定日と受渡日のどちらを基準にしているのか、源泉徴収税が関係しているのかなど、いくつか仮説を立てて検証していきました。
しかし、どれも原因ではありませんでした。
最終的には、楽天証券のサイトから実現損益の明細CSVをダウンロードして、日付ごと・銘柄ごとに一つずつ突き合わせるという、かなり地道な方法で確認しました。
原因は「平均取得単価の端数処理」だった
そして、ようやく原因が分かりました。
現物取引の平均取得単価の端数処理です。
楽天証券の計算では、平均取得単価の1円未満の端数を単純に四捨五入するわけではなく、切り上げる処理が行われていました。
さらに、その丸め処理を買い増しのたびに保存するのではなく、売却時に利用するタイミングで行う必要があることも分かりました。
このあたりは、実際の取引データと証券会社側の明細を突き合わせなければ、なかなか気づけなかったと思います。
計算ロジックを修正したところ、最終的には日別の実現損益が1円単位で一致しました。
「+1,100円くらいなら誤差かな」と済ませなくてよかったです(笑)。
実際に作ってみて思ったこと
UIを表示するだけなら、正直そこまで大変ではありませんでした。
今回時間がかかったのは、実際のお金の数字を扱う以上、「なんとなく合っていそう」では意味がないというところです。
実データと証券会社側のデータを突き合わせて、1円単位まで確認する必要がありました。
Claude Codeは、単純にコードを書くだけではありませんでした。
CSVの中身を読み解いたり、計算ロジックの仮説を立てたり、実際にブラウザで動かして確認したり、数字のズレから原因を探したり。
こういったところまで一緒に進められるのは、実際に使ってみて面白いところでした。
ただし、最終的に「本当に正しいのか」を判断するのは自分です。
今回も、自分の実際の取引データとiSPEEDの結果を比較したからこそ、1,100円のズレに気づくことができました。
AIに作ってもらったから大丈夫、ではなく、実際に使って検証するところまでが開発なんだなと改めて感じました。
まだまだ作り始めたばかり
今回は、「楽天証券のCSVを読み込んで、損益をカレンダーで確認する」というところまで作りました。
もちろん、まだまだ改善できるところはあります。
今後は、
- 月別・年別のグラフ表示
- 銘柄ごとの損益の確認
- スマホでも見やすい画面
- CSVをより簡単に取り込めるようにする
あたりを追加していきたいと思っています。
せっかくなので、自分でも実際に使いながら少しずつ育てていく予定です。
「こんなの欲しい」を実際に作れるのは面白い
今回のきっかけは、知人からのちょっとした相談でした。
すでに似たようなアプリやサービスがあるのも分かっています。
それでも、「こういうものがあったら便利そう」というところから、自分で実際に作ってみる。
以前なら、仕様を考えて、プロジェクトを作って、コードを書いて、エラーを調べて……と、最初の一歩だけでも結構な時間がかかりました。
それが今は、Claude CodeのようなAIを使いながら、「こういうものを作りたい」と伝えていくことで、実際に動くものをかなり早い段階で作れるようになっています。
もちろん、AIに任せきりにできるわけではありません。
仕様を決めるのも、出てきたものを確認するのも、数字が正しいか検証するのも自分です。
それでも、「こんなのが欲しいから、とりあえず作ってみる」ということが以前より気軽にできるようになったのは、エンジニアとして結構面白い変化だなと思っています。
今回はまだ作り始めたばかりなので、これからもう少し使いやすいアプリに育てていこうと思います。
