【確定申告用】仮想通貨自動取引履歴から年間損益をpythonで計算する

仮想通貨

今年も確定申告の季節ですね!

こちらの記事では仮想通貨の自動取引履歴から年間損益をpythonで計算する方法を紹介します。確定申告では総平均法 or 移動平均法で計算した年間損益(売却利益と買付費用)が必要になりますが、自動取引では取引数が大変多くなるため特に移動平均法の計算が大変です。今回の記事ではcoincheckの取引履歴から両方の計算方法で利益を計算する方法を紹介します。今回の記事は以下の方にオススメです。

  • coincheckで仮想通貨を取引している
  • 仮想通貨の自動取引で発生した大量の取引から年間損益を計算する必要がある
  • 損益計算の有料サービスにお金を払いたくない
  • 総平均法と移動平均法のどちらが自分にあっているのかわからない

※実際の個人の確定申告に使用される場合は自己責任でお願いします。

仮想通貨確定申告のための事前知識

仮想通貨の確定申告に必要な項目

国税庁のホームページに記載されている必要情報は以下になります。(参考:【確定申告書等作成コーナー】-仮想通貨の取引に係る収入がある場合 (nta.go.jp)

  • 種目:仮想通貨名
  • 取引所名称
  • 取引所所在地
  • 収入金額:売却利益
  • 必要経費:買付費用(+ 手数料)

coincheckのBTC取引は手数料無料なので、取引履歴から売却利益と買付費用を算出する必要があります。

ちなみにこちらのページには各計算方法ごとのエクセルが公開されていますが、いかんせん行数が少なすぎます・・・(参考:暗号資産等に関する税務上の取扱い及び計算書について(令和5年12月)|国税庁 (nta.go.jp)

総平均法と移動平均法の比較

総平均法

  • 一年間の全買付から年間平均取得レートを計算し、[年間の売却量] x [年間平均買付レート]を年間総買付費用として扱う。
  • 年間損益 = [年間総売却利益] – [年間総買付費用]
  • 損益計算が簡単

移動平均法

  • 売却のタイミングごとに[売却量] x [買付レート]から売却利益を計算し、その累積額を年間総売却益とする
  • 年間総買付費用 = [年間総買付費用] – [最後の取引後の保有数量] x [買付レート]
  • 損益計算が複雑

文字による計算が難しいので、youtubeなどで上手な説明を視聴して頂けると助かります。重要なのは下記2点です。

① 計算方法によって年単位の損益が異なりますが、生涯の損益は同じ金額になります。

② ただし仮想通貨で得た利益は税法上は雑所得して扱われ、個人の雑所得の合計が20万円以上の場合は課税対象となります。

2023年のような年末にかけて高騰する相場の場合、総平均法のほうがその年の利益を低くすることができますが、翌年以降に利益は持ち越される点に注意してください。

また確定申告ではデフォルトで総平均法が採用されるため、移動平均法で申告するためには別途申請が必要です。そして一度採用した計算方法は3年間は変更できません。

Pythonによる損益計算

coincheckから取引データの取得

下記の公式サイトに年単位のファイルを作成&取得するだけです。詳細は割愛します。

Coincheckフォーマットでの取引履歴(CSV)の取得方法 | FAQ/お問い合わせ

以下では”coincheckフォーマット(新)”で取得したcsvファイルを”coincheck_all_trades.csv”として処理しています。

総平均法

df = pd.read_csv('./coincheck_all_trades.csv')
df = df[~(df['取引種別'] == '入金')]

# 購入
df_buy = df[df['取引種別'] == '購入']
btc_buy = df_buy['増加数量'].sum()
jpy_buy = df_buy['約定価格/数量'].sum()
mean_jpy_buy = jpy_buy / btc_buy

# 売却
df_sell = df[df['取引種別'] == '売却']
jpy_sell = df_sell['増加数量'].sum()
btc_sell = df_sell['減少数量'].sum()

# 総平均法利益
cost = btc_sell * mean_jpy_buy
annual_profit_mean = jpy_sell - cost

# 翌年持越し分
btc_carryover = btc_buy - btc_sell
jpy_btc_carryover = btc_carryover * mean_jpy_buy

# 出力
print(f'年間購入額: {jpy_buy} [JPY]')
print(f'年間取得量: {btc_buy} [BTC]')
print(f'年間平均取得レート: {mean_jpy_buy} [JPY/BTC]')
print()
print(f'年間売却益: {jpy_sell} [JPY]')
print(f'年間売却量: {btc_sell} [BTC]')
print()

# 確定申告書類記載内容
print('='*5, '総平均法', '='*5)
print(f'収入金額: {round(jpy_sell)}')
print(f'必要経費: {round(cost)}')

実行して出力される”総平均法年間利益”が今年の損益になります。参考までに少額取引の私の場合は以下の出力でした。

年間購入額: 24655025.278431952 [JPY]
年間取得量: 5.1996500900000004 [BTC]
年間平均取得レート: 4741670.083886731 [JPY/BTC]

年間売却益: 24502771.6732654 [JPY]
年間売却量: 5.160622829999999 [BTC]

===== 総平均法 =====
収入金額: 24502772
必要経費: 24469971

2023年のように年末にかけて高騰する相場の場合、移動平均法ではその年の利益を抑えることができます。しかし翌年に持ち越した仮想通貨分は現在レートよりも低いレートで取得したことになっているため、翌年の利益が高くなる傾向があります。もちろん逆もしかりです。

移動平均法

df = pd.read_csv('./coincheck_all_trades.csv')
df = df[~(df['取引種別'] == '入金')]

btc_amount = 0 # 所持量
position = 0 # 所持価格
jpy_buys = [] # 全購入費リスト
jpy_sells = [] # 全売却益リスト

for i, r in df.iterrows():
    if r['取引種別'] == '購入':
        btc_amount += r['増加数量']
        jpy_buys.append(r['減少数量'])
        position = position + r['減少数量']
        moving_mean_jpy_btc = position / btc_amount
        
    elif r['取引種別'] == '売却':
        btc_amount -= r['減少数量']
        jpy_sells.append(r['増加数量'])                
        position = moving_mean_jpy_btc * btc_amount       

    else:
        print(f'Error in row {i+1}')
        print('allowed only "購入" or "売却", but another type is included')

btc_carryover = btc_amount
jpy_btc_carryover = moving_mean_jpy_btc

cost = sum(jpy_buys) - position
profit = sum(jpy_sells)
annual_profit_move = profit - cost

# 出力
print(f'移動平均法年間損益: {annual_profit_move} [JPY]')
print(f'翌年持越し量: {btc_amount} [BTC]')
print(f'翌年持越しレート: {jpy_btc_carryover} [JPY/BTC]')
print()

# 確定申告書類記載内容
print('='*5, '移動平均法', '='*5)
print(f'収入金額: {round(profit)}')
print(f'必要経費: {round(cost)}')

移動平均法では買付ごとに平均買付レートを更新し、売却ごとに買付レートから売却利益と算出する必要があります。また総購入費用 – 現ポジション(最後の取引直後の所持価格)が売却済み仮想通貨の総購入費用となります。手計算では複雑ですが、しかし所詮はルールベースの処理なので簡単にプログラム化できます。参考までに私のケースの出力値を以下に紹介します。

移動平均法年間損益: 80571.31649251282 [JPY]
翌年持越し量: 0.03902726000000013 [BTC]
翌年持越しレート: 5965699.91485644 [JPY/BTC]

===== 移動平均法 =====
収入金額: 24502772
必要経費: 24422200

移動平均法では売却ごとに損益を計算するため、総平均法よりも実態に即した損益が出力されます。また2023年のような上げ相場でも翌年に持ち越すレートが年末のレートから大きく乖離しません。

総平均法と移動平均法のどちらにすべきか?

自分のような少額取引では2023年のような上げ相場でも年間利益が20万円を超えないためどちらでもよいのですが、”上げ相場”かつ”移動平均法でも利益が20万円以下”なら移動平均法を選択した方が翌年に税金が発生するリスクを抑えられます。

一方で仮に20万円を超える利益だった場合、総平均法でなんとか今年凌いでも来年以降に20万円を超えて税金が発生する可能性があります。

ということでどちらを選んでも将来発生する税金総額は神のみぞ知るところなのですが、自分はとりあえず移動平均法を選択することにします。

今回の記事は以上になります!

コメント