Initial commit of IQFeed API client

This commit is contained in:
moshferatu 2023-09-15 13:09:39 -07:00
parent f12b5edf8c
commit 71379aba8e
4 changed files with 113 additions and 0 deletions

0
iqfeed/__init__.py Normal file
View File

102
iqfeed/iqfeed.py Normal file
View File

@ -0,0 +1,102 @@
import pandas as pd
import socket
from datetime import datetime
from io import StringIO
def read_data_from_socket(sock, recv_buffer=4096):
buffer = b''
data = b''
while True:
data = sock.recv(recv_buffer)
buffer += data
if b'!ENDMSG!' in buffer:
break
# Remove the ENDMSG string
buffer = buffer[:-12]
return buffer.decode('utf-8')
def _get_daily_data(symbol: str, max_days: int) -> pd.DataFrame:
host = '127.0.0.1'
port = 9100 # Historical data socket port
message = 'HDX,{symbol},{max_days},1\n'.format(
symbol=symbol,
max_days=max_days
)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
sock.sendall(message.encode('utf-8'))
data = read_data_from_socket(sock)
sock.close()
# Remove extraneous line endings
data = ''.join(data.split('\r'))
data = data.replace(',\n','\n')[:-1]
data = StringIO(data)
return pd.read_csv(data, index_col=False,
names=['Date', 'High', 'Low', 'Open', 'Close', 'Total Volume', 'Period Volume'])
def get_daily_data(symbol: str, start_date: datetime, end_date: datetime) -> pd.DataFrame:
max_days = (datetime.today() - start_date).days
data = _get_daily_data(symbol, max_days)
# Filter data between start_date and end_date
data['Date'] = pd.to_datetime(data['Date'])
data['Date'] = data['Date'].dt.date
data = data[(data['Date'] >= start_date.date()) & (data['Date'] <= end_date.date())]
data = data.reset_index(drop=True)
return data
def seconds(value):
return value
def minutes(value):
return value * 60
def hours(value):
return value * 3600
def get_historical_data(symbol: str, interval: int,
start_date: datetime, end_date: datetime = None,
start_filter_time: datetime = datetime.strptime('093000', '%H%M%S').time(),
end_filter_time: datetime = datetime.strptime('160000', '%H%M%S').time()) -> pd.DataFrame:
host = '127.0.0.1'
port = 9100 # Historical data socket port
message = 'HIT,{symbol},{interval},{begin},{end},,{begin_filter},{end_filter},1\n'.format(
symbol=symbol,
interval=interval,
begin=start_date.strftime('%Y%m%d %H%M%S'),
end=end_date.strftime('%Y%m%d %H%M%S') if end_date else '',
begin_filter=start_filter_time.strftime('%H%M%S') if start_filter_time else '',
end_filter=end_filter_time.strftime('%H%M%S') if end_filter_time else ''
)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
sock.sendall(message.encode('utf-8'))
data = read_data_from_socket(sock)
sock.close()
# Remove extraneous line endings
data = ''.join(data.split('\r'))
data = data.replace(',\n','\n')[:-1]
data = StringIO(data)
return pd.read_csv(data, index_col=False,
names=['Date', 'High', 'Low', 'Open', 'Close', 'Total Volume', 'Period Volume'])
if __name__ == '__main__':
symbols = ['SPY']
start_date = datetime(2023, 1, 1, 7, 50)
end_date = datetime(2023, 1, 31, 16, 0)
for symbol in symbols:
data = get_historical_data(symbol, minutes(5), start_date, end_date)
data.to_csv(symbol + '.csv')

1
requirements.txt Normal file
View File

@ -0,0 +1 @@
pandas

10
setup.py Normal file
View File

@ -0,0 +1,10 @@
from setuptools import setup, find_packages
setup(
name="iqfeed",
version="1.0",
packages=find_packages(),
install_requires=[
'pandas'
]
)