rqalpha.portfolio.capital_gains_tax 源代码
from datetime import date
from rqalpha.core.events import EVENT
DEFAULT_CAPITAL_GAINS_TAX_RATE = 0
class CapitalGainsTaxMixin:
"""
计算 `金融商品转让增值税` + `附加税`,具体计算逻辑和公式如下:
定义:
annual_deductible_balance: 年度可抵余额 <= 0,每年年初重置为 0;
monthly_realized_pnl: 月初为 0,当月所有的卖出交易中,卖出价扣除买入价(成本价)后加总的总额
"""
def __init__(self):
self._annual_deductible_balance = 0
self._monthly_realized_pnl = 0
self._env.event_bus.add_listener(EVENT.BEFORE_TRADING, self._on_before_trading)
def _on_before_trading(self, event):
"""
每年年初将 K 重置为 0
"""
if self._is_start_of_year():
self._annual_deductible_balance = 0
def calc_capital_gains_tax(self) -> float:
"""
每月月底进行缴纳税额计算 (tax_basis = annual_deductible_balance + monthly_realized_pnl):
1) tax_basis > 0:
a. tax = (tax_basis * 3%)[增值税] + (tax_basis * 3% * (3.5% + 1.5% + 1%))[附加税]
b. set annual_deductible_balance = monthly_realized_pnl = 0
2) tax_basis <= 0:
annual_deductible_balance = tax_basis then set monthly_realized_pnl = 0
3) 特别说明:
为了方便计算,此处将「增值税」和 「附加税」的费率统一为配置中的 base.capital_gain_tax_rate,用户可以进行自定义
"""
if not self._is_end_of_month():
return 0
tax_basis = self._annual_deductible_balance + self._monthly_realized_pnl
if tax_basis > 0:
tax_rate = getattr(self._env.config.base, "capital_gain_tax_rate", DEFAULT_CAPITAL_GAINS_TAX_RATE)
tax = tax_basis * tax_rate
self._monthly_realized_pnl = self._annual_deductible_balance = 0
return tax
else:
self._annual_deductible_balance = tax_basis
self._monthly_realized_pnl = 0
return 0
def _is_end_of_month(self) -> bool:
trading_dt = self._env.trading_dt
next_trading_date = self._env.data_proxy.get_next_trading_date(trading_dt)
return next_trading_date.month != trading_dt.month
def _is_start_of_year(self) -> bool:
trading_dt = self._env.trading_dt
if trading_dt.month != 1: # 减少交易日获取
return False
prev_trading_date = self._env.data_proxy.get_previous_trading_date(trading_dt)
return prev_trading_date.year != trading_dt.year
def _add_monthly_realized_pnl(self, delta_amount: float) -> None:
self._monthly_realized_pnl += delta_amount