Seeking Help with Instrument Keys for Specific Options in Upstox API

Hello everyone,

I’m currently working with the Upstox API and I’ve hit a bit of a roadblock. I’ve been trying to understand the logic behind the creation of instrument keys, specifically for options trading. I’ve gone through the documentation available at Upstox API - Instruments, but I’m still unclear about a few things.

My main issue is that I can’t seem to find the instrument key for a specific option, namely the “20000PE Nifty 30 Dec”. I’ve looked through the available resources but haven’t had any luck.

Does anyone know if there’s a way to programmatically retrieve or construct the instrument key for such specific options? Any guidance, tips, or code snippets would be greatly appreciated. I’m sure others might also benefit from this information.

Thanks in advance for your help!

Best regards,
Charly

Let’s consider you know the date, strike price, and whether it’s a put or call option for the contract NIFTY23DEC23000PE. To programmatically find the instrument_key (such as NSE_FO|37721) for a given trading symbol like NIFTY23DEC23000PE, when you have the date, strike price, and whether it’s a put or call option, you can follow these steps:

  1. Standardize the Date Format: Ensure the date is in a standard format that matches the format used in your dataset. For example, if your date is 23-Dec-2023, you may need to convert it to a format like 23DEC.
  2. Concatenate Strings for Trading Symbol: Construct the trading symbol by concatenating the index name, standardized expiry date, strike price, and option type (PE for Put, CE for Call).
  3. Filter the Dataset: Use the constructed trading symbol to filter your dataset and extract the instrument_key.

Here’s a Python function that demonstrates this:

python

import pandas as pd

def find_instrument_key(df, index, date, strike_price, option_type):
    """
    Finds the instrument key in the dataframe for a given option.

    :param df: DataFrame containing the data.
    :param index: The index, e.g., 'NIFTY'.
    :param date: Expiry date in the format 'DD-MMM-YYYY' (e.g., '23-Dec-2023').
    :param strike_price: Strike price as an integer or float.
    :param option_type: 'Put' or 'Call'.
    :return: The instrument key or None if not found.
    """
    # Convert date to the required format (e.g., '23DEC')
    date_str = pd.to_datetime(date).strftime('%d%b').upper()

    # Define option type abbreviation
    option_abbr = 'PE' if option_type.lower() == 'put' else 'CE'

    # Construct the trading symbol
    trading_symbol = f"{index}{date_str}{strike_price}{option_abbr}"

    # Filter the dataframe for the trading symbol
    filtered_df = df[df['tradingsymbol'] == trading_symbol]

    # Return the instrument key
    if not filtered_df.empty:
        return filtered_df.iloc[0]['instrument_key']
    else:
        return None

# Example usage
data = pd.read_csv('/path/to/NSE.csv',  low_memory=False)  # Load the dataset
instrument_key = find_instrument_key(data, 'NIFTY', '23-Dec-2023', 23000, 'Put')
instrument_key

This function will find the instrument_key for the trading symbol constructed from the given date, strike price, and option type. If the trading symbol does not exist in the dataset, it will return None. Make sure to adjust the date format conversion (strftime('%d%b')) to match the format used in your dataset.

Tested it randomly for 3-4 entries and worked for me. You can give a shot and let me know.

Hi Pradeep_Jaiswar,

Thank you for sharing the Python function to find the instrument_key for options contracts. I appreciate your effort in crafting this solution. However, I’ve encountered some issues when applying it to certain use cases.

Specifically, the function doesn’t seem to work for options with expiry dates within this week or for those expiring next year. For instance, when I tried to find the instrument_key for NIFTY30NOV23000PE, the function did not return the expected results. Similarly, I faced an issue with an option expiring in March next year.

Thanks,
Charly

I tried something like this

import pandas as pd
from datetime import datetime, timedelta

def get_thursday_date():
    today = datetime.today()
    days_until_thursday = (3 - today.weekday() + 7) % 7
    thurdays_date = today + timedelta(days=days_until_thursday)
    format_date = thurdays_date.strftime('%y%m%d')
    if format_date[2] == '0':
        format_date = format_date[0:2]+format_date[3:]
    return format_date

def find_instrument_key(df, index, date, strike_price, option_type):
    """
    Finds the instrument key in the dataframe for a given option.

    :param df: DataFrame containing the data.
    :param index: The index, e.g., 'NIFTY'.
    :param date: Expiry date in the format 'DD-MMM-YYYY' (e.g., '23-Dec-2023').
    :param strike_price: Strike price as an integer or float.
    :param option_type: 'Put' or 'Call'.
    :return: The instrument key or None if not found.
    """
    # Convert date to the required format (e.g., '23DEC')
    date_str = pd.to_datetime(date).strftime('%y%b').upper()
    date_str_1 = get_thursday_date()

    # Define option type abbreviation
    option_abbr = 'PE' if option_type.lower() == 'put' else 'CE'

    # Construct the trading symbol
    trading_symbol = f"{index}{date_str}{strike_price}{option_abbr}"
    trading_symbol_1 = f"{index}{date_str_1}{strike_price}{option_abbr}"
    #print(trading_symbol,trading_symbol_1)
    # Filter the dataframe for the trading symbol
    filtered_df = df[df['tradingsymbol'] == trading_symbol]
    filtered_df_1 = df[df['tradingsymbol'] == trading_symbol_1]

    # Return the instrument key
    if not filtered_df.empty:
        return filtered_df.iloc[0]['instrument_key']
    elif not filtered_df_1.empty:
        return filtered_df_1.iloc[0]['instrument_key']
    else:
        return None

# Example usage
# get_thursday_date()
data = pd.read_csv('\NSE.csv',  low_memory=False)  # Load the dataset
instrument_key = find_instrument_key(data, 'NIFTY', '29-Feb-2024', 21500, 'CALL')
print(instrument_key)
1 Like

How to i get the prevours 6 months instrument key

@Dev_Jalla The Upstox API does not offer access to the keys for historical instruments. However, you can find keys for all currently active instruments in the BOD (Beginning of Day) file, available at Instruments | Upstox Developer API.

Could you share more details about why you need the instrument keys from the past six months?

I also need to get instruments keys for past periods for back testing strategy. At least for past one month.

Instrument keys are needed to fetch the historical data. I see two options here:

  1. Provide an API to get instrument keys.
  2. Accept option info in the API used to fetch historical data.
1 Like

I also need instrument keys of expired option contracts in order to get historical price movement of that option contract and then further backtest and validate my trading strategy.
Is there any work around this?

Your feedback has been noted. We will forward it to the product team.

Hi @Pradeep_Jaiswar
I am trying to get OptionContract with intrument_key = NSE_FO|64210

request:
payload={‘instrument_key’ : ‘NSE_FO|64210’}
response = Upstox.GetOptionContracts(Upstox.AccessToken, payload)
print(str(response.json()))

but data is not coming
{‘status’: ‘success’, ‘data’: }

this is a subset of the data I found when called…
payload={‘instrument_key’ : ‘NSE_INDEX|Nifty Bank’}
response = Upstox.GetOptionContracts(Upstox.AccessToken, payload)
print(str(response.json()))

data:
{‘name’: ‘BANKNIFTY’, ‘segment’: ‘NSE_FO’, ‘exchange’: ‘NSE’, ‘expiry’: ‘2024-09-25’, ‘weekly’: False, ‘instrument_key’: ‘NSE_FO|64210’, ‘exchange_token’: ‘64210’, ‘trading_symbol’: ‘BANKNIFTY 54000 PE 25 SEP 24’, ‘tick_size’: 5.0, ‘lot_size’: 15, ‘instrument_type’: ‘PE’, ‘freeze_quantity’: 900.0, ‘underlying_key’: ‘NSE_INDEX|Nifty Bank’, ‘underlying_type’: ‘INDEX’, ‘underlying_symbol’: ‘BANKNIFTY’, ‘strike_price’: 54000.0, ‘minimum_lot’: 15}

Hi, @chapterMurphy,

The get OptionContract API retrieves option contracts for an underlying symbol, listing available contracts for symbols like NSE_INDEX|Nifty Bank , NSE_INDEX|Nifty 50 etc.

However, in the case of NSE_FO|64210, this is a contract itself, so it won’t have any underlying symbol.

To get information on such contracts, you can use the historical APIs or subscribe to the market feeder WebSocket

Thank you.

1 Like

Hi @Ketan
Now what is the problem with this call?

url : ‘https://api.upstox.com/v2/historical-candle/intraday
headers = {
‘Accept’: ‘application/json’
}
payload={‘instrument_key’ : ‘NSE_INDEX|Nifty Bank’, ‘interval’ : ‘1minute’}
payload={‘instrument_key’ : ‘NSE_FO|64210’, ‘interval’ : ‘1minute’}

(Both payload I tried but error is same)

response = requests.request(“GET”, url, headers=headers, params=payload)

Error:
{‘status’: ‘error’, ‘errors’: [{‘errorCode’: ‘UDAPI100060’, ‘message’: ‘Resource not Found.’, ‘propertyPath’: None, ‘invalidValue’: None, ‘error_code’: ‘UDAPI100060’, ‘property_path’: None, ‘invalid_value’: None}]}

FYI… it is not working with AuthToken too
headers = {
‘Accept’: ‘application/json’,
‘Authorization’: 'Bearer ’ + accessToken
}

@chapterMurphy, kindly paste the following URL into your browser to receive the response:

https://api.upstox.com/v2/historical-candle/intraday/NSE_FO%7C64210/1minute

Additionally, please refer to Example Codes | Historical Data for more examples.

Thank you.

@Ketan
What sort of answer is this?

If you are hungry and instead of food I will give you glass of water will it work for you?

I want an answer what is the problem with my python code? you are giving me URL to hit on browser

My apologies, @chapterMurphy, if my previous response did not meet your expectations.

In the message above, I provided links to example codes in various languages such as Python, Node.js, Java, and PHP, which you can incorporate into your code. Rest assured, all the codes in the example section have been thoroughly tested.

Since you encountered the error “Resource not Found,” I shared a direct URL for you to try in your browser to guide you to the correct resource. By pasting that URL, you will be directed to the appropriate resource.

Thank you.

@Ketan, It is not woking, I picked as is Sir.

My only worry is If payload is not there, then url will be hard-coded… which is a problem

Bro he was just asking what the problem in API call is? You could simply reply that your URL and Parameters are wrong. you need to pass instrument and interval in URL itself. like https://api.upstox.com/v2/historical-candle/intraday/NSE_FO|64210/1minute

URL format: https://api.upstox.com/v2/historical-candle/intraday/**instrument_key**/**interval**

Also, @Jagdish_j_ptl

If URL is hard coded… my other request should not work…
Like for every other API request I am sending payload… either they should change the documentation. or allow what I am requesting…

See this is Full Market Quotes calls on upstox website
url = ‘https://api.upstox.com/v2/market-quote/quotes?instrument_key=NSE_EQ|INE848E01016
headers = {
‘Accept’: ‘application/json’,
‘Authorization’: ‘Bearer {your_access_token}’
}

response = requests.get(url, headers=headers)

print(response.text)

Yes I know I was also facing same issue. But I managed to do it.