Engine icon indicating copy to clipboard operation
Engine copied to clipboard

Bond Option

Open Othmane-Ch opened this issue 2 years ago • 6 comments

I m trying to adapt example 18 to calculate the npv on a bond option trade. I get this error on the logs:

NOTICE   [2023-May-04 11:59:07.310847]   (OREData\ored\portfolio\portfolio.cpp:123) : Building Portfolio of size 1 for context = 'analytic/PRICING'
DEBUG    [2023-May-04 11:59:07.311846]   (OREData\ored\portfolio\bondoption.cpp:50) : Building Bond Option: BondOptionDirty
DEBUG    [2023-May-04 11:59:07.312849]        (OREData\ored\portfolio\bond.cpp:187) : could not get BondReferenceDatum for name Security/ISIN:XS0983610930 leave data in trade unchanged
ALERT    [2023-May-04 11:59:07.314846]   (OREData\ored\portfolio\portfolio.cpp:280) : StructuredMessage { "category":"Error", "group":"Trade", "message":"BondData invalid: missing SettlementDays, Currency - check if reference data is set up for 'Security/ISIN:XS0983610930'", "sub_fields": [ { "name": "exceptionType", "value": "Error building trade for context 'analytic/PRICING'" }, { "name": "tradeId", "value": "BondOptionDirty" }, { "name": "tradeType", "value": "BondOption" } ] }
NOTICE   [2023-May-04 11:59:07.315845]   (OREData\ored\portfolio\portfolio.cpp:141) : Built Portfolio. Initial size = 1, size now 0, built 0 failed trades, context is analytic/PRICING
ALERT    [2023-May-04 11:59:07.317850]       (OREAnalytics\orea\app\oreapp.cpp:273) : Error in ORE analytics: Portfolio does not contain any built trades, context is 'analytic/PRICING'
ALERT    [2023-May-04 11:59:07.318845]       (OREAnalytics\orea\app\oreapp.cpp:341) : StructuredMessage { "category":"Warning", "group":"Analytics", "message":"Error in ORE analytics: Portfolio does not contain any built trades, context is 'analytic/PRICING'", "sub_fields": [ { "name": "analyticType", "value": "OREApp::run()" }, { "name": "warningType", "value": "Error" } ] }

I added the reference_data.xml in the input files as it is described in the userguide but still get the same error. Does anyone have a bond option and bond repo examples to share ? Thank you

Othmane-Ch avatar May 04 '23 10:05 Othmane-Ch

Can you please attach your reference_data.xml ? Irrelevant for your case, but there are some typos in BondReferenceDatum::BondData::toXML , here is a patch: https://github.com/OpenSourceRisk/Engine/commit/749c4b9740d0afa5154ec4e2583acadb5dfdeb17

noonediesalone avatar May 04 '23 10:05 noonediesalone

It's the one from the userguide :

<?xml version="1.0"?>
<ReferenceData>
  <!-- Bond reference datum -->
  <ReferenceDatum id="SECURITY_1">
    <Type>Bond</Type>
    <BondReferenceData>
      <IssuerId>CPTY_C</IssuerId>
      <CreditCurveId>ZERO</CreditCurveId>
      <ReferenceCurveId>EURBENCHMARK-EUR-6M</ReferenceCurveId>
      <SettlementDays>2</SettlementDays>
      <Calendar>TARGET</Calendar>
      <IssueDate>20110215</IssueDate>
      <LegData>
        <LegType>Fixed</LegType>
        <Payer>false</Payer>
        <Currency>EUR</Currency>
        <Notionals>
          <Notional>1</Notional>
        </Notionals>
        <DayCounter>ActActISMA</DayCounter>
        <PaymentConvention>F</PaymentConvention>
        <FixedLegData>
          <Rates>
            <Rate>0.02</Rate>
          </Rates>
        </FixedLegData>
        <ScheduleData>
          <Rules>
            <StartDate>20190103</StartDate>
            <EndDate>20200103</EndDate>
            <Tenor>1Y</Tenor>
            <Calendar>TARGET</Calendar>
            <Convention>U</Convention>
            <TermConvention>U</TermConvention>
            <Rule>Forward</Rule>
            <EndOfMonth/>
            <FirstDate/>
            <LastDate/>
          </Rules>
        </ScheduleData>
      </LegData>
    </BondReferenceData>
  </ReferenceDatum>
</ReferenceData>

I get this error in the logs now:

DEBUG    [2023-May-04 12:36:51.479191]        (OREData\ored\portfolio\bond.cpp:211) : Bond::build() called for trade 
DEBUG    [2023-May-04 12:36:51.480152]        (OREData\ored\portfolio\bond.cpp:174) : Got BondReferenceDatum for name SECURITY_1 overwrite empty elements in trade
DEBUG    [2023-May-04 12:36:51.481150]    (OREData\ored\portfolio\bondutils.cpp:33) : populating data bond from reference data
DATA     [2023-May-04 12:36:51.482147]    (OREData\ored\portfolio\bondutils.cpp:53) : overwrite priceQuoteMethod with ''
DATA     [2023-May-04 12:36:51.483158]    (OREData\ored\portfolio\bondutils.cpp:57) : overwrite priceQuoteBaseValue with ''
DATA     [2023-May-04 12:36:51.485152]    (OREData\ored\portfolio\bondutils.cpp:65) : overwrite creditGroup with ''
DATA     [2023-May-04 12:36:51.486150]    (OREData\ored\portfolio\bondutils.cpp:73) : overwrite incomeCurveId with ''
DATA     [2023-May-04 12:36:51.487150]    (OREData\ored\portfolio\bondutils.cpp:77) : overwrite volatilityCurveId with ''
DEBUG    [2023-May-04 12:36:51.488152]   (OREData\ored\portfolio\bondutils.cpp:108) : populating bond data from reference data done.
DEBUG    [2023-May-04 12:36:51.489149]     (OREData\ored\utilities\parsers.hpp:400) : tryParse: attempting to parse 
DATA     [2023-May-04 12:36:51.490150]     (OREData\ored\utilities\parsers.hpp:404) : String  could not be parsed
DEBUG    [2023-May-04 12:36:51.492152]     (OREData\ored\utilities\parsers.hpp:400) : tryParse: attempting to parse 
DATA     [2023-May-04 12:36:51.493152]     (OREData\ored\utilities\parsers.hpp:404) : String  could not be parsed
DEBUG    [2023-May-04 12:36:51.494117] (...ta\ored\marketdata\todaysmarket.cpp:823) : market object YieldCurve(EURBENCHMARK-EUR-6M) required for configuration 'libor'
DEBUG    [2023-May-04 12:36:51.495150] (...ta\ored\marketdata\todaysmarket.cpp:865) : not found, retry with default configuration
DEBUG    [2023-May-04 12:36:51.497152] (...ta\ored\marketdata\todaysmarket.cpp:823) : market object YieldCurve(EURBENCHMARK-EUR-6M) required for configuration 'default'
DEBUG    [2023-May-04 12:36:51.498147] (...ta\ored\marketdata\todaysmarket.cpp:873) : not found, do nothing
DEBUG    [2023-May-04 12:36:51.499150] (OREData\ored\utilities\indexparser.cpp:249) : tryParseIborIndex(EURBENCHMARK-EUR-6M) failed: parseIborIndex "EURBENCHMARK-EUR-6M" not recognized
DEBUG    [2023-May-04 12:36:51.500152]  (OREData\ored\marketdata\marketimpl.cpp:83) : no ibor index found under 'EURBENCHMARK-EUR-6M' - look for a genuine yield curve
DEBUG    [2023-May-04 12:36:51.501150] (...ta\ored\marketdata\todaysmarket.cpp:823) : market object YieldCurve(EURBENCHMARK-EUR-6M) required for configuration 'libor'
DEBUG    [2023-May-04 12:36:51.502150] (...ta\ored\marketdata\todaysmarket.cpp:865) : not found, retry with default configuration
DEBUG    [2023-May-04 12:36:51.503150] (...ta\ored\marketdata\todaysmarket.cpp:823) : market object YieldCurve(EURBENCHMARK-EUR-6M) required for configuration 'default'
DEBUG    [2023-May-04 12:36:51.504150] (...ta\ored\marketdata\todaysmarket.cpp:873) : not found, do nothing
ALERT    [2023-May-04 12:36:51.507147]   (OREData\ored\portfolio\portfolio.cpp:280) : StructuredMessage { "category":"Error", "group":"Trade", "message":"did not find object EURBENCHMARK-EUR-6M of type yield curve / ibor index under configuration 'libor' or 'default' in YieldCurves", "sub_fields": [ { "name": "exceptionType", "value": "Error building trade for context 'analytic/PRICING'" }, { "name": "tradeId", "value": "BondOptionDirty" }, { "name": "tradeType", "value": "BondOption" } ] }
NOTICE   [2023-May-04 12:36:51.508157]   (OREData\ored\portfolio\portfolio.cpp:141) : Built Portfolio. Initial size = 1, size now 0, built 0 failed trades, context is analytic/PRICING
ALERT    [2023-May-04 12:36:51.510150]       (OREAnalytics\orea\app\oreapp.cpp:273) : Error in ORE analytics: Portfolio does not contain any built trades, context is 'analytic/PRICING'
ALERT    [2023-May-04 12:36:51.511151]       (OREAnalytics\orea\app\oreapp.cpp:341) : StructuredMessage { "category":"Warning", "group":"Analytics", "message":"Error in ORE analytics: Portfolio does not contain any built trades, context is 'analytic/PRICING'", "sub_fields": [ { "name": "analyticType", "value": "OREApp::run()" }, { "name": "warningType", "value": "Error" } ] }

Othmane-Ch avatar May 04 '23 10:05 Othmane-Ch

You can use defined yield: <ReferenceCurveId>BENCHMARK_EUR</ReferenceCurveId> or genuine ibor curve: <ReferenceCurveId>EUR-EURIBOR-6M</ReferenceCurveId>

noonediesalone avatar May 04 '23 13:05 noonediesalone

Is ORE going to add examples on the new added instruments in the near future ?

Or does anyone has knowledge on the steps to follow to calculate the npv for a bond option ? I have added the reference data and volatility curve id, but somehow ORE doesn't find bondReferenceDatum for name SECURITY_1. Can anyone provide help on this matter ? this is the files that I'm working on for now:

referencedata.xml:

<?xml version="1.0"?>
<ReferenceData>
  <!-- Bond reference datum -->
  <ReferenceDatum id="default">
    <Type>Bond</Type>
    <BondReferenceData>
      <IssuerId>CPTY_C</IssuerId>
      <CreditCurveId>ZERO</CreditCurveId>
      <ReferenceCurveId>BENCHMARK_EUR</ReferenceCurveId>
      <SettlementDays>2</SettlementDays>
      <Calendar>TARGET</Calendar>
      <IssueDate>20110215</IssueDate>
      <LegData>
        <LegType>Fixed</LegType>
        <Payer>false</Payer>
        <Currency>EUR</Currency>
        <Notionals>
          <Notional>1</Notional>
        </Notionals>
        <DayCounter>ActActISMA</DayCounter>
        <PaymentConvention>F</PaymentConvention>
        <FixedLegData>
          <Rates>
            <Rate>0.02</Rate>
          </Rates>
        </FixedLegData>
        <ScheduleData>
          <Rules>
            <StartDate>20190103</StartDate>
            <EndDate>20200103</EndDate>
            <Tenor>1Y</Tenor>
            <Calendar>TARGET</Calendar>
            <Convention>U</Convention>
            <TermConvention>U</TermConvention>
            <Rule>Forward</Rule>
            <EndOfMonth/>
            <FirstDate/>
            <LastDate/>
          </Rules>
        </ScheduleData>
      </LegData>
    </BondReferenceData>
  </ReferenceDatum>
</ReferenceData>

Portfolio.xml:

<?xml version="1.0"?>
<Portfolio>
  <Trade id="BondOptionDirty">
    <TradeType>BondOption</TradeType>
    <Envelope>
      <CounterParty>CPTY_c</CounterParty>
      <NettingSetId/>
      <AdditionalFields/>
    </Envelope>
    <BondOptionData>
      <OptionData>
        <LongShort>Long</LongShort>
        <OptionType>Call</OptionType>
        <Style>European</Style>
        <ExerciseDates>
          <ExerciseDate>20210203</ExerciseDate>
        </ExerciseDates>
      </OptionData>
      <StrikeData>
        <StrikePrice>
          <Value>1.23</Value>
          <Currency>EUR</Currency>
        </StrikePrice>
      </StrikeData>
      <PriceType>Dirty</PriceType>
      <KnocksOut>false</KnocksOut>
      <BondData>
        <SecurityId>SECURITY_1</SecurityId>
        <VolatilityCurveId>YieldVols-EUR</VolatilityCurveId>
        <BondNotional>100000</BondNotional>
        <SettlementDays>2</SettlementDays>
        <Currency>EUR</Currency>
      </BondData>
    </BondOptionData>
  </Trade>
</Portfolio>

The logs :

DEBUG    [2023-May-05 11:09:03.135937] (...ored\marketdata\dependencygraph.cpp:437) : Dependency graph built with 96 vertices, 115 edges.
NOTICE   [2023-May-05 11:09:03.140938] (...ta\ored\marketdata\todaysmarket.cpp:227) : Build objects in TodaysMarket lazily, i.e. when requested.
NOTICE   [2023-May-05 11:09:03.141937] (...ta\ored\marketdata\todaysmarket.cpp:232) : TodaysMarket build stats:
NOTICE   [2023-May-05 11:09:03.142937] (...ta\ored\marketdata\todaysmarket.cpp:238) : 1 load fixings                    :        7.92e+03 ms         1       7.92e+03 ms
NOTICE   [2023-May-05 11:09:03.143937] (...ta\ored\marketdata\todaysmarket.cpp:238) : 2 load dividends                  :           0.013 ms         1          0.013 ms
NOTICE   [2023-May-05 11:09:03.144940] (...ta\ored\marketdata\todaysmarket.cpp:238) : 3 add all fx quotes               :              10 ms         1             10 ms
NOTICE   [2023-May-05 11:09:03.145937] (...ta\ored\marketdata\todaysmarket.cpp:238) : 4 build dep graphs                :        1.21e+03 ms         1       1.21e+03 ms
NOTICE   [2023-May-05 11:09:03.146904] (...ta\ored\marketdata\todaysmarket.cpp:241) : Total build time              :         9142.42 ms
NOTICE   [2023-May-05 11:09:03.148904]     (OREAnalytics\orea\app\analytic.cpp:172) : Market Build time 9.156150 sec
NOTICE   [2023-May-05 11:09:03.150936]    (OREData\ored\portfolio\portfolio.cpp:44) : Reset portfolio of size 1
NOTICE   [2023-May-05 11:09:03.151937]     (OREAnalytics\orea\app\analytic.cpp:190) : Build the portfolio
NOTICE   [2023-May-05 11:09:03.152937]     (OREAnalytics\orea\app\analytic.cpp:124) : Analytic::engineFactory() called
NOTICE   [2023-May-05 11:09:03.153937]     (OREAnalytics\orea\app\analytic.cpp:134) : MarketContext::pricing = libor
NOTICE   [2023-May-05 11:09:03.154937] (...ta\ored\portfolio\enginefactory.cpp:152) : Building EngineFactory
NOTICE   [2023-May-05 11:09:03.158936]   (OREData\ored\portfolio\portfolio.cpp:123) : Building Portfolio of size 1 for context = 'analytic/PRICING'
DEBUG    [2023-May-05 11:09:03.159937]   (OREData\ored\portfolio\bondoption.cpp:50) : Building Bond Option: BondOptionDirty
DEBUG    [2023-May-05 11:09:03.160939]        (OREData\ored\portfolio\bond.cpp:187) : could not get BondReferenceDatum for name SECURITY_1 leave data in trade unchanged
ALERT    [2023-May-05 11:09:03.162948]   (OREData\ored\portfolio\portfolio.cpp:280) : StructuredMessage { "category":"Error", "group":"Trade", "message":"BondData invalid: missing Currency - check if reference data is set up for 'SECURITY_1'", "sub_fields": [ { "name": "exceptionType", "value": "Error building trade for context 'analytic/PRICING'" }, { "name": "tradeId", "value": "BondOptionDirty" }, { "name": "tradeType", "value": "BondOption" } ] }
NOTICE   [2023-May-05 11:09:03.163943]   (OREData\ored\portfolio\portfolio.cpp:141) : Built Portfolio. Initial size = 1, size now 0, built 0 failed trades, context is analytic/PRICING
ALERT    [2023-May-05 11:09:03.165937]       (OREAnalytics\orea\app\oreapp.cpp:273) : Error in ORE analytics: Portfolio does not contain any built trades, context is 'analytic/PRICING'
ALERT    [2023-May-05 11:09:03.166936]       (OREAnalytics\orea\app\oreapp.cpp:341) : StructuredMessage { "category":"Warning", "group":"Analytics", "message":"Error in ORE analytics: Portfolio does not contain any built trades, context is 'analytic/PRICING'", "sub_fields": [ { "name": "analyticType", "value": "OREApp::run()" }, { "name": "warningType", "value": "Error" } ] }

Othmane-Ch avatar May 05 '23 08:05 Othmane-Ch

Here is some pretty basic example of BondRepo. You can unzip attached Input.zip into your local %ORE%\Examples\Example_18\Input and run cd /d %ORE%\Examples\Example_18 & ore.exe Input\ore_repo.xml.

Main takeaways:

  1. Pricing engine def.
  <Product type="BondRepo">
    <Model>DiscountedCashflows</Model>
    <EngineParameters/>
    <Engine>DiscountingRepoEngine</Engine>
    <ModelParameters>
      <Parameter name="IncludeSecurityLeg">true</Parameter>
    </ModelParameters>
  </Product>

And another choice with Accrual\AccrualRepoEngine.

  1. BondReferenceData has to include discount curve into this element IncomeCurveId

BondOptionData is setup pretty similarly.

But I guess the main thing is you can always debug the error you're getting and fix it.

noonediesalone avatar May 05 '23 13:05 noonediesalone

Thank you for your reply @noonediesalone .

I managed to load the bond option data into the portfolio. However, I still need to provide a volatility curve id for the bond option as in the errors :

NOTICE   [2023-May-10 12:28:55.140211] (...ta\ored\marketdata\defaultcurve.cpp:576) : DefaultCurve: add asof (February 5th, 2016), hazard rate 0, as not given
NOTICE   [2023-May-10 12:28:55.141243] (...ta\ored\marketdata\defaultcurve.cpp:586) : DefaultCurve: set up interpolated hazard rate curve
NOTICE   [2023-May-10 12:28:55.143244] (...ta\ored\marketdata\defaultcurve.cpp:604) : Finished building default curve of type HazardRate for curve CPTY_C_SR_EUR
ALERT    [2023-May-10 12:28:55.232210]   (OREData\ored\portfolio\portfolio.cpp:280) : StructuredMessage { "category":"Error", "group":"Trade", "message":"did not find object 'YieldVols-EUR' of type yield volatility curve under configuration 'libor' or 'default'", "sub_fields": [ { "name": "exceptionType", "value": "Error building trade for context 'analytic/PRICING'" }, { "name": "tradeId", "value": "BondOptionDirty" }, { "name": "tradeType", "value": "BondOption" } ] }
NOTICE   [2023-May-10 12:28:55.233244]   (OREData\ored\portfolio\portfolio.cpp:141) : Built Portfolio. Initial size = 1, size now 0, built 0 failed trades, context is analytic/PRICING
ALERT    [2023-May-10 12:28:55.236214]       (OREAnalytics\orea\app\oreapp.cpp:273) : Error in ORE analytics: Portfolio does not contain any built trades, context is 'analytic/PRICING'
ALERT    [2023-May-10 12:28:55.237243]       (OREAnalytics\orea\app\oreapp.cpp:341) : StructuredMessage { "category":"Warning", "group":"Analytics", "message":"Error in ORE analytics: Portfolio does not contain any built trades, context is 'analytic/PRICING'", "sub_fields": [ { "name": "analyticType", "value": "OREApp::run()" }, { "name": "warningType", "value": "Error" } ] }

Yieldcurveconfig is used in TodaysMarket.cpp : image

when I add the yieldvolatilites to todaysmarket.xml , it doesn't recongnize it. I get the same error.

Othmane-Ch avatar May 10 '23 09:05 Othmane-Ch