银行贴现率

银行贴现率 证券的银行贴现率(货币市场)
根据结算日、到期日、面值与证券价格,计算证券(例如美国国库券)的银行贴现率。银行贴现率按面值进行正常化,会低估投资者获得的真实收益。可选参数 Basis 指定计息天数规则,默认 0(实际/实际)。
格式 yyyy-mm-dd
格式 yyyy-mm-dd
计算结果
点击「计算」查看输出
code 计算逻辑代码
以下为「ISDA国际通用」银行贴现率的 Python 代码示例(基于 QuantLib)。

# 依赖版本:
# python==3.9
# QuantLib==1.43
import traceback
from datetime import datetime

import QuantLib as ql


def qjquant_calu_discrate(
    settle: str,
    maturity: str,
    face: float,
    price: float,
    basis: int = 0,
):
    try:
        # ---------- 参数校验 ----------
        if face <= 0:
            return {"ok": False, "msg": "面值必须大于 0"}
        if price <= 0:
            return {"ok": False, "msg": "证券价格必须大于 0"}
        if price > face:
            return {"ok": False, "msg": "证券价格不能高于面值(贴现证券)"}

        # ---------- 日期解析 ----------
        try:
            d1 = datetime.strptime(settle, "%Y-%m-%d")
            d2 = datetime.strptime(maturity, "%Y-%m-%d")
        except ValueError:
            return {"ok": False, "msg": "日期格式必须为 YYYY-MM-DD"}

        settle_date = ql.Date(d1.day, d1.month, d1.year)
        maturity_date = ql.Date(d2.day, d2.month, d2.year)
        if maturity_date <= settle_date:
            return {"ok": False, "msg": "到期日必须晚于结算日"}

        # ---------- 计息天数规则 ----------
        day_counter_map = {
            0: ql.Actual365Fixed(),          # MATLAB discrate 中 Basis=0 实际为 Actual/365
            1: ql.Thirty360(ql.Thirty360.BondBasis),
            2: ql.Actual360(),
            3: ql.Actual365Fixed(),
            4: ql.Thirty360(ql.Thirty360.USA),      # BMA 近似
            5: ql.Thirty360(ql.Thirty360.ISDA),
            6: ql.Thirty360(ql.Thirty360.European),
            7: ql.Actual365Fixed(),                  # 日语近似
            8: ql.ActualActual(ql.ActualActual.ISMA),
            9: ql.Actual360(),
            10: ql.Actual365Fixed(),
            11: ql.Thirty360(ql.Thirty360.European),
            12: ql.Actual365Fixed(),
            13: ql.Actual365Fixed(),                 # BUS/252 需另行处理
        }
        dc = day_counter_map.get(basis, ql.ActualActual(ql.ActualActual.Bond))

        # ---------- 年化天数比例 ----------
        year_frac = dc.yearFraction(settle_date, maturity_date)
        if year_frac <= 0:
            return {"ok": False, "msg": "结算日至到期日的年数必须大于 0"}

        # ---------- 银行贴现率公式 ----------
        disc_rate = (face - price) / face / year_frac

        return {
            "ok": True,
            "disc_rate": round(disc_rate, 4),
        }

    except Exception as e:
        traceback.print_exc()
        return {"ok": False, "msg": f"未知错误: {e}"}


# ============================================================
# 示例:复制本文件后直接运行
# ============================================================
if __name__ == "__main__":
    print("=" * 60)
    print("示例 1:美国国库券(实际/360)")
    print("=" * 60)
    r1 = qjquant_calu_discrate(
        settle="2024-03-15",
        maturity="2024-09-15",
        face=100.0,
        price=98.0,
        basis=2,
    )
    print(r1)

    print()
    print("=" * 60)
    print("示例 2:短期证券(Basis=0,MATLAB 口径为 Actual/365)")
    print("=" * 60)
    r2 = qjquant_calu_discrate(
        settle="2024-03-15",
        maturity="2024-06-15",
        face=1000.0,
        price=985.0,
        basis=0,
    )
    print(r2)

    print()
    print("=" * 60)
    print("示例 3:30/360 BondBasis 口径")
    print("=" * 60)
    r3 = qjquant_calu_discrate(
        settle="2024-01-31",
        maturity="2024-07-31",
        face=100.0,
        price=97.5,
        basis=1,
    )
    print(r3)

    print()
    print("=" * 60)
    print("示例 4:实际/365(Basis=3)")
    print("=" * 60)
    r4 = qjquant_calu_discrate(
        settle="2024-03-15",
        maturity="2024-09-15",
        face=100.0,
        price=98.0,
        basis=3,
    )
    print(r4)