Join the 80,000 other DTN customers who enjoy the fastest, most reliable data available. There is no better value than DTN!

(Move your cursor to this area to pause scrolling)




"This beats the pants off CQG, I am definitely switching to the ProphetX 3.0!" - Comment from Stephen
"I cannot believe what a difference it makes trading with ProphetX!" - Comment from Bruce in Los Angeles
"IQFeed version 4 is a real screamer compared to anything else I have seen." - Comment from Tom
"Just a quick one to say I'm very impressed so far :) The documentation for developers is excellent and I've quickly managed to get an app written to do historical downloads. The system is very robust and pretty quick considering the extent of data that's available. The support guys have been very helpful too, in combination with the forums it's been plain sailing so far!" - Comment from Adam
"This is an excellent value, the system is generous (allowing for 500 stocks) and stable (and really is tick-by-tick), and the support is fantastic." - Comment from Shirin via Email
"I just wanted to tell you what a fine job you have been doing. While *******, from what I hear, has been down and out, off and on, IQ feed has held like a champ this week." - Comment from Shirin
"I've been using IQFeed 4 in a multi-threaded situation for the last week or two on 2600 symbols or so with 100 simultaneous daily charts, and I have had 100% responsiveness." - Comment from Scott
"I would just like to say that IQFeed version 4 is running very well and I am very happy with its performance. I would also like to extend a big thanks for the fast and efficient help that I always receive. My questions and concerns are always addressed promptly. Way to go!" - Comment from Josh in CO.
"IQ feed is brilliant. The support is mind-bending. What service!" - Comment from Public Forum Post
"Boy, probably spent a thousand hours trying to get ******* API to work right. And now two hours to have something running with IQFeed. Hmmm, guess I was pretty stupid to fight rather than switch all this time. And have gotten more customer service from you guys already than total from them… in five years." - Comment from Jim
Home  Search  Register  Login  Recent Posts

Information on DTN's Industries:
DTN Oil & Gas | DTN Trading | DTN Agriculture | DTN Weather
Follow DTNMarkets on Twitter
DTN.IQ/IQFeed on Twitter
DTN News and Analysis on Twitter
Viewing User Profile for: emp
About Contact
Joined: Aug 10, 2011 02:11 AM
Last Post: Jul 21, 2023 04:59 AM
Last Visit: Jul 21, 2023 04:59 AM
Website:  
Location:
Occupation:
Interests:
AIM:
ICQ:
MSN IM:
Yahoo IM:
Post Statistics
emp has contributed to 32 posts out of 21183 total posts (0.15%) in 4,634 days (0.01 posts per day).

20 Most recent posts:
New IQFeed Forum » Futures Option Chain prices Jul 21, 2023 04:59 AM (Total replies: 4)

thanks. Exporting from the options chains app worked fine for me. Gave the same result when I used the more time consuming method. But I have lost interest in option chains for the moment. At least this "Maximum Pain" method appears to be useless. It does not give accurate longer term predictions.

New IQFeed Forum » Futures Option Chain prices Jul 19, 2023 05:37 AM (Total replies: 4)

hi, thanks. Yes that is what I did. I exported the data to a CSV file and then processed that file with Python code. But I lost interest in the chains because I used them to do Max Pain calculations and I watched it for a while but it is basically pretty useless. It does not give predictions that are anywhere near accurate.

New IQFeed Forum » Futures Option Chain prices Apr 20, 2023 12:18 AM (Total replies: 4)

I opened a new thread for 1 question because my previous thread got cluttered with too many questions.

When I open the "IQFeed option chain" App, select "Futures Options" then type in the Futures symbols @ES and in the "Chains criteria" chose the month June and the year 2023 I almost instantly get a table with Open Interest numbers for all the options in the chain, see attached PDF.

When I however use my code below to access the Open Interest for all the option symbols in the chain it takes forever.

My question: is there a better way to access the open interest numbers. Maybe some automated way to save the data from the "IQFeed Option Chain" App to CSV files? How does IQFeed do this internally? I guess IQFeed stores these numbers somewhere where they can be accessed instantly in a table form?

thank you


 
# filesname: charpHistoricalDataTest.py
# To run code IQFeed should be launched already
# To run code type in the CMD window (path to python should be known)
# python charpHistoricalDataTest.py

# Dynamically add IQFeed.CSharpApiClient DLL
# for instructions see: https://github.com/mathpaquette/IQFeed.CSharpApiClient/blob/master/docs/USING-WITH-PYTHON.md
import sys
import clr
assembly_path = r'C:/Program Files/AmiBroker/IQFeedCSharpApiClient'
sys.path.append(assembly_path)
clr.AddReference("IQFeed.CSharpApiClient")
from System import DateTime
from datetime import datetime, timedelta
from IQFeed.CSharpApiClient.Lookup import LookupClientFactory
from IQFeed.CSharpApiClient.Lookup.Chains import OptionSideFilterType
import pandas as pd
import matplotlib.pyplot as plt

lookupClient = LookupClientFactory.CreateNew()
lookupClient.Connect()

def total_loss_at_strike(chainC, chainP, expiry_price):
"""Calculate loss at strike price"""
# All call options with strike price below the expiry price will result in loss for option writers
in_money_calls = chainC[chainC['Strike'] < expiry_price][["OpenInterest", "Strike"]]
in_money_calls["CE loss"] = (expiry_price - in_money_calls['Strike'])*in_money_calls["OpenInterest"]

# All put options with strike price above the expiry price will result in loss for option writers
in_money_puts = chainP[chainP['Strike'] > expiry_price][["OpenInterest", "Strike"]]
in_money_puts["PE loss"] = (in_money_puts['Strike'] - expiry_price)*in_money_puts["OpenInterest"]
total_loss = in_money_calls["CE loss"].sum() + in_money_puts["PE loss"].sum()

return total_loss

def createListofSymbolPlusStrikePrice(f_symbol, o_month, o_year, o_side):
f_symbol = str(f_symbol)
o_month = str(o_month)
o_year = str(o_year)

if( o_side == 1):
side = OptionSideFilterType.C
if( o_side == 2):
side = OptionSideFilterType.P

try:
ticks = lookupClient.Chains.GetChainFutureOption( f_symbol, side, o_month, o_year )
symbollist = '
strikepricelist = '
for tt in ticks:
symbollist += str(tt.Symbol)
symbollist += ','
strikepricelist += str(tt.StrikePrice)
#print(tt.StrikePrice)
strikepricelist += ','

# remove last comma
symbollist = symbollist[:len(symbollist)-1]
except Exception as err:
print(f"Unexpected {err=}, {type(err)=}")

return symbollist,strikepricelist

def getOpenInterestdata( sym, d1, d2 ):
sym = str(sym)
#ticks = lookupClient.Historical.GetHistoryDailyDatapoints(sym, 1)
ticks = lookupClient.Historical.GetHistoryDailyTimeframe(sym, d1, d2)

for tick in ticks:
s = str(tick)
datalist = s.split(',')
#print(int(str(datalist[6]).replace(' OpenInterest: ',')))
oi = int(str(datalist[6]).replace(' OpenInterest: ','))

return oi

def main():
##################
# input parameters
''
Month codes:
January: F
February: G
March: H
April: J
May: K
June: M
July: N
August: Q
September: U
October: V
November: X
December: Z
''
f_symbol = '@ES'
o_month = 'M'
o_year = '23'
##################

yesterday = datetime.now() - timedelta(1)
d1 = DateTime(yesterday.year,yesterday.month,yesterday.day)
d2 = DateTime(yesterday.year,yesterday.month,yesterday.day)

# Calls
symbollist,strikepricelist = createListofSymbolPlusStrikePrice(f_symbol, o_month, o_year, 1)
list1 = symbollist.split(',')
list2 = strikepricelist.split(',')
df_calls = pd.DataFrame(list(zip(list1, list2)), columns =['Symbols', 'Strike'])
df_calls = df_calls.astype({'Strike':'float'})
df_calls = df_calls.sort_values(by=['Strike'])
df_calls['OpenInterest'] = 0

idx = 0
for index, row in df_calls.iterrows():
sym = row['Symbols']
oi = getOpenInterestdata( sym, d1, d2 )
df_calls.iloc[idx, 2] = oi
print(idx,row['Strike'],row['Symbols'],oi)
idx += 1

print(df_calls)

# Puts
symbollist,strikepricelist = createListofSymbolPlusStrikePrice(f_symbol, o_month, o_year, 2)
list1 = symbollist.split(',')
list2 = strikepricelist.split(',')
df_puts = pd.DataFrame(list(zip(list1, list2)), columns =['Symbols', 'Strike'])
df_puts = df_puts.astype({'Strike':'float'})
df_puts = df_puts.sort_values(by=['Strike'])
df_puts['OpenInterest'] = 0

idx = 0
for index, row in df_puts.iterrows():
sym = row['Symbols']
oi = getOpenInterestdata( sym, d1, d2 )
df_puts.iloc[idx, 2] = oi
print(idx,row['Strike'],row['Symbols'],oi)
idx += 1

print(df_puts)

strikes = list(df_calls['Strike'])
losses = [total_loss_at_strike(df_calls, df_puts, strike)/1000000 for strike in strikes]

m = losses.index(min(losses))
print("Max pain > {}".format(strikes[m]))

plt.plot(strikes, losses)
plt.ylabel('Total loss in (Millon)')
plt.show()

if __name__ == "__main__":
main()


New IQFeed Forum » (futures and equity) option chains using Python Apr 19, 2023 10:57 AM (Total replies: 11)

this is the final "max pain" code. Kind of slowwwwww. Maybe IQFeed can add max pain so we do not have to calculate it.

Getting max pain for NQ June expiration 12800 and ES June expiration 4050

 
# filesname: charpHistoricalDataTest.py
# to run code IQFeed should be launched already
# to run code type in the CMD window (path to python should be known)
# python charpHistoricalDataTest.py

# Dynamically add IQFeed.CSharpApiClient DLL
import sys
import clr
assembly_path = r'C:/Program Files/AmiBroker/IQFeedCSharpApiClient'
sys.path.append(assembly_path)
clr.AddReference("IQFeed.CSharpApiClient")
from System import DateTime
from datetime import datetime, timedelta
from IQFeed.CSharpApiClient.Lookup import LookupClientFactory
from IQFeed.CSharpApiClient.Lookup.Chains import OptionSideFilterType
import pandas as pd
import matplotlib.pyplot as plt

lookupClient = LookupClientFactory.CreateNew()
lookupClient.Connect()

def total_loss_at_strike(chainC, chainP, expiry_price):
"""Calculate loss at strike price"""
# All call options with strike price below the expiry price will result in loss for option writers
in_money_calls = chainC[chainC['Strike'] < expiry_price][["OpenInterest", "Strike"]]
in_money_calls["CE loss"] = (expiry_price - in_money_calls['Strike'])*in_money_calls["OpenInterest"]

# All put options with strike price above the expiry price will result in loss for option writers
in_money_puts = chainP[chainP['Strike'] > expiry_price][["OpenInterest", "Strike"]]
in_money_puts["PE loss"] = (in_money_puts['Strike'] - expiry_price)*in_money_puts["OpenInterest"]
total_loss = in_money_calls["CE loss"].sum() + in_money_puts["PE loss"].sum()

return total_loss

def createListofSymbolPlusStrikePrice(f_symbol, o_month, o_year, o_side):

'''
Month codes:
January: F
February: G
March: H
April: J
May: K
June: M
July: N
August: Q
September: U
October: V
November: X
December: Z
'''

f_symbol = str(f_symbol)
o_month = str(o_month)
o_year = str(o_year)

if( o_side == 1):
side = OptionSideFilterType.C
if( o_side == 2):
side = OptionSideFilterType.P

try:
ticks = lookupClient.Chains.GetChainFutureOption( f_symbol, side, o_month, o_year )
symbollist = ''
strikepricelist = ''
for tt in ticks:
symbollist += str(tt.Symbol)
symbollist += ','
strikepricelist += str(tt.StrikePrice)
strikepricelist += ','

# remove last comma
symbollist = symbollist[:len(symbollist)-1]
except Exception as err:
print(f"Unexpected {err=}, {type(err)=}")

return symbollist,strikepricelist

def getOpenInterestdata( sym, d1, d2 ):
sym = str(sym)
#ticks = lookupClient.Historical.GetHistoryDailyDatapoints(sym, 1)
ticks = lookupClient.Historical.GetHistoryDailyTimeframe(sym, d1, d2)

for tick in ticks:
s = str(tick)
datalist = s.split(',')
#print(int(str(datalist[6]).replace(' OpenInterest: ','')))
oi = int(str(datalist[6]).replace(' OpenInterest: ',''))

return oi

def main():
f_symbol = '@NQ'
o_month = 'M'
o_year = '23'

yesterday = datetime.now() - timedelta(1)
d1 = DateTime(yesterday.year,yesterday.month,yesterday.day)
d2 = DateTime(yesterday.year,yesterday.month,yesterday.day)

# Calls
symbollist,strikepricelist = createListofSymbolPlusStrikePrice(f_symbol, o_month, o_year, 1)
list1 = symbollist.split(',')
list2 = strikepricelist.split(',')
df_calls = pd.DataFrame(list(zip(list1, list2)), columns =['Symbols', 'Strike'])
df_calls = df_calls.astype({'Strike':'float'})
df_calls = df_calls.sort_values(by=['Strike'])
df_calls['OpenInterest'] = 0

idx = 0
for index, row in df_calls.iterrows():
sym = row['Symbols']
oi = getOpenInterestdata( sym, d1, d2 )
df_calls.iloc[idx, 2] = oi
#print(idx,row['Strike'],row['Symbols'],oi)
idx += 1

print(df_calls)

# Puts
symbollist,strikepricelist = createListofSymbolPlusStrikePrice(f_symbol, o_month, o_year, 2)
list1 = symbollist.split(',')
list2 = strikepricelist.split(',')
df_puts = pd.DataFrame(list(zip(list1, list2)), columns =['Symbols', 'Strike'])
df_puts = df_puts.astype({'Strike':'float'})
df_puts = df_puts.sort_values(by=['Strike'])
df_puts['OpenInterest'] = 0

idx = 0
for index, row in df_puts.iterrows():
sym = row['Symbols']
oi = getOpenInterestdata( sym, d1, d2 )
df_puts.iloc[idx, 2] = oi
#print(idx,row['Strike'],row['Symbols'],oi)
idx += 1

print(df_puts)

strikes = list(df_calls['Strike'])
losses = [total_loss_at_strike(df_calls, df_puts, strike)/1000000 for strike in strikes]

m = losses.index(min(losses))
print("Max pain > {}".format(strikes[m]))

plt.plot(strikes, losses)
plt.ylabel('Total loss in (Millon)')
plt.show()

if __name__ == "__main__":
main()


New IQFeed Forum » (futures and equity) option chains using Python Apr 19, 2023 09:42 AM (Total replies: 11)

yes it seems that this line (in the function getOpenInterestdata) makes it slow:

 
ticks = lookupClient.Historical.GetHistoryDailyTimeframe(sym, d1, d2)


the total code is below. What it does is it makes 2 pandas dataframes. 1 for Futures Call contracts and 1 for the Futures Put contracts. In the columns are, the symbols, strike price and Open interest.

It works but it is slow. The openInterest for various strike prices should be instantly accessible. At least the IQFeed chains App finds them almost instantly. So somethings is wrong with this code.

 
# filesname: charpHistoricalDataTest.py
# to run code IQFeed should be launched already
# to run code type in the CMD window (path to python should be known)
# python charpHistoricalDataTest.py

# Dynamically add IQFeed.CSharpApiClient DLL
import sys
import clr
assembly_path = r'C:/Program Files/AmiBroker/IQFeedCSharpApiClient'
sys.path.append(assembly_path)
clr.AddReference("IQFeed.CSharpApiClient")
from System import DateTime
from datetime import datetime, timedelta
from IQFeed.CSharpApiClient.Lookup import LookupClientFactory
from IQFeed.CSharpApiClient.Lookup.Chains import OptionSideFilterType
import pandas as pd

lookupClient = LookupClientFactory.CreateNew()
lookupClient.Connect()

def createListofSymbolPlusStrikePrice(f_symbol, o_month, o_year, o_side):

'''
Month codes:
January: F
February: G
March: H
April: J
May: K
June: M
July: N
August: Q
September: U
October: V
November: X
December: Z
'''

f_symbol = str(f_symbol)
o_month = str(o_month)
o_year = str(o_year)

if( o_side == 1):
side = OptionSideFilterType.C
if( o_side == 2):
side = OptionSideFilterType.P

try:
ticks = lookupClient.Chains.GetChainFutureOption( f_symbol, side, o_month, o_year )
symbollist = ''
strikepricelist = ''
for tt in ticks:
symbollist += str(tt.Symbol)
symbollist += ','
strikepricelist += str(tt.StrikePrice)
strikepricelist += ','

# remove last comma
symbollist = symbollist[:len(symbollist)-1]
except Exception as err:
print(f"Unexpected {err=}, {type(err)=}")

return symbollist,strikepricelist

def getOpenInterestdata( sym, d1, d2 ):
sym = str(sym)
#ticks = lookupClient.Historical.GetHistoryDailyDatapoints(sym, 1)
ticks = lookupClient.Historical.GetHistoryDailyTimeframe(sym, d1, d2)

for tick in ticks:
s = str(tick)
datalist = s.split(',')
#print(int(str(datalist[6]).replace(' OpenInterest: ','')))
oi = int(str(datalist[6]).replace(' OpenInterest: ',''))

return oi

def main():
f_symbol = 'QNG'
o_month = 'K'
o_year = '23'

yesterday = datetime.now() - timedelta(1)
d1 = DateTime(yesterday.year,yesterday.month,yesterday.day)
d2 = DateTime(yesterday.year,yesterday.month,yesterday.day)

# Calls
symbollist,strikepricelist = createListofSymbolPlusStrikePrice(f_symbol, o_month, o_year, 1)
list1 = symbollist.split(',')
list2 = strikepricelist.split(',')
df_calls = pd.DataFrame(list(zip(list1, list2)), columns =['Symbols', 'Strike'])
df_calls = df_calls.astype({'Strike':'float'})
df_calls = df_calls.sort_values(by=['Strike'])
df_calls['OpenInterest'] = 0

idx = 0
for index, row in df_calls.iterrows():
sym = row['Symbols']
oi = getOpenInterestdata( sym, d1, d2 )
df_calls.iloc[idx, 2] = oi
#print(idx,row['Strike'],row['Symbols'],oi)
idx += 1

print(df_calls)

# Puts
symbollist,strikepricelist = createListofSymbolPlusStrikePrice(f_symbol, o_month, o_year, 2)
list1 = symbollist.split(',')
list2 = strikepricelist.split(',')
df_puts = pd.DataFrame(list(zip(list1, list2)), columns =['Symbols', 'Strike'])
df_puts = df_puts.astype({'Strike':'float'})
df_puts = df_puts.sort_values(by=['Strike'])
df_puts['OpenInterest'] = 0

idx = 0
for index, row in df_puts.iterrows():
sym = row['Symbols']
oi = getOpenInterestdata( sym, d1, d2 )
df_puts.iloc[idx, 2] = oi
#print(idx,row['Strike'],row['Symbols'],oi)
idx += 1

print(df_puts)

if __name__ == "__main__":
main()


New IQFeed Forum » (futures and equity) option chains using Python Apr 19, 2023 09:01 AM (Total replies: 11)

thanks. I also check in the Options Chain App and the Open Interest shown is the value of yesterdays close. So it is not updated. I mean the Volume is updating but not the OI. Not sure if this is normal, I am no expert on this.

Maybe I post my Python code later. It is really slow. What I do I first get the Option Chain list (for calls and puts). I put them in a pandas dataframe sorted for the strike price. Then I loop through all the symbols of the chain to find the OI for all the symbols. That takes too long.

Will post code complete later.

A snippet of the code shows what I do, see below. The function passes the future option symbol and the startdate plus enddate (which are the same and I use yesterdays date since todays values are zero). This is slow. It gives the correct OI values. Maybe it is because I get the OI from a string. I should be able to access it directly but I do not know the correct csharp code for that.

 
def getOpenInterestdata( sym, d1, d2 ):
sym = str(sym)
lookupClient = LookupClientFactory.CreateNew()
lookupClient.Connect()

# Step 4 - Make any requests you need or want!
#ticks = lookupClient.Historical.GetHistoryTickDatapoints("QNGK23C2250", 10)
#ticks = lookupClient.Historical.GetHistoryDailyDatapoints(sym, 5)
ticks = lookupClient.Historical.GetHistoryDailyTimeframe(sym, d1, d2)

for tick in ticks:
s = str(tick)
datalist = s.split(',')
#print(int(str(datalist[6]).replace(' OpenInterest: ','')))
oi = int(str(datalist[6]).replace(' OpenInterest: ',''))

return oi


New IQFeed Forum » (futures and equity) option chains using Python Apr 19, 2023 04:58 AM (Total replies: 11)

actually using the Csharp code I get access to OpenInterest data using GetHistoryDailyDatapoints, see code below.

About the OpenInterest. It seems the last data point is zero. Is this data updated only at certain times?

Data output from code below looks like:


C:\Users\win 10\AppData\Local\Programs\Python\Python38\mypython\iqfeed>python charpHistoricalDataTest.py
Timestamp: 4/19/2023 12:00:00 AM, High: 0.181, Low: 0.181, Open: 0.181, Close: 0.181, PeriodVolume: 3, OpenInterest: 0, RequestId:
Timestamp: 4/18/2023 12:00:00 AM, High: 0.192, Low: 0.13, Open: 0.154, Close: 0.19, PeriodVolume: 18, OpenInterest: 221, RequestId:
Timestamp: 4/17/2023 12:00:00 AM, High: 0.155, Low: 0.09, Open: 0.099, Close: 0.143, PeriodVolume: 28, OpenInterest: 226, RequestId:
Timestamp: 4/14/2023 12:00:00 AM, High: 0.08, Low: 0.039, Open: 0.055, Close: 0.079, PeriodVolume: 57, OpenInterest: 240, RequestId:
Timestamp: 4/13/2023 12:00:00 AM, High: 0.073, Low: 0.053, Open: 0.073, Close: 0.055, PeriodVolume: 19, OpenInterest: 265, RequestId:
Completed!


So this output I created at 2023-04-19 at 05:55 ET and the OpenInterest on the 19-th is showing 0. Why is it showing 0? Shouldn't that be showing the last value of the prior day? At what time of the day is it updated?

Thanks.

Python code using Csharp plugin
 
# python charpHistoricalDataTest.py

# Dynamically add IQFeed.CSharpApiClient DLL
import sys
import clr
assembly_path = r'C:/Program Files/AmiBroker/IQFeedCSharpApiClient'
sys.path.append(assembly_path)
clr.AddReference("IQFeed.CSharpApiClient")

# Step 2 - Use the appropriate factory to create the client
from IQFeed.CSharpApiClient.Lookup import LookupClientFactory
#from IQFeed.CSharpApiClient.Lookup.Historical import LookupClientFactory
lookupClient = LookupClientFactory.CreateNew()

# Step 3 - Connect it
lookupClient.Connect()

# Step 4 - Make any requests you need or want!
#ticks = lookupClient.Historical.GetHistoryTickDatapoints("QNGK23C2250", 10)
ticks = lookupClient.Historical.GetHistoryDailyDatapoints("QNGK23C2250", 5)

for tick in ticks:
print(tick)

print('Completed!')


New IQFeed Forum » (futures and equity) option chains using Python Apr 19, 2023 01:09 AM (Total replies: 11)

thanks for your help. I will try that. I also managed to access the data inside Amibroker. But I use Python to access the list (chain) of options. Will later ask Amibroker if they also can add a function to access this chain of option symbols.

Is there also a call to access the list of expiration dates for a particular symbol? So if I give the futures symbol it would give a list of expiration dates?

For instance in the Python example using Yahoo data (see code below) the command in line 10, osym.options gives me a list of expiration dates for the stock symbol given.

For futures options it would coincide with the expiration of the underlying future. I guess for futures options you rather would want a list of expiration months. Not sure.

thank you


 
# python medium_options.py

import yfinance as yf
import matplotlib.pyplot as plt

def main():
symbol = input("Enter the Symbol: " )
#symbol = 'UNG'
osym = yf.Ticker(symbol)
exps = osym.options

print("Expiry dates:")
print(exps)
expiry = input("\nEnter the Expiry data [format: YYYY-MM-DD]: " )

#expiry = '2023-04-21'
opc = osym.option_chain(expiry)
opccalls = opc.calls
opcputs = opc.puts
print(opc.calls)
print(opc.puts)
print('')
print(opc.calls.info())

'''
plt.subplot(211)
plt.plot(opccalls['strike'],opccalls['openInterest'])
plt.subplot(212)
plt.plot(opcputs['strike'],opcputs['openInterest'])
plt.show()
'''

if __name__ == "__main__":
main()


New IQFeed Forum » (futures and equity) option chains using Python Apr 18, 2023 01:40 AM (Total replies: 11)

and yes I am after the "Futures Options" for now since I have an IQFeed subscription for US futures only. And I have no access to the "development library" since I only have a subscription to use the data.

actually using csharp I managed to get the list of options that belong to a chain for a certain month and year, see code below.

Now I still need to get the data. I have some code that gets the price data for the futures options but the Open Interest is apparently stored somewhere else. I still need to figure out how to access the Open Interest. Apparently this is not saved in a similar way as the price is.

Also the option chain lists are not saved in history apparently. I have access to historical futures options data but the "historical futures chain lists" are apparently not saved.

here the code that uses Csharp that gives the symbols of a chain

 
https://github.com/mathpaquette/IQFeed.CSharpApiClient/blob/master/docs/USING-WITH-PYTHON.md
# Dynamically add IQFeed.CSharpApiClient DLL
# assembly_path = r"C:\<folder>"
# filename: iqfeedcsharpGetFuturesOptionChainAFL.py


if '__' + __file__ + '_initialized' not in globals():
globals()['__' + __file__ + '_initialized'] = True
assembly_path = r'C:/Program Files/AmiBroker/IQFeedCSharpApiClient'

import sys
sys.path.append(assembly_path)

# Reference IQFeed.CSharpApiClient DLL
import clr
clr.AddReference("IQFeed.CSharpApiClient")

from IQFeed.CSharpApiClient.Lookup import LookupClientFactory
from IQFeed.CSharpApiClient.Lookup.Chains import OptionSideFilterType
#import AmiPy

def getFuturesOptionsChainSymbols(f_symbol, o_month, o_year):

'''
Month codes:
January: F
February: G
March: H
April: J
May: K
June: M
July: N
August: Q
September: U
October: V
November: X
December: Z
'''

f_symbol = str(f_symbol)
o_month = str(o_month)
o_year = str(o_year)

lookupClient = LookupClientFactory.CreateNew()
lookupClient.Connect()

try:
# symtax Symbol (QNG), OptionSideFilterType.CP, Month Code, Year Code
ticks = lookupClient.Chains.GetChainFutureOption( f_symbol, OptionSideFilterType.CP, o_month, o_year )
symbollist = ''
for tt in ticks:
symbollist += tt.Symbol
symbollist += ','

# remove last comma
symbollist = symbollist[:len(symbollist)-1]
#AmiPy.Print(symbollist)
except Exception as err:
#AmiPy.Print(f"Unexpected {err=}, {type(err)=}")
print(f"Unexpected {err=}, {type(err)=}")

return symbollist

def main():
optionchain = getFuturesOptionsChainSymbols("QNG", "K", "23")
print(optionchain)

if __name__ == "__main__":
main()



New IQFeed Forum » (futures and equity) option chains using Python Apr 18, 2023 12:56 AM (Total replies: 11)

thanks for your help, I will try that

New IQFeed Forum » (futures and equity) option chains using Python Apr 16, 2023 04:03 AM (Total replies: 11)

i think I understand the idea of the csharp plugin. "GetChainFutureOption" gives the list of symbols for "Futures Options". These symbols one can then use to retrieve the data. I was thinking the data would come with it but it is just a list. So hopefully I can use this list of symbols to retrieve the data.


# https://github.com/mathpaquette/IQFeed.CSharpApiClient/blob/master/docs/USING-WITH-PYTHON.md
# Dynamically add IQFeed.CSharpApiClient DLL
# assembly_path = r"C:\<folder>"
# type in CMD window: python iqfeedcsharpapiclientOptionTest.py

assembly_path = r'C:/Program Files/AmiBroker/IQFeedCSharpApiClient'

import sys
sys.path.append(assembly_path)

# Reference IQFeed.CSharpApiClient DLL
import clr
clr.AddReference("IQFeed.CSharpApiClient")

from IQFeed.CSharpApiClient.Lookup import LookupClientFactory
from IQFeed.CSharpApiClient.Lookup.Chains import OptionSideFilterType

lookupClient = LookupClientFactory.CreateNew()
lookupClient.Connect()

ticks = lookupClient.Chains.GetChainFutureOption( "QNG", OptionSideFilterType.CP, "K", '23')

for tt in ticks:
print(tt.Symbol)

print('Completed!')



New IQFeed Forum » (futures and equity) option chains using Python Apr 16, 2023 02:15 AM (Total replies: 11)

hi, I am just an IQFeed user so I do not have access to the development documentation. I have access to futures and "futures options" data via my subscription with IQFeed.

I want to use Python to get access to "futures option" chains (and maybe I add an Equity options subscription as well at some point).

For Yahoo Equity Options data there exists Python code that allows to have acces to put and call option chain data for a specific expiration date (see example code below). It basically puts the put and call data in a pandas dataframe.

I want to make similar dataframes for the IQFeed "futures option" data. I explain further below the Python code that can access Yahoo data.


# python medium_options.py

import yfinance as yf
import matplotlib.pyplot as plt

def main():
symbol = input("Enter the Symbol: " )
#symbol = 'UNG'
osym = yf.Ticker(symbol)
exps = osym.options

print("Expiry dates:")
print(exps)
expiry = input("\nEnter the Expiry data [format: YYYY-MM-DD]: " )

#expiry = '2023-04-21'
opc = osym.option_chain(expiry)
opccalls = opc.calls
opcputs = opc.puts
print(opc.calls)
print(opc.puts)
print(')
print(opc.calls.info())

''
plt.subplot(211)
plt.plot(opccalls['strike'],opccalls['openInterest'])
plt.subplot(212)
plt.plot(opcputs['strike'],opcputs['openInterest'])
plt.show()
''

if __name__ == "__main__":
main()


The resulting dataframes looks like this:


contractSymbol lastTradeDate strike lastPrice bid ask change percentChange volume openInterest impliedVolatility inTheMoney contractSize currency
0 UNG230421P00002000 2023-03-27 13:33:21+00:00 2.0 0.05 0.00 0.04 0.00 0.000000 2.0 24 4.750004 False REGULAR USD
1 UNG230421P00003000 2023-04-10 16:31:05+00:00 3.0 0.01 0.00 0.01 0.00 0.000000 16.0 306 2.625003 False REGULAR USD
2 UNG230421P00004000 2023-04-14 14:03:58+00:00 4.0 0.01 0.00 0.01 0.00 0.000000 88.0 752 1.750001 False REGULAR USD
3 UNG230421P00004500 2023-04-14 17:42:34+00:00 4.5 0.01 0.00 0.01 0.00 0.000000 206.0 3347 1.375003 False REGULAR USD
4 UNG230421P00005000 2023-04-14 19:54:54+00:00 5.0 0.01 0.01 0.03 -0.02 -66.666670 242.0 5222 1.375003 False REGULAR USD
5 UNG230421P00005500 2023-04-14 19:55:37+00:00 5.5 0.02 0.01 0.03 -0.02 -50.000000 595.0 7400 0.984375 False REGULAR USD
6 UNG230421P00006000 2023-04-14 19:59:43+00:00 6.0 0.06 0.05 0.07 -0.08 -57.142853 6339.0 63012 0.859376 False REGULAR USD
7 UNG230421P00006500 2023-04-14 20:09:03+00:00 6.5 0.19 0.19 0.20 -0.14 -42.424248 2028.0 8081 0.828127 False REGULAR USD
8 UNG230421P00007000 2023-04-14 20:14:48+00:00 7.0 0.45 0.42 0.46 -0.23 -33.823532 1107.0 17013 0.730471 True REGULAR USD
9 UNG230421P00007500 2023-04-14 17:42:34+00:00 7.5 0.91 0.80 1.02 -0.25 -21.551720 68.0 1799 1.031255 True REGULAR USD
10 UNG230421P00008000 2023-04-14 19:43:35+00:00 8.0 1.32 1.29 1.35 -0.34 -20.481924 104.0 37005 0.781252 True REGULAR USD
11 UNG230421P00008500 2023-04-13 13:54:25+00:00 8.5 2.09 1.59 2.05 0.00 0.000000 4.0 58 0.968750 True REGULAR USD
12 UNG230421P00009000 2023-04-14 17:13:51+00:00 9.0 2.38 2.26 2.51 -0.24 -9.160297 4.0 6204 1.750001 True REGULAR USD


I have Python code to access historical data. The message rule used I found on this forum I believe. For instance I use this code to download historical futures data. Further explanation below this code.

 
def read_historical_data_socket(sock, recv_buffer=524288):
buffer = ""
data = ""
while True:
data = sock.recv(recv_buffer)
buffer += data.decode()

# Check if the end message string arrives
if "!ENDMSG!" in buffer:
break

# Remove the end message string
buffer = buffer[:-12]
# Remove protocol message at the start
buffer = buffer[22:]
return buffer

def downloadTickDataPerDay2(sym,
bdate,
edate,
filename,
dataPath):

sym = str(sym)
bdate = str(bdate)
edate = str(edate)
filename = str(filename)
dataPath = str(dataPath)

host = "127.0.0.1" # Localhost
port = 9100 # Historical data socket port
message = "HTT,%s,%s,%s,,,,1\n" % ( sym, bdate, edate )

# Open a streaming socket to the IQFeed server locally
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
sock.sendall(b'S,SET PROTOCOL,6.2\r\n')

# Send the historical data request
# message and buffer the data
sock.sendall(message.encode())
data = read_historical_data_socket(sock)
sock.close

# remove blank line at start where the protocol message was removed
data = data.strip()
# Remove all the endlines and line-ending
# comma delimiter from each record
data = "".join(data.split("\r"))
data = data.replace(",\n","\n")[:-1]
data = data.replace("LH,","")

if data != 'E,!NO_DATA!,':
# Write the data stream to disk
f = open(dataPath + sym + "//" + filename, "w")
f.write(data)
f.close()
else:
print("No Data found ....")


so I am after Python code that can either download "futures option chains" and "equity options chains". It should give
1) a list of expiration dates
2) if the expiration date is given it should put the put and call option chains in for instance pandas dataframes

Probably the Python code would be similar to the code posted just above but I do not know the correct message rule and port etc.

I will also ask Math Paquette later using his Csharp plugin. I tried to use it but the documentation is basically the Csharp source code which is slightly above my head. Here is some code using the plugin which gives some output (assuming IQFeed is launched). However, I have not been able to find the put and call data. I would however prefer pure Python code without having to use the Csharp plugin.

thanks

 
# https://github.com/mathpaquette/IQFeed.CSharpApiClient/blob/master/docs/USING-WITH-PYTHON.md
# Dynamically add IQFeed.CSharpApiClient DLL
# assembly_path = r"C:\<folder>"
# type in CMD window: python iqfeedcsharpapiclientOptionTest.py

assembly_path = r'C:/Program Files/AmiBroker/IQFeedCSharpApiClient'

import sys
sys.path.append(assembly_path)

# Reference IQFeed.CSharpApiClient DLL
import clr
clr.AddReference("IQFeed.CSharpApiClient")

# from IQFeed.CSharpApiClient import IQFeedLauncher

# Step 2 - Use the appropriate factory to create the client
from IQFeed.CSharpApiClient.Lookup import LookupClientFactory
from IQFeed.CSharpApiClient.Lookup.Chains import OptionSideFilterType

lookupClient = LookupClientFactory.CreateNew()

# Step 3 - Connect it
lookupClient.Connect()

ticks = lookupClient.Chains.GetChainFutureOption( "QNG", OptionSideFilterType.CP, "K", '23')

for tt in ticks:
print(tt.Symbol,tt.StrikePrice)
#print(dir(tt))

print('Completed!')



IQFeed API Questions » IQFeed API documentation source? Oct 18, 2022 08:00 AM (Total replies: 15)

to finish off my message marathon here is the solution and I have to so say it works great

So when loading Python you have to additionally load:

 
clr.AddReference('System.Collections')
from System import DateTime


then to get the data between 2 dates is done by using for instance

 
d1 = DateTime(2022,10,17,9,10,10)
d2 = DateTime(2022,10,18,8,0,0)
ticksFilename = lookupClient.Historical.File.GetHistoryTickTimeframe(sym,d1,d2,None,None,None,1)


so the parameters used in DatetTime are Year, Month, Day, Hour, Minute, Second
Edited by emp on Oct 18, 2022 at 08:00 AM

IQFeed API Questions » IQFeed API documentation source? Oct 18, 2022 03:51 AM (Total replies: 15)

well I made some progress. At least it seems to accept the type: <class 'System.DateTime'>

so this code at least makes the function work. So making some progress. I know the type it needs now. Still getting some weird results but I have something to work with now


import clr
from pandas import to_datetime, Series
clr.AddReference('System.Collections')
from System.Collections.Generic import List
from System import DateTime
Contracts = to_datetime(Series(['13/10/2022','14/10/2022']))

DateList = List[DateTime](range(len(Contracts)))
for i in range(len(Contracts)):
DateList.Add(DateTime(Contracts.year,Contracts.month,Contracts.day))

d1 = DateList.get_Item(0)
d2 = DateList.get_Item(1)

ticksFilename = lookupClient.Historical.File.GetHistoryTickTimeframe("@ES#",d1,d2,None,None,None,1)


Edited by emp on Oct 18, 2022 at 03:52 AM

IQFeed API Questions » IQFeed API documentation source? Oct 18, 2022 02:37 AM (Total replies: 15)

and I know the endDate and beginDate are supposed to be of the DateTime type. I also tried this, see console printout below. Again I get a type error. So it does not accept "datetime" types and also no "str" types. Also no "int" types ....


Python 3.8.5 (tags/v3.8.5:580fbb0, Jul 20 2020, 15:57:54) [MSC v.1924 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> import clr
>>> assembly_path = r'C:/Program Files/AmiBroker/IQFeedCSharpApiClient'
>>> sys.path.append(assembly_path)
>>> clr.AddReference("IQFeed.CSharpApiClient")
<System.Reflection.RuntimeAssembly object at 0x000002E7DA40BDC0>
>>> import time
>>> import numpy as np
>>> import pandas as pd
>>> from IQFeed.CSharpApiClient.Lookup import LookupClientFactory
>>> from IQFeed.CSharpApiClient.Lookup.Historical.Messages import TickMessage
>>> import datetime
>>> from System import DateTime
>>>
>>> # Create Lookup client
>>> lookupClient = LookupClientFactory.CreateNew()
>>> # Connect
>>> lookupClient.Connect()
>>> d1 = datetime.date(2022, 10, 13)
>>> d2 = datetime.date(2022, 10, 14)
>>> d1
datetime.date(2022, 10, 13)
>>> d2
datetime.date(2022, 10, 14)
>>> ticksFilename = lookupClient.Historical.File.GetHistoryTickTimeframe("@ES#",d1,d2,None,None,None,1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: No method matches given arguments for GetHistoryTickTimeframe: (<class 'str'>, <class 'datetime.date'>, <class 'datetime.date'>, <class 'NoneType'>, <class 'NoneType'>, <class 'NoneType'>, <class 'int'>)
>>>


IQFeed API Questions » IQFeed API documentation source? Oct 18, 2022 01:32 AM (Total replies: 15)

hi, in response to an email from Gary:


I'd need to know what command mathpaquette is trying to send, and what failure message you're getting. An iqconnect log file would be helpful. To generate one, open the Diagnostics app and go to the Logging tab. Make sure "lookup request" "lookup data" and "lookup error" are all checked. Try making the request again in mathpaquette. then go back to the diagnostics tab and collect the log file. You can email it to support or post it here, and I can review it.


I add the diagnostics file but it seems no info there on the error. So I explain what I do. The IQFeed connection manager is launched via Amibroker. So I test the code in the Python 3.8 console.

First I load into the console:


import sys
import clr
assembly_path = r'C:/Program Files/AmiBroker/IQFeedCSharpApiClient'
sys.path.append(assembly_path)
clr.AddReference("IQFeed.CSharpApiClient")
import time
import numpy as np
import pandas as pd
from IQFeed.CSharpApiClient.Lookup import LookupClientFactory
from IQFeed.CSharpApiClient.Lookup.Historical.Messages import TickMessage
from datetime import datetime

# Create Lookup client
lookupClient = LookupClientFactory.CreateNew()
# Connect
lookupClient.Connect()



so in the console what I did looks like:


 
Python 3.8.5 (tags/v3.8.5:580fbb0, Jul 20 2020, 15:57:54) [MSC v.1924 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> import clr
>>> assembly_path = r'C:/Program Files/AmiBroker/IQFeedCSharpApiClient'
>>> sys.path.append(assembly_path)
>>> clr.AddReference("IQFeed.CSharpApiClient")
<System.Reflection.RuntimeAssembly object at 0x000002560C99BDC0>
>>> import time
>>> import numpy as np
>>> import pandas as pd
>>> from IQFeed.CSharpApiClient.Lookup import LookupClientFactory
>>> from IQFeed.CSharpApiClient.Lookup.Historical.Messages import TickMessage
>>> from datetime import datetime
>>>
>>> # Create Lookup client
>>> lookupClient = LookupClientFactory.CreateNew()
>>> # Connect
>>> lookupClient.Connect()
>>>
>>>
>>> ticksFilename = lookupClient.Historical.File.GetHistoryTickDatapoints("@ES#",100,1)
>>> ticksFilename = lookupClient.Historical.File.GetHistoryTickDays("@ES#",1,None,None,None,1)
>>> ticksFilename = lookupClient.Historical.File.GetHistoryTickTimeframe("@ES#","20221013 093001","20221014 093020")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: No method matches given arguments for GetHistoryTickTimeframe: (<class 'str'>, <class 'str'>, <class 'str'>)
>>> ticksFilename = lookupClient.Historical.File.GetHistoryTickTimeframe("@ES#","20221013","20221014",None,None,None,1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: No method matches given arguments for GetHistoryTickTimeframe: (<class 'str'>, <class 'str'>, <class 'str'>, <class 'NoneType'>, <class 'NoneType'>, <class 'NoneType'>, <class 'int'>)
>>> ticksFilename = lookupClient.Historical.File.GetHistoryTickTimeframe("@ES#")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: No method matches given arguments for GetHistoryTickTimeframe: (<class 'str'>)
>>> ticksFilename = lookupClient.Historical.File.GetHistoryTickTimeframe("@ES#",None,None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
System.ArgumentException: Begin date or End date must have value.
at IQFeed.CSharpApiClient.Lookup.Historical.Facades.HistoricalFileFacade.GetHistoryTickTimeframe(String symbol, Nullable`1 beginDate, Nullable`1 endDate, Nullable`1 maxDatapoints, Nullable`1 beginFilterTime, Nullable`1 endFilterTime, Nullable`1 dataDirection, String requestId, Nullable`1 datapointsPerSend)
>>>



as you can see I use 2 of the 3 tickMessage functions succesfully, these 2:

 
ticksFilename = lookupClient.Historical.File.GetHistoryTickDatapoints("@ES#",100,1)
ticksFilename = lookupClient.Historical.File.GetHistoryTickDays("@ES#",1,None,None,None,1)


there is a third function in which you can add the beinDate/Time endDate/Time. I tried all kinds of formats. For this error log I tried these 4:

 
ticksFilename = lookupClient.Historical.File.GetHistoryTickTimeframe("@ES#","20221013 093001","20221014 093020")
ticksFilename = lookupClient.Historical.File.GetHistoryTickTimeframe("@ES#","20221013","20221014",None,None,None,1)
ticksFilename = lookupClient.Historical.File.GetHistoryTickTimeframe("@ES#")
ticksFilename = lookupClient.Historical.File.GetHistoryTickTimeframe("@ES#",None,None)


as you can see from the 4-th error message in the console it knows the function since the error it gives is:

 
>>> ticksFilename = lookupClient.Historical.File.GetHistoryTickTimeframe("@ES#",None,None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
System.ArgumentException: Begin date or End date must have value.
at IQFeed.CSharpApiClient.Lookup.Historical.Facades.HistoricalFileFacade.GetHistoryTickTimeframe(String symbol, Nullable`1 beginDate, Nullable`1 endDate, Nullable`1 maxDatapoints, Nullable`1 beginFilterTime, Nullable`1 endFilterTime, Nullable`1 dataDirection, String requestId, Nullable`1 datapointsPerSend)
>>>


I can see the 2 successful requests in the log, but not the last 4 unsuccessful. Going through the csharp source code I am pretty sure the format for the beginDate and endDate needs to be like:

"yyyyMMdd HHmmss"

And I also have other pure Python code that just passes the beginDate and endDate as strings in which I use (and this actually WORKS):


fdate = next_day.strftime("%Y") + next_day.strftime("%m") + next_day.strftime("%d") # format YYYYMMDD
message = "HTT,%s,%s,%s,,,,1\n" % ( sym, fdate, fdate )


I tried about everything so I hope someone can figure it out.

thanks

IQFeed API Questions » IQFeed API documentation source? Oct 17, 2022 05:26 AM (Total replies: 15)

hi,

i wonder if someone else is playing around with this. So I am already making good progress. From the examples (see csharp manual by mathpagquette) I can get for instance 1000 lines of data using:

 
ticksFilename = lookupClient.Historical.File.GetHistoryTickDatapoints("@ES#", 1000, 1)


also I succeeded getting a certain number of days using, e.g.


ticksFilename = lookupClient.Historical.File.GetHistoryTickDays("@ES#",3,None,None,None,1)


I am however having difficulties getting tick data from a begindate to an enddate.

In the source the format is given as:

 
public string GetHistoryTickTimeframe(string symbol, DateTime? beginDate, DateTime? endDate, int? maxDatapoints = null,
TimeSpan? beginFilterTime = null, TimeSpan? endFilterTime = null, DataDirection? dataDirection = null,
string requestId = null, int? datapointsPerSend = null)
{
return GetHistoryTickTimeframeAsync(symbol, beginDate, endDate, maxDatapoints, beginFilterTime,
endFilterTime, dataDirection, requestId, datapointsPerSend).SynchronouslyAwaitTaskResult();
}



so I tried:

 
ticksFilename = lookupClient.Historical.File.GetHistoryTickTimeframe("@ES#",20221013,20221014,None,None,None,1)


but it rejects this. I tried various alternatives but it doesn't accept it. Could someone show the proper format? I use the same dateformat as IQFeed uses. I tried passing it as a string but no success

Thanks

IQFeed Developer Support » Error processing news story counts from server Oct 16, 2022 11:18 AM (Total replies: 17)

well today it is already Sunday. Still no access to historical data here. Well I give up for today

IQFeed API Questions » IQFeed API documentation source? Oct 16, 2022 04:34 AM (Total replies: 15)

already found this "ticks.csv" file. So this can be read at once into pandas and is very fast. Pretty excited about this.

Unfortunately the server is still down. At least I can't get historical data. Looks like everyone at IQFeed is on holiday. Is there no STATUS page or something like that? Since it is down now for more than 24 hours. I know it is weekend but some people need to write code in the weekends. Strange, seems like everybody left the shop. Guess they will show up around 9AM ET tomorrow (if we are lucky).

IQFeed Developer Support » Error processing news story counts from server Oct 16, 2022 12:01 AM (Total replies: 17)

IQFeed has been down since Saturday. Or I can connect to the server but it does not give historical data. I am in the EU but I also checked with fellow trader in Singapore and he is not getting data either. So the problem is with IQFeed. This is a pain since I was working on code over the weekend. Code that is supposed to get historical and streaming data so I can not work on that over the whole weekend ...


Time: Tue April 16, 2024 5:50 PM CFBB v1.2.0 13 ms.
© AderSoftware 2002-2003