dati Forex di Polygon

Creare una serie dei rendimenti con i dati Forex di Polygon

In questo articolo descriviamo come creare una serie temporale dei rendimenti  dei prezzi in Python usando i dati Forex di Polygon. Descriviamo come accedere all’API Polygon e scaricare un mese di dati Forex intraday. Vediamo come come accedere all’API, creando una funzione Python che può essere facilmente  modificata per estrarre dati FX per varie coppie in diversi timeframe. Creiamo e visualizziamo una serie dei rendimenti con la libreria Pandas.

Questo articolo fa parte della serie di tutorial relativi all’analisi dei Dati Finanziari per il Trading Algoritmico. Negli articoli successivi usiamo la volatilità realizzata per addestrare un modello di apprendimento automatico e prevedere il regime di mercato.

Per seguire il codice di questo tutorial abbiamo bisogno di:

  • Python 3.9
  • Matplotlib 3.5
  • Pandas 1.4
  • Requests 2.27

Polygon.io e il mercato Forex

Il mercato Forex è costituito da coppie FX principali,  altamente scambiate, e coppie FX scarsamente scambiate o esotiche. Attualmente la maggior parte del volume delle transazioni Forex viene effettuato su tre principali coppie FX; EURUSD, USDJPY e GBPUSD. Tuttavia, ci sono molte altre combinazioni di coppie.

dati Forex di Polygon

Polygon dispone di dati su 1000 coppie forex. Polygon.io è stato fondato nel 2006 e “Costruito da sviluppatori per sviluppatori”. Vogliono fornire agli sviluppatori un accesso  facile e semplice ai dati finanziari più accurati ad oggi disponibili, sia storici che in tempo reale. Polygon offre un’API per i dati sulle azioni, opzioni, criptovalute e Forex. Hanno una copertura del mercato del 100% per le azioni statunitensi, con dati provenienti da tutte le borse statunitensi e dalle sedi OTC. I dati sulle opzioni includono contratti di opzioni attivi e storici, greche e volatilità implicita. Inoltre, Polygon dispone di 166 ticker di valute Crypto con dati provenienti da quattro diversi exchange tra cui Coinbase e Kraken. Per i dati Forex, offrono aggiornamenti tick by tick su tutte le 1000 coppie di valute. Con la licenza d’uso individuale i dati Crypto e Forex vengono concessi in licenza insieme su un pacchetto Basic (gratuito) o Currencies Starter (premium).

In questo articolo usiamo l’API di Polygon per ottenere 1 mese di dati Forex intraday (con timeframe ad 1 minuto) per una coppia FX principale e una esotica. Descriviamo come ottenere i dati dall’API tramite le librerie simplejson e requests di Python. Creiamo poi la serie dei rendimenti per entrambe le coppie FX usando le funzioni di Pandas ed esploriamo alcuni dei metodi che possiamo applicare quando lavoriamo e visualizziamo i dati delle serie temporali. Iniziamo sottoscrivendo un abbonamento  Basic Currencies. Questo abbonamento è gratuito e fornisce una chiave API che possiamo usare per accedere ai dati Forex.

Usare l’API  di Polygon

Colleghiamoci al sito web di Polygon e premiamo sul pulsante “Get your free API key”. Dopo esserci registrati e aver effettuato l’accesso, possiamo visualizzare la chiave API nel menu a discesa Dashboard selezionando la voce API Key. La chiave Key è visualizzata anche quando  accediamo alla documentazione. La documentazione di Polygon è incredibilmente completa e facile da usare. Possiamo formulare una request all’API tramite i menu a tendina presenti sul sito. Dopo aver selezionato le opzioni richieste, si visualizza l’URL dell’API sotto il menu a discesa. Dai un’occhiata alla documentazione introduttiva per vederlo in azione.

Una delle prime cose da notare sul parametro forexTicker nell’endpoint dell’API dei dati di mercato è che tutte le coppie FX in Polygon hanno il prefisso C:, quindi per EURUSD dobbiamo usare  C:EURUSD nella chiamata all’API. Se non siamo sicuri del ticker corretto da utilizzare, possiamo eseguire una query sull’endpoint dei dati di riferimento usando il parametro Tickers. In questo caso possiamo specificare il mercato a cui siamo interessato (FX, criptovalute, azioni, ecc.) e lasciando vuoto il parametro ticker possiamo ottenere tutti i ticker per quel mercato. L’impostazione predefinita per il parametro limit restituisce 100 risultati, che possiamo modificare fino a un massimo di 1000. Ora che sappiamo come sono formattati i ticker, diamo un’occhiata a come verrà formato il resto della chiamata API.

Ogni chiamata API all’endpoint dei dati di mercato inizia con lo stesso indirizzo https https://api/polygon.io/v2/aggs/ e ogni chiamata API termina con la tua chiave API univoca. Quindi nel codice dobbiamo creare variabili per evitare ripetizioni. Di seguito iniziamo a creare il codice che collegarci all’API.

				
					import json
import matplotlib.pyplot as plt
import pandas as pd
import requests

POLYGON_API_KEY = 'YOUR_API_KEY'
HEADERS = {
    'Authorization': 'Bearer ' + POLYGON_API_KEY 
}
BASE_URL = 'https://api.polygon.io/v2/aggs'
				
			

Abbiamo creato tre variabili globali che possono  essere usate da tutte le funzioni che creiamo nel codice.  La variabile POLYGON_API_KEY memorizza la chiave API in modo che non dobbiamo scriverla continuamente. Il dizionario HEADERS contiene l’intestazione dell’autorizzazione come mostrato nella documentazione introduttiva di Polygon. Infine abbiamo BASE_URL che contiene l’inizio della chiamata API. Ora siamo pronti per creare la nostra prima funzione che effettua la chiamata API per i dati Forex ad un minuto.

				
					pg_tickers = ["C:EURUSD", "C:MXNZAR"]

def get_fx_pairs_data(pg_tickers):
    start = '2023-01-01'
    end = '2023-01-31'
    multiplier = '1'
    timespan = 'minute'
    fx_url = f"range/{multiplier}/{timespan}/{start}/{end}?adjusted=true&sort=asc&limit=50000"
    fx_pairs_dict = {}
    for pair in pg_tickers:
        response = requests.get(
            f"{BASE_URL}ticker/{pair}/{fx_url}", 
            headers=HEADERS
        ).json()
        fx_pairs_dict[pair] = pd.DataFrame(response['results'])
    return fx_pairs_dict
				
			

La funzione get_fx_pairs_data(pg_tickers) prevede il parametro pg_tickers. Questo parametro è semplicemente una lista di ticker che può essere definito in __main__. Questa lista può essere facilmente estesa, ma ricordiamo che usare una chiave API gratuita permette solo 5 chiamate API al minuto. Abbiamo scelto di usare la coppia principale EURUSD (Euro : Dollaro USA) e la coppia esotica MZXZAR (Peso messicano : Rand sudafricano). Puoi scegliere di selezionare i ticker che preferisci. 

All’interno della funzione definiamo le variabili start, end, multiplier, timespan in modo da modificare facilmente il timeframe e l’intervallo di tempo dei dati che vogliamo ottenere. Successivamente inseriamo tutte le parti dell’URL nella variabile fx_url. Quindi (come abbiamo fatto nei tutorial precedenti) possiamo creare il dizionario di DataFrames fx_pairs_dict con il ticker come chiave e i dati OHLC come valore. Per approfondimenti è possibile consultare l’articolo su tiingo. Ora possiamo chiamare la funzione e i dati  sono archiviati nella variabile fx_pairs_dict.

				
					fx_pairs_dict = get_fx_pairs_data(pg_tickers)
				
			

Possiamo accedere ai dati per ciascuna coppia chiamando la variabile dict con la chiave per la coppia fx.

				
					print(fx_pairs_dict['C:EURUSD'])
				
			
dati Forex di Polygon

Un elenco completo del contenuto dei dati è disponibile nella documentazione di Polygon. Le colonne che attualmente ci interessano includono c, il prezzo di chiusura rettificato e t, il timestamp. Come possiamo vedere, il timestamp è un valore Unix Msec. La prossima funzione lo converte in un datetime e lo imposta come indice.

				
					
def format_fx_pairs(fx_pair_dict):
    for pair in fx_pairs_dict.keys():
        fx_pairs_dict[pair]['t'] = pd.to_datetime(fx_pairs_dict[pair]['t'],unit='ms')
        fx_pairs_dict[pair] = fx_pairs_dict[pair].set_index('t')
    return fx_pairs_dict
				
			

Ora possiamo chiamare la funzione e passare il fx_pairs_dict come segue:

				
					formatted_fx_pairs = format_fx_pairs(fx_pairs_dict)
				
			

In questo modo salviamo i DataFrames formattati in una variabile chiamata formatted_fx_dict.

Visualizzare i prezzi di chiusura

Ora possiamo visualizzare la serie di prezzi di chiusura dei dati Forex di Polygon, come mostrato nel codice seguente.

				
					
for pair in formatted_fx_pairs:
    formatted_fx_pairs[pair].plot(y='c', figsize=(16, 10))
				
			

La seguente figura mostra la la coppia EURUSD. Sfortunatamente, come possiamo vedere, ci sono delle lacune nei dati che vengono visualizzati come pendenze ripetute interpolate linearmente. Quattro di questi sono visibili per EURUSD. Se esaminiamo i dati più da vicino scopriamo che questi gap coincidono con periodi in cui non venivano effettuate negoziazioni. Per la nostra principale coppia FX, EURUSD, che è altamente scambiata, questi eventi si verificano raramente.

dati-azionari-polygon-eurusd_ts_index

Lo stesso fenomeno si osserva nella coppia esotica MZXZAR. Poiché questa coppia non viene scambiata molto spesso, possiamo vedere che l’interpolazione avvenire con una frequenza molto maggiore.

dati-azionari-polygon-mzxzar_ts_index

Le lacune sono causate dal modo in cui la funzione di disegno gestisce l’indice DateTime. L’asse x è una serie temporale uniforme che va dall’inizio alla fine dell’indice. Visualizza tutte le date non solo quelle nell’indice. Per le date in cui non sono disponibili dati, la funzione di grafico esegue l’interpolazione tra l’ultimo prezzo di chiusura noto e il successivo prezzo di chiusura noto.

Esistono diverse opzioni che possiamo considerare per gestire questo tipo di problema quando lavoriamo con i dati di serie temporali. Se desideriamo che l’indice rispecchi la funzione di tracciamento e abbia un indice DateTime completo, Pandas offre la possibilità di eseguire il backfill o il forwardfill delle celle durante la creazione dell’indice. Il backfill dei dati prende il primo dato successivo non-Nan nella colonna e lo usa per riempire tutte le celle vuote precedenti (all’indietro). 

Quando lavoriamo con una serie temporale come i dati finanziari non dovremmo mai effettuare il backfill dei prezzi. Il backfill introduce il bias look-ahead perchè permette a qualsiasi algoritmo di trading l’accesso ai dati futuri, rispetto al punto temporale attuale. Il fowardfill usa il prezzo precedente per valorizzare le successive celle vuote (NaN). In questo modo non si introduce  bias di previsione, ma dobbiamo fare attenzione se usarlo o meno.

Esistono molti altri modi diversi per eseguire il riempimento avanti e indietro. Non è necessario copiare semplicemente il prezzo precedente o successivo. Potremmo fare una media o applicare una serie di funzioni diverse per calcolare il valore. Tuttavia, potrebbe non essere opportuno effettuare alcuna estrapolazione dei dati. È qui che dobbiamo pensare ai dati e alle domande che dobbiamo porci. 

Chiediamoci se le modifiche che vogliamo apportare riflettono o meno accuratamente ciò che sta realmente accadendo ai dati. I dati con cui stiamo lavorando dovrebbero essere completi? Oppure i dati mancanti significano qualcosa? In questo caso abbiamo a che fare con prezzi di chiusura che rappresentano scambi reali di una coppia FX. Riempiendo in avanti i dati creiamo operazioni che non sono avvenute. In questo caso è semplicemente più sicuro ignorare o rimuovere i dati mancanti dal grafico.

Per visualizzare la serie di prezzi di chiusura senza l’interpolazione dei dati mancanti, dobbiamo creare un indice di timestamp. Ciò impedirà l’esecuzione dell’interpolazione. Il nostro indice conterrà ancora il timestamp dell’operazione ma non come oggetto DateTime.

				
					
def create_str_index(formatted_fx_dict):
    fx_pair_str_ind = {}
    for pair in formatted_fx_dict.keys():
        fx_pair_str_ind[pair] = formatted_fx_dict[pair].set_index(
            formatted_fx_dict[pair].index.to_series().dt.strftime(
                '%Y-%m-%d-%H-%M-%S'
            )
        )
    return fx_pair_str_ind
				
			

Possiamo salvare le coppie di stringhe indicizzate in una variabile chiamando fx_pair_str_ind = create_str_index(formatted_fx_dict). Se tracciamo nuovamente i nostri prezzi di chiusura possiamo vedere che l’interpolazione è stata rimossa.

dati-azionari-polygon-mzxzar_str_index

Visualizzare i rendimenti

Possiamo quindi creare le serie di rendimenti dei dati Forex di Polygon con la certezza che la funzione del grafico non includerà alcuna interpolazione di dati. Il codice seguente crea i rendimenti, questi sono semplicemente la variazione percentuale del prezzo di chiusura.

				
					
def create_returns_series(fx_pairs_str_ind):
    for pair in fx_pairs_str_ind.keys():
        fx_pairs_str_ind[pair]['rets'] = fx_pairs_str_ind[pair]['c'].pct_change()
    return fx_pair_str_ind 
				
			

Ora possiamo salvare il nostro dizionario di DataFrames completamente formattato nella variabile fx_returns_dict tramite il seguente codice.

				
					
fx_returns_dict = create_returns_series(fx_pair_str_ind)
				
			

Possiamo tracciare le serie di rendimenti per ciascuna coppia. La seguente funzione può essere utilizzata per creare una figura di sottotrama per un numero qualsiasi di coppie FX. Dobbiamo solo cambiare la forma dell’array restituito da matplotlib nella chiamata a plt.subplots(rows, cols, *kwargs).

				
					
def plot_returns_series(fx_pairs_str_ind):
    fig, ax = plt.subplots(1,2, figsize=(16, 10), squeeze=False)

    for idx, fxpair in enumerate(fx_pairs_str_ind.keys()):
        row = (idx//2)
        col = (idx%2)
                    
        ax[row][col].plot(fx_pairs_str_ind[fxpair].index, fx_pairs_str_ind[fxpair]['rets'])
        ax[row][col].set_xticks('')
        ax[row][col].set_title(fxpair)
    fig.suptitle("Returns Series 1/1/2023 - 31/01/23")
    plt.show() 
				
			
dati-azionari-polygon-ret_series

Come possiamo vedere, i rendimenti sono tracciati senza alcuna interpolazione per i dati mancanti. A prima vista è abbastanza facile vedere che c’è molta più variazione nella coppia esotica MZXZAR che nella coppia principale EURUSD nello stesso periodo di tempo.

In questo articolo abbiamo  descritto come creare una serie temporale dei rendimenti  dei prezzi in Python usando i dati Forex di Polygon. Nel prossimo articolo della serie esamineremo come creare volatilità realizzata. Effettueremo anche alcune analisi dei dati e valuteremo come iniziare a formulare il nostro modello di apprendimento automatico per prevedere il cambiamento del regime di mercato.

Gli altri articoli di questa serie

Benvenuto su DataTrading!

Sono Gianluca, ingegnere software e data scientist. Sono appassionato di coding, finanza e trading. Leggi la mia storia.

Ho creato DataTrading per aiutare le altre persone ad utilizzare nuovi approcci e nuovi strumenti, ed applicarli correttamente al mondo del trading.

DataTrading vuole essere un punto di ritrovo per scambiare esperienze, opinioni ed idee.

SCRIVIMI SU TELEGRAM

Per informazioni, suggerimenti, collaborazioni...

Torna in alto
Scroll to Top