Hi, I struggled with options in research environment for a somewhile. I see some other guys stumble a bit as me .. Here is a template of how I managed to use it:

# Say, today is 20th of Apr 2020 and time is 10:30
# I want prices of 'SPY' at-the-money (ATM) options with expiry on 24th of April 2020

stock = "SPY"
today = "2020-04-20"
exp = "2020-04-24"

### Initialization

from clr import AddReference
from System import *
from QuantConnect import *
from QuantConnect.Data.Market import TradeBar, QuoteBar
from QuantConnect.Jupyter import *
from QuantConnect.Indicators import *
from datetime import datetime, timedelta
import matplotlib.pyplot as plt
import pandas as pd

qb = QuantBook()
security = qb.AddEquity(stock)
security_opt = qb.AddOption(stock, Resolution.Minute)

### Logic

# I need to change that into datetime format and add time of the day
time = datetime.strptime(today, '%Y-%m-%d') + timedelta(hours=10, minutes=30)
expiry = datetime.strptime(exp, '%Y-%m-%d').replace(hour=0, minute=0)

# Now I need to get current SPY price and round it to ATM strike.
# To do that, we pull SPY price history for the last 1 min:
startOpt = time
endOpt = startOpt + timedelta(minutes=1)
secPrice = float(qb.History(security.Symbol, startOpt, endOpt, Resolution.Minute).close)
strike = round(secPrice)
print(f"Current SPY price is: {secPrice}, our ATM strike will be: {strike}")

# ---- Get options history --------
# First set your options filter. Here I chose 2 strikes into both sides from ATM
# and expiration from today to 7 days ahead (so our expiration date surely gets there)
security_opt.SetFilter(lambda universe: universe.IncludeWeeklys().Strikes(-2, 2).Expiration(timedelta(0), timedelta(4)) )
startOpt = time
endOpt = startOpt + timedelta(minutes=1)
security_option_history = qb.GetOptionHistory(security_opt.Symbol, startOpt, endOpt)
data = security_option_history.GetAllData()

# To visualize the data, you may print it.
# print(data)

## Once updated data is available, you could use a boolean accessor to find
## the options with expiry and assign them to a new DataFrame 'df'
boolean = data.index.get_level_values('expiry') == expiry
dfInit = data.loc[boolean].sort_index()
boolean_close = dfInit.index.get_level_values('strike') == strike
df = dfInit.loc[boolean_close]

# Here, depending on what you want, you choose which particular item needed.
# Say if you plan to simulate market BUY of options, you want to choose
# average of 'askclose' and 'askopen' fields
call_price = (df.iloc[idx,0] + df.iloc[idx,3]) / 2
put_price = (df.iloc[idx+1,0] + df.iloc[idx+1,3]) / 2
print(f"CALL price: {call_price}, PUT price: {put_price}")

I'm not the programmer, so it could probably been done better. But it worked for me :))