aboutsummaryrefslogtreecommitdiffstats
path: root/python/risk
diff options
context:
space:
mode:
Diffstat (limited to 'python/risk')
-rw-r--r--python/risk/tranches.py34
1 files changed, 27 insertions, 7 deletions
diff --git a/python/risk/tranches.py b/python/risk/tranches.py
index e88b48ea..01c08951 100644
--- a/python/risk/tranches.py
+++ b/python/risk/tranches.py
@@ -1,3 +1,4 @@
+from pyisda.date import cds_accrued
from serenitas.analytics.api import Portfolio, DualCorrTranche
from serenitas.analytics.dates import prev_business_day
from serenitas.analytics.utils import get_fx
@@ -65,8 +66,11 @@ def insert_tranche_pnl_explain(portf, conn):
)
daily_trades = {rec.id: rec for rec in c}
c.execute(
- "SELECT dealid, termination_amount, termination_fee, currency::text "
- "FROM terminations WHERE deal_type='CDS' AND termination_date=%s",
+ "SELECT terminations.dealid, termination_amount, termination_fee, terminations.currency::text, "
+ "cds.notional * delta_alloc * (CASE WHEN cds.protection='Buyer' THEN -1.0 ELSE 1.0 END) AS notional, "
+ "cds.upfront * delta_alloc AS delta_upfront "
+ "FROM terminations LEFT JOIN cds ON cds.id=terminations.delta_id "
+ "WHERE deal_type='CDS' AND termination_date=%s",
(value_date,),
)
terminations = {int(rec.dealid.removeprefix("SCCDS")): rec for rec in c}
@@ -90,7 +94,20 @@ def insert_tranche_pnl_explain(portf, conn):
if trade_id not in current_trades:
previous_risk = prev_day_risk[trade_id]
pnl = pnl - (previous_risk.clean_nav + previous_risk.accrued)
- delta_pnl = 0 # FIXME
+ dirty_index_pv = (
+ 1
+ - previous_risk.index_refprice * 0.01
+ - cds_accrued(prev_day, previous_risk.running * 1e-4)
+ )
+ if (
+ term.delta_upfront
+ ): # if None means either no delta or we didn't populate
+ delta_pnl = (
+ term.delta_upfront
+ - term.notional * dirty_index_pv * previous_risk.index_factor
+ )
+ else:
+ delta_pnl = 0.0
else:
trade = current_trades[trade_id]
if trade_id in prev_day_risk:
@@ -118,10 +135,13 @@ def insert_tranche_pnl_explain(portf, conn):
fx_pnl = 0.0
day_trade = daily_trades[trade_id]
dirty_index_pv = float(trade._index.pv() - trade._index.accrued())
- delta_pnl = (
- day_trade.notional * dirty_index_pv * trade._index.factor
- - day_trade.delta_upfront
- )
+ if day_trade.notional:
+ delta_pnl = (
+ day_trade.notional * dirty_index_pv * trade._index.factor
+ - day_trade.delta_upfront
+ )
+ else: # if None means either no delta or we didn't populate
+ delta_pnl = 0
pnl += trade.pv * get_fx(value_date, trade.currency)
unexplained = pnl - delta_pnl - fx_pnl
to_insert.append(