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):
    """
    Lettura delle informazioni dal socket, in un buffer
    su misura, ricevendo solo 4096 byte alla volta.

    Parametri:
    sock - L'oggetto socket
    recv_buffer - Quantità in byte da ricevere per lettura
    """

    ibuffer = ""
    data = ""
    while True:
        data = sock.recv(recv_buffer)
        ibuffer += data

        # Controllo se è arrivata la stringa di fine messaggio
        if "!ENDMSG!" in ibuffer:
            break

    # Rimuovere la stringa di fine messaggio
    ibuffer = ibuffer[:-12]
    return ibuffer
        

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__":
    # Definizione dell'host del server, la porta e il simbolo da scaricare
    host = "127.0.0.1"  # Localhost
    port = 9100  # porta del socket per i dati storici
    syms = ["SPY", "AAPL", "GOOG", "AMZN"]

    # Download ogni simbolo su disco
    for sym in syms:
        print "Downloading symbol: %s..." % sym

        # Costruzione del messaggio previsto da IQFeed per ricevere i dati
        message = "HIT,%s,60,20140101 075000,,,093000,160000,1\n" % sym

        # Apertura di un socket streaming localmente verso un server IQFeed
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.connect((host, port))

        # Invia i messaggi per le richieste di dati 
        # storici e immagazziona i dati
        sock.sendall(message)
        data = read_historical_data_socket(sock)
        sock.close

        # Rimuovere tutte le linee finali e le virgole di fine
        # linea che delimitano ogni record
        data = "".join(data.split("\r"))
        data = data.replace(",\n","\n")[:-1]

        # Scrive il flusso dei deti sul disco
        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.

 

Per il codice completo riportato in questo articolo utilizzando il modulo di backtesting vettoriale VectorBacktest si può consultare il seguente repository di github:
https://github.com/datatrading-info/VectorBacktest

Recommended Posts