Gestire il margine e la leva di Oanda con backtrader

Gestire il Margine e la Leva di Oanda con Backtrader

In questo articolo descriviamo come gestire il margine e la leva di Oanda con backtrader per creare e verificare strategie di trading algoritmico.

I concetti di margine e leva finanziaria possono essere complicati da implementare correttamente in un ambiente di backtest. Ogni paese e broker può avere regole e regolamenti diversi sulle modalità di applicazione del margine. A complicare ulteriormente la gestione, anche la definizione stessa di margine può essere differente. In alcuni mercati, il margine è semplicemente un deposito di importo fisso che bisogna fornire per entrare in una posizione. In altri mercati (come il Forex) è necessario prevedere un margine iniziale (il deposito) per aprire una posizione e un ulteriore margine per mantenere aperta la posizione. L’architettura di Backtrader supporta solo il concetto di margine iniziale. Se desideriamo simulare il margine di mantenimento e la chiusura del margine, dobbiamo implementare una funzione personalizzata. In questo articolo descriviamo come implementare questa logica.

Introduzione

Quando configuriamo Backtrader per gestire correttamente il margine e la leva finanziaria dobbiamo considerare i seguenti aspetti:

  1. I requisiti normativi del paese/area geografica dove vogliamo operare.
  2. Il tipo di asset che vogliamo negoziare.
  3. Le regole/metodi di calcolo del broker.

Seguiranno collegamenti e alcune brevi note che coprono tutti e tre i punti, ma non sono una soluzione valida per tutti i casi. Invece, ci concentriamo sulle logiche e regolamenti per Oanda, negoziando una singola coppia Forex con un conto in valuta USD. In un prossimo articolo approfondiremo questo aspetto descrivendo come aggiungere più strumenti e gestire gli strumenti che non sono denominati nella valuta del conto. Infatti, dopo aver esaminato la possibilità  di eseguire conversioni Forex prima/dopo aver negoziato uno strumento (ad esempio andare long su GBP/USD su un conto in EUR), ci sono implementazioni che renderebbero questo articolo troppo complesso. Pertanto, è opportuno concentrarci inizialmente su un semplice caso d’uso per gettare le basi. Infine, descriviamo il costo del finanziamento (l’interesse addebitato quando si utilizza la leva finanziaria) in un articolo successivo.

Disclaimer: gli esempi e i tassi di margine utilizzati in questo articolo erano corretti al tempo di scrittura di questo articolo. Con il passare del tempo, i tassi e le normative potrebbero cambiare. 

Fare la ricerca

Per essere sicuri di impostare correttamente la gestire il margine e la leva di Oanda con backtrader, dobbiamo dare un’occhiata al sito Web di Oanda per vedere come calcolano il margine e le liquidazioni del margine. Prima di tutto, è necessario familiarizzare con il gergo del margine. Oanda ha una buona panoramica di tutti i termini relativi al margine sulla pagina relativa alla normativa degli Stati Uniti. Per qualche ragione, non includono questo glossario nella versione europea! Quindi gli europei dovrebbero comunque dare un’occhiata alla pagina degli Stati Uniti per familiarizzare con la terminologia, e quindi cercare la pagina  relativa alla normativa della propria nazione. https://www.oanda.com/resources/legal/united-states/legal/margin-rules Alcuni termini che dobbiamo conoscere sono i seguenti. Tuttavia, ci sono molti altri termini elencati nella pagina. E’ opportuno leggerli tutti!.

Margine: si tratta di un deposito in buona fede o una garanzia di esecuzione. Nel trading con leva finanziaria, l’importo del margine viene tenuto in deposito mentre l’operazione è aperta. L’importo del margine richiesto per entrare in un’operazione è determinato dalle regole descritte di seguito. Sebbene non sia richiesto un deposito di margine minimo per aprire un conto fxTrade con OANDA, il margine disponibile nel tuo conto limiterà la dimensione delle posizioni che puoi aprire.
Leva finanziaria: è il reciproco del margine. Ad esempio, il margine del 2% equivale alla leva 50:1. La leva finanziaria massima consentita è determinata dalle autorità di regolamentazione in ciascuna area geografica. I clienti di OANDA possono scegliere di essere prudenti e limitare l’utilizzo della leva finanziaria a livelli inferiori a quelli consentiti dalle autorità di regolamentazione.
Valore di liquidazione del margine: Il valore di chiusura del margine è pari al tuo saldo più il tuo P/L non realizzato da tutte le posizioni aperte, convertito nella valuta del conto, il tutto calcolato utilizzando i tassi medi correnti. Vedere l’esempio di calcolo del valore di chiusura del margine riportato di seguito per un esempio di come calcolare il capitale proprio del conto.
Margine iniziale: il margine iniziale per un’operazione è uguale alla dimensione dell’operazione moltiplicata per il requisito di margine. Questo importo viene poi convertito nella valuta del conto. Quando apri una nuova operazione, il tuo margine iniziale deve essere inferiore o uguale al tuo margine disponibile. Se il tuo margine iniziale è maggiore del tuo margine disponibile, non puoi aprire l’operazione.
Liquidazione del margine: Se il tuo valore di chiusura del margine scende a meno della metà del tuo margine utilizzato, tutte le posizioni aperte verranno automaticamente chiuse utilizzando i tassi fxTrade correnti al momento della chiusura. Se il trading non è disponibile per determinate posizioni aperte al momento della chiusura del margine, tali posizioni rimarranno aperte e la piattaforma fxTrade continuerà a monitorare i tuoi requisiti di margine. Quando i mercati riaprono per le restanti posizioni aperte, potrebbe verificarsi un’altra chiusura del margine se il tuo conto rimane con margini inferiori.

Controllare i tassi di margine

Prima di negoziare uno specifico strumento, dobbiamo conoscere il relativo tasso di margine. Nonostante il contro Oanda ha una leva di 50:1, dobbiamo considerare che non possiamo utilizzarlo tutto. Inoltre alcune coppie esotiche e i CFD richiedono un margine iniziale del 5% (20:1) indipendentemente dalla leva finanziaria del conto. Ad esempio i conti statunitensi sono oggetti a una normativa abbastanza rigida che impone una leva massima di 20:1 su tutte le coppie minori.

La Commodity Futures Trading Commission (CFTC) limita la leva disponibile per i commercianti di forex al dettaglio negli Stati Uniti a 50:1 sulle principali coppie di valute e 20:1 su tutte le altre.

https://www.oanda.com/resources/legal/united-states/legal/margin-rates

Calcoli del margine

Le descrizioni del margine iniziale e della chiusura del margine riportate in precedenza forniscono tutte le informazioni di cui abbiamo bisogno per implementare la logica necessaria all’interno della strategia. Sono:

Margine iniziale = ( prezzo x dimensione) / leva finanziaria.

Margin Closeout Value* = Balance + PnL aperto

Margin Closeout = Margin Closeout Value < (Initial Margin / 2)

*In backtrader il valore di margin closeout è semplicemente lo stesso di self.broker.getvalue() .

Gestire il margine e la leva di Oanda

Nel seguente codice di esempio, operiamo su EUR/USD tramite un conto in base USD soggetto alle normative statunitensi e usando una leva 50:1. Di seguito una copia dei dati usati nel test:  EUR_USD-2005-2017-D1

				
					
import backtrader as bt
from datetime import datetime


class Mltests(bt.Strategy):
    '''
    Questa strategia contiene alcuni metodi aggiuntivi che possono essere utilizzati per calcolare
    se una posizione debba essere soggetta a una chiusura con margine da parte di Oanda.
    '''
    params = (('size', 100000),)

    def __init__(self):
        self.count = 0
        self.buybars = [1, 150]
        self.closebars = [100, 250]

    def next(self):
        bar = len(self.data)
        self.dt = self.data.datetime.date()
        if not self.position:
            if bar in self.buybars:
                self.cash_before = self.broker.getcash()
                value = self.broker.get_value()
                entry = self.buy(size=self.p.size)
                entry.addinfo(name='Entry')
        else:
            '''
            Controlla se le condizioni di chiusura del margine sono soddisfatte. 
            In caso contrario, controlla per vedere se dobbiamo chiudere la 
            posizione attraverso le regole della strategia.

            Se si verifica una chiusura, dobbiamo aggiungere informazioni all'ordine 
            in modo che possiamo avere il corretto log
            '''
            mco_result = self.check_mco(
                value=self.broker.get_value(),
                margin_used=self.margin
            )

            if mco_result == True:
                close = self.close()
                close.addinfo(name='MCO')

            elif bar in self.closebars:
                close = self.close()
                close.addinfo(name='Close')

        self.count += 1

    def notify_trade(self, trade):
        if trade.isclosed:
            print('{}: Trade closed '.format(self.dt))
            print('{}: PnL Gross {}, Net {}\n\n'.format(self.dt,
                                                round(trade.pnl,2),
                                                round(trade.pnlcomm,2)))

    def notify_order(self,order):
        if order.status == order.Completed:
            ep = order.executed.price
            es = order.executed.size
            tv = ep * es
            leverage = self.broker.getcommissioninfo(self.data).get_leverage()
            self.margin = abs((ep * es) / leverage)

            if 'name' in order.info:
                if order.info['name'] == 'Entry':
                    print('{}: Entry Order Completed '.format(self.dt))
                    print('{}: Order Executed Price: {}, Executed Size {}'.format(self.dt,ep,es,))
                    print('{}: Position Value: {} Margin Used: {}'.format(self.dt,tv,self.margin))
                elif order.info['name'] == 'MCO':
                    print('{}: WARNING: Margin Close Out'.format(self.dt))
                else:
                    print('{}: Close Order Completed'.format(self.dt))

    def check_mco(self, value, margin_used):
        '''
        Controlla se il valore di chiusura del margine è sceso al di sotto della metà
        del margine utilizzato, chiudere la posizione.

        value: valore del portafoglio per uno specifico dato. Questo è essenzialmente 
        uguale al valore di chiusura del margine che è saldo + pnl
        margin_used: margine iniziale
        '''

        if value < (margin_used /2):
            return True
        else:
            return False

class OandaCSVData(bt.feeds.GenericCSVData):
    params = (
        ('nullvalue', float('NaN')),
        ('dtformat', '%Y-%m-%dT%H:%M:%S.%fZ'),
        ('datetime', 6),
        ('time', -1),
        ('open', 5),
        ('high', 3),
        ('low', 4),
        ('close', 1),
        ('volume', 7),
        ('openinterest', -1),
    )

tframes = dict(
    minutes=bt.TimeFrame.Minutes,
    daily=bt.TimeFrame.Days,
    weekly=bt.TimeFrame.Weeks,
    monthly=bt.TimeFrame.Months)

# Capitale iniziale
startcash = 10000

# Creo un istanza di cerebro
cerebro = bt.Cerebro()

# Imposto commissioni
cerebro.broker.setcommission(leverage=50)

# Aggiungo la strategia
cerebro.addstrategy(Mltests)

# Dati di Oanda
data = OandaCSVData(
    dataname='data/EUR_USD-2005-2017-D1.csv',
    fromdate=datetime(2005,1,1),
    todate=datetime(2006,1,1))

# Aggiungo i dati a Cerebro
cerebro.adddata(data)

# Imposto il capitale iniziale
cerebro.broker.setcash(startcash)

# Esecuzione del backtest
cerebro.run()

portvalue = cerebro.broker.getvalue()
pnl = portvalue - startcash

print('Final Portfolio Value: ${}'.format(portvalue))
print('P/L: ${}'.format(pnl))

# Grafico dei risultati
cerebro.plot(style='candlestick')
				
			

Commenti

Per lo scopo di test, la strategia è piuttosto semplice. Apre e chiude porzioni del capitale per specifiche barre fisse. Successivamente, il metodo check_mco() è usato per verificare se dobbiamo applicare una chiusura del margine. Una volta che siamo in una posizione a mercato, dobbiamo chiamare check_mco() all’interno del metodo next() per vefericare se il valore di chiusura del margine è sceso al di sotto della soglia. In caso affermativo, chiudiamo la posizione e usiamo addinfo() per contrassegnare che abbiamo chiuso la posizione a causa di un margine insufficiente invece di seguire le regole della strategia. Infine, impostiamo il parametro self.margin dopo aver ricevuto la notifica order.Completed. In questo modo possiamo accedere al prezzo dell’eseguito e quindi calcolare il margine iniziale richiesto dall’eseguito. Lo facciamo a seguito di una notifica (piuttosto che durante ilnext()call) perché, per gli ordini a mercato, Backtrader riempie l’ordine utilizzando il prezzo di apertura della barra successiva. In caso di gap verso l’alto o verso il basso, potremmo correre il rischio di calcolare in modo errato il margine iniziale.

I risultati

Vediamo i risultati dei test per gestire il margine e la leva di Oanda con backtrader. Nei primi due screenshot il test è stato effettuato impostando la dimensione del trade a $100.000. Lo script viene eseguito senza una chiusura del margine.

Backtrader-Run-without-MCO
Backtrader-Run-without-MCO-terminal

Nel secondo test, aumentiamo la dimensione della posizione a $ 200.000 e forziamo una chiusura del margine quando il trade va contro di noi.

Backtrader-Run-MCO-triggered
Backtrader-Run-MCO-triggered-terminal

Dall’output del terminale possiamo vedere che la posizione è stata chiusa dopo 3 giorni. Inoltre, l’operazione ha perso così tanti soldi che non era rimasto abbastanza denaro per coprire il margine di una seconda operazione.

Codice completo

In questo articolo abbiamo descritto come gestire il margine e la leva di Oanda con backtrader per creare e verificare strategie di trading algoritmico. Per il codice completo riportato in questo articolo, si può consultare il seguente repository di github:
https://github.com/datatrading-info/BackTrader

Torna in alto
Scroll to Top