I would like to get a single strike price say SPX = 3270 Bid/ Ask price and Option greeks to form a dataframe table like below
? exp_date? OptionPrice? ImpliedVolatility? ...? ? ?Gamma? BidPrice AskPrice
0? ?2020-11-02? ? 14.241455? ? ? ? ? ?0.254689? ...? 0.011956? ? ? None? ? ?None
1? ?2020-11-04? ? 45.551861? ? ? ? ? ?0.410343? ...? 0.003532? ? ? None? ? ?None
2? ?2020-11-06? ? 60.029626? ? ? ? ? ?0.410054? ...? 0.002654? ? ? None? ? ?None
The problem is I'm getting below values where the Bid price and Ask price values are NONE
TickOptionComputation. TickerId: 21 tickType: 83 ImpliedVolatility: 0.33391930803094855 Delta: 0.5120104766126846 OptionPrice: 113.18464549592791 pvDividend: 6.193513473841583 Gamma:? 0.0013812397555831267 Vega: 3.4475913921237153 Theta: -2.254673784090535 UnderlyingPrice: 3271.87
TickOptionComputation. TickerId: 21 tickType: 80 ImpliedVolatility: None Delta: None OptionPrice: None pvDividend: 6.193513473841583 Gamma:? None Vega: None Theta: None UnderlyingPrice: 3271.87
TickOptionComputation. TickerId: 21 tickType: 81 ImpliedVolatility: None Delta: None OptionPrice: None pvDividend: 6.193513473841583 Gamma:? None Vega: None Theta: None UnderlyingPrice: 3271.87
TickOptionComputation. TickerId: 21 tickType: 82 ImpliedVolatility: None Delta: None OptionPrice: None pvDividend: 6.193513473841583 Gamma:? None Vega: None Theta: None UnderlyingPrice: 3271.87
TickOptionComputation. TickerId: 21 tickType: 83 ImpliedVolatility: 0.33391930803094855 Delta: 0.5120104766126846 OptionPrice: 113.18464549592791 pvDividend: 6.193513473841583 Gamma:? 0.0013812397555831267 Vega: 3.4475913921237153 Theta: -2.254673784090535 UnderlyingPrice: 3271.87 Below is my code:
import ibapi from ibapi.client import EClient from ibapi.wrapper import EWrapper from ibapi.contract import Contract from ibapi.ticktype import TickTypeEnum
import math import threading import time import datetime import pandas as pd import numpy as np
class IBapi(EWrapper, EClient): current_price = 0.0 ticker_cntrl = 0 option_greeks_df = pd.DataFrame() option_bid_df = pd.DataFrame() option_ask_df = pd.DataFrame() expiry_dates = []
def nextValidId(self, orderId: int): super().nextValidId(orderId)
print("setting nextValidOrderId: %d", orderId) self.nextValidOrderId = orderId
def __init__(self): EClient.__init__(self, self)
def initialize_output(self, exp_dates, ticker_cntrl): option_greeks_columns = ['exp_date', 'OptionPrice', 'ImpliedVolatility', 'Delta', 'Gamma'] type(self).option_greeks_df = pd.DataFrame(columns=option_greeks_columns) type(self).expiry_dates = exp_dates type(self).ticker_cntrl = ticker_cntrl option_bid_columns = ['exp_date', 'BidPrice'] type(self).option_bid_df = pd.DataFrame(columns=option_bid_columns) option_ask_columns = ['exp_date', 'AskPrice'] type(self).option_ask_df = pd.DataFrame(columns=option_ask_columns)
def tickPrice(self, reqId, tickType, price, attrib): if (reqId == 1): if (TickTypeEnum.DELAYED_LAST == tickType): print("Tick Price Ticker ID: " + str(reqId) + " tickType: " + TickTypeEnum.to_str( tickType) + " Price : " + str(price) + "\n") type(self).current_price = price # else: # print("Tick Price Ticker ID: " + str(reqId) + " tickType: " + TickTypeEnum.to_str( # tickType) + " Price : " + str(price) + "\n")
# def tickOptionComputation(self, reqId, tickType, tickAttrib, impliedVol, delta, optPrice, pvDividend, gamma, vega, theta, undPrice): print("TickOptionComputation. TickerId:", reqId, "tickType:", tickType, "ImpliedVolatility:", impliedVol, "Delta:", delta, "OptionPrice:", optPrice, "pvDividend:", pvDividend, "Gamma: ", gamma, "Vega:", vega, "Theta:", theta, "UnderlyingPrice:", undPrice) if (optPrice == None ): super().tickOptionComputation(reqId, tickType,tickAttrib, impliedVol, delta, optPrice, pvDividend, gamma, vega, theta, undPrice)
if (tickType == 80): # Delayed Bid Option 80 type(self).option_bid_df.loc[reqId - type(self).ticker_cntrl] = [ type(self).expiry_dates[reqId - type(self).ticker_cntrl], optPrice]
if (tickType == 81): # Delayed Ask Option 81 type(self).option_ask_df.loc[reqId - type(self).ticker_cntrl] = [ type(self).expiry_dates[reqId - type(self).ticker_cntrl], optPrice]
if (tickType == 83): # Delayed Model Option 83 type(self).option_greeks_df.loc[reqId - type(self).ticker_cntrl] = [ type(self).expiry_dates[reqId - type(self).ticker_cntrl], optPrice, impliedVol, delta, gamma]
def get_spx_stk_contract(): spx_contract = Contract() spx_contract.symbol = 'SPX' spx_contract.secType = 'IND' spx_contract.exchange = 'CBOE' spx_contract.currency = 'USD' spx_contract.tradingClass = "SPXW" return spx_contract
def get_spx_opt_contract(strike_price, exp_date, c_type): spx_contract = Contract() spx_contract.symbol = 'SPX' spx_contract.secType = 'OPT' spx_contract.exchange = 'SMART' spx_contract.currency = 'USD' spx_contract.lastTradeDateOrContractMonth = exp_date # "20180523" spx_contract.strike = strike_price # 2750 if (c_type == 0): spx_contract.right = 'C' else: spx_contract.right = 'P' spx_contract.multiplier = '100' spx_contract.tradingClass = 'SPXW' return spx_contract
def return_contract(tick_symbol): i_contract = Contract() i_contract.symbol = tick_symbol i_contract.secType = 'STK' i_contract.exchange = 'SMART' i_contract.currency = 'USD' return i_contract
def next_weekday(d, weekday, week_multiplier): # Function to get the next weekday from current day (0- Monday, 2 - Wednesday, 4 - Friday) days_ahead = weekday - d.weekday() if days_ahead < 0: # Target day already happened this week days_ahead += 7 * week_multiplier return d + datetime.timedelta(days_ahead)
def exp_dates(n_weeks=4, s_type=0): # n_weeks = number of weeks required # s_type = 0 or 1 (0 is for SPY & SPX, 1 is for other stocks) d = datetime.date.today() expiration_dates = [] if (s_type == 0): for i in range(n_weeks): # Monday, Wednesday & Friday expiry for SPY & SPX expiration_dates.append(next_weekday(d + datetime.timedelta(7 * i), 0, (i + 1))) expiration_dates.append(next_weekday(d + datetime.timedelta(7 * i), 2, (i + 1))) expiration_dates.append(next_weekday(d + datetime.timedelta(7 * i), 4, (i + 1))) else: for i in range(n_weeks): # Only Friday expiry for stocks expiration_dates.append(next_weekday(d + datetime.timedelta(7 * i), 4, (i + 1))) return expiration_dates
def get_floor_price(s_type, current_price): # s_type = 0 or 1 (0 is for SPX, 1 is for SPY & other stocks) floor_price = 0.0 if (s_type == 0): floor_price = (math.floor(current_price / 5)) * 5 else: floor_price = math.floor(current_price) return floor_price
def get_ceil_price(s_type, current_price): # s_type = 0 or 1 (0 is for SPX, 1 is for SPY & other stocks) ceil_price = 0.0 if (s_type == 0): ceil_price = (math.ceil(current_price / 5)) * 5 else: ceil_price = math.ceil(current_price) return ceil_price
def main(): app = IBapi() app.connect('127.0.0.1', 7496, 0)
def run_loop(): app.run()
# Start the socket in a thread api_thread = threading.Thread(target=run_loop, daemon=True) api_thread.start()
time.sleep(1) # Sleep interval to allow time for connection to server
# To get stk contracts use # return_contract('SPY') # return_contract('AAPL')
# Create contract object stk_contract = get_spx_stk_contract()
app.reqMarketDataType(4) # Request Market Data app.reqMktData(1, stk_contract, "", False, False, [])
time.sleep(4) # Sleep interval to allow time for incoming price data
# set the ceil & floor price from current price app.ceil_price = get_ceil_price(0, app.current_price) app.floor_price = get_floor_price(0, app.current_price)
# Print the current prices print(app.current_price, app.floor_price, app.ceil_price)
# Get the next 4 week expiration expiration_dates = exp_dates(4, 0)
# print(expiration_dates)
# Create a common data frame format # data_frame_column = ['exp_date', 'OptionPrice', 'ImpliedVolatility', 'Delta', 'Gamma', 'BidPrice', 'AskPrice', # 'AvgPrice'] # floor_call_price_df = pd.DataFrame(columns=data_frame_column) # floor_put_price_df = pd.DataFrame(columns=data_frame_column) # ceil_call_price_df = pd.DataFrame(columns=data_frame_column) # ceil_put_price_df = pd.DataFrame(columns=data_frame_column)
# initialize the output app.initialize_output(expiration_dates, 10)
# Set floor price call ticker_id_counter = 0 for exp_d in expiration_dates: app.reqMarketDataType(4) opt_contract = get_spx_opt_contract(app.floor_price, exp_d.strftime('%Y%m%d'), 0) app.reqMktData(10 + ticker_id_counter, opt_contract, "", False, False, []) ticker_id_counter = ticker_id_counter + 1 time.sleep(10) # Sleep interval to allow time for incoming price data
# Add to our floor call data frame floor_call_price_df = pd.merge(pd.merge(app.option_greeks_df, app.option_bid_df, how='outer', on='exp_date'), app.option_ask_df, how='outer', on='exp_date')
print(app.option_greeks_df) print(app.option_bid_df) print(app.option_ask_df) print(floor_call_price_df)
app.disconnect()
if __name__ == '__main__': main()
|
Were you running this outside of the market hours? What if you get "last" price instead of bid/ask?
toggle quoted message
Show quoted text
I would like to get a single strike price say SPX = 3270 Bid/ Ask price and Option greeks to form a dataframe table like below
? exp_date? OptionPrice? ImpliedVolatility? ...? ? ?Gamma? BidPrice AskPrice
0? ?2020-11-02? ? 14.241455? ? ? ? ? ?0.254689? ...? 0.011956? ? ? None? ? ?None
1? ?2020-11-04? ? 45.551861? ? ? ? ? ?0.410343? ...? 0.003532? ? ? None? ? ?None
2? ?2020-11-06? ? 60.029626? ? ? ? ? ?0.410054? ...? 0.002654? ? ? None? ? ?None
The problem is I'm getting below values where the Bid price and Ask price values are NONE
TickOptionComputation. TickerId: 21 tickType: 83 ImpliedVolatility: 0.33391930803094855 Delta: 0.5120104766126846 OptionPrice: 113.18464549592791 pvDividend: 6.193513473841583 Gamma:? 0.0013812397555831267 Vega: 3.4475913921237153 Theta: -2.254673784090535 UnderlyingPrice: 3271.87
TickOptionComputation. TickerId: 21 tickType: 80 ImpliedVolatility: None Delta: None OptionPrice: None pvDividend: 6.193513473841583 Gamma:? None Vega: None Theta: None UnderlyingPrice: 3271.87
TickOptionComputation. TickerId: 21 tickType: 81 ImpliedVolatility: None Delta: None OptionPrice: None pvDividend: 6.193513473841583 Gamma:? None Vega: None Theta: None UnderlyingPrice: 3271.87
TickOptionComputation. TickerId: 21 tickType: 82 ImpliedVolatility: None Delta: None OptionPrice: None pvDividend: 6.193513473841583 Gamma:? None Vega: None Theta: None UnderlyingPrice: 3271.87
TickOptionComputation. TickerId: 21 tickType: 83 ImpliedVolatility: 0.33391930803094855 Delta: 0.5120104766126846 OptionPrice: 113.18464549592791 pvDividend: 6.193513473841583 Gamma:? 0.0013812397555831267 Vega: 3.4475913921237153 Theta: -2.254673784090535 UnderlyingPrice: 3271.87 Below is my code:
import ibapi from ibapi.client import EClient from ibapi.wrapper import EWrapper from ibapi.contract import Contract from ibapi.ticktype import TickTypeEnum
import math import threading import time import datetime import pandas as pd import numpy as np
class IBapi(EWrapper, EClient): current_price = 0.0 ticker_cntrl = 0 option_greeks_df = pd.DataFrame() option_bid_df = pd.DataFrame() option_ask_df = pd.DataFrame() expiry_dates = []
def nextValidId(self, orderId: int): super().nextValidId(orderId)
print("setting nextValidOrderId: %d", orderId) self.nextValidOrderId = orderId
def __init__(self): EClient.__init__(self, self)
def initialize_output(self, exp_dates, ticker_cntrl): option_greeks_columns = ['exp_date', 'OptionPrice', 'ImpliedVolatility', 'Delta', 'Gamma'] type(self).option_greeks_df = pd.DataFrame(columns=option_greeks_columns) type(self).expiry_dates = exp_dates type(self).ticker_cntrl = ticker_cntrl option_bid_columns = ['exp_date', 'BidPrice'] type(self).option_bid_df = pd.DataFrame(columns=option_bid_columns) option_ask_columns = ['exp_date', 'AskPrice'] type(self).option_ask_df = pd.DataFrame(columns=option_ask_columns)
def tickPrice(self, reqId, tickType, price, attrib): if (reqId == 1): if (TickTypeEnum.DELAYED_LAST == tickType): print("Tick Price Ticker ID: " + str(reqId) + " tickType: " + TickTypeEnum.to_str( tickType) + " Price : " + str(price) + "\n") type(self).current_price = price # else: # print("Tick Price Ticker ID: " + str(reqId) + " tickType: " + TickTypeEnum.to_str( # tickType) + " Price : " + str(price) + "\n")
# def tickOptionComputation(self, reqId, tickType, tickAttrib, impliedVol, delta, optPrice, pvDividend, gamma, vega, theta, undPrice): print("TickOptionComputation. TickerId:", reqId, "tickType:", tickType, "ImpliedVolatility:", impliedVol, "Delta:", delta, "OptionPrice:", optPrice, "pvDividend:", pvDividend, "Gamma: ", gamma, "Vega:", vega, "Theta:", theta, "UnderlyingPrice:", undPrice) if (optPrice == None ): super().tickOptionComputation(reqId, tickType,tickAttrib, impliedVol, delta, optPrice, pvDividend, gamma, vega, theta, undPrice)
if (tickType == 80): # Delayed Bid Option 80 type(self).option_bid_df.loc[reqId - type(self).ticker_cntrl] = [ type(self).expiry_dates[reqId - type(self).ticker_cntrl], optPrice]
if (tickType == 81): # Delayed Ask Option 81 type(self).option_ask_df.loc[reqId - type(self).ticker_cntrl] = [ type(self).expiry_dates[reqId - type(self).ticker_cntrl], optPrice]
if (tickType == 83): # Delayed Model Option 83 type(self).option_greeks_df.loc[reqId - type(self).ticker_cntrl] = [ type(self).expiry_dates[reqId - type(self).ticker_cntrl], optPrice, impliedVol, delta, gamma]
def get_spx_stk_contract(): spx_contract = Contract() spx_contract.symbol = 'SPX' spx_contract.secType = 'IND' spx_contract.exchange = 'CBOE' spx_contract.currency = 'USD' spx_contract.tradingClass = "SPXW" return spx_contract
def get_spx_opt_contract(strike_price, exp_date, c_type): spx_contract = Contract() spx_contract.symbol = 'SPX' spx_contract.secType = 'OPT' spx_contract.exchange = 'SMART' spx_contract.currency = 'USD' spx_contract.lastTradeDateOrContractMonth = exp_date # "20180523" spx_contract.strike = strike_price # 2750 if (c_type == 0): spx_contract.right = 'C' else: spx_contract.right = 'P' spx_contract.multiplier = '100' spx_contract.tradingClass = 'SPXW' return spx_contract
def return_contract(tick_symbol): i_contract = Contract() i_contract.symbol = tick_symbol i_contract.secType = 'STK' i_contract.exchange = 'SMART' i_contract.currency = 'USD' return i_contract
def next_weekday(d, weekday, week_multiplier): # Function to get the next weekday from current day (0- Monday, 2 - Wednesday, 4 - Friday) days_ahead = weekday - d.weekday() if days_ahead < 0: # Target day already happened this week days_ahead += 7 * week_multiplier return d + datetime.timedelta(days_ahead)
def exp_dates(n_weeks=4, s_type=0): # n_weeks = number of weeks required # s_type = 0 or 1 (0 is for SPY & SPX, 1 is for other stocks) d = datetime.date.today() expiration_dates = [] if (s_type == 0): for i in range(n_weeks): # Monday, Wednesday & Friday expiry for SPY & SPX expiration_dates.append(next_weekday(d + datetime.timedelta(7 * i), 0, (i + 1))) expiration_dates.append(next_weekday(d + datetime.timedelta(7 * i), 2, (i + 1))) expiration_dates.append(next_weekday(d + datetime.timedelta(7 * i), 4, (i + 1))) else: for i in range(n_weeks): # Only Friday expiry for stocks expiration_dates.append(next_weekday(d + datetime.timedelta(7 * i), 4, (i + 1))) return expiration_dates
def get_floor_price(s_type, current_price): # s_type = 0 or 1 (0 is for SPX, 1 is for SPY & other stocks) floor_price = 0.0 if (s_type == 0): floor_price = (math.floor(current_price / 5)) * 5 else: floor_price = math.floor(current_price) return floor_price
def get_ceil_price(s_type, current_price): # s_type = 0 or 1 (0 is for SPX, 1 is for SPY & other stocks) ceil_price = 0.0 if (s_type == 0): ceil_price = (math.ceil(current_price / 5)) * 5 else: ceil_price = math.ceil(current_price) return ceil_price
def main(): app = IBapi() app.connect('127.0.0.1', 7496, 0)
def run_loop(): app.run()
# Start the socket in a thread api_thread = threading.Thread(target=run_loop, daemon=True) api_thread.start()
time.sleep(1) # Sleep interval to allow time for connection to server
# To get stk contracts use # return_contract('SPY') # return_contract('AAPL')
# Create contract object stk_contract = get_spx_stk_contract()
app.reqMarketDataType(4) # Request Market Data app.reqMktData(1, stk_contract, "", False, False, [])
time.sleep(4) # Sleep interval to allow time for incoming price data
# set the ceil & floor price from current price app.ceil_price = get_ceil_price(0, app.current_price) app.floor_price = get_floor_price(0, app.current_price)
# Print the current prices print(app.current_price, app.floor_price, app.ceil_price)
# Get the next 4 week expiration expiration_dates = exp_dates(4, 0)
# print(expiration_dates)
# Create a common data frame format # data_frame_column = ['exp_date', 'OptionPrice', 'ImpliedVolatility', 'Delta', 'Gamma', 'BidPrice', 'AskPrice', # 'AvgPrice'] # floor_call_price_df = pd.DataFrame(columns=data_frame_column) # floor_put_price_df = pd.DataFrame(columns=data_frame_column) # ceil_call_price_df = pd.DataFrame(columns=data_frame_column) # ceil_put_price_df = pd.DataFrame(columns=data_frame_column)
# initialize the output app.initialize_output(expiration_dates, 10)
# Set floor price call ticker_id_counter = 0 for exp_d in expiration_dates: app.reqMarketDataType(4) opt_contract = get_spx_opt_contract(app.floor_price, exp_d.strftime('%Y%m%d'), 0) app.reqMktData(10 + ticker_id_counter, opt_contract, "", False, False, []) ticker_id_counter = ticker_id_counter + 1 time.sleep(10) # Sleep interval to allow time for incoming price data
# Add to our floor call data frame floor_call_price_df = pd.merge(pd.merge(app.option_greeks_df, app.option_bid_df, how='outer', on='exp_date'), app.option_ask_df, how='outer', on='exp_date')
print(app.option_greeks_df) print(app.option_bid_df) print(app.option_ask_df) print(floor_call_price_df)
app.disconnect()
if __name__ == '__main__': main()
|
HI
I ran this outside & during the market hours still didnt work.
I was able to get last price from?def tickPrice but bid/ ask results are -1. Do we need extra permission to access the bid/ask price?
Regards Alan
|
Try to use real-time or delayed data, not frozen
app.reqMarketDataType(3)
because frozen data seems to return only last price from end of trading session
|
I've only used tickPrice() to get option prices, not quite sure how?tickOptionComputation works. What does it return for "optPrice"?
toggle quoted message
Show quoted text
Try to use real-time or delayed data, not frozen
app.reqMarketDataType(3)
because frozen data seems to return only last price from end of trading session
|
yes, you can take option prices from tickPrice() method too. I think that tickPrice() pushes more accurate values, rounded to minimal tick size.
|