取得原価計算エンジン
特定の株式売却方法(個別法、先入先出法など)や一部売却時の処理に対応し、さまざまな方法で取得費を計算して、税務申告などを支援するSkill。
📜 元の英語説明(参考)
Multi-method cost basis computation including specific identification, FIFO, LIFO, HIFO, and proportional average cost with partial sell handling
🇯🇵 日本人クリエイター向け解説
特定の株式売却方法(個別法、先入先出法など)や一部売却時の処理に対応し、さまざまな方法で取得費を計算して、税務申告などを支援するSkill。
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o cost-basis-engine.zip https://jpskill.com/download/10402.zip && unzip -o cost-basis-engine.zip && rm cost-basis-engine.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/10402.zip -OutFile "$d\cost-basis-engine.zip"; Expand-Archive "$d\cost-basis-engine.zip" -DestinationPath $d -Force; ri "$d\cost-basis-engine.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
cost-basis-engine.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
cost-basis-engineフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
Cost Basis Engine
複数の会計方法を使用して暗号通貨取引の原価基準を計算し、方法間で生じる税務上の責任を比較します。このスキルは、部分的な売却、トークンの移行、エアドロップ、ステーキング報酬、LP の参入/退出、マルチホップスワップなど、オンチェーンアクティビティの複雑さ全体を処理します。
免責事項: このスキルは、情報提供のみを目的とした計算ツールを提供します。税務、法務、または財務に関するアドバイスを構成するものではありません。具体的な状況については、資格のある税務専門家にご相談ください。税法は管轄区域によって異なり、頻繁に変更されます。
前提条件
- Python 3.10+
- 外部依存関係は不要 (標準ライブラリのみ)
- 取引履歴は、辞書のリストまたは次の列を持つ CSV として:
date、action、token、quantity、price_usd、fee_usd
メソッドの概要
| メソッド | ロジック | 最適な用途 |
|---|---|---|
| FIFO | 最初に購入したロットから最初に売却する | 単純さ、多くの管轄区域でのデフォルト |
| LIFO | 最後に購入したロットから最初に売却する | 価格が時間とともに上昇する場合に利益を繰り延べる |
| HIFO | 最もコストの高いロットから最初に売却する | 現在の税務上の責任を最小限に抑える |
| Specific ID | トレーダーがどのロットを売却するかを選択する | 最大限の制御、記録保持が必要 |
| Average Cost | 保有するすべてのロットの加重平均 | 単純さ、一部の管轄区域で必須 |
1. FIFO (First-In, First-Out)
最も古いロットから最初に売却します。これは、他の方法が選択されていない場合、米国でのデフォルトの方法です。
def fifo_sell(lots: list[dict], sell_qty: float, sell_price: float) -> list[dict]:
"""FIFO を使用して売却します。lots は最も古いものから順にソートされます。"""
remaining = sell_qty
realized = []
while remaining > 0 and lots:
lot = lots[0]
used = min(lot["qty"], remaining)
gain = (sell_price - lot["cost_per_unit"]) * used
realized.append({"qty": used, "basis": lot["cost_per_unit"], "gain": gain})
lot["qty"] -= used
remaining -= used
if lot["qty"] <= 0:
lots.pop(0)
return realized
部分的な売却の例
TOKEN の 3 つのロットを保有しています。
- ロット A: 100 ユニット @ $1.00 (最古)
- ロット B: 50 ユニット @ $2.00
- ロット C: 75 ユニット @ $1.50
120 ユニットを $3.00 で売却します。
- ロット A から 100: 利益 = (3.00 - 1.00) * 100 = $200
- ロット B から 20: 利益 = (3.00 - 2.00) * 20 = $20
- 合計実現利益: $220
- ロット B の残り: 30 ユニット @ $2.00
2. LIFO (Last-In, First-Out)
最も新しいロットから最初に売却します。FIFO と比較して順序が逆になります。
def lifo_sell(lots: list[dict], sell_qty: float, sell_price: float) -> list[dict]:
"""LIFO を使用して売却します。末尾からポップします (最も新しいものから)。"""
remaining = sell_qty
realized = []
while remaining > 0 and lots:
lot = lots[-1]
used = min(lot["qty"], remaining)
gain = (sell_price - lot["cost_per_unit"]) * used
realized.append({"qty": used, "basis": lot["cost_per_unit"], "gain": gain})
lot["qty"] -= used
remaining -= used
if lot["qty"] <= 0:
lots.pop()
return realized
同じロットを使用して、120 を $3.00 で LIFO で売却します。
- ロット C から 75: 利益 = (3.00 - 1.50) * 75 = $112.50
- ロット B から 45: 利益 = (3.00 - 2.00) * 45 = $45
- 合計実現利益: $157.50
3. HIFO (Highest-In, First-Out)
実現利益を最小限に抑えるために、最もコストの高いロットから最初に売却します。
def hifo_sell(lots: list[dict], sell_qty: float, sell_price: float) -> list[dict]:
"""HIFO を使用して売却します。コストの高い順にソートし、最も高いものから消費します。"""
lots.sort(key=lambda x: x["cost_per_unit"], reverse=True)
remaining = sell_qty
realized = []
for lot in lots:
if remaining <= 0:
break
used = min(lot["qty"], remaining)
gain = (sell_price - lot["cost_per_unit"]) * used
realized.append({"qty": used, "basis": lot["cost_per_unit"], "gain": gain})
lot["qty"] -= used
remaining -= used
lots[:] = [l for l in lots if l["qty"] > 0]
return realized
同じロットを使用して、120 を $3.00 で HIFO で売却します。
- ロット B から 50 ($2.00、最高): 利益 = (3.00 - 2.00) * 50 = $50
- ロット C から 70 ($1.50、次に高い): 利益 = (3.00 - 1.50) * 70 = $105
- 合計実現利益: $155
- 残り: ロット A 100 @ $1.00、ロット C 5 @ $1.50
4. Specific Identification
トレーダーは、どのロットを売却するかを明示的に選択します。最大限の制御を提供しますが、綿密な記録保持が必要です。各ロットは、一意に識別可能である必要があります (例: 購入日時、またはロット ID)。
def specific_id_sell(lots: dict[str, dict], lot_ids: list[tuple[str, float]],
sell_price: float) -> list[dict]:
"""ID で特定のロットを売却します。lot_ids = [(lot_id, qty_to_sell), ...]"""
realized = []
for lot_id, sell_qty in lot_ids:
lot = lots[lot_id]
used = min(lot["qty"], sell_qty)
gain = (sell_price - lot["cost_per_unit"]) * used
realized.append({"lot_id": lot_id, "qty": used, "basis": lot["cost_per_unit"], "gain": gain})
lot["qty"] -= used
if lot["qty"] <= 0:
del lots[lot_id]
return realized
5. Proportional / Average Cost Method
保有するすべてのロットにわたって、1 ユニットあたりの単一の加重平均コストを計算します。すべての売却はその平均コストを使用します。平均は購入ごとに更新されます。
def average_cost_basis(lots: list[dict]) -> float:
"""すべてのロットにわたって、1 ユニットあたりの加重平均コストを計算します。"""
total_cost = sum(l["qty"] * l["cost_per_unit"] for l in lots)
total_qty = sum(l["qty"] for l in lots)
if total_qty == 0:
return 0.0
return total_cost / total_qty
def average_cost_sell(lots: list[dict], sell_qty: float, sell_price: float) -> dict:
"""平均コストを使用して売却します。すべてのロットを比例的に削減します。"""
avg = average_cost_basis(lots)
total_qty = sum(l["qty"] for l in lots)
sell_qty = min(sell_qty, total_qty)
gain = (sell_price - avg) * sell_qty
# 各ロットを比例的に削減します
ratio = sell_qty / total_qty
for lo 📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
Cost Basis Engine
Compute cost basis for crypto trades using multiple accounting methods and compare the resulting tax liability across methods. This skill handles the full complexity of on-chain activity: partial sells, token migrations, airdrops, staking rewards, LP entry/exit, and multi-hop swaps.
Disclaimer: This skill provides computational tools for informational purposes only. It does not constitute tax, legal, or financial advice. Consult a qualified tax professional for your specific situation. Tax law varies by jurisdiction and changes frequently.
Prerequisites
- Python 3.10+
- No external dependencies required (standard library only)
- Trade history as a list of dicts or CSV with columns:
date,action,token,quantity,price_usd,fee_usd
Methods Overview
| Method | Logic | Best For |
|---|---|---|
| FIFO | First lots purchased are sold first | Simplicity, many jurisdictions' default |
| LIFO | Last lots purchased are sold first | Deferring gains when prices rise over time |
| HIFO | Highest-cost lots are sold first | Minimizing current tax liability |
| Specific ID | Trader selects which lots to sell | Maximum control, requires record-keeping |
| Average Cost | Weighted average of all held lots | Simplicity, required in some jurisdictions |
1. FIFO (First-In, First-Out)
Sell the oldest lots first. This is the default method in the US if no other method is elected.
def fifo_sell(lots: list[dict], sell_qty: float, sell_price: float) -> list[dict]:
"""Sell using FIFO. lots sorted oldest-first."""
remaining = sell_qty
realized = []
while remaining > 0 and lots:
lot = lots[0]
used = min(lot["qty"], remaining)
gain = (sell_price - lot["cost_per_unit"]) * used
realized.append({"qty": used, "basis": lot["cost_per_unit"], "gain": gain})
lot["qty"] -= used
remaining -= used
if lot["qty"] <= 0:
lots.pop(0)
return realized
Partial sell example
You hold three lots of TOKEN:
- Lot A: 100 units @ $1.00 (oldest)
- Lot B: 50 units @ $2.00
- Lot C: 75 units @ $1.50
You sell 120 units at $3.00:
- 100 from Lot A: gain = (3.00 - 1.00) * 100 = $200
- 20 from Lot B: gain = (3.00 - 2.00) * 20 = $20
- Total realized gain: $220
- Lot B remainder: 30 units @ $2.00
2. LIFO (Last-In, First-Out)
Sell the newest lots first. Reverses the order compared to FIFO.
def lifo_sell(lots: list[dict], sell_qty: float, sell_price: float) -> list[dict]:
"""Sell using LIFO. Pops from end (newest first)."""
remaining = sell_qty
realized = []
while remaining > 0 and lots:
lot = lots[-1]
used = min(lot["qty"], remaining)
gain = (sell_price - lot["cost_per_unit"]) * used
realized.append({"qty": used, "basis": lot["cost_per_unit"], "gain": gain})
lot["qty"] -= used
remaining -= used
if lot["qty"] <= 0:
lots.pop()
return realized
Using the same lots and selling 120 at $3.00 with LIFO:
- 75 from Lot C: gain = (3.00 - 1.50) * 75 = $112.50
- 45 from Lot B: gain = (3.00 - 2.00) * 45 = $45
- Total realized gain: $157.50
3. HIFO (Highest-In, First-Out)
Sell the highest-cost lots first to minimize realized gains.
def hifo_sell(lots: list[dict], sell_qty: float, sell_price: float) -> list[dict]:
"""Sell using HIFO. Sort by cost descending, consume highest first."""
lots.sort(key=lambda x: x["cost_per_unit"], reverse=True)
remaining = sell_qty
realized = []
for lot in lots:
if remaining <= 0:
break
used = min(lot["qty"], remaining)
gain = (sell_price - lot["cost_per_unit"]) * used
realized.append({"qty": used, "basis": lot["cost_per_unit"], "gain": gain})
lot["qty"] -= used
remaining -= used
lots[:] = [l for l in lots if l["qty"] > 0]
return realized
Same lots, selling 120 at $3.00 with HIFO:
- 50 from Lot B ($2.00, highest): gain = (3.00 - 2.00) * 50 = $50
- 70 from Lot C ($1.50, next highest): gain = (3.00 - 1.50) * 70 = $105
- Total realized gain: $155
- Remaining: Lot A 100 @ $1.00, Lot C 5 @ $1.50
4. Specific Identification
The trader explicitly selects which lots to sell. Provides maximum control but requires meticulous record-keeping. Each lot must be uniquely identifiable (e.g., by purchase date and time, or a lot ID).
def specific_id_sell(lots: dict[str, dict], lot_ids: list[tuple[str, float]],
sell_price: float) -> list[dict]:
"""Sell specific lots by ID. lot_ids = [(lot_id, qty_to_sell), ...]"""
realized = []
for lot_id, sell_qty in lot_ids:
lot = lots[lot_id]
used = min(lot["qty"], sell_qty)
gain = (sell_price - lot["cost_per_unit"]) * used
realized.append({"lot_id": lot_id, "qty": used, "basis": lot["cost_per_unit"], "gain": gain})
lot["qty"] -= used
if lot["qty"] <= 0:
del lots[lot_id]
return realized
5. Proportional / Average Cost Method
Compute a single weighted-average cost per unit across all held lots. Every sell uses that average cost. The average updates after each buy.
def average_cost_basis(lots: list[dict]) -> float:
"""Compute weighted average cost per unit across all lots."""
total_cost = sum(l["qty"] * l["cost_per_unit"] for l in lots)
total_qty = sum(l["qty"] for l in lots)
if total_qty == 0:
return 0.0
return total_cost / total_qty
def average_cost_sell(lots: list[dict], sell_qty: float, sell_price: float) -> dict:
"""Sell using average cost. Reduces all lots proportionally."""
avg = average_cost_basis(lots)
total_qty = sum(l["qty"] for l in lots)
sell_qty = min(sell_qty, total_qty)
gain = (sell_price - avg) * sell_qty
# Reduce each lot proportionally
ratio = sell_qty / total_qty
for lot in lots:
lot["qty"] *= (1 - ratio)
lots[:] = [l for l in lots if l["qty"] > 1e-12]
return {"qty": sell_qty, "avg_basis": avg, "gain": gain}
Partial sell with average cost
Lots: 100 @ $1.00, 50 @ $2.00, 75 @ $1.50. Total: 225 units, total cost $312.50.
Average cost = $312.50 / 225 = $1.3889/unit
Sell 120 at $3.00: gain = (3.00 - 1.3889) * 120 = $193.33
After the sell, 105 units remain at the same $1.3889 average.
6. Special Events
Airdrops
Airdrops are treated as income at fair market value (FMV) on the date received. The FMV becomes the cost basis for future sales.
airdrop_lot = {
"date": "2025-03-15",
"qty": 1000,
"cost_per_unit": 0.05, # FMV at time of receipt
"income_recognized": 50.0, # 1000 * 0.05 reported as income
"source": "airdrop"
}
Staking Rewards
Staking rewards are income at FMV when received (similar to airdrops). Each reward event creates a new lot.
staking_lot = {
"date": "2025-04-01",
"qty": 5.2,
"cost_per_unit": 150.0, # SOL price at receipt
"income_recognized": 780.0,
"source": "staking_reward"
}
Token Splits and Migrations
A token split or migration (old token to new token 1:1 or N:M) is generally not a taxable event. The total cost basis transfers to the new tokens.
def apply_split(lots: list[dict], split_ratio: float) -> None:
"""Apply a token split. split_ratio > 1 means more tokens."""
for lot in lots:
lot["qty"] *= split_ratio
lot["cost_per_unit"] /= split_ratio
For a 1:10 split of 100 tokens @ $5.00: result is 1000 tokens @ $0.50. Total basis unchanged at $500.
7. LP Entry/Exit as Token Swaps
Entering an LP position is treated as selling the deposited tokens and receiving LP tokens. Exiting is the reverse.
LP Entry (deposit 10 SOL + 1500 USDC into SOL/USDC pool):
- Dispose of 10 SOL at current FMV → capital gain/loss event
- Dispose of 1500 USDC at current FMV → usually negligible gain/loss
- Receive LP tokens with cost basis = FMV of deposited assets
LP Exit (redeem LP tokens for 12 SOL + 1400 USDC):
- Dispose of LP tokens at FMV of received assets → capital gain/loss
- Receive 12 SOL with cost basis = FMV at redemption
- Receive 1400 USDC with cost basis = FMV at redemption
def lp_entry(sol_qty: float, sol_price: float, usdc_qty: float,
lp_tokens_received: float) -> dict:
"""Model LP entry as disposal of component tokens."""
total_value = sol_qty * sol_price + usdc_qty * 1.0
lp_cost_basis = total_value / lp_tokens_received
return {
"disposals": [
{"token": "SOL", "qty": sol_qty, "price": sol_price},
{"token": "USDC", "qty": usdc_qty, "price": 1.0},
],
"lp_lot": {"qty": lp_tokens_received, "cost_per_unit": lp_cost_basis}
}
8. Multi-Hop Swaps
A multi-hop swap (e.g., SOL -> USDC -> TOKEN) creates multiple taxable events, one for each intermediate step. Jupiter often routes through intermediate tokens.
def multi_hop_events(hops: list[dict]) -> list[dict]:
"""
Each hop is: {"sell_token", "sell_qty", "sell_price",
"buy_token", "buy_qty", "buy_price"}
Each hop is a separate taxable event.
"""
events = []
for i, hop in enumerate(hops):
events.append({
"event": i + 1,
"dispose": hop["sell_token"],
"dispose_qty": hop["sell_qty"],
"dispose_value": hop["sell_qty"] * hop["sell_price"],
"acquire": hop["buy_token"],
"acquire_qty": hop["buy_qty"],
"acquire_basis": hop["buy_qty"] * hop["buy_price"],
})
return events
Example: Swap 1 SOL ($150) -> 150 USDC -> 10,000 TOKEN ($0.015 each)
- Event 1: Dispose 1 SOL (basis vs. $150 proceeds) → gain/loss on SOL
- Event 2: Dispose 150 USDC (basis vs. $150 proceeds) → usually ~$0 gain
- Result: 10,000 TOKEN with cost basis = $0.015/unit
9. Comparison View
The core value of this skill: run the same trade history through all five methods and compare total realized gain and estimated tax liability.
methods = ["FIFO", "LIFO", "HIFO", "Specific ID", "Average Cost"]
# After processing all trades through each method:
comparison = {
"FIFO": {"total_gain": 220.00, "tax_at_30pct": 66.00},
"LIFO": {"total_gain": 157.50, "tax_at_30pct": 47.25},
"HIFO": {"total_gain": 155.00, "tax_at_30pct": 46.50},
"Specific ID": {"total_gain": 160.00, "tax_at_30pct": 48.00},
"Average Cost":{"total_gain": 193.33, "tax_at_30pct": 58.00},
}
# HIFO minimizes liability in this example
See scripts/cost_basis_calculator.py for a full runnable comparison with realistic trade data including partial sells.
Quick Start
from scripts.cost_basis_calculator import CostBasisEngine
engine = CostBasisEngine()
# Add purchases
engine.add_buy("2025-01-10", "TOKEN", 100, 1.00)
engine.add_buy("2025-02-15", "TOKEN", 50, 2.00)
engine.add_buy("2025-03-01", "TOKEN", 75, 1.50)
# Sell and compare methods
results = engine.sell_compare("2025-04-01", "TOKEN", 120, 3.00)
engine.print_comparison(results)
Use Cases
- Tax season preparation: Run your full year of trades through all methods before choosing one to report.
- Accumulation strategy: Track partial sells during DCA accumulation, see how each method affects remaining basis.
- LP position tracking: Model LP entry/exit as swaps and capture the associated gain/loss events.
- Airdrop and staking income: Properly record income events and set cost basis for future disposals.
- Multi-hop swap decomposition: Break down Jupiter routes into individual taxable events.
Files
| File | Description |
|---|---|
references/planned_features.md |
Method formulas, partial sell worked examples, special event handling, multi-hop treatment |
scripts/cost_basis_calculator.py |
Full engine with all 5 methods, comparison table, demo mode with realistic trades |
Remember: The "best" method depends on your jurisdiction, your specific trade history, and your tax situation. This engine helps you compare — a tax professional helps you decide.