ข้ามไปยังเนื้อหา

ข้อตกลงการนับวัน (Day-Count Conventions)

อนุสัญญาการนับวันใช้สำหรับคำนวณสัดส่วนของปี (τ\tau) ระหว่างวันที่สองวัน d1d_1 และ d2d_2 เพื่อใช้คิดดอกเบี้ยค้างรับและตัวคูณคิดลด (Discount Factors):

τ(d1,d2)=Days(d1,d2)YearBase\tau(d_1, d_2) = \frac{\text{Days}(d_1, d_2)}{\text{YearBase}}

อนุสัญญาที่รองรับ (Supported Conventions)

1. Actual/Actual ICMA (มาตรฐานตราสารหนี้)

ใช้สำหรับพันธบัตรรัฐบาลและหุ้นกู้เอกชน คำนวณวันจริงเทียบกับจำนวนวันจริงในรอบการจ่ายคูปองปัจจุบัน:

τ(d1,d2)=d2−d1f⋅(p2−p1)\tau(d_1, d_2) = \frac{d_2 - d_1}{f \cdot (p_2 - p_1)}

โดย ff คือความถี่ในการจ่ายดอกเบี้ยต่อปี และ [p1,p2][p_1, p_2] คือช่วงเวลาอ้างอิงของงวดคูปอง

2. Actual/Actual ISDA (มาตรฐานสัญญา Swap)

แบ่งการคำนวณแยกตามปีปฏิทิน:

τ(d1,d2)=Days in Year1Days in Year1 (365 or 366)+Days in Year2Days in Year2 (365 or 366)\tau(d_1, d_2) = \frac{\text{Days in Year}_1}{\text{Days in Year}_1 \text{ (365 or 366)}} + \frac{\text{Days in Year}_2}{\text{Days in Year}_2 \text{ (365 or 366)}}

3. Actual/360 และ Actual/365 Fixed

  • Actual/360: มาตรฐานตลาดเงิน (ตั๋วเงินคลังสหรัฐฯ, ตราสารหนี้ระยะสั้น, ดอกเบี้ยกู้ยืม SOFR/Euribor): τ(d1,d2)=d2−d1360\tau(d_1, d_2) = \frac{d_2 - d_1}{360}
  • Actual/365 Fixed: มาตรฐานในสหราชอาณาจักร ประเทศในเครือจักรภพ และตลาดเยน (JPY): τ(d1,d2)=d2−d1365\tau(d_1, d_2) = \frac{d_2 - d_1}{365}

4. ตระกูล 30/360 (US & Eurobond)

กำหนดให้ทุกเดือนมี 30 วัน และหนึ่งปีมี 360 วัน:

Days=360(Y2−Y1)+30(M2−M1)+(D2−D1)\text{Days} = 360(Y_2 - Y_1) + 30(M_2 - M_1) + (D_2 - D_1)

  • 30/360 US (Bond Basis): ปรับวัน D1D_1 และ D2D_2 ตามกฎสิ้นเดือนและกฎเดือนกุมภาพันธ์
  • 30E/360 (Eurobond Basis): หาก D1=31⇒D1=30D_1 = 31 \Rightarrow D_1 = 30 และหาก D2=31⇒D2=30D_2 = 31 \Rightarrow D_2 = 30

5. Business/252

ใช้เป็นหลักในตลาดตราสารหนี้ของบราซิลและละตินอเมริกา:

τ(d1,d2)=BusinessDays(d1,d2,Calendar)252\tau(d_1, d_2) = \frac{\text{BusinessDays}(d_1, d_2, \text{Calendar})}{252}


ตัวอย่างโค้ดในภาษา Rust

use sabiquant::core::Date;
use sabiquant::core::daycount::{
DayCounter, ActualActualICMA, ActualActualISDA, Actual360, Actual365Fixed, Thirty360US
};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let d1 = Date::from_ymd(2024, 2, 1)?; // ปีอธิกสุรทิน (Leap year)
let d2 = Date::from_ymd(2024, 8, 1)?;
let act_360 = Actual360::default();
let act_365 = Actual365Fixed::default();
let thirty_360 = Thirty360US::default();
let isda = ActualActualISDA::default();
println!("Actual/360: {:.6}", act_360.year_fraction(d1, d2)?);
println!("Actual/365: {:.6}", act_365.year_fraction(d1, d2)?);
println!("30/360 US: {:.6}", thirty_360.year_fraction(d1, d2)?);
println!("Act/Act ISDA: {:.6}", isda.year_fraction(d1, d2)?);
Ok(())
}