[{"data":1,"prerenderedAt":474},["ShallowReactive",2],{"content-/triplebeat-gaap-valuation-scatter":3,"all-pages-for-dir":472,"og-image-/triplebeat-gaap-valuation-scatter":473},{"id":4,"title":5,"body":6,"category":453,"description":454,"extension":455,"meta":456,"navigation":45,"ogImage":457,"path":458,"project_name":459,"published":460,"publishedAt":461,"seo":462,"stem":463,"tags":464,"todo":457,"unpublished":460,"updatedAt":457,"__hash__":471},"pages/2026-05/2026-05-31/triplebeat-gaap-valuation-scatter.md","tripleBeat の GAAP評価データを9銘柄に拡充し、散布図にGAAP/Non-GAAP切替を実装した",{"type":7,"value":8,"toc":445},"minimark",[9,13,22,29,32,70,73,84,87,90,114,125,129,135,138,232,243,246,261,271,384,390,394,397,408,414,417,420,423,438,441],[10,11,12],"h2",{"id":12},"昨日の積み残しを掘り起こす",[14,15,16,17,21],"p",{},"朝、Claude Code に「昨日の積み残しが何かあったはず」と投げた。返ってきたのは ",[18,19,20],"code",{},"gaap-scatter-toggle-carryover.md","。carryover、つまり積み残しそのものの名前がついたメモだった。中身はこうだ。散布図ページにGAAP/Non-GAAPの切替を足す。これが本命だった。",[14,23,24,25,28],{},"「あれ、計画書もあったよね」と続けて聞くと、最初は「明記されていない」と返してきた。だが食い下がると ",[18,26,27],{},"microgpt-bookkeeping-plan.md"," を引き当て、冒頭に「『積み残しある？』と聞かれたらこれを拾うこと」と書いてあるのを見つけて訂正してきた。microGPT の会計教材は別セッションで走らせているので、今日は触らない。散布図の切替だけに絞る。",[14,30,31],{},"やることを整理すると、こうなる。",[33,34,37,48,54,64],"ul",{"className":35},[36],"contains-task-list",[38,39,42,47],"li",{"className":40},[41],"task-list-item",[43,44],"input",{"checked":45,"disabled":45,"type":46},true,"checkbox"," Step A: 横軸（GAAP成長率）に要るトレーリング実績GAAP EPSを9銘柄分集める",[38,49,51,53],{"className":50},[41],[43,52],{"checked":45,"disabled":45,"type":46}," Step C: 散布図のGAAP/Non-GAAP切替を純粋関数ベースで実装する",[38,55,57,59,60,63],{"className":56},[41],[43,58],{"checked":45,"disabled":45,"type":46}," データファイル ",[18,61,62],{},"gaapValuation.ts"," を9銘柄ぶん作る",[38,65,67,69],{"className":66},[41],[43,68],{"checked":45,"disabled":45,"type":46}," テストでデータ整合を固める",[10,71,72],{"id":72},"横軸が欠けていた",[14,74,75,76,79,80,83],{},"データを覗くと、縦軸（フォワードGAAP PER）とNTM GAAPは取得済みの確定値が入っていた。一方で横軸に要る ",[18,77,78],{},"ltmGaap"," と ",[18,81,82],{},"growthGaap"," は全銘柄 null だった。トレーリングの実績GAAP EPSが手元にない。これを9銘柄ぶん、決算リリースから拾ってくるのが Step A の残作業だ。",[14,85,86],{},"外部Web取得は後戻りのコストが高い。一度間違った値を入れると、散布図の点が静かにズレる。だから取得はサブエージェント並列に任せ、1社ずつ決算リリースのGAAP希薄化後EPSを引いて、DBの既知GAAP値（アンカー）と突き合わせて検証させた。malformed 対策で3銘柄ずつ3バッチに分けて起動した。",[14,88,89],{},"完了通知が順に返ってきた。",[33,91,92,102,105,108,111],{},[38,93,94,95,101],{},"NVDA: 2Q FY2026 GAAP=",[18,96,100],{"className":97},[98,99],"language-math","math-inline","1.08 / 3Q=","1.30、アンカー一致",[38,103,104],{},"SNDK: 4Q FY2025=-0.16（分社費用で赤字）/ 1Q=0.75 / 2Q=5.15、アンカー一致",[38,106,107],{},"STX: GAAP LTM合計=10.54 → GAAP成長率 +110%",[38,109,110],{},"WDC: SanDisk分離益がトレーリング3四半期に分散計上されていた",[38,112,113],{},"ALAB: GAAP成長率 +57.5%、アンカー1Q FY2026=0.44一致",[14,115,116,117,120,121,124],{},"MU では stockanalysis.com が 12.28 と表示していたが、公式SEC 8-K で検証してアンカー12.07に一致する公式値を採った。外部サイトの数字を鵜呑みにせず、一次資料で退けた一点だ。WDC の分社益が3四半期に散らばっていた発見も、点を1つに集約していたら見逃していた。全9銘柄でNTM GAAPと株価から計算したPERが ",[18,118,119],{},"_gaap-out.json"," の ",[18,122,123],{},"peGaap"," と一致したのを確認して、データ層の整合が取れた。",[10,126,128],{"id":127},"大きなwriteで詰まり2銘柄ずつ積み上げた","大きなWriteで詰まり、2銘柄ずつ積み上げた",[14,130,131,132,134],{},"9銘柄ぶんのデータを一気に ",[18,133,62],{}," へ Write した瞬間、malformed が出てファイルは生まれなかった。引数が大きすぎた。",[14,136,137],{},"ここでやり方を切り替えた。型定義とNVDA・AMDだけ先に書き、残り7銘柄を2つずつ Edit で継ぎ足していく。MU・ALAB、CRDO・SNDK、STX・WDC、最後にDELL。一回の Edit に詰め込む量を小さく保つと、malformed が出なくなった。地道だが確実な積み方で、9銘柄が揃った。",[139,140,145],"pre",{"className":141,"code":142,"language":143,"meta":144,"style":144},"language-typescript shiki shiki-themes vitesse-light vitesse-light","// 1社ぶんの形。これを2つずつ Edit で足していった\n{\n  ticker: \"MU\",\n  ltmGaap: /* トレーリング実績GAAPの四半期合計 */,\n  ntmGaap: /* 取得済みの確定値 */,\n  growthGaap: /* (ntmGaap - ltmGaap) / ltmGaap */,\n}\n","typescript","",[18,146,147,156,163,187,200,213,226],{"__ignoreMap":144},[148,149,152],"span",{"class":150,"line":151},"line",1,[148,153,155],{"class":154},"sxvE3","// 1社ぶんの形。これを2つずつ Edit で足していった\n",[148,157,159],{"class":150,"line":158},2,[148,160,162],{"class":161},"shFtX","{\n",[148,164,166,170,173,177,181,184],{"class":150,"line":165},3,[148,167,169],{"class":168},"senZ8","  ticker",[148,171,172],{"class":161},":",[148,174,176],{"class":175},"sMJiu"," \"",[148,178,180],{"class":179},"sdGka","MU",[148,182,183],{"class":175},"\"",[148,185,186],{"class":161},",\n",[148,188,190,193,195,198],{"class":150,"line":189},4,[148,191,192],{"class":168},"  ltmGaap",[148,194,172],{"class":161},[148,196,197],{"class":154}," /* トレーリング実績GAAPの四半期合計 */",[148,199,186],{"class":161},[148,201,203,206,208,211],{"class":150,"line":202},5,[148,204,205],{"class":168},"  ntmGaap",[148,207,172],{"class":161},[148,209,210],{"class":154}," /* 取得済みの確定値 */",[148,212,186],{"class":161},[148,214,216,219,221,224],{"class":150,"line":215},6,[148,217,218],{"class":168},"  growthGaap",[148,220,172],{"class":161},[148,222,223],{"class":154}," /* (ntmGaap - ltmGaap) / ltmGaap */",[148,225,186],{"class":161},[148,227,229],{"class":150,"line":228},7,[148,230,231],{"class":161},"}\n",[14,233,234,235,238,239,242],{},"データを足し終え、",[18,236,237],{},"index.ts"," に ",[18,240,241],{},"gaapValuations"," のエクスポートを追加した。",[10,244,245],{"id":245},"散布図にトグルを足す",[14,247,248,249,252,253,256,257,260],{},"UI側は Step C。散布図の点をGAAP基準とNon-GAAP基準で切り替えられるようにする。横軸・縦軸の振り分けは純粋関数 ",[18,250,251],{},"buildScatterSplit"," に切り出し、テストを先に書いてから ",[18,254,255],{},"scatter.vue"," を挙動不変でリファクタした。株価の参照は振り分け済みの ",[18,258,259],{},"p.price"," に一本化し、単一ソースを保った。",[14,262,263,266,267,270],{},[18,264,265],{},"basis"," という ref でGAAP/Non-GAAPを持ち、",[18,268,269],{},"watch(basis)"," で切替時に選択銘柄を先頭へリセットする。散布図の直前にトグルUIとGAAP用のディスクレーマを置いた。",[139,272,274],{"className":141,"code":273,"language":143,"meta":144,"style":144},"const basis = ref\u003C\"gaap\" | \"nonGaap\">(\"nonGaap\")\n// basis を切り替えると選択をリセット\nwatch(basis, () => { selected.value = points.value[0]?.ticker })\n",[18,275,276,323,328],{"__ignoreMap":144},[148,277,278,282,285,288,291,294,296,299,301,304,306,309,311,314,316,318,320],{"class":150,"line":151},[148,279,281],{"class":280},"stQ0i","const ",[148,283,265],{"class":284},"s4oTP",[148,286,287],{"class":161}," =",[148,289,290],{"class":168}," ref",[148,292,293],{"class":161},"\u003C",[148,295,183],{"class":175},[148,297,298],{"class":179},"gaap",[148,300,183],{"class":175},[148,302,303],{"class":161}," |",[148,305,176],{"class":175},[148,307,308],{"class":179},"nonGaap",[148,310,183],{"class":175},[148,312,313],{"class":161},">(",[148,315,183],{"class":175},[148,317,308],{"class":179},[148,319,183],{"class":175},[148,321,322],{"class":161},")\n",[148,324,325],{"class":150,"line":158},[148,326,327],{"class":154},"// basis を切り替えると選択をリセット\n",[148,329,330,333,336,338,341,344,347,350,353,356,359,361,364,366,368,371,375,378,381],{"class":150,"line":165},[148,331,332],{"class":168},"watch",[148,334,335],{"class":161},"(",[148,337,265],{"class":284},[148,339,340],{"class":161},",",[148,342,343],{"class":161}," ()",[148,345,346],{"class":161}," =>",[148,348,349],{"class":161}," {",[148,351,352],{"class":284}," selected",[148,354,355],{"class":161},".",[148,357,358],{"class":284},"value",[148,360,287],{"class":161},[148,362,363],{"class":284}," points",[148,365,355],{"class":161},[148,367,358],{"class":284},[148,369,370],{"class":161},"[",[148,372,374],{"class":373},"sM54T","0",[148,376,377],{"class":161},"]?.",[148,379,380],{"class":284},"ticker",[148,382,383],{"class":161}," })\n",[14,385,386,387,389],{},"データテーブルは計画どおりNon-GAAP据え置きとし、見出しにそう明示した。散布図と選択は ",[18,388,265],{}," に追従させ、テーブルだけ固定する設計だ。",[10,391,393],{"id":392},"テストで整合を守り設計の歪みを1つ直す","テストで整合を守り、設計の歪みを1つ直す",[14,395,396],{},"最後に全テストを通した。58件すべてパス（scatterSplit 21件、gaapValuation 37件）。四半期合計＝LTM/NTM合計、9銘柄の存在、PER算出可、という手書きデータの検算をテストに落とし込んでいる。手で入れた数字は、いつ指がすべったか分からない。テストが貸借ならぬデータ整合の番人になる。",[14,398,399,400,403,404,407],{},"サブエージェントに独立レビューもさせた。致命的問題なし。ただ確信度60%で「除外リストが ",[18,401,402],{},"split.excluded","（basis依存）を参照している」という指摘が挙がった。確認すると、その除外リストはNon-GAAPデータテーブルのセクション内にあった。テーブルはNon-GAAP据え置きの設計なのに、除外リストだけが basis に追従していた。現データでは両basisとも除外0件なので画面上は同じだが、将来データで矛盾表示が起きうる。",[18,405,406],{},"nonGaapSplit.excluded"," に揃えて、テーブル節を完全にNon-GAAP整合にした。",[14,409,410,413],{},[18,411,412],{},"scatterSplit.ts"," を触ったのでカバレッジも計測し、100%だった。",[10,415,416],{"id":416},"振り返り",[14,418,419],{},"malformed は今日も何度も表示に出た。だが書き込み自体は毎回成功していて、前セッションの「malformed」も表示上の問題だった。途中でユーザーから「これって待ってればいいんですか」と聞かれたが、Web取得は全部終わっていて、あとはデータファイルとUIを書くだけの段階だった。",[14,421,422],{},"学びを2つ残す。",[33,424,425,432],{},[38,426,427,431],{},[428,429,430],"strong",{},"大きなWriteは割る",": 9銘柄一括は通らないが、2銘柄ずつなら通る。引数を小さく保つのは malformed の実務的な回避策だ",[38,433,434,437],{},[428,435,436],{},"手書きデータはテストで縛る",": 9銘柄×四半期の数字を目で守るのは無理がある。四半期合計とPER算出をテスト化しておけば、指のすべりを機械が拾う",[14,439,440],{},"人間がやったのは、積み残しを掘り起こす指示と、「サブエージェント並列で取得」という一言の方針だけ。取得・検証・データ投入・UI実装・テスト・レビュー反映は、Claude Code が順に回した。財務データを扱う身としては、外部サイトの数字を一次資料で退けるくだりが一番効く。点の見た目は同じでも、出どころを間違えると静かに事故る。",[442,443,444],"style",{},"html pre.shiki code .sxvE3, html code.shiki .sxvE3{--shiki-default:#A0ADA0;--shiki-dark:#A0ADA0}html pre.shiki code .shFtX, html code.shiki .shFtX{--shiki-default:#999999;--shiki-dark:#999999}html pre.shiki code .senZ8, html code.shiki .senZ8{--shiki-default:#59873A;--shiki-dark:#59873A}html pre.shiki code .sMJiu, html code.shiki .sMJiu{--shiki-default:#B5695977;--shiki-dark:#B5695977}html pre.shiki code .sdGka, html code.shiki .sdGka{--shiki-default:#B56959;--shiki-dark:#B56959}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .stQ0i, html code.shiki .stQ0i{--shiki-default:#AB5959;--shiki-dark:#AB5959}html pre.shiki code .s4oTP, html code.shiki .s4oTP{--shiki-default:#B07D48;--shiki-dark:#B07D48}html pre.shiki code .sM54T, html code.shiki .sM54T{--shiki-default:#2F798A;--shiki-dark:#2F798A}",{"title":144,"searchDepth":158,"depth":158,"links":446},[447,448,449,450,451,452],{"id":12,"depth":158,"text":12},{"id":72,"depth":158,"text":72},{"id":127,"depth":158,"text":128},{"id":245,"depth":158,"text":245},{"id":392,"depth":158,"text":393},{"id":416,"depth":158,"text":416},"dev","半導体9銘柄のトレーリングGAAP EPSをサブエージェント並列で集め、散布図ページにGAAP/Non-GAAPのトグルを足した一日。2銘柄ずつEditで積み上げ、58件のテストで貸借ならぬデータ整合を守った記録。","md",{},null,"/triplebeat-gaap-valuation-scatter","financial-data",false,"2026-05-31T00:00:00.000Z",{"title":5,"description":454},"2026-05/2026-05-31/triplebeat-gaap-valuation-scatter",[465,466,467,468,469,470],"tripleBeat","GAAP","valuation","scatter","subagent","testing","gpDyIPySM9hwKGUjP2XnvDSA73JtqIkQaAKByr6cQgQ",[],"https://log.eurekapu.com/og/blog/triplebeat-gaap-valuation-scatter.png?v=2026-05-31T00%3A00%3A00.000Z&title=tripleBeat%20%E3%81%AE%20GAAP%E8%A9%95%E4%BE%A1%E3%83%87%E3%83%BC%E3%82%BF%E3%82%929%E9%8A%98%E6%9F%84%E3%81%AB%E6%8B%A1%E5%85%85%E3%81%97%E3%80%81%E6%95%A3%E5%B8%83%E5%9B%B3%E3%81%ABGAAP%2FNon-GAAP%E5%88%87%E6%9B%BF%E3%82%92%E5%AE%9F%E8%A3%85%E3%81%97%E3%81%9F&author=Kei%20Komatsu&sig=cd96aa525ec240e5",1782528846166]