Code is to extract implied volatility data for multiple stocks/indices from Equity Volatility Surfac

Hi, Below code is to extract implied volatility data for SP500 index. However, I want to pull data for multiple stocks and indices for multiple time horizon using single run. How can I amend the code to do that?


import refinitiv.data as rd

from refinitiv.data.content.ipa import surfaces

import pandas as pd

import plotly.express as px

import plotly.graph_objects as go

rd.open_session()


request_definition = rd.delivery.endpoint_request.Definition(


url="https://api.refinitiv.com/data/quantitative-analytics-curves-and-surfaces/v1/surfaces",

method=rd.delivery.endpoint_request.RequestMethod.POST,

body_parameters={

"universe": [

{

"surfaceTag": "SPX",

"underlyingType": "Eti",

"underlyingDefinition": {

"instrumentCode": ".SPX@RIC"

},

"surfaceParameters": {

"inputVolatilityType": "Quoted",

"timeStamp": "Default",

"priceSide": "Mid",

"volatilityModel": "SSVI",

"xAxis": "Tenor",

"yAxis": "Moneyness",

"calculationDate": "2024-03-21"

},

"surfaceLayout": {

"format": "Matrix",

}

}],



"outputs": ["Data", "ForwardCurve", "MoneynessStrike"]


}

)

response = request_definition.get_data()


surface_tag = response.data.raw['data'][0]['surfaceTag']


_surface_df = pd.DataFrame(

data=response.data.raw['data'][0]['surface'])

surface_df_title = f"{surface_tag} Equity Volatility Surface"

surface_df = pd.DataFrame(

data=_surface_df.loc[1:,1:].values,

index=_surface_df[0][1:],

columns=_surface_df.iloc[0][1:])

surface_df.columns.name = "Moneyness"

surface_df.index.name = "Tenor"


surface_df.loc[["3M","6M"],["1"]]

Best Answer

  • aramyan.h
    Answer ✓

    Hi @Wasim Akram01 ,


    Regarding making the code cleaner and more readable, you can probably use the following example where I refactored the code:

    stocks = {".SPX":["2024-03-21"], "AAPL.O": ["2024-03-21", "2024-02-22"]}

    universe = [
    {
    "surfaceTag": stock,
    "underlyingType": "Eti",
    "underlyingDefinition": {
    "instrumentCode": f"{stock}@RIC"
    },
    "surfaceParameters": {
    "inputVolatilityType": "Quoted",
    "timeStamp": "Default",
    "priceSide": "Mid",
    "volatilityModel": "SSVI",
    "xAxis": "Tenor",
    "yAxis": "Moneyness",
    "calculationDate": date
    },
    "surfaceLayout": {
    "format": "Matrix",
    }
    } for stock, dates in stocks.items() for date in dates
    ]

    request_definition = rd.delivery.endpoint_request.Definition(
    url="https://api.refinitiv.com/data/quantitative-analytics-curves-and-surfaces/v1/surfaces",
    method=rd.delivery.endpoint_request.RequestMethod.POST,
    body_parameters={
    "universe": universe,
    "outputs": ["Data", "ForwardCurve", "MoneynessStrike"]
    }
    )

    response = request_definition.get_data()


    Best regards,

    Haykaz


Answers

  • Hi @Wasim Akram01 ,


    You can include multiple entries in the "universe" list within the request body. Here's an example of how you can modify the provided code:

    request_definition = rd.delivery.endpoint_request.Definition(
    url="https://api.refinitiv.com/data/quantitative-analytics-curves-and-surfaces/v1/surfaces",
    method=rd.delivery.endpoint_request.RequestMethod.POST,
    body_parameters={
    "universe": [
    {
    "surfaceTag": "SPX",
    "underlyingType": "Eti",
    "underlyingDefinition": {
    "instrumentCode": ".SPX@RIC"
    },
    "surfaceParameters": {
    "inputVolatilityType": "Quoted",
    "timeStamp": "Default",
    "priceSide": "Mid",
    "volatilityModel": "SSVI",
    "xAxis": "Tenor",
    "yAxis": "Moneyness",
    "calculationDate": "2024-03-21"
    },
    "surfaceLayout": {
    "format": "Matrix",
    }
    },
    {
    "surfaceTag": "AAPL",
    "underlyingType": "Eti",
    "underlyingDefinition": {
    "instrumentCode": "AAPL.O@RIC"
    },
    "surfaceParameters": {
    "inputVolatilityType": "Quoted",
    "timeStamp": "Default",
    "priceSide": "Mid",
    "volatilityModel": "SVI",
    "xAxis": "Tenor",
    "yAxis": "Moneyness",
    "calculationDate": "2024-03-21"
    },
    "surfaceLayout": {
    "format": "Matrix",
    }
    },
    {
    "surfaceTag": "AAPL",
    "underlyingType": "Eti",
    "underlyingDefinition": {
    "instrumentCode": "AAPL.O@RIC"
    },
    "surfaceParameters": {
    "inputVolatilityType": "Quoted",
    "timeStamp": "Default",
    "priceSide": "Mid",
    "volatilityModel": "SVI",
    "xAxis": "Tenor",
    "yAxis": "Moneyness",
    "calculationDate": "2024-02-22"
    },
    "surfaceLayout": {
    "format": "Matrix",
    }
    }
    ],
    "outputs": ["Data", "ForwardCurve", "MoneynessStrike"]
    }
    )

    response = request_definition.get_data()


    Hope this helps.


    Best regards,

    Haykaz

  • @aramyan.h ,


    I have around 100 stocks, the approach you advised it is good for 3 or 5 stocks, however not useful for 100 stocks. Can you please check if there is any possibility to enter multiple stocks in "instrumentCode" line (like any list/tuple/dictionary) ?

  • Hi @Wasim Akram01 ,


    Just checked, according to the Swagger type for instrumentCode is string. So I am afraid, you can't have list of instruments there:

            "instrumentCode": {
    "description": "Code to define the instrument. Only RIC is supported.",
    "type": "string"
    },


  • Hi
    @aramyan.h ,


    Any other way make the code shorter, otherwise universe will be very lengthy.