Codice di TQforex – Trading System sul Forex Parte 3

Codice di TQforex

In questa lezione del corso per il trading automatico sul Forex, descriviamo il piano a lungo termine per il nostro sistema di trading forex e rilasciamo open-source il codice di TQforex. Inoltre, esploriamo l’uso del tipo di dato Decimal di Python per rendere i calcoli più precisi.

Finora, abbiamo testato l’API Rest di OANDA per confrontarla con quella di Interactive Brokers. Abbiamo anche visto come aggiungere un elemento base per replicare il portafoglio, come primo passo per costruire un sistema di backtesting basato sugli eventi. Vogliamo descrivere come scaricare ed installare il codice di TQforex in modo che possiate modificare ed estendere il codice in modo autonomo e personalizzato.

Codice di TQforex per il Trading sul Forex

Per i motivi sopra esposti, abbiamo deciso di rendere open-source il nostro sistema di trading sul forex. Cosa significa questo? Significa che tutto il codice, attuale e futuro, sarà disponibile gratuitamente, con licenza open-source MIT, sul nostro repository su Github: tradingquant-it/DTForex.

Chi è già pratico con git e Github può eseguire il git clone del repository e iniziare subito a modificarlo per i propri scopi.

Il sistema di trading automatico sul Forex di TradingQuant è ora open-source con licenza MIT. Puoi trovare il codice più recente su Github nel repository DTForex su tradingquant-it/DTForex.

Per chi non conosce il controllo di versione del codice sorgente, consigliamo di leggere questo ebook gratuito Pro Git per comprendere come funziona git e il controllo di versione in generale. Vale la pena dedicare del tempo a studiare il controllo del codice sorgente, poiché ci farà risparmiare tempo e problemi futuri quando ci dedicheremo alla programmazione e all’aggiornamento dei progetti!

Installazione

In Ubuntu, possiamo installare git velocemente con il seguente comando:

				
					sudo apt-get install git-core
				
			

Creiamo una directory per il progetto TQforex e “cloniamo” il repository dal sito Github, come segue:

				
					mkdir -p ~/progetti/
cd ~/progetti/
git clone
https://github.com/tradingquant-it/DTForex.git
				
			

A questo punto dobbiamo creare un ambiente virtuale dove eseguire il codice:

				
					mkdir -p ~/venv/dtforex
cd ~/venv/dtforex
virtualenv .
source ~/venv/dtforex/bin/activate
				
			

Successivamente dobbiamo installare le librerie python richieste dal progetto (ci vorrà qualche minuto!):

				
					pip install -r ~/progetti/dtforex/requirements.txt
				
			

Come abbiamo accennato nelle lezioni precedenti, creiamo le variabili di ambiente necessarie per le credenziali di autenticazione OANDA.

Prestiamo attenzione al README associato al repository, che contiene le istruzioni di installazione, un disclaimer e una garanzia sull’utilizzo del codice.

Poiché il software è in modalità “alpha”, semplificheremo queste istruzioni nel tempo. In particolare, lavoreremo per includere il progetto in un pacchetto Python, rendendolo installabile facilmente tramite pip.

In caso di domande sulla procedura di installazione, scrivici senza esitazioni: .

Piano a lungo termine

La filosofia del sistema di trading forex che implementiamo nel codice di TQforex, come in tutti i progetti di TradingQuant, punta a costruire un motore di backtesting che imiti il più possibile il trading reale. Includiamo dettagli spesso ignorati nei backtest di tipo più “accademico”: latenza, interruzioni del server, automazione, monitoraggio e costi di transazione realistici, così da ottenere una visione più accurata della profittabilità di una strategia.

Dal momento che disponiamo dei dati tick (timestamp bid/ask), integriamo lo spread nei costi di transazione e modelliamo anche lo slippage. Modellare l’impatto di mercato risulta meno immediato, ma per trade su piccoli volumi o strumenti liquidi non rappresenta una grande preoccupazione.

Oltre ai costi di transazione, progettiamo una solida gestione del portafoglio, includendo gestione del rischio e dimensionamento della posizione.

Funzionalità implementate

Quindi, cosa abbiamo incluso finora nel codice di TQforex, il nostro Forex Trading System?

  • Architettura guidata dagli eventi – Abbiamo progettato il sistema di trading forex da zero come un sistema guidato dagli eventi, proprio come si farebbe per un sistema di trading intraday in ambiente reale.
  • Streaming dei prezzi – Gestiamo lo streaming dei prezzi di mercato tramite un oggetto base. Al momento supportiamo una sola coppia di valute, ma possiamo estenderlo facilmente a più coppie.
  • Generazione del segnale – Utilizziamo l’oggetto Strategy per incorporare strategie di trading sui prezzi tick, generando l’oggetto SignalEvent.
  • Esecuzione degli ordini – Con il nostro sistema inviamo ordini da Portfolio a OANDA in modo diretto, senza gestione del rischio o esecuzione algoritmica, il che potrebbe influire sui costi di transazione.
  • Valuta di base EUR – Per semplicità, iniziamo con EUR come valuta di base, ma pianifichiamo di estendere il supporto anche a USD, GBP, CAD, JPY, AUD e NZD.
  • Trading EUR/USD – Testiamo i nostri oggetti Position e Portfolio sulla coppia EUR/USD. Gestiremo più coppie di valute nei prossimi aggiornamenti.
  • Gestione dei decimali – Utilizziamo tipi di dato appropriati per evitare errori di arrotondamento, come spiegato in questo ottimo articolo sulle rappresentazioni in virgola mobile.
  • Trading Long/Short – Dalla lezione #2 alla lezione #3 abbiamo aggiunto la possibilità di shortare una coppia di valute, funzione che testiamo tramite unit test.
  • Gestione del portafoglio locale – Introducendo un oggetto di portafoglio locale che replica i calcoli di OANDA, possiamo monitorare i nostri calcoli durante il paper trading, aumentando la fiducia nei backtest futuri.
  • Unit test per Position/Portfolio – Abbiamo creato unit test per Portfolio e Position per assicurarci che tutto funzioni come previsto, facilitando modifiche future senza compromettere il sistema.

Sviluppi Futuri

In questa fase il codice di TQforex non include ancora le seguenti funzionalità:

  • Gestione dello slippage – A causa della natura ad alta frequenza dei dati tick, subiamo molto slippage. Miglioreremo la gestione degli eventi per riflettere fedelmente il saldo reale.
  • Valute di base multiple – Ora supportiamo solo EUR. Amplieremo il supporto anche a USD, GBP, CAD, AUD, JPY e NZD.
  • Coppie di valute multiple – Estenderemo il supporto alle principali coppie di valute e affronteremo le complessità dei calcoli multi-currency.
  • Gestione del rischio – Integreremo un sistema di gestione del rischio reale per proteggere il capitale ed evitare grosse perdite.
  • Ottimizzazione del portafoglio – Implementeremo sistemi di gestione del portafoglio robusti, come il criterio di Kelly per ottimizzare la crescita a lungo termine.
  • Strategie robuste – Svilupperemo strategie di trading più sofisticate basate su filtri tecnici, modelli di serie storiche e machine learning.
  • Distribuzione remota – Prevediamo di distribuire il sistema su server remoti, garantendo ridondanza e monitoraggio h24.
  • Backtest storico – Progetteremo un sistema di archiviazione dei dati tick storici per eseguire backtest realistici utilizzando database come HDF5.
  • Database dei Trade – Salveremo i trade in tempo reale in database relazionali come PostgreSQL o MySQL per analisi approfondite.
  • Monitoraggio e alta disponibilità – Implementeremo sistemi di monitoraggio delle risorse e strategie di backup per mantenere la continuità operativa anche in caso di crash del server.
  • Integrazione Multiple Broker/FIX – Intendiamo integrare più broker tramite il protocollo FIX, aumentando la flessibilità del sistema oltre OANDA.
  • Controllo e reportistica GUI – Costruiremo una GUI per visualizzare i risultati dei backtest, report sulle prestazioni e metriche del portafoglio.

Tipi di dati decimali

Dopo aver discusso il piano a lungo termine, descriviamo alcune modifiche che abbiamo apportato al codice di TQforex presentato nella precedente lezione di questo corso. In particolare, illustriamo le modifiche al codice che ci permettono di gestire il tipo di dati Decimal invece di usare variabili a virgola mobile. Questo cambiamento risulta estremamente importante perché le rappresentazioni in virgola mobile generano facilmente errori a lungo termine nei sistemi di gestione del portafoglio e degli ordini.

Python supporta nativamente le rappresentazioni decimali con precisione arbitraria. Questa funzionalità si trova nella libreria decimal.

Dobbiamo modificare ogni valore presente nei calcoli implementati in Position trasformandolo in un tipo di dato Decimal. Includiamo unità, esposizione, pip, profitto e profitto percentuale. In questo modo, manteniamo il pieno controllo su come gestiamo i problemi di arrotondamento quando rappresentiamo valute con precisione a due cifre decimali. In particolare, scegliamo il metodo di arrotondamento. Python supporta diversi tipi di arrotondamento, e in questo caso utilizziamo ROUND_HALF_DOWN, che arrotonda all’intero più vicino con legami che vanno verso lo zero.

Implementazione

Ecco un esempio delle modifiche che applichiamo al codice di TQforex per gestire i tipi di dati Decimal rispetto alle precedenti rappresentazioni in virgola mobile. Di seguito mostriamo il codice aggiornato di position.py:

				
					from decimal import Decimal, getcontext, ROUND_HALF_DOWN

class Position(object):
    def __init__(
        self, side, market, units,
        exposure, avg_price, cur_price
    ):
        self.side = side
        self.market = market
        self.units = units
        self.exposure = Decimal(str(exposure))
        self.avg_price = Decimal(str(avg_price))
        self.cur_price = Decimal(str(cur_price))
        self.profit_base = self.calculate_profit_base(self.exposure)
        self.profit_perc = self.calculate_profit_perc(self.exposure)

    def calculate_pips(self):
        getcontext.prec = 6
        mult = Decimal("1")
        if self.side == "SHORT":
            mult = Decimal("-1")
        return (mult * (self.cur_price - self.avg_price)).quantize(
            Decimal("0.00001"), ROUND_HALF_DOWN
        )

    def calculate_profit_base(self, exposure):
        pips = self.calculate_pips()
        return (pips * exposure / self.cur_price).quantize(
            Decimal("0.00001"), ROUND_HALF_DOWN
        )

    def calculate_profit_perc(self, exposure):
        return (self.profit_base / exposure * Decimal("100.00")).quantize(
            Decimal("0.00001"), ROUND_HALF_DOWN
        )

    def update_position_price(self, cur_price, exposure):
        self.cur_price = cur_price
        self.profit_base = self.calculate_profit_base(exposure)
        self.profit_perc = self.calculate_profit_perc(exposure)
				
			

Notiamo che l’argomento di Decimal deve essere una stringa, piuttosto che un valore in virgola mobile. Questo avviene perché una stringa specifica con precisione il valore, mentre un argomento a virgola mobile non permette lo stesso livello di accuratezza.

Ricordiamo inoltre che, quando memorizziamo le operazioni in un database relazionale (come spiegato nella roadmap nel paragrafo precedente), dobbiamo utilizzare il tipo di dati corretto. PostgreSQL e MySQL supportano la rappresentazione decimale. È fondamentale scegliere questi tipi di dati durante la creazione dello schema del database, altrimenti rischiamo di introdurre errori di arrotondamento estremamente difficili da diagnosticare!

Conclusione

Chi desidera approfondire questi temi in matematica e informatica può consultare l’argomento dell’analisi numerica, che tratta i problemi di archiviazione in virgola mobile, insieme a molti altri argomenti interessanti.

Nelle prossime lezioni del corso descriveremo come applicare gli unit test al codice di TQforex e come estendere il sistema per gestire più coppie di valute, modificando i calcoli di posizione.

Il codice completo presentato in questa lezione, basato sul sistema di trading automatico sul Forex TQforex, è disponibile nel seguente repository GitHub: https://github.com/tradingquant-it/TQforex.”

Torna in alto