aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--python/position.py57
-rw-r--r--sql/serenitasdb.sql11
2 files changed, 37 insertions, 31 deletions
diff --git a/python/position.py b/python/position.py
index 6be0f477..6f7c5e83 100644
--- a/python/position.py
+++ b/python/position.py
@@ -1,4 +1,5 @@
from serenitas.analytics.bbg_helpers import init_bbg_session, retrieve_data, BBG_IP
+from itertools import product
import datetime
import numpy as np
import pandas as pd
@@ -223,9 +224,11 @@ def insert_swaption_vol(data, conn, source, vol_type="N"):
def update_swaption_vol(
conn,
session,
- tenors=["A", "C", "F", "I"] + list(range(1, 11)) + [15, 20, 25, 30],
+ expiries=["A", "C", "F", "I"] + list(range(1, 11)) + [15, 20, 25, 30],
+ tenors=[1, 2, 3, 4, 5, 7, 10, 12, 15, 20, 25, 30],
+ start_from=datetime.date.today(),
*,
- sources=["BBIR", "CMPN", "ICPL"],
+ sources=("BBIR", "CMPN", "ICPL"),
vol_type="N",
):
"""
@@ -233,36 +236,28 @@ def update_swaption_vol(
----------
vol_type : one of 'N' or 'V' (normal or log-normal)
"""
- table_name = "swaption_normal_vol" if vol_type == "N" else "swaption_lognormal_vol"
- for source in ["BBIR", "CMPN", "ICPL"]:
- tickers = []
- for expiry in tenors:
- for tenor in tenors:
- tickers.append(f"USS{vol_type}{expiry:0>2}{tenor} {source} Curncy")
-
- data = retrieve_data(session, tickers, ["PX_YEST_CLOSE", "PX_CLOSE_DT"])
- for t in tenors[4:]:
- sql_str = (
- f'INSERT INTO {table_name}(date, "{t}y", source) '
- + "VALUES(%s, %s, %s) ON CONFLICT (date, source)"
- + f' DO UPDATE SET "{t}y" = excluded."{t}y", source = excluded.source'
- )
- r = []
- dates = []
- for expiry in tenors:
- ticker = f"USS{vol_type}{expiry:0>2}{t} {source} Curncy"
- if data[ticker]:
-
- r.append(data[ticker]["PX_YEST_CLOSE"])
- dates.append(data[ticker]["PX_CLOSE_DT"])
- else:
- r.append(None)
- dates.append(dates[-1])
- if dates.count(dates[0]) < len(dates):
- raise ValueError("Not all quotes are from the same date")
+ db_vol_type = "Normal" if vol_type == "N" else "LogNormal"
+ mappings = {"A": "1M", "C": "3M", "F": "6M", "I": "9M"}
+ for source in sources:
+ tickers = {
+ f"USS{vol_type}{e:0>2}{t} {source} Curncy": (e, t)
+ for e, t in product(expiries, tenors)
+ }
+ data = retrieve_data(session, tickers, ["PX_LAST"], start_date=start_from)
+ data = pd.concat(data, names=["ticker", "date"])
+ for date, df in data.groupby(level="date"):
with conn.cursor() as c:
- c.execute(sql_str, (dates[0], r, source))
- conn.commit()
+ for ticker, val in df.reset_index("date", drop=True).itertuples():
+ e, t = tickers[ticker]
+ tenor = f"{t}Y"
+ expiry = mappings.get(e, f"{e}Y")
+ c.execute(
+ "INSERT INTO swaption_vol VALUES (%s, %s, %s, %s, %s, %s)"
+ " ON CONFLICT (date, expiry, tenor, vol_type, source) "
+ "DO UPDATE SET vol=EXCLUDED.vol",
+ (date, expiry, tenor, db_vol_type, source, val),
+ )
+ conn.commit()
def update_swap_rates(
diff --git a/sql/serenitasdb.sql b/sql/serenitasdb.sql
index 01b9ad9b..ac509a9b 100644
--- a/sql/serenitasdb.sql
+++ b/sql/serenitasdb.sql
@@ -278,6 +278,7 @@ CREATE TYPE bbgSource AS ENUM('MSG1', 'CBIN', 'CBGN', 'MKIT', 'CMAN', 'SRNTAS');
CREATE TYPE DocClause AS ENUM('No Restructuring', 'Modified Modified Restructurin', 'Full Restructuring', 'Modified Restructuring');
CREATE TYPE ShortCode AS ENUM('CR14', 'XR14', 'MM14');
CREATE TYPE tenor AS ENUM('6mo', '1yr', '2yr', '3yr', '4yr', '5yr', '7yr', '10yr');
+CREATE TYPE TENOR AS ENUM('1M', '3M', '6M', '9M', '1Y', '2Y', '3Y', '4Y', '5Y', '6Y', '7Y', '8Y', '9Y', '10Y', '12Y', '15Y', '20Y', '25Y', '30Y');
CREATE TYPE index_type AS ENUM('IG', 'HY', 'EU', 'LCDX', 'XO', 'BS', 'HY.BB');
CREATE TYPE BBG_CC AS ENUM('OC');
@@ -999,6 +1000,7 @@ CREATE TABLE USD_swap_fixings(
);
CREATE TYPE VOL_SOURCE AS ENUM('BVOL', 'CMPN', 'BBIR', 'GFIS');
+CREATE TYPE "VOL_TYPE" AS ENUM('Normal', 'LogNormal');
CREATE TABLE swaption_normal_vol(
date date,
@@ -1038,6 +1040,15 @@ CREATE TABLE swaption_lognormal_vol(
source VOL_SOURCE,
PRIMARY KEY(date, source));
+CREATE TABLE swaption_vol(
+ date date,
+ expiry "TENOR",
+ tenor "TENOR",
+ vol_type "VOL_TYPE",
+ source vol_source,
+ vol double precision,
+PRIMARY KEY (date, expiry, tenor, vol_type, source));
+
CREATE TABLE swaption_quotes(
quote_id SERIAL PRIMARY KEY,
ref_id integer REFERENCES swaption_ref_quotes ON DELETE CASCADE,