Strasmore Research
학습 Matt Connor작성자 Matt Connor · data as of August 12, 2026 · refreshed weekly

Rust 기반 QuantLib 포트 libitofin 분석

Rust로 포팅된 QuantLib인 libitofin의 특징과 itofin을 통한 파이썬 연동을 설명합니다. 스프레드시트와 차별화되는 가격 결정 라이브러리의 구조적 장점과 1.0 버전 이전 프로젝트를 실무에 도입할 때 고려해야 할 태그된 릴리스의 중요성을 다룹니다.

libitofin은 Rust로 구현된 QuantLib입니다. 이는 2000년대 초반부터 파생상품 가격 결정의 오픈소스 표준으로 자리 잡은 C++ 라이브러리인 QuantLib을 Rust로 포팅한 것이며, 그 위에 itofin이라는 파이썬 패키지를 얹은 형태입니다. 2026년 8월 기준, 이 프로젝트는 스스로를 1.0 버전 이전(pre-1.0)으로 정의하고 있으며, 이 라벨은 해당 라이브러리 사용과 관련된 모든 실무적 측면에 영향을 미칩니다. 가격 결정 라이브러리는 공식 주변을 감싸는 기계적 장치(machinery)를 통해 그 가치를 증명하며, 이러한 장치를 구축하는 작업은 어떤 언어에서든 동일한 난이도를 가집니다.

스프레드시트 공식이 제공하지 못하는 가격 결정 라이브러리의 기능

스프레드시트의 블랙-숄즈(Black-Scholes) 셀은 5개의 입력을 받아 가격을 반환합니다. 공식 자체는 쉬운 부분에 불과합니다. 그 주변을 감싸는 네 가지 계층이 존재하며, 이 계층들이 곧 라이브러리의 본질입니다.

기간 구조(Term structures). 할인율은 만기별 곡선이며, 실제 시장에서 호가되는 지점 사이의 간극을 메우기 위한 보간법(interpolation) 규칙을 포함합니다. 아래 패널은 원재료인 특정 날짜의 국채 만기별 호가를 보여줍니다.

조회최근 고시일 기준 국채 수익률 곡선
모든 수치 뒤에 숨겨진 정확한 SQL
SELECT
    arrayElement(tenors, i)                  AS tenor,
    round(arrayElement(rates, i), 2)         AS yield_pct,
    formatDateTime(curve_date, '%b %e, %Y')  AS as_of
FROM
(
    SELECT
        date AS curve_date,
        ['1 month', '3 months', '6 months', '1 year', '2 years', '3 years',
         '5 years', '7 years', '10 years', '20 years', '30 years']         AS tenors,
        [toFloat64(yield_1_month), toFloat64(yield_3_month), toFloat64(yield_6_month),
         toFloat64(yield_1_year),  toFloat64(yield_2_year),  toFloat64(yield_3_year),
         toFloat64(yield_5_year),  toFloat64(yield_7_year),  toFloat64(yield_10_year),
         toFloat64(yield_20_year), toFloat64(yield_30_year)]                AS rates,
        arrayJoin(range(1, 12))                                            AS i
    FROM global_markets.treasury_yields
    WHERE date = (SELECT max(date) FROM global_markets.treasury_yields)
)
WHERE yield_pct > 0
ORDER BY i
Run this yourself

Aug 10, 2026 기준, 호가 곡선은 7개의 만기를 포함하며, 3.79%에서 1 month까지, 그리고 5.25%에서 30 years까지 이어집니다. 스프레드시트는 이를 조회(lookup)와 4%라는 고정값으로 처리합니다. 반면 라이브러리는 모든 상품이 가격을 산출하는 기준이 되는 곡선 객체를 사용합니다. 여기에는 명시된 보간법(제로 금리 선형 보간, 할인 계수 로그-선형 보간, 단조 스플라인 등)과 마지막 지점 이후에 대한 명시된 외삽법(extrapolation) 정책이 적용됩니다. 이 객체를 1bp(basis point)만 이동시켜도 장부상의 모든 민감도(sensitivity)가 일관되게 조정됩니다.

날짜 계산 관행(Day-count conventions). 이자는 1년 중 일정 기간에 대해 발생하며, 그 기간을 정의하는 방식은 해당 상품에 부착된 관행에 따릅니다. Actual/360은 경과 일수를 360으로 나누고, Actual/365는 365로 나눕니다. 30/360 방식은 모든 달을 30일로 가정합니다. Business/252는 252일 영업일 기준 연간 거래 세션을 계산하며, 이를 위해서는 휴일이 포함된 실제 거래소 달력(exchange calendar)이 필요합니다. 예를 들어 100만 달러를 5% 금리로 90일간 빌렸을 때, Actual/360은 12,500달러의 이자를 발생시키지만 Actual/365는 동일한 거래에 대해 12,329달러를 발생시킵니다. 아래 패널은 왜 영업일 기준 계산에 제수(divisor)가 아닌 달력이 필요한지 보여줍니다.

조회월별 달력 일수 대비 거래일 수
모든 수치 뒤에 숨겨진 정확한 SQL
SELECT
    formatDateTime(toStartOfMonth(date), '%Y-%m')      AS month,
    countDistinct(date)                                AS trading_days,
    toUInt8(toDayOfMonth(toLastDayOfMonth(max(date)))) AS calendar_days
FROM global_markets.stocks_daily_aggs
WHERE ticker = 'SPY'
  AND date >= toStartOfMonth(today() - 365)
  AND date <  toStartOfMonth(today())
GROUP BY month
ORDER BY month
Run this yourself

관찰된 12개월 동안, 2026-0731일의 달력 일수 대비 22회의 세션을 기록했습니다. 산술 규칙만으로는 첫 번째 숫자를 도출할 수 없습니다. 이는 휴일 달력에서 비롯되며, 매달 결과가 다릅니다. 라이브러리는 국가별, 거래소별 달력을 제공하지만, 스프레드시트는 사용자가 직접 이를 유지 관리해야 합니다.

보정(Calibration) 기계 장치. 모델 파라미터는 어디에도 호가되지 않습니다. 사용자는 전체 호가 표면(surface)에 걸쳐 관측된 시장 가격에 모델 가격을 맞춤으로써 파라미터를 선택하고, 표면이 움직일 때마다 다시 맞춥니다. 이는 제한된 최소제곱 문제(bounded least-squares problem)이며, 라이브러리는 이를 위한 루프를 제공합니다. 레벤버그-마쿼트(Levenberg-Marquardt) 최적화 알고리즘, 강제 제약 없이 분산을 양수로 유지하는 파라미터 변환, 호가 집합에 대한 비용 함수, 그리고 단순히 시작 값을 반환하는 대신 실패를 명확히 알리는 수렴 기준 등이 포함됩니다.

수치 해석 계층. 모든 것의 밑바닥에는 선형 대수와 적분이 자리 잡고 있습니다. QR 및 SVD 분해는 피팅 과정에서 발생하는 시스템을 해결하고, 구적법(quadrature)과 푸리에 적분은 공식이 적분 형태인 모델의 가격을 산출하며, 근 찾기(root finder) 알고리즘은 내재 변동성(implied volatility)을 역산합니다. 이 계층은 지루하지만, 바로 이 계층이 잘못 구현되기 쉽습니다. 전형적인 예로 유동성이 높은 등가격(at-the-money) 호가에서는 수렴하지만 외가격(out-of-the-money) 호가에서는 발산하는 직접 만든 뉴턴 솔버(Newton solver)가 있습니다. 근사 특이 피팅(near-singular fit)에서 정밀도를 잃고 그럴듯해 보이는 파라미터를 반환하는 행렬 역연산도 흔한 실수입니다. 처음부터 개념 모델을 구축 중이라면, 라이브러리의 API 레퍼런스보다 오픈소스 퀀트 트레이딩 서적이 더 나은 출발점입니다.

libitofin이란 무엇이며, Rust 버전의 QuantLib인가?

중요한 의미에서 그렇습니다. 이 프로젝트는 QuantLib의 설계를 Rust로 포팅한 것이며, QuantLib 자체의 테스트 스위트를 통해 검증되었다고 명시하고 있습니다. 이것이 수치 해석 라이브러리를 포팅하는 정직한 방법입니다. 즉, 결과값이 정답일 것이라고 예상하는 것이 아니라 참조 구현체와 비교하여 검증하는 것입니다. 파이썬 경로로는 itofin이라는 패키지가 제공되므로, 파이썬 프로세스에서 C++ 툴체인 없이도 Rust 엔진에 접근할 수 있습니다.

더 중요한 라벨은 1.0 버전 이전이라는 점입니다. Rust의 버전 관리 관행에 따라 0.x 릴리스는 마이너 버전 간 호환성을 보장하지 않습니다. 0.4에서 0.5로 넘어갈 때 이름 변경, 이동, 삭제가 자유롭습니다. API를 움직이는 표적으로 간주하고 다음 습관을 들이는 것이 좋습니다.

  • 락파일(lockfile)에 정확한 태그가 지정된 릴리스를 고정하고, 자체 테스트 스위트를 관문으로 삼아 의도적으로 업그레이드하십시오.
  • 라이브러리 타입 주변에 얇은 래퍼(wrapper)를 유지하여, 이름 변경 시 40개의 파일이 아닌 한 곳만 수정하도록 하십시오.
  • 라이브러리 버전을 생성된 숫자 옆에 기록하여, 재실행 시 결과가 다를 경우 시장이 아닌 업그레이드 탓임을 알 수 있게 하십시오.
  • 생산 마진, 담보, 규제 리스크 수치는 1.0 버전이 나올 때까지 호환성을 보장하는 환경에서 관리하십시오.

이는 프로젝트에 대한 비판이 아닙니다. 1.0 버전 이전이라는 설명은 정확하며, 거대한 라이브러리를 포팅하는 초기 단계로서 적절한 위치입니다. 실패 사례는 독자가 이를 기존 QuantLib의 대체제로 생각하고 분기 중간에 변경된 시그니처를 마주하는 경우입니다. 설치 지침 또한 버전에 따라 변경되며, cargo와 pip 모두 네트워크 접근이 필요하므로 블로그 게시물에서 복사한 코드 조각보다는 의도한 태그의 README를 직접 읽으십시오.

파이썬, 컴파일된 엔진, 아니면 Rust?

두 가지 질문이 이를 결정하며, 취향과는 무관합니다. 초당 몇 번이나 재평가(reprice)를 수행하는지, 그리고 서로 다른 프로세스 간에 숫자가 일치해야 하는지 여부입니다. 체인 크기가 첫 번째 질문의 규모를 결정합니다.

조회일일 거래된 개별 옵션 계약 수
모든 수치 뒤에 숨겨진 정확한 SQL
WITH (SELECT max(date) FROM global_markets.options_greeks) AS last_session
SELECT
    underlying_symbol                      AS symbol,
    countDistinct(ticker)                  AS contracts_priced,
    formatDateTime(max(date), '%b %e, %Y') AS as_of
FROM global_markets.options_greeks
WHERE date = last_session
  AND underlying_symbol IN ('SPY', 'AAPL', 'NVDA', 'MSFT', 'KO')
  AND volume > 0
GROUP BY symbol
ORDER BY contracts_priced DESC
Run this yourself

Aug 11, 2026에, SPY은 단일 세션에서 5336개의 서로 다른 계약이 거래되었고, KO360개를 기록했습니다. 방대한 체인을 한 번 가격 결정하는 것은 아무것도 아닙니다. 모든 호가 업데이트 시마다, 기초자산 장부 전체에 걸쳐, 계약당 5개의 민감도를 계산하는 것은 제약 조건이 다른 완전히 다른 프로그램입니다.

루프가 분당 수천 건의 평가를 측정하고 주변 작업이 연구, 분석 또는 일일 마감가 산출이라면 기존 라이브러리를 사용하는 파이썬에 머무르십시오. QuantLib의 파이썬 바인딩은 성숙한 선택입니다. 동일한 C++ 엔진, 가장 넓은 상품 커버리지, 그리고 수년간의 실무 경험이 뒷받침됩니다. 연구 코드에서 속도는 거의 제약 조건이 아니며, 커버리지와 정확성이 중요합니다.

루프는 뜨겁지만 주변 코드는 그렇지 않다면 파이썬에서 컴파일된 엔진을 호출하십시오. 주의할 비용은 경계면 자체입니다. 파이썬에서 계약당 호출을 수행하면 호출마다 오버헤드가 발생하므로, 엔진에 배열을 전달하고 배열을 돌려받는 방식으로 해결해야 합니다. 이것이 itofin이 QuantLib-Python과 함께 지향하는 위치입니다.

가격 결정 루프 자체가 제품인 경우(호가 서비스 내의 프라이서, 놓칠 수 없는 일정의 리스크 실행, 파이썬이 없는 환경에 배포되는 바이너리 등)에는 Rust로 작성하십시오. 두 번째 질문도 여기에 해당합니다. 부동 소수점 결과는 연산 순서에 따라 달라지므로, 동일한 모델을 두 번 구현해도 마지막 자릿수에서 차이가 날 수 있습니다. 연구용 노트북과 운영 서비스의 결과가 다르면 일주일 내내 원인 분석을 해야 합니다. 양쪽에서 동일한 엔진을 사용하면 이러한 불일치 범주가 완전히 제거되며, 이것이 어떤 언어로 작성되었든 바인딩을 갖춘 컴파일된 코어를 사용해야 하는 강력한 논거입니다. 재현 가능한 백테스트가 보여주듯, 전략 작업에도 동일한 원칙이 적용됩니다.

보정 대상은 실제로 어디에 존재하는가

보정에는 맞출 대상이 필요하며, 그것은 시장 내재 변동성 표면(surface)입니다. 그중 근 찾기 측면은 내재 변동성 계산 방법에서 다룹니다. 아래 형태가 모델이 맞춰야 할 대상입니다.

조회만기별 AAPL 등가격(near-the-money) 내재 변동성
모든 수치 뒤에 숨겨진 정확한 SQL
SELECT
    multiIf(days_to_expiry <=   7, '0 to 7 days',
            days_to_expiry <=  30, '8 to 30 days',
            days_to_expiry <=  60, '31 to 60 days',
            days_to_expiry <= 120, '61 to 120 days',
            days_to_expiry <= 240, '121 to 240 days',
                                   '241 days or more') AS dte_bucket,
    round(avg(implied_volatility) * 100, 1)            AS iv_pct,
    countDistinct(ticker)                              AS contracts
FROM global_markets.options_greeks
WHERE underlying_symbol = 'AAPL'
  AND date >= today() - 10
  AND days_to_expiry >= 0
  AND iv_converged = 1
  AND volume > 0
  AND abs(toFloat64(strike_price) / toFloat64(underlying_close) - 1) < 0.05
GROUP BY dte_bucket
ORDER BY min(days_to_expiry)
Run this yourself

등가격 근처에서 0 to 7 days 버킷의 AAPL 계약은 관찰된 세션 동안 평균 29.6%의 내재 변동성을 보였고, 241 days or more에서는 29.3%을 기록했습니다. 하나의 변동성 파라미터만 가진 모델은 두 지점에 동시에 위치할 수 없으며, 이것이 변동성 기간 구조를 가진 모델이 존재하는 이유입니다. 이와 같은 표면에 모델을 맞추는 것이 보정 단계이며, 피팅된 모델에서 도출되는 민감도가 그리스(greeks)입니다. 이는 옵션 그리스 설명에서 다룹니다.

이 패널들이 구축된 방법

곡선 패널은 국채 시리즈에서 가장 최근의 호가 날짜를 읽어 11개의 만기 열을 행으로 펼치며, 해당 날짜에 호가가 없는 만기는 제외합니다. 세션 패널은 월별 SPY 테이프의 고유 날짜를 계산하며, 이는 전체 거래소 세션 수를 나타내는 깔끔한 지표입니다. 체인 패널은 가장 최근 세션에서 거래량이 0이 아닌 고유 계약 코드를 기초자산별로 그룹화하여 계산합니다. 변동성 패널은 수렴된 솔브(solve) 중 거래량이 0이 아니고 행사가격이 기초자산 종가의 5% 이내인 경우만 유지하며, 이는 표준 등가격 밴드입니다. 앞쪽 버킷에는 당일 만기 상품이 포함됩니다.

FAQ

libitofin은 QuantLib의 완벽한 대체제인가요?

아닙니다. 2026년 8월 기준, 이는 QuantLib의 일부를 다루고 QuantLib 자체 테스트 스위트로 결과를 검증하는 1.0 버전 이전의 포팅 버전입니다. 파이썬 바인딩을 통해 접근하는 QuantLib 자체가 운영 환경에서는 더 광범위하고 안정적인 선택지입니다.

가격 결정 라이브러리에서 1.0 버전 이전이란 무엇을 의미하나요?

Rust의 버전 관리 관행에 따라 0.x 릴리스는 호환성을 보장하지 않습니다. 다음 마이너 버전에서 무엇이든 이름이 바뀌거나 삭제될 수 있습니다. 실무적으로는 정확한 태그가 지정된 릴리스를 고정하고 업그레이드할 때마다 자체 테스트 스위트를 다시 실행해야 함을 의미합니다.

libitofin을 사용하려면 Rust를 작성해야 하나요?

아닙니다. 이 프로젝트는 itofin이라는 파이썬 패키지를 게시하므로, 일반적인 파이썬 프로세스에서 엔진을 호출할 수 있습니다. Rust 작성은 가격 결정 루프 자체가 배포하려는 제품일 때 중요해집니다.

스프레드시트 공식이 제공하지 못하는 가격 결정 라이브러리의 기능은 무엇인가요?

단일 금리가 아닌 곡선, 실제 거래소 달력이 뒷받침되는 날짜 계산 관행, 모델 파라미터를 호가에 맞추는 보정 루프, 그리고 이 모든 것의 밑바닥에 있는 검증된 수치 해석 계층입니다. 닫힌 형식(closed-form)의 공식은 전체 작업의 작은 부분일 뿐입니다.

프로그래밍 언어가 옵션 가격을 바꾸나요?

수학적으로는 그렇지 않습니다. 재현성에 영향을 미칩니다. 부동 소수점 결과는 연산 순서에 따라 달라지므로, 동일한 모델의 두 구현체가 마지막 자릿수에서 다를 수 있습니다. 연구와 운영 환경에서 동일한 엔진을 사용하면 이러한 격차가 제거됩니다.


여기에 있는 모든 패널은 그 아래에 정확한 SQL을 포함하고 있으므로, 하나를 확장하여 계산 방식을 확인하십시오. 동일한 곡선, 달력, 체인 관련 질문은 Strasmore 터미널에서 평이한 영어로 문의할 수 있습니다.