Python string indice must be an int while converting date (%Y-%m-%d) in a dataframe?

Question:

I’m trying to keep this as simple as possible, while keeping the object oriented in-tact. I’m a beginner, but I’m struggling to figure out why I’m getting the error below and how to correct it, while keeping the object oriented style in-tact.

   import json
    from datetime import datetime, timedelta
    from dateutil import tz
    import numpy as np
    import pandas as pd
    import requests
    
    
    def run(ticker):
        today_date, data = scrape_data(ticker)
        calculate_gamma_levels(today_date,data)
    
    def scrape_data(ticker):
        #Scrape data from CBOE website
        
        raw_data = requests.get(f"https://cdn.cboe.com/api/global/delayed_quotes/options/{ticker}.json")
        dict_data = pd.DataFrame.from_dict(raw_data.json())
        data = pd.DataFrame(dict_data.loc["options", "data"])
        data_update_time = dict_data.timestamp[0]
        data["data_update_time"] = data_update_time
        data["expiration_date"] = str(20)+ data.option.str.extract(r"[A-Z](d+)").astype(str)
        expiration_date = pd.to_datetime(data["expiration_date"], format="%Y-%m-%d")
        print(expiration_date)
        today_date = data["data_update_time"][0]
        today_date = datetime.strptime(str(today_date), "%Y-%m-%d %H:%M:%S").strftime("%Y-%m-%d")
        data["today_date"] = today_date
     
        return data, today_date
    
    def calculate_gamma_levels(today_date,data):
        print(today_date)
        data['days_till_exp'] = [1/262 if (np.busday_count(today_date.date(), x.date())) == 0 
                                else np.busday_count(today_date.date(), x.date())/262 for x in int(data["expiration_date"])]
        next_expire = data['expiration_date'].min()    
    
    if __name__ == "__main__":
        ticker = "SPY"
        run(ticker)

The error that I’m getting is the following:

  File "c:pythonexample option date.py", line 46, in calculate_gamma_levels
    else np.busday_count(today_date.date(), x.date())/262 for x in int(data["expiration_date"])]
TypeError: string indices must be integers

I’ve tried doing the following and several other attempts on the expiration date, but had no success and continued to get the error above.

#    expiration_date = datetime.strptime(str(data["expiration_date"].values), "%Y%m%d").strftime("%Y-%m-%d")
#    expiration_date = datetime.strptime(str(data["expiration_date"]), "%Y%m%d").strftime("%Y-%m-%d")
    print(expiration_date)
#    print(data["expiration_date"])
 #   data["expiration_date"] = pd.to_datetime(data["expiration_date"], format="%Y%m%d")
    #print(data["expiration_date"])
Asked By: user1470034

||

Answers:

Try:

import json
from datetime import datetime, timedelta
from dateutil import tz
import numpy as np
import pandas as pd
import requests


def run(ticker):
    data, today_date = scrape_data(ticker)
    calculate_gamma_levels(today_date, data)


def scrape_data(ticker):
    # Scrape data from CBOE website

    raw_data = requests.get(
        f"https://cdn.cboe.com/api/global/delayed_quotes/options/{ticker}.json"
    )
    dict_data = pd.DataFrame.from_dict(raw_data.json())
    data = pd.DataFrame(dict_data.loc["options", "data"])
    data_update_time = dict_data.timestamp[0]
    data["data_update_time"] = data_update_time
    data["expiration_date"] = str(20) + data.option.str.extract(
        r"[A-Z](d+)"
    ).astype(str)
    expiration_date = pd.to_datetime(data["expiration_date"], format="%Y-%m-%d")
    today_date = data["data_update_time"][0]
    today_date = datetime.strptime(
        str(today_date), "%Y-%m-%d %H:%M:%S"
    ).strftime("%Y-%m-%d")
    data["today_date"] = today_date

    return data, today_date


def calculate_gamma_levels(today_date, data):
    data["expiration_date"] = pd.to_datetime(data["expiration_date"])
    data["days_till_exp"] = (
        np.busday_count(
            today_date,
            data["expiration_date"].dt.strftime("%Y-%m-%d").to_list(),
        )
        / 262
    )
    data.loc[data["days_till_exp"].eq(0), "days_till_exp"] = 1 / 262
    print(data)

    next_expire = data["expiration_date"].min()
    print(next_expire)

if __name__ == "__main__":
    ticker = "SPY"
    run(ticker)

Calculates the days_till_exp column divided by 262. Then all zeros are substituted with 1/262. Then minimal value is selected:

                  option     bid  bid_size     ask  ask_size       iv  open_interest    volume   delta   gamma   theta     rho    vega      theo  change    open    high     low       tick  last_trade_price      last_trade_time  percent_change  prev_day_close     data_update_time expiration_date  today_date  days_till_exp
0     SPY220831C00275000  119.94       2.0  121.13       1.0  25.1486            0.0       3.0  1.0000  0.0000  0.0000  0.0000  0.0000  122.4753   0.050  123.43  123.43  123.43         up            123.43  2022-08-31T12:19:26    4.052430e-02      123.380001  2022-08-31 22:55:42      2022-08-31  2022-08-31       0.003817
1     SPY220831P00275000    0.00       0.0    0.01    1711.0  12.0010         1056.0       1.0  0.0000  0.0000  0.0000  0.0000  0.0000    0.0052   0.005    0.01    0.01    0.01  no_change              0.01  2022-08-31T15:10:17    1.000000e+02        0.005000  2022-08-31 22:55:42      2022-08-31  2022-08-31       0.003817
2     SPY220831C00280000  114.94       2.0  116.13       1.0  24.1168            0.0       0.0  1.0000  0.0000  0.0000  0.0000  0.0000  117.4750   0.000    0.00    0.00    0.00  no_change              0.00                 None    0.000000e+00      118.385002  2022-08-31 22:55:42      2022-08-31  2022-08-31       0.003817

...

2022-08-31 00:00:00
Answered By: Andrej Kesely
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.