使用Grok製作2025年所得稅試算
馬上要到5月的繳稅季節了,我想要算一下我該繳多少稅,其實應該是要算該領多少股息時,我可以繳最低的稅。
我的薪資所得很好算(領固定月薪),兩季獎金也分別在2月、6月領(噓!!)
所以當我的薪資所得出來了,我再來配我領的股息可以多少~
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
def calculate_income_tax():
# 設置中文字型
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False
# 2024 年稅制參數(適用 2025 年申報)
TAX_BRACKETS = [
(590000, 0.05, 0),
(1330000, 0.12, 41300),
(2420000, 0.20, 147700),
(4530000, 0.30, 389700),
(float('inf'), 0.40, 842700)
]
EXEMPTION_PER_PERSON = 97000 # 每人免稅額
STANDARD_DEDUCTION_SINGLE = 131000 # 單身標準扣除額
STANDARD_DEDUCTION_COUPLE = 262000 # 有配偶標準扣除額
SALARY_DEDUCTION = 218000 # 薪資特別扣除額
DEPENDENT_DEDUCTION = 97000 # 每位扶養人扣除額
DIVIDEND_CREDIT_RATE = 0.085 # 股利抵減稅率
DIVIDEND_CREDIT_CAP = 80000 # 股利抵減上限
DIVIDEND_SEPARATE_TAX_RATE = 0.28 # 分離計稅股利稅率
# 輸入資料(單位:萬元)
print("=== 2025 年台灣所得稅計算器 ===")
try:
salary_wan = float(input("請輸入您的年薪資所得(萬元):"))
dividend_wan = float(input("請輸入您的年股利所得(萬元):"))
has_spouse = input("是否有配偶?(是:Y / 否:N):").strip().upper() == 'Y'
dependents = int(input("請輸入扶養人數(不含配偶):"))
# 將輸入的萬元轉換為元
salary = salary_wan * 10000
dividend = dividend_wan * 10000
except ValueError:
print("輸入格式錯誤,請輸入數字!")
return
# 計算扣除額
exemption = EXEMPTION_PER_PERSON * (1 + (1 if has_spouse else 0) + dependents)
standard_deduction = STANDARD_DEDUCTION_COUPLE if has_spouse else STANDARD_DEDUCTION_SINGLE
salary_deduction = SALARY_DEDUCTION if salary > 0 else 0
total_deductions = exemption + standard_deduction + salary_deduction
# 計算基準稅額(股利 = 0)
base_taxable_income = max(0, salary - total_deductions)
base_tax = 0
for bracket_limit, rate, progressive_diff in TAX_BRACKETS:
if base_taxable_income <= bracket_limit:
base_tax = base_taxable_income * rate - progressive_diff
break
base_tax = max(0, base_tax)
# 方式一:合併計稅
total_income = salary + dividend
taxable_income = max(0, total_income - total_deductions)
tax_merged = 0
for bracket_limit, rate, progressive_diff in TAX_BRACKETS:
if taxable_income <= bracket_limit:
tax_merged = taxable_income * rate - progressive_diff
break
tax_merged = max(0, tax_merged)
dividend_credit = min(dividend * DIVIDEND_CREDIT_RATE, DIVIDEND_CREDIT_CAP)
tax_merged_final = max(0, tax_merged - dividend_credit)
# 方式二:分離計稅(計算但不顯示在圖表中)
salary_taxable_income = max(0, salary - exemption - standard_deduction - salary_deduction)
tax_salary = 0
for bracket_limit, rate, progressive_diff in TAX_BRACKETS:
if salary_taxable_income <= bracket_limit:
tax_salary = salary_taxable_income * rate - progressive_diff
break
tax_salary = max(0, tax_salary)
tax_dividend = dividend * DIVIDEND_SEPARATE_TAX_RATE
tax_separate_final = tax_salary + tax_dividend
# 計算交叉點(合併計稅稅額 = 基準稅額)
def find_intersection(salary, total_deductions, base_tax):
x_intersection = None
base_taxable_income = max(0, salary - total_deductions)
for bracket_limit, rate, progressive_diff in TAX_BRACKETS:
if base_taxable_income > bracket_limit:
continue
lower_bound = max(0, total_deductions - salary)
upper_bound = bracket_limit - (salary - total_deductions)
if x_intersection is None:
coeff = rate - 0.085
if coeff != 0:
x = (base_tax + progressive_diff - (salary - total_deductions) * rate) / coeff
if x >= lower_bound and x <= upper_bound and x * 0.085 <= 80000:
x_intersection = x
if x_intersection is None:
x = (base_tax + progressive_diff + 80000 - (salary - total_deductions) * rate) / rate
if x >= lower_bound and x <= upper_bound and x * 0.085 > 80000:
x_intersection = x
return x_intersection / 10000 if x_intersection is not None else None # 轉回萬元
x_intersection_wan = find_intersection(salary, total_deductions, base_tax)
# 動態調整 X 軸範圍(根據輸入股利)
max_dividend_wan = max(100, dividend_wan) # 如果股利大於 100 萬,則以輸入股利為上限
# 確保 X 軸上限為 10 萬的倍數
max_dividend_wan = np.ceil(max_dividend_wan / 10) * 10
# 繪製曲線圖(Y 軸單位為萬元,只顯示合併計稅)
dividend_range_wan = np.linspace(0, max_dividend_wan, int(max_dividend_wan * 10) + 1) # 每 0.1 萬一個點
dividend_range = dividend_range_wan * 10000
tax_merged_values = []
for div in dividend_range:
total_income = salary + div
taxable_income = max(0, total_income - total_deductions)
tax_merged = 0
for bracket_limit, rate, progressive_diff in TAX_BRACKETS:
if taxable_income <= bracket_limit:
tax_merged = taxable_income * rate - progressive_diff
break
tax_merged = max(0, tax_merged)
dividend_credit = min(div * DIVIDEND_CREDIT_RATE, DIVIDEND_CREDIT_CAP)
tax_merged_values.append(max(0, tax_merged - dividend_credit) / 10000) # 轉為萬元
# 計算轉折點(稅率級距變化點)
turning_points = []
for bracket_limit, rate, progressive_diff in TAX_BRACKETS:
div = bracket_limit - (salary - total_deductions) # 股利(元)
if div < 0: # 如果股利為負,跳過
continue
if div / 10000 > max_dividend_wan: # 如果股利超出圖表範圍,跳過
break
taxable_income = bracket_limit
tax_merged = taxable_income * rate - progressive_diff
tax_merged = max(0, tax_merged)
dividend_credit = min(div * DIVIDEND_CREDIT_RATE, DIVIDEND_CREDIT_CAP)
tax_value = max(0, tax_merged - dividend_credit) / 10000 # 轉為萬元
turning_points.append((div / 10000, tax_value)) # (X, Y) 轉折點
# 計算輸入股利所得的應繳稅額(Y 值)
input_dividend_tax = tax_merged_final / 10000 # 轉為萬元
plt.figure(figsize=(12, 10))
plt.plot(dividend_range_wan, tax_merged_values, label='合併計稅', color='blue')
plt.axhline(y=base_tax / 10000, color='green', linestyle='--', label=f'基準稅額 ({base_tax / 10000:,.1f} 萬)')
if x_intersection_wan is not None and 0 <= x_intersection_wan <= max_dividend_wan:
plt.axvline(x=x_intersection_wan, color='purple', linestyle='--', label=f'交叉點 (股利 {x_intersection_wan:.2f} 萬)')
plt.text(x_intersection_wan, 0, f'{x_intersection_wan:.2f}', color='purple', ha='center', va='top', fontsize=10, bbox=dict(facecolor='white', alpha=0.8))
plt.text(0, base_tax / 10000, f'{base_tax / 10000:,.1f}', color='green', ha='right', va='center', fontsize=10, bbox=dict(facecolor='white', alpha=0.8))
# 標記轉折點
for x, y in turning_points:
plt.scatter(x, y, color='blue', s=50, zorder=5) # 畫轉折點
plt.text(x, -0.2, f'{x:.2f}', color='blue', ha='center', va='top', fontsize=10, bbox=dict(facecolor='white', alpha=0.8))
plt.text(x + 2, y, f'{y:.1f}', color='blue', ha='left', va='center', fontsize=10, bbox=dict(facecolor='white', alpha=0.8))
# 標記輸入的股利所得位置
if 0 <= dividend_wan <= max_dividend_wan: # 確保輸入的股利在圖表範圍內
plt.axvline(x=dividend_wan, color='orange', linestyle='--', label=f'輸入股利 ({dividend_wan:.2f} 萬)')
plt.scatter(dividend_wan, input_dividend_tax, color='orange', s=50, zorder=5) # 畫輸入點
plt.text(dividend_wan, 0, f'{dividend_wan:.2f}', color='orange', ha='center', va='top', fontsize=10, bbox=dict(facecolor='white', alpha=0.8))
plt.text(dividend_wan + 2, input_dividend_tax, f'{input_dividend_tax:.1f}', color='orange', ha='left', va='center', fontsize=10, bbox=dict(facecolor='white', alpha=0.8))
plt.xlabel('股利所得 (萬元)')
plt.ylabel('應繳稅額 (萬元)')
plt.title(f'薪資所得 {salary_wan:.0f} 萬 - 應繳稅額隨股利所得變化')
plt.legend()
plt.grid(True)
plt.ylim(-0.5, max(max(tax_merged_values), base_tax / 10000) + 0.5) # 調整 Y 軸範圍,僅考慮合併計稅
plt.xticks(np.arange(0, max_dividend_wan + 10, 10)) # X 軸以每 10 萬為間距
plt.show()
# 輸出結果
print("\n=== 計算結果 ===")
print(f"薪資所得:{salary_wan:,.0f} 萬元 ({salary:,.0f} 元)")
print(f"股利所得:{dividend_wan:,.0f} 萬 ({dividend:,.0f} 元)")
print(f"配偶:{'有' if has_spouse else '無'}")
print(f"扶養人數:{dependents} 人")
print(f"總扣除額:{total_deductions:,.0f} 元(免稅額:{exemption:,.0f} 元,標準扣除額:{standard_deduction:,.0f} 元,薪資扣除額:{salary_deduction:,.0f} 元)")
print(f"基準稅額(股利 = 0):{base_tax:,.0f} 元 ({base_tax / 10000:,.1f} 萬)")
print("\n合併計稅:")
print(f" 綜合所得淨額:{taxable_income:,.0f} 元")
print(f" 應納稅額:{tax_merged:,.0f} 元")
print(f" 股利抵減稅額:{dividend_credit:,.0f} 元")
print(f" 應繳稅額:{tax_merged_final:,.0f} 元 ({tax_merged_final / 10000:,.1f} 萬)")
print("\n分離計稅:")
print(f" 薪資所得淨額:{salary_taxable_income:,.0f} 元")
print(f" 薪資稅額:{tax_salary:,.0f} 元")
print(f" 股利稅額:{tax_dividend:,.0f} 元")
print(f" 應繳稅額:{tax_separate_final:,.0f} 元 ({tax_separate_final / 10000:,.1f} 萬)")
print("\n交叉點:")
if x_intersection_wan is not None:
print(f"當股利所得為 {x_intersection_wan:.2f} 萬時,合併計稅稅額等於基準稅額 {base_tax:,.0f} 元 ({base_tax / 10000:,.1f} 萬)")
else:
print("未找到交叉點(可能因稅率級距或抵減上限)")
print("\n建議選擇:", end="")
if tax_merged_final <= tax_separate_final:
print(f"合併計稅,應繳稅額 {tax_merged_final:,.0f} 元 ({tax_merged_final / 10000:,.1f} 萬)")
else:
print(f"分離計稅,應繳稅額 {tax_separate_final:,.0f} 元 ({tax_separate_final / 10000:,.1f} 萬)")
# 執行程式
if __name__ == "__main__":
calculate_income_tax()這個程式主要功能有:
1.輸入薪資所得
2.輸入股利所得
3.有無配偶
4.扶養人數(不含配偶)
5.會匯出一個應繳稅額與股利所得的曲線圖。
我輸入薪資所得100萬、股利30萬、有配偶、扶養人數零,輸出結果與曲線圖如下:
=== 計算結果 ===
薪資所得:100 萬元 (1,000,000 元)
股利所得:30 萬 (300,000 元)
配偶:有
扶養人數:0 人
總扣除額:674,000 元(免稅額:194,000 元,標準扣除額:262,000 元,薪資扣除額:218,000 元)
基準稅額(股利 = 0):16,300 元 (1.6 萬)
合併計稅:
綜合所得淨額:590,000 元
應納稅額:29,500 元
股利抵減稅額:22,440 元
應繳稅額:8,320 元 (0.8 萬)
分離計稅:
薪資所得淨額:326,000 元
薪資稅額:16,300 元
股利稅額:84,000 元
應繳稅額:100,300 元 (10.0 萬)
交叉點:
當股利所得為 -0.00 萬時,合併計稅稅額等於基準稅額 16,300 元 (1.6 萬)
建議選擇:合併計稅,應繳稅額 8,320 元 (0.8 萬)

可以看到:我的稅只要繳8320,同時也可以看到,當我的股利為26.4萬時,我要繳7000元的稅。
這程式還不賴吧~!
好了,我要去湊我的股利了。