In questo articolo voglio presentare un approccio per scaricare i dati storici intraday delle azioni statunitensi  dal fornitore di dati DTN IQFeed. È possibile ottenere i dati tramite una connessione socket al server locale IQLink che viene fornito quando si crea un account. In questo articolo utilizzeremo una connessione di streaming socket con Python per bufferizzare questi dati e creare file CSV di dati infragiornalieri il mercato  delle azioni statunitensi.

Nota: non ho alcuna affiliazione con DTN IQFeed oltre ad essere un loro cliente. Sto semplicemente scrivendo questo articolo per aiutare coloro che hanno un account IQFeed (o stanno prendendo in considerazione l’idea di acquistarne uno) per scaricare i dati senza la necessità di un software GUI.

Connessioni Socket in Python per IQFeed

Ipotizziamo che tu abbia già un account con IQFeed. In caso contrario, è possibile ottenere una prova gratuita di due settimane al momento dell’iscrizione.

Dopo esserti iscritto agli  exchange e al livello di granularità dei dati che si desidera, ti verrà chiesto di scaricare il launcher IQLink. Questo strumento funziona solo in modo nativo su Windows ma può essere eseguito anche su un Mac o una macchina Linux con WINE e un po ‘di lavoro!

L’avvio di IQLink avvia la finestra di dialogo di connessione:

Facendo clic su “Avvia IQLink” verrà avviato il server. Ti verrà richiesto il nome utente e la password. Una volta che il server è in esecuzione, è necessario creare una connessione Stream Socket  a una porta locale (9100 è l’impostazione predefinita). È quindi possibile inviare messaggi attraverso questo socket e ricevere i dati. Il primo compito è creare il file iqfeed.py e importare sia il sistema che le librerie di socket:
# iqfeed.py

import sys
import socket
Il buffering dei dati viene gestito dalla funzione read_historical_data_socket, che richiede in input un oggetto socket e il numero di byte da prelevare per ogni. La funzione aggiunge semplicemente l’ultima serie di dati prelevati ad una stringa e la restituisce una volta che trova la stringa “! ENDMSG!” all’interno dei dati (cioè il buffer ha raggiunto la fine!):
# 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

Il socket deve connettersi al computer locale sulla porta 9100. In questo esempio, scarichiamo quattro simboli di azioni: SPY, AAPL, GOOG e AMZN dall’inizio del 2014 ad oggi.

IQFeed accetta messaggi nel seguente formato: CMD,SYM,[options]\n. Si noti il carattere “newline”, che deve aggiunta altrimenti il messaggio non funzionerà. Le opzioni fornite sono [bars in seconds], [beginning date: CCYYMMDD HHmmSS], [ending date: CCYYMMDD HHmmSS], [empty],[beginning time filter: HHmmSS], [ending time filter: HHmmSS], [old or new: 0 or 1], [empty] ,[queue data points per second].

Ad esempio il messaggio avrà un formato simile al seguente: "HIT,GOOG,60,20140101 075000,,,093000,160000,1\n". Questo messaggio ci restituisce i dati storici (HIT) per il simbolo del ticker GOOG, ad frequenza pari a una volta ogni 60 secondi (ad es. Timeframe ad un minuto), dalle 07:50:00 del 1 ° gennaio 2014 fino ad oggi. I dati vengono filtrati per essere presenti solo dalle 09:30:00 alle 16:00:00, che è l’orario di apertura del mercato NYSE.

Il primo compito è definire l’host, la porta e i simboli per il download. Ciascuno dei quattro simboli viene ripetuto e viene creato il messaggio per i dati storici. Quindi viene aperto un socket. AF_INET specifica che una tupla (host, port) deve essere prevista durante la connessione. SOCK_STREAM afferma che il socket deve essere un socket di streaming.

Una volta aperto il socket, il messaggio viene inviato e i dati cronologici vengono memorizzati nel buffer, dopodiché il socket viene chiuso. Tutte le terminazioni di riga vengono rimosse e i dati vengono scritti in un file chiamato “sym.csv” archiviato nella stessa directory del codice Python, dove “sym” è il simbolo ticker:

# 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()
I dati restituite hanno il seguente formato: [YYYY-MM-DD HH:mm:SS],[OPEN],[LOW],[HIGH],[CLOSE],[VOLUME],[OPEN INTEREST] Quindi le righe all’interno del file dovrebbero essere come segue:
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
I dati disponibili su IQFeed possono risalire anche a molti anni indietro. Tuttavia, può essere necessario del tempo per scaricarli una volta che si inizia a considerare i dati di molti simboli, risalenti a cinque o più anni di storico. Se desideri scaricare tipi di dati diversi dalle azioni, puoi consultare la guida di IQFeed. Ovviamente è necessario essere abbonati all’exchange appropriato affinché il download del simbolo funzioni. Tieni presente che i dati intraday forniti da IQFeed non sono “aggiustati”. Ciò significa che non tiene conto degli eventi societarie come i  dividendi o le scissioni di azioni. Dovrai personalmente seguire la correzione dei prezzi delle azioni.

Recommended Posts