FX & Loan Trades
A summary of the load process for fx and loan trades.
Step 1
Load trades from Calypso.
Criteria: Has had activity in the last 5 days and Products matching:
Loan Trades
‘SimpleMM’, ‘Cash’, ‘CallNotice’, ‘Bond’, ‘CapFloor’,’Swap’
FX Trades
‘FX’, ‘FXSwap’, ‘FXOption’, ‘FXOptionForward’, ‘FXForward’, ‘FXTakeUp’
Loan Trades
SELECT
distinct cast(tr.trade_id as numeric) as trade_id,
case
when tr.bundle_id = 0 then null
else cast(tr.bundle_id as numeric)
end as bundle_id,
cast(od.desk_id as numeric) as desk_id,
cast(tr.book_id as numeric) as book_id,
cast(tr.product_id as numeric) as product_id,
cast(tr.cpty_id as numeric) as cpty_id,
pd.product_type,
tr.trade_date_time,
tr.trade_currency as trade_ccy,
case
pd.product_type
when 'SimpleMM' then smm.principal_amount
when 'Cash' then cas.principal_amount
when 'CallNotice' then cno.principal_amount
when 'CapFloor' then cf.principal_amount
when 'Bond' then pb.total_issued
end as principal_amt,
tr.trade_price,
tr.neg_price_type as final_price_type,
tr.neg_trade_price as final_price,
tr.trade_status,
tr.settlement_date as settle_date,
tr.entered_user,
str_replace(rtrim(tr.external_reference), '', null) as external_ref,
coalesce(kos.strategy, kdp.deposit_product) as strategy,
hr.hedge_relationship_id as hedge_id,
hr.name as hedge_name,
case
when ht.hedge_relationship_id is not null then case
when pd.product_type in ('SimpleMM', 'Cash', 'CallNotice') then 'Hedged'
when pd.product_type = 'Swap' then 'Hedging'
end
end hedge_type,
convert(
datetime,
convert(varchar(10), hr.effective_from, 103),
103
) as hedge_effective_from,
convert(
datetime,
convert(varchar(10), hr.effective_to, 103),
103
) as hedge_effective_to,
convert(datetime, ea.attr_value, 103) as retro_date
FROM
calypso.trade tr
INNER JOIN calypso.product_desc pd ON tr.product_id = pd.product_id
LEFT JOIN calypso.product_simple_mm smm ON tr.product_id = smm.product_id
LEFT JOIN calypso.product_call_not cno ON pd.product_id = cno.product_id
LEFT JOIN calypso.product_cash cas ON pd.product_id = cas.product_id
LEFT JOIN calypso.product_bond pb ON pd.product_id = pb.product_id
LEFT JOIN calypso.product_cap_floor cf ON pd.product_id = cf.product_id
LEFT JOIN calypso.hedge_relationship_trade ht ON tr.trade_id = ht.trade_id
LEFT JOIN calypso.hedge_relationship hr ON ht.hedge_relationship_id = hr.hedge_relationship_id
LEFT JOIN calypso.entity_attributes ea ON hr.hedge_relationship_id = ea.entity_id
AND ea.attr_name = 'Retro_Start (dd/mm/yyyy)'
LEFT JOIN (
SELECT
book_id,
cast(attribute_value as numeric) as desk_id
FROM
calypso.book_attr_value
WHERE
attribute_name = 'BusinessUnit'
) od ON tr.book_id = od.book_id
LEFT JOIN (
SELECT
trade_id,
keyword_value as strategy
FROM
calypso.trade_keyword
WHERE
keyword_name = 'FXOption_Strategy'
) kos ON tr.trade_id = kos.trade_id
LEFT JOIN (
SELECT
trade_id,
keyword_value as deposit_product
FROM
calypso.trade_keyword
WHERE
keyword_name = 'Deposit_Product'
) kdp ON tr.trade_id = kdp.trade_id
WHERE
pd.product_type in (
'SimpleMM',
'Cash',
'CallNotice',
'Bond',
'CapFloor',
'Swap'
)
and tr.trade_id in (
SELECT
distinct entity_id
FROM
calypso.bo_audit
WHERE
entity_class_name = 'Trade'
FX Trades
SELECT
distinct cast(tr.trade_id as numeric) as trade_id,
case
when tr.bundle_id = 0 then null
else cast(tr.bundle_id as numeric)
end as bundle_id,
cast(od.desk_id as numeric) as desk_id,
cast(tr.book_id as numeric) as book_id,
cast(tr.product_id as numeric) as product_id,
cast(tr.cpty_id as numeric) as cpty_id,
case
when pd.product_type = 'FX' then 'FXSpot'
else pd.product_type
end as product_type,
tr.trade_date_time,
tr.trade_currency as trade_ccy,
case
fo.option_side
when 'BUY' then 'Buy'
when 'SELL' then 'Sell'
end as principal_dir,
case
when pd.product_sub_type <> 'DIGITAL' then tr.quantity
end as principal_amt,
case
fo.option_side
when 'BUY' then 'Sell'
when 'SELL' then 'Buy'
end as quoting_dir,
case
when pd.product_type = 'FXOption' then case
when pd.product_sub_type <> 'DIGITAL' then round(tr.quantity * fo.option_strike, 2)
end
else tr.accrual
end as quoting_amt,
tr.trade_price,
tr.neg_price_type as final_price_type,
tr.neg_trade_price as final_price,
pm.trade_premium_ccy,
pm.trade_premium_amt,
tr.trade_status,
tr.settlement_date as settle_date,
tr.entered_user,
str_replace(rtrim(tr.external_reference), '', null) as external_ref,
tr.comments as trade_comment,
coalesce(om.off_mkt_rate_y, 'N') as off_mkt_rate_yn,
coalesce(im.imkt_y, 'N') as imkt_yn,
kos.strategy
FROM
calypso.trade tr
INNER JOIN calypso.product_desc pd ON tr.product_id = pd.product_id
LEFT JOIN calypso.product_fx_option fo ON tr.product_id = fo.product_id
LEFT JOIN (
SELECT
book_id,
cast(attribute_value as numeric) as desk_id
FROM
calypso.book_attr_value
WHERE
attribute_name = 'BusinessUnit'
) od ON tr.book_id = od.book_id
LEFT JOIN (
SELECT
trade_id,
'Y' as imkt_y
FROM
calypso.trade_keyword
WHERE
keyword_value = 'IMKT'
) im ON tr.trade_id = im.trade_id
LEFT JOIN (
SELECT
trade_id,
'Y' as off_mkt_rate_y
FROM
calypso.trade_keyword
WHERE
rtrim(keyword_name) = 'Off_Market_Rate'
) om ON tr.trade_id = om.trade_id
LEFT JOIN (
SELECT
trade_id,
keyword_value as strategy
FROM
calypso.trade_keyword
WHERE
keyword_name = 'FXOption_Strategy'
) kos ON tr.trade_id = kos.trade_id
LEFT JOIN (
SELECT
trade_id,
currency_code as trade_premium_ccy,
sum(amount) as trade_premium_amt
FROM
calypso.trade_fee
WHERE
fee_type = 'PREMIUM'
GROUP BY
trade_id,
currency_code
) pm ON tr.trade_id = pm.trade_id
WHERE
pd.product_type in (
'FX',
'FXSwap',
'FXOption',
'FXOptionForward',
'FXForward',
'FXTakeUp'
)
and tr.trade_id in (
SELECT
distinct entity_id
FROM
calypso.bo_audit
WHERE
entity_class_name = 'Trade'
AND convert(datetime, convert(varchar(10), modif_date, 103), 103) >= convert(
datetime,
convert(varchar(10), dateadd(day, -5, getdate()), 103),
103
)
)
Step 2
Load all trades to a temporary table and replace the trade date time with that of the non-exercised trade leg if it is earlier.
Load trades into temporary table and adjust trade date
CREATE TABLE #tmp_adj_trade_date
(
trade_id numeric(20) NOT NULL,
product_id numeric(20) NULL,
desk_id numeric(20) NULL,
product_type varchar(32) NULL,
principal_amt float NULL,
quoting_amt float NULL,
trade_date_adj datetime NULL
)
INSERT INTO
#tmp_adj_trade_date
(
trade_id,
product_id,
desk_id,
product_type,
principal_amt,
quoting_amt,
trade_date_adj
)
SELECT
tr.trade_id,
tr.product_id,
tr.desk_id,
tr.product_type,
tr.principal_amt,
tr.quoting_amt,
min(
case
when tr.trade_date_time < coalesce(ltr.trade_date_time, getdate()) then tr.trade_date_time
else ltr.trade_date_time
end
) as trade_date_adj
FROM
dbo.stage_calypso_trades tr
INNER JOIN dbo.dw_control_desks_included_in_dw cd ON tr.desk_id = cd.desk_id
LEFT JOIN dbo.dw_trade_legs tl ON tr.trade_id = tl.trade_id
AND tr.desk_id = tl.trade_desk_id
LEFT JOIN dbo.vw_stage_load_trade_legs_trades ltr ON tl.leg_trade_id = ltr.trade_id
AND tl.leg_trade_desk_id = ltr.desk_id
AND ltr.trade_status <> 'EXERCISED'
GROUP BY
tr.trade_id,
tr.product_id,
tr.desk_id,
tr.product_type,
tr.principal_amt,
tr.quoting_amt
create index idx_tmp_adj_trade_date_ids on #tmp_adj_trade_date (trade_id, desk_id)
create index idx_tmp_adj_trade_date_prod_id on #tmp_adj_trade_date (product_id)
create index idx_tmp_adj_trade_date_prod_typ on #tmp_adj_trade_date (product_type)
Step 3
Calculate the profit and loss for each trade.
FXOption, FXForward, FXSpot, FXSwap, FXTakeUp, SimpleMM, Cash:
P&L amount from Calypso converted to GBP.
FXOptionForward:
Principal amount converted to GBP + Quoting amount converted to GBP.
Calculate the profit and loss amounts
-- P&L calculation for FX and Cash
CREATE TABLE #tmp_pnl_amts
(
trade_id numeric(20) NOT NULL,
desk_id numeric(20) NULL,
pnl_component_ccy char(3) NULL,
pnl_component_amt float NULL,
pnl_component_amt_gbp float NULL
)
INSERT INTO
#tmp_pnl_amts
(
trade_id,
desk_id,
pnl_component_ccy,
pnl_component_amt,
pnl_component_amt_gbp
)
SELECT
pc.trade_id,
st.desk_id,
null as pnl_component_ccy,
null as pnl_component_amt,
round(
sum(
pnl_component_amt * dbo.fnc_get_fx_rate(pc.pnl_component_ccy, 'GBP', st.trade_date_adj)
),
2
) as pnl_component_amt_gbp
FROM
dbo.stage_calypso_trade_pnl_component pc
INNER JOIN #tmp_adj_trade_date st ON pc.trade_id=st.trade_id
WHERE
st.product_type in (
'FXForward',
'FXSpot',
'FXSwap',
'FXTakeUp',
'SimpleMM',
'Cash'
)
GROUP BY
pc.trade_id,
st.desk_id create index idx_tmp_pnl_amts_ids on #tmp_pnl_amts (trade_id, desk_id)
UNION
SELECT
tr.trade_id,
tr.desk_id,
null as pnl_component_ccy,
null as pnl_component_amt,
sum(
round(
(
dbo.fnc_get_fx_rate(
pd.principal_ccy,
'GBP',
tr.trade_date_adj
) * tr.principal_amt
) + (
dbo.fnc_get_fx_rate(
pd.quoting_ccy,
'GBP',
tr.trade_date_adj
) * tr.quoting_amt
),
2
)
) as pnl_component_amt_gbp
FROM
#tmp_adj_trade_date tr
INNER JOIN dbo.stage_calypso_trade_products pd ON tr.product_id = pd.product_id
WHERE
tr.product_type = 'FXOptionForward'
GROUP BY
tr.trade_id,
tr.desk_id
Step 4
Load the main trades table
Load the main trade table from staging with adjusted trade date and profit and loss.
INSERT INTO
dbo.dw_trades (
trade_id,
bundle_id,
desk_id,
book_id,
product_id,
cpty_id,
cpty_ext_yn,
product_type,
product_sub_type,
trade_date_time,
trade_ccy,
trade_ccy_tr_date_gbp_fxrate,
has_exercised_option_yn,
option_side,
principal_dir,
principal_ccy,
principal_amt,
prin_ccy_tr_date_gbp_fxrate,
quoting_dir,
quoting_ccy,
quoting_amt,
quot_ccy_tr_date_gbp_fxrate,
trade_price,
final_price_type,
final_price,
trade_premium_ccy,
trade_premium_amt,
trade_status,
settle_date,
entered_user,
external_ref,
trade_comment,
off_mkt_rate_yn,
imkt_yn,
strategy,
hedge_id,
hedge_name,
hedge_type,
hedge_effective_from,
hedge_effective_to,
retro_date,
pro_user,
pnl_component_ccy,
pnl_component_amt,
pnl_component_amt_gbp,
pnl_comp_ccy_tr_date_gbp_fxrate,
excl_from_rep_yn
)
SELECT
tr.trade_id,
tr.bundle_id,
tr.desk_id,
tr.book_id,
tr.product_id,
tr.cpty_id,
c.cpty_ext_yn,
tr.product_type,
pd.product_sub_type,
tr.trade_date_time,
tr.trade_ccy,
dbo.fnc_get_fx_rate(trade_ccy, 'GBP', ta.trade_date_adj) as trade_ccy_tr_date_gbp_fxrate,
coalesce(ex_opt.has_ex_option_yn, 'N') as has_exercised_option_yn,
pd.option_side,
case
when tr.product_type = 'FXOption' then pd.option_type
when tr.product_type in (
'SimpleMM',
'Cash',
'CallNotice',
'Bond',
'CapFloor'
) then tr.principal_dir
when tr.product_type not in ('SimpleMM', 'Cash', 'CallNotice', 'Bond')
AND pd.ccy_pair_dir_positive_yn = 'Y' then tr.principal_dir
else tr.quoting_dir
end as principal_dir,
case
when tr.product_type in (
'SimpleMM',
'Cash',
'CallNotice',
'Bond',
'CapFloor'
) then pd.principal_ccy
when tr.product_type not in ('SimpleMM', 'Cash', 'CallNotice', 'Bond')
AND pd.ccy_pair_dir_positive_yn = 'Y' then pd.principal_ccy
else pd.quoting_ccy
end as principal_ccy,
case
when tr.product_type in (
'SimpleMM',
'Cash',
'CallNotice',
'Bond',
'CapFloor'
) then tr.principal_amt
when tr.product_type not in (
'SimpleMM',
'Cash',
'CallNotice',
'Bond',
'CapFloor'
)
AND pd.ccy_pair_dir_positive_yn = 'Y' then tr.principal_amt
else tr.quoting_amt
end as principal_amt,
case
when pd.product_sub_type <> 'DIGITAL' then dbo.fnc_get_fx_rate(
case
when tr.product_type in ('SimpleMM', 'Cash', 'CallNotice', 'Bond') then pd.principal_ccy
when tr.product_type not in ('SimpleMM', 'Cash', 'CallNotice')
AND pd.ccy_pair_dir_positive_yn = 'Y' then pd.principal_ccy
else pd.quoting_ccy
end,
'GBP',
ta.trade_date_adj
)
end as prin_ccy_tr_date_gbp_fxrate,
case
when tr.product_type = 'FXOption' then case
pd.option_type
when 'Put' then 'Call'
when 'Call' then 'Put'
end
when tr.product_type in (
'SimpleMM',
'Cash',
'CallNotice',
'Bond',
'CapFloor'
) then null
when tr.product_type not in (
'SimpleMM',
'Cash',
'CallNotice',
'Bond',
'CapFloor'
)
AND pd.ccy_pair_dir_positive_yn = 'Y' then tr.quoting_dir
else tr.principal_dir
end as quoting_dir,
case
when tr.product_type in (
'SimpleMM',
'Cash',
'CallNotice',
'Bond',
'CapFloor'
) then null
when tr.product_type not in (
'SimpleMM',
'Cash',
'CallNotice',
'Bond',
'CapFloor'
)
AND pd.ccy_pair_dir_positive_yn = 'Y' then pd.quoting_ccy
else pd.principal_ccy
end as quoting_ccy,
case
when tr.product_type in (
'SimpleMM',
'Cash',
'CallNotice',
'Bond',
'CapFloor'
) then null
when tr.product_type not in (
'SimpleMM',
'Cash',
'CallNotice',
'Bond',
'CapFloor'
)
AND pd.ccy_pair_dir_positive_yn = 'Y' then tr.quoting_amt
else tr.principal_amt
end as quoting_amt,
case
when pd.product_sub_type <> 'DIGITAL' then dbo.fnc_get_fx_rate(
case
when tr.product_type in ('SimpleMM', 'Cash', 'CallNotice', 'Bond') then null
when tr.product_type not in ('SimpleMM', 'Cash', 'CallNotice', 'Bond')
AND pd.ccy_pair_dir_positive_yn = 'Y' then pd.quoting_ccy
else pd.principal_ccy
end,
'GBP',
ta.trade_date_adj
)
end as quot_ccy_tr_date_gbp_fxrate,
case
when tr.product_type in (
'SimpleMM',
'Cash',
'CallNotice',
'Bond',
'CapFloor'
) then null
else tr.trade_price
end as trade_price,
case
when tr.product_type in (
'SimpleMM',
'Cash',
'CallNotice',
'Bond',
'CapFloor'
) then null
else tr.final_price_type
end as final_price_type,
case
when tr.product_type in (
'SimpleMM',
'Cash',
'CallNotice',
'Bond',
'CapFloor'
) then null
else tr.final_price
end as final_price,
trade_premium_ccy,
abs(trade_premium_amt) as trade_premium_amt,
tr.trade_status,
tr.settle_date,
tr.entered_user,
tr.external_ref,
case
when len(rtrim(tr.trade_comment)) = 0 then null
else tr.trade_comment
end as trade_comment,
tr.off_mkt_rate_yn,
tr.imkt_yn,
tr.strategy,
tr.hedge_id,
tr.hedge_name,
tr.hedge_type,
tr.hedge_effective_from,
tr.hedge_effective_to,
tr.retro_date,
rtrim(c.pro_user) as pro_user,
pa.pnl_component_ccy,
pa.pnl_component_amt,
case
when tr.product_type <> 'FXTakeup' then pa.pnl_component_amt_gbp
end as pnl_component_amt_gbp,
case
when pa.pnl_component_ccy is not null then dbo.fnc_get_fx_rate(pa.pnl_component_ccy, 'GBP', ta.trade_date_adj)
end as pnl_comp_ccy_tr_date_gbp_fxrate,
'N' as excl_from_rep_yn
FROM
dbo.stage_calypso_trades tr
INNER JOIN dbo.stage_calypso_trade_products pd ON tr.product_id = pd.product_id
INNER JOIN dbo.dw_control_desks_included_in_dw d ON tr.desk_id = d.desk_id
LEFT JOIN dbo.stage_counterparties c ON cast(tr.cpty_id as char) = c.cpty_id
AND c.system_name = 'calypso'
LEFT JOIN #tmp_adj_trade_date ta ON tr.trade_id=ta.trade_id
LEFT JOIN #tmp_pnl_amts pa ON tr.trade_id=pa.trade_id AND tr.desk_id=pa.desk_id
LEFT JOIN (
select
distinct trade_id,
'Y' as has_ex_option_yn
FROM
dbo.dw_trade_legs_pivot
WHERE
xopt_trade_id is not null
GROUP BY
trade_id
) ex_opt ON tr.trade_id = ex_opt.trade_id