コード例 #1
0
        public override ResetStrikeOption GenerateInstrument()
        {
            var startDate        = TradeInfo.StartDate.ToDate();
            var calendar         = TradeInfo.Calendar.ToCalendarImpl();
            var strikefixingDate = TradeInfo.StrikeFixingDate.ToDate();

            TradeUtil.GenerateOptionDates(TradeInfo, out Date[] exerciseDates, out Date[] obsDates, out DayGap settlementGap);
コード例 #2
0
ファイル: XlManager.cs プロジェクト: stepinto163/Qdp
        public static Dictionary <string, PnLResultBase> DoPnLExplain(string[] tradeIds,
                                                                      PrebuiltQdpMarket t0Mkt,
                                                                      PrebuiltQdpMarket t1Mkt,
                                                                      PrebuiltQdpMarket t0MktDateRolledFwd,
                                                                      PrebuiltQdpMarket t0MktRolldownForBond,
                                                                      PrebuiltQdpMarket t0MktPriceNow    = null,
                                                                      PrebuiltQdpMarket t0MktPriceVolNow = null,
                                                                      PrebuiltQdpMarket t0MktVolNow      = null)
        {
            //TODO: add the following for more exotic product where rate/price interplay is more pronounced
            //resultRateNow,  resultPriceRateNow, resultVolRateNow, resultPriceVolRateNow

            var useRevalPnLFramework = (t0MktPriceNow != null && t0MktVolNow != null && t0MktPriceVolNow != null);
            //use reval for pnl attribution
            //PnL = PriceImpact + VolImpact + PriceVolCrossImpact + Unexplained

            var ret = new Dictionary <string, PnLResultBase>();

            var tMarketName  = t0Mkt.MarketName;
            var t1MarketName = t1Mkt.MarketName;

            var t0Vals = new Dictionary <string, IPricingResult>();
            var t0ValsRolledForward = new Dictionary <string, IPricingResult>();
            var t1Vals = new Dictionary <string, IPricingResult>();

            var t0ValsPriceNow         = new Dictionary <string, IPricingResult>();
            var t0RolldownPriceForBond = new Dictionary <string, IPricingResult>();
            var t0ValsVolNow           = new Dictionary <string, IPricingResult>();
            var t0ValsPriceVolNow      = new Dictionary <string, IPricingResult>();

            //use minimium price request to make it faster
            #region requests
            var pricingRequest =
                PricingRequest.Pv |
                PricingRequest.Cashflow |
                PricingRequest.DirtyPrice |
                PricingRequest.KeyRateDv01 |
                PricingRequest.DollarDuration |
                PricingRequest.DollarConvexity |
                PricingRequest.Delta |
                PricingRequest.Gamma |
                PricingRequest.Vega |
                PricingRequest.Theta |
                PricingRequest.Rho |
                PricingRequest.DVegaDvol | //one high order risk
                PricingRequest.ZeroSpread |
                PricingRequest.ZeroSpreadDelta |
                PricingRequest.AiEod |
                PricingRequest.Basis |
                PricingRequest.CheapestToDeliver |
                PricingRequest.Ytm |
                PricingRequest.UnderlyingPv |
                PricingRequest.Carry;
            #endregion requests

            foreach (var tradeId in tradeIds)
            {
                t0Vals[tradeId] = xl_ValueTrade(tradeId, t0Mkt, pricingRequest);
                var t1Request = PricingRequest.Pv | PricingRequest.DirtyPrice | PricingRequest.ZeroSpread | PricingRequest.AiEod
                                | PricingRequest.Ytm | PricingRequest.Basis | PricingRequest.Cashflow;
                t1Vals[tradeId] = xl_ValueTrade(tradeId, t1Mkt, t1Request);
                t0ValsRolledForward[tradeId] = xl_ValueTrade(tradeId, t0MktDateRolledFwd, PricingRequest.Pv | PricingRequest.DirtyPrice | PricingRequest.UnderlyingPv);

                //reval framework for better pnl attribution
                if (useRevalPnLFramework)
                {
                    t0ValsPriceNow[tradeId]         = xl_ValueTrade(tradeId, t0MktPriceNow, PricingRequest.Pv);
                    t0ValsVolNow[tradeId]           = xl_ValueTrade(tradeId, t0MktVolNow, PricingRequest.Pv);
                    t0ValsPriceVolNow[tradeId]      = xl_ValueTrade(tradeId, t0MktPriceVolNow, PricingRequest.Pv);
                    t0RolldownPriceForBond[tradeId] = xl_ValueTrade(tradeId, t0MktRolldownForBond, PricingRequest.Pv | PricingRequest.ZeroSpread);
                }
            }

            //For old interface:
            //var tCurves = GetXlMarket(tMarketName).MarketInfo.YieldCurveDefinitions.Select(x => x.Name)
            //            .Select(x => t0Mkt.GetData<CurveData>(x).YieldCurve).ToDictionary(x => x.Name, x => x);
            //var t1Curves = GetXlMarket(t1MarketName).MarketInfo.YieldCurveDefinitions.Select(x => x.Name)
            //    .Select(x => t1Mkt.GetData<CurveData>(x).YieldCurve).ToDictionary(x => x.Name, x => x);
            var tCurves  = t0Mkt.YieldCurves;
            var t1Curves = t1Mkt.YieldCurves;

            var curveMoveScaling = 1e4;

            foreach (var tradeId in tradeIds)
            {
                var t1cf = (t1Vals[tradeId].Cashflows != null) ?
                           t1Vals[tradeId].Cashflows.Where(x => x.PaymentDate <= t1Mkt.ReferenceDate && x.PaymentDate > t0Mkt.ReferenceDate).Sum(x => x.PaymentAmount) :
                           0.0;

                var tradeInfo = GetTrade(tradeId);
                if (tradeInfo is InterestRateSwapInfo || tradeInfo is BondInfoBase || tradeInfo is BondFuturesInfo)
                {
                    //PnL using bond discounted cash flows
                    //curve risk is between T0_{prime} and T1
                    var _tPv        = t0Vals[tradeId].Pv;
                    var _t1Pv       = t1Vals[tradeId].Pv;
                    var _tPvRecalib = t0ValsRolledForward[tradeId].Pv;
                    var curvePnL    = new Dictionary <string, CurveRisk[]>();

                    foreach (var curveRiskse in t0Vals[tradeId].KeyRateDv01)
                    {
                        var tCurve  = tCurves[curveRiskse.Key];
                        var t1Curve = t1Curves[curveRiskse.Key];

                        curvePnL[curveRiskse.Key] =
                            curveRiskse.Value.Select(x =>
                                                     new CurveRisk(
                                                         x.Tenor,
                                                         x.Risk * (t1Curve[x.Tenor] - tCurve[x.Tenor]) * curveMoveScaling
                                                         )).ToArray();
                    }

                    //include raw t1 curve risks in result
                    foreach (var curveRisks in t0Vals[tradeId].KeyRateDv01)
                    {
                        curvePnL[curveRisks.Key + "KeyRateDv01"] = curveRisks.Value;
                    }

                    var pnLCurve = new CommonPnLResult(_tPv, _t1Pv, _tPvRecalib - _tPv, t1cf, curvePnL);
                    ret[tradeId] = pnLCurve;
                }

                if (tradeInfo is InterestRateSwapInfo)
                {
                    var swap = tradeInfo as InterestRateSwapInfo;
                    //carry & roll down
                    var rollDown = t0ValsRolledForward[tradeId].Pv - t0Vals[tradeId].Pv;
                    var carry    = t0Vals[tradeId].Carry;
                    var pnlTime  = rollDown + carry;

                    var commonPnl = ret[tradeId];
                    var pnlPv01   =
                        ret.ContainsKey(tradeId) && ret[tradeId].YieldCurvePnL.Count > 0
                        ? ret[tradeId].YieldCurvePnL.First().Value.Sum(x => x.Risk)
                        : 0.0;
                    var pnl = new SwapPnLResult(commonPnl.TPv, commonPnl.T1Pv, pnlTime: pnlTime, t1Cf: t1cf, pnlPv01: pnlPv01,
                                                pnlCarry: carry, pnlRolldown: rollDown);

                    ret[tradeId + "durationConvexity"] = pnl;
                }

                if (tradeInfo is BondInfoBase)
                {
                    var bond       = tradeInfo as BondInfoBase;
                    var tPv        = t0Vals[tradeId].DirtyPrice;
                    var t1Pv       = t1Vals[tradeId].DirtyPrice;
                    var tPvRecalib = t0ValsRolledForward[tradeId].DirtyPrice;

                    //bond market PnL
                    var pnlPv01 =
                        ret.ContainsKey(tradeId) && ret[tradeId].YieldCurvePnL.Count > 0
                        ? ret[tradeId].YieldCurvePnL.First().Value.Sum(x => x.Risk)
                        : 0.0;

                    //bond specific pnl
                    var tZSpread      = t0Vals[tradeId].ZeroSpread;
                    var t1ZSpread     = t1Vals[tradeId].ZeroSpread;
                    var tZSpreadDelta = t0Vals[tradeId].ZeroSpreadDelta;
                    var zSpreadPnl    = tZSpreadDelta * (t1ZSpread - tZSpread) * curveMoveScaling;

                    var pnlCarry = t1Vals[tradeId].Ai - t0Vals[tradeId].Ai;
                    //bond roll down effect:  cashflow less, but benefit from still curve,  note that zspread also changes due to rolling down the curve
                    var pnlRolldown = t0RolldownPriceForBond[tradeId].Pv - t0Vals[tradeId].Pv +
                                      tZSpreadDelta * (t0RolldownPriceForBond[tradeId].ZeroSpread - tZSpread) * curveMoveScaling;

                    var pnlTime = pnlCarry + pnlRolldown;

                    //duration pnl is  not used in book level pnl explain
                    var pnlDuration  = t0Vals[tradeId].ModifiedDuration * (t1Vals[tradeId].Ytm - t0Vals[tradeId].Ytm) * bond.Notional;
                    var pnlConverixy = 0.5 * Math.Pow(t1Vals[tradeId].Ytm - t0Vals[tradeId].Ytm, 2.0) * t0Vals[tradeId].DollarConvexity / 100.0;

                    var explainedPriceImpact = pnlPv01 + zSpreadPnl + pnlConverixy + pnlTime;

                    var pnl = new BondPnLResult(tPv, t1Pv, pnlTime: pnlTime, t1Cf: t1cf, pnlPv01: pnlPv01, pnlZspread: zSpreadPnl, pnlCarry: pnlCarry, pnlRolldown: pnlRolldown,
                                                pnlDuration: pnlDuration, pnlConvexity: pnlConverixy);
                    ret[tradeId + "durationConvexity"] = pnl;
                }
                if (tradeInfo is BondFuturesInfo)
                {
                    var tPv  = t0Vals[tradeId].DirtyPrice;
                    var t1Pv = t1Vals[tradeId].DirtyPrice;

                    //curve pnl
                    var pnlPv01 =
                        ret.ContainsKey(tradeId) && ret[tradeId].YieldCurvePnL.Count > 0
                        ? ret[tradeId].YieldCurvePnL.First().Value.Sum(x => x.Risk)
                        : 0.0;

                    //zspread pnl from CTD, converted to future equivalen t
                    var zspreadT0  = t0Vals[tradeId].ZeroSpread;
                    var zspreadT1  = t1Vals[tradeId].ZeroSpread;
                    var zspreadPnl = (zspreadT1 - zspreadT0) * curveMoveScaling * t0Vals[tradeId].ZeroSpreadDelta;

                    //basis pnl from  CTD/cf - Future
                    var basisT0       = t0Vals[tradeId].Basis;
                    var basisT1       = t1Vals[tradeId].Basis;
                    var bondFut       = XlManager.GetTrade(tradeId) as BondFuturesInfo;
                    var futPosScaling = 1.0 / 100.0 * bondFut.Notional;
                    var basisPnL      = (basisT1 - basisT0) * futPosScaling;

                    //convexity pnl from CTD
                    var ctdId        = t0Vals[tradeId].CheapestToDeliver;
                    var pnlConvexity = 0.0;
                    var bondMktData  = t0Mkt.BondPrices[ctdId];
                    if (bondMktData != null)
                    {
                        var ctdCleanPriceT0 = bondMktData.CleanPrice;
                        var ctdInfo         = bondFut.DeliverableBondInfos.Where(x => x.BondId == ctdId).First();
                        var ctdResultT0     = XlUdf.BondEngineCalc(ctdId, t0Mkt.ReferenceDate.ToString(),
                                                                   PriceQuoteType.Clean, ctdCleanPriceT0, PricingRequest.DirtyPrice,
                                                                   fixedBond: ctdInfo) as PricingResult;
                        pnlConvexity = 0.5 * Math.Pow(t1Vals[tradeId].Ytm - t0Vals[tradeId].Ytm, 2.0) * t0Vals[tradeId].DollarConvexity / 100.0;
                    }

                    //time pnl from CTD
                    var timePnL = t0ValsRolledForward[tradeId].UnderlyingPv - t0Vals[tradeId].UnderlyingPv;

                    var pnl = new BondFuturesPnLResult(tPv, t1Pv, pnlPv01: pnlPv01, pnlZspread: zspreadPnl, pnlBasis: basisPnL,
                                                       pnlTime: timePnL, pnlConvexity: pnlConvexity, curveRisks: null);

                    ret[tradeId] = pnl;
                }
                if (tradeInfo is VanillaOptionInfo || tradeInfo is BinaryOptionInfo || GetTrade(tradeId) is BarrierOptionInfo || tradeInfo is AsianOptionInfo)
                {
                    OptionValuationParameters valuationParameters = null;
                    Date   exerciseDate = null;
                    double strike       = 0.0;

                    var trade = tradeInfo as OptionInfoBase;
                    valuationParameters = trade.ValuationParamter;
                    TradeUtil.GenerateOptionDates(trade, out Date[] exerciseDates, out Date[] obsDates, out DayGap settlementGap);
コード例 #3
0
ファイル: BinaryOptionVf.cs プロジェクト: stepinto163/Qdp
        public override BinaryOption GenerateInstrument()
        {
            var startDate    = TradeInfo.StartDate.ToDate();
            var maturityDate = TradeInfo.UnderlyingMaturityDate.ToDate();

            TradeUtil.GenerateOptionDates(TradeInfo, out Date[] exerciseDates, out Date[] obsDates, out DayGap settlementGap);