国库券收益率
根据价格计算三种口径收益率
根据每 100 元面值的国库券价格、结算日与到期日,计算货币市场收益率(MMYield)、债券等价收益率(BEYield)和贴现率(Discount)。
格式 yyyy-mm-dd
格式 yyyy-mm-dd
计算结果
点击「计算」查看输出
code
计算逻辑代码
以下为「国库券收益率」QuantLib 代码示例。
# 依赖版本:
# python==3.9
# QuantLib==1.43
import traceback
from datetime import datetime,date as py_date
import QuantLib as ql
from fastapi import Query
# ============================================================
# 工具函数
# ============================================================
def _parse_date(s: str) -> ql.Date:
d = datetime.strptime(s.strip(), "%Y-%m-%d")
return ql.Date(d.day, d.month, d.year)
# ============================================================
# 核心计算函数
# ============================================================
def qjquant_calu_tbillyield(
price: float = Query(...),
settle_date: str = Query(...),
maturity_date: str = Query(...),
):
try:
# ---------- 参数校验 ----------
if price <= 0 or price > 100:
return {"ok": False, "msg": "价格必须大于 0 且不超过 100"}
settle_qd = _parse_date(settle_date)
maturity_qd = _parse_date(maturity_date)
if settle_qd >= maturity_qd:
return {"ok": False, "msg": "结算日必须早于到期日"}
# ---------- 实际天数 ----------
# 结算日至到期日的实际天数(Actual/360 与 Actual/365 的天数部分相同)
days = ql.Actual360().dayCount(settle_qd, maturity_qd)
if days <= 0:
return {"ok": False, "msg": "到期天数异常"}
FACE = 100.0
# ---------- 1) 货币市场收益率 MMYield(Actual/360) ----------
# 价格关系:Price = FACE / (1 + MMYield * days/360)
mm_yield = (FACE / price - 1.0) * 360.0 / days
# ---------- 3) 贴现率 Discount(Actual/360) ----------
# 价格关系:Price = FACE * (1 - Discount * days/360)
discount = (1.0 - price / FACE) * 360.0 / days
# ---------- 2) 债券等价收益率 BEYield ----------
# MATLAB tbillyield 口径:
# 期限 <= 182 天:BEY = (FACE/Price - 1) * 365/days
# 期限 > 182 天:BEY 由二次方程求解(长期国库券口径)
if days <= 182:
be_yield = (FACE / price - 1.0) * 365.0 / days
else:
# 长期 T-Bill BEY 定价公式:
# Price = FACE / (1 + BEY * days/365) 的精确反向需解二次方程
# 采用市场标准的二次公式:
# BEY = [-2*days/365 + sqrt((2*days/365)^2 + 4*(FACE/Price - 1))] / 2
# 即求解: (days/365)*BEY^2/2 + BEY - (FACE/Price - 1) = 0
# 但更常见的长期公式为:
# Price = FACE / (1 + BEY * days/365) 仅在 <=182 天有效;
# 长期使用:
# BEY = (2 * (FACE/Price - 1)) / (days/365 + sqrt((days/365)^2 + 4*(FACE/Price - 1)))
# 下面采用与 MATLAB 一致的二次公式:
t = days / 365.0
r = FACE / price - 1.0
# 解方程: t * BEY^2 / 2 + BEY - r = 0 => BEY = [-1 + sqrt(1 + 2*t*r)] / t
# 注意:MATLAB 文档对长期 T-Bill 的 BEY 使用如下公式:
# BEY = (2*(FACE/Price - 1)) / (t + sqrt(t^2 + 4*(FACE/Price - 1)))
# 等价于解 t*BEY^2/2 + BEY - r = 0 的正根。
discriminant = 1.0 + 2.0 * t * r
if discriminant < 0:
return {"ok": False, "msg": "长期国库券 BEY 计算判别式异常"}
be_yield = (-1.0 + (discriminant ** 0.5)) / t
# ---------- 结果 ----------
return {
"ok": True,
"mm_yield": round(mm_yield, 4),
"be_yield": round(be_yield, 4),
"discount": round(discount, 4),
}
except ValueError as ve:
traceback.print_exc()
return {"ok": False, "msg": f"参数错误: {ve}"}
except Exception as e:
traceback.print_exc()
return {"ok": False, "msg": f"未知错误: {e}"}
# ============================================================
# 可复制运行的示例
# ============================================================
if __name__ == "__main__":
print("=" * 60)
print("国库券收益率 tbillyield 示例")
print("=" * 60)
# 示例 1:期限 <= 182 天(短期,BEY 用简单公式)
r1 = qjquant_calu_tbillyield(
price=97.8172,
settle_date="2024-01-02",
maturity_date="2024-07-01",
)
print("\n[示例1] 短期 180 天,价格 97.8172")
print(" 结果:", r1)
# 示例 2:期限 > 182 天(长期,BEY 用二次公式)
r2 = qjquant_calu_tbillyield(
price=95.5000,
settle_date="2024-01-02",
maturity_date="2024-12-31",
)
print("\n[示例2] 长期 364 天,价格 95.5000")
print(" 结果:", r2)
# 示例 3:价格 = 100(边界,收益率为 0)
r3 = qjquant_calu_tbillyield(
price=100.0,
settle_date="2024-01-02",
maturity_date="2024-07-01",
)
print("\n[示例3] 价格 100.0(边界)")
print(" 结果:", r3)