Hi everyone, 
One of the great things about QuantConnect is that it's data-independent, which allows us to integrate any data source.  I'm primarily a derivatives trader and have been a long-time user of ORATS. Since I've been building out my QC ML options trading algos, I wanted reliable derived options data for backtesting, without having to construct my own models.   Very recently I noticed that ORATS is now selling daily and minute historical data.  I purchased the daily version, it's simplified a lot for me when conducting research.  The issue still persists for any algos running intraday, I still need to use QC's framework or make my own for anything needing intraday greeks.  Hopefully in the future it will be easier to integrate any data source which operates on our brokerage platform.

I'm sharing the code to process the ORATS csv file in the hopes it helps someone else better leverage QuantConnect. 

Lauren Roberts

Roberts Trading

def explode_orats_format(df):
    print("ORATS raw columns before rename:", df.columns.tolist())
    df.rename(columns={"ticker": "underlying", "expirDate": "expiry"}, inplace=True)
    df["trade_date"] = pd.to_datetime(df["trade_date"], errors="coerce")
    df["expiry"] = pd.to_datetime(df["expiry"], errors="coerce")

    # --- Call side ---
    call_cols = [
        "underlying", "trade_date", "expiry", "strike", "stkPx",
        "cVolu", "cOi", "cValue", "extCTheo", "smoothSmvVol", "residualRateData",
        "delta", "gamma", "theta", "vega", "rho", "phi", "driftlessTheta", "extVol"
    ]
    calls = df[call_cols].copy()
    calls.columns = [
        "underlying", "trade_date", "expiry", "strike", "stkPx",
        "volume", "openinterest", "close_orats", "orats_theo", "smoothSmvVol", "residualRateData",
        "delta", "gamma", "theta", "vega", "rho", "phi", "driftlessTheta", "extVol"
    ]
    calls["right"] = "c"

    # --- Put side ---
    put_cols = [
        "underlying", "trade_date", "expiry", "strike", "stkPx",
        "pVolu", "pOi", "pValue", "extPTheo", "smoothSmvVol", "residualRateData",
        "delta", "gamma", "theta", "vega", "rho", "phi", "driftlessTheta", "extVol"
    ]
    puts = df[put_cols].copy()
    puts.columns = [
        "underlying", "trade_date", "expiry", "strike", "stkPx",
        "volume", "openinterest", "close_orats", "orats_theo", "smoothSmvVol", "residualRateData",
        "delta", "gamma", "theta", "vega", "rho", "phi", "driftlessTheta", "extVol"
    ]
    puts["right"] = "p"

    # --- Combine ---
    combined = pd.concat([calls, puts], ignore_index=True)
    combined.sort_values(["trade_date", "expiry", "strike", "right"], inplace=True)
    print("ORATS cleaned shape:", combined.shape)
    print("ORATS columns:", combined.columns.tolist())
    return combined