使用 Python 从 DTN IQFeed 下载历史日内美国股票数据
在本文中,我们将讨论如何从DTN IQFeed市场数据供应商处获取日内历史美国股票数据。可以通过创建帐户时提供的本地 IQLink 服务器套接字连接获取数据。在本文中,我们将利用 Python 的流式套接字连接来缓冲这些数据并创建美国股票日内市场数据的 CSV 文件。
注意:我与 DTN IQFeed 没有任何关系,只是客户而已。我写这篇文章只是为了帮助那些拥有 IQFeed 帐户(或正在考虑获取帐户)的人无需 GUI 软件即可下载数据。
与 IQFeed 的 Python 套接字连接
我假设您已经拥有 IQFeed 帐户。如果没有,那么您可以在注册后获得两周的免费试用。在注册所需的交易所和数据粒度级别后,您将被要求下载 IQLink 启动器。此工具仅在 Windows 上本机运行,但只需稍加操作即可在 Mac 或 Linux 机器上使用 WINE 执行!
启动 IQLink 启动器会弹出连接对话框:
DTN IQFeed IQLink 启动器
单击“启动 IQLink”将启动服务器。系统将提示您输入用户名和密码。服务器运行后,需要创建到本地端口(默认为 9100)的流套接字连接。然后,您可以通过此套接字发送消息并以缓冲方式接收数据。
第一项任务是创建iqfeed.py
文件并导入系统库和套接字库:
# iqfeed.py
import sys
import socket
数据缓冲由read_historical_data_socket
函数处理。它需要一个套接字对象和每次读取缓冲的字节数。该函数只是将最新一批缓冲数据附加到字符串中,并在找到“!ENDMSG!”字符串后返回它(即缓冲区已到达数据末尾!):
# iqfeed.py
def read_historical_data_socket(sock, recv_buffer=4096):
"""
Read the information from the socket, in a buffered
fashion, receiving only 4096 bytes at a time.
Parameters:
sock - The socket object
recv_buffer - Amount in bytes to receive per read
"""
buffer = ""
data = ""
while True:
data = sock.recv(recv_buffer)
buffer += data
# Check if the end message string arrives
if "!ENDMSG!" in buffer:
break
# Remove the end message string
buffer = buffer[:-12]
return buffer
套接字必须连接到本地机器的端口 9100。在这个例子中,我们将下载从 2014 年初到现在的四个股票代码:SPY、AAPL、GOOG 和 AMZN。
IQFeed 接受以下格式的消息:CMD,SYM,[options]\n
。请注意换行符。必须添加换行符,否则消息将不起作用。提供的选项是 [以秒为单位的条数]、[开始日期:CCYYMMDD HHmmSS]、[结束日期:CCYYMMDD HHmmSS]、[空]、[开始时间过滤器:HHmmSS]、[结束时间过滤器:HHmmSS]、[旧或新:0 或 1]、[空]、[每秒队列数据点数]。
我们将使用以下示例消息:"HIT,GOOG,60,20140101 075000,,,093000,160000,1\n"
。这表示返回HIT
GOOG 股票代码的历史数据 (),频率为每 60 秒一次(即每分钟条形图),从 2014 年 1 月 1 日 07:50:00 开始,没有结束(即到“昨天”为止)。使用新数据,数据经过筛选,仅显示从 09:30:00 到 16:00:00 的数据,这是纽约证券交易所市场时间的开盘时间。
第一个任务是定义要下载的主机、端口和符号。循环遍历四个符号中的每一个,并构造历史数据的消息。然后打开一个套接字。AF_INET
指定(host, port)
连接时应预期一个元组。SOCK_STREAM
指出套接字应为流套接字。
一旦打开套接字,就会发送消息并缓冲历史数据,之后关闭套接字。所有行尾都会被删除,数据会写入与 Python 代码位于同一目录中的名为“sym.csv”的文件中,其中“sym”是股票代码:
# iqfeed.py
if __name__ == "__main__":
# Define server host, port and symbols to download
host = "127.0.0.1" # Localhost
port = 9100 # Historical data socket port
syms = ["SPY", "AAPL", "GOOG", "AMZN"]
# Download each symbol to disk
for sym in syms:
print "Downloading symbol: %s..." % sym
# Construct the message needed by IQFeed to retrieve data
message = "HIT,%s,60,20140101 075000,,,093000,160000,1\n" % sym
# Open a streaming socket to the IQFeed server locally
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
# Send the historical data request
# message and buffer the data
sock.sendall(message)
data = read_historical_data_socket(sock)
sock.close
# Remove all the endlines and line-ending
# comma delimiter from each record
data = "".join(data.split("\r"))
data = data.replace(",\n","\n")[:-1]
# Write the data stream to disk
f = open("%s.csv" % sym, "w")
f.write(data)
f.close()
数据格式如下:
[YYYY-MM-DD HH:mm:SS],[OPEN],[LOW],[HIGH],[CLOSE],[VOLUME],[OPEN INTEREST]
文件中的一组典型行如下:
2012-01-03 09:31:00,30.6400,30.5000,30.6400,30.5100,6128,6128
2012-01-03 09:32:00,30.5600,30.4900,30.4900,30.5600,6528,400
2012-01-03 09:33:00,30.5000,30.5000,30.5000,30.5000,6672,144
2012-01-03 09:34:00,30.3800,30.3400,30.3400,30.3500,8423,1751
2012-01-03 09:35:00,30.5300,30.5300,30.5300,30.5300,8623,200
2012-01-03 09:36:00,30.6400,30.5500,30.5500,30.6400,9423,800
2012-01-03 09:37:00,30.6500,30.6500,30.6500,30.6500,10329,906
2012-01-03 09:38:00,30.6900,30.6600,30.6900,30.6600,12329,2000
2012-01-03 09:39:00,30.7200,30.6400,30.6500,30.7200,13729,1400
2012-01-03 09:40:00,30.7500,30.6900,30.7200,30.7500,17029,3300
就可用年份而言,这些数据可以追溯到很久以前。但是,一旦您开始考虑大量可追溯到五年或更久以前的符号,下载可能需要一些时间。如果您希望下载除股票以外的数据类型,请查看 IQFeed符号指南。显然,您需要订阅相应的交易所才能下载符号。
w.iqfeed.net/symbolguide/index.cfm?symbolguide=guide&displayaction=support§ion=guide&web=iqfeed)。显然,您需要订阅相应的交易所才能下载符号。
请注意, IQFeed 提供的日内数据未经调整。也就是说,它不考虑股息或股票分割等公司行为。您需要自行处理公司行为。