Recherche sur la stratégie de couverture multi-monnaie des contrats à terme de Binance Partie 1

Auteur:La bonté, Créé: 2020-05-09 11:14:50, Mis à jour: 2023-11-04 19:49:01

img

Recherche sur la stratégie de couverture multi-monnaie des contrats à terme de Binance Partie 1

Cliquez sur le bouton de recherche sur la page Dashboard, puis cliquez sur la flèche pour entrer. Ouvrez le fichier de suffixe.pynb téléchargé et appuyez sur shift + enter pour exécuter ligne par ligne. Il y a des tutoriels de base dans l'aide à l'utilisation de l'environnement de recherche.

img

Motifs stratégiques

Bien que les fluctuations à court terme soient incertaines, si vous regardez la ligne quotidienne pendant une longue période, vous constaterez qu'elles ont fondamentalement chuté de plus de 90%, et certaines n'ont même que des fractions de la fraction de prix la plus élevée. Cependant, il n'existe pas de méthode universelle de vente à découvert pour le spot, et il n'y a pas de recommandation spéciale, sauf de ne pas toucher à l'altcoin. Au cours des deux derniers mois, Binance Futures a lancé plus de 20 contrats perpétuels, dont la plupart sont des devises grand public, et certains sont inconnus. Cela nous donne les moyens de court-circuiter ces combinaisons d'altcoins.

Principaux de stratégie

La première stratégie: vendre court le panier sélectionné d'altcoins dans un équivalent décentralisé, et en même temps acheter long la même quantité de position BTC à couvrir, afin de réduire les risques et la volatilité.

La deuxième stratégie: court-circuiter les devises dont le prix est supérieur à l'indice de prix altcoin-bitcoin, et longueur avec des devises inférieures à l'indice, plus l'écart est grand, plus la position est grande.

# Libraries to import
import pandas as pd
import requests
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
%matplotlib inline

Afficher la devise requise

Le contrat perpétuel de Binance répertorie actuellement 23 devises, qui peuvent être obtenues à l'aide de son interface API (hors BTC).

#Info = requests.get('https://fapi.binance.com/fapi/v1/exchangeInfo')
#symbols = [symbol_info['baseAsset'] for symbol_info in Info.json()['symbols']]
symbols = ['ETH', 'BCH', 'XRP', 'EOS', 'LTC', 'TRX', 'ETC', 'LINK', 'XLM', 'ADA', 'XMR', 'DASH', 'ZEC', 'XTZ', 'BNB', 'ATOM', 'ONT', 'IOTA', 'BAT', 'VET', 'NEO', 'QTUM', 'IOST']

Tout d'abord, étudions le mouvement des prix des altcoins par rapport au Bitcoin au cours de l'année écoulée.

price_btc = pd.read_csv('https://www.fmz.com/upload/asset/1ef1af8ec28a75a2dcb.csv', index_col = 0)
price_btc.index = pd.to_datetime(price_btc.index,unit='ms') #Index date
price_btc.tail()

Résultats:

img img

5 lignes × 23 colonnes

On peut voir que, sauf pour quatre devises, les tendances des prix des autres devises sont fondamentalement les mêmes, montrant une tendance à la baisse.

price_btc_norm = price_btc/price_btc.fillna(method='bfill').iloc[0,]
price_btc_norm.plot(figsize=(16,6),grid = True,legend=False);

img

En triant les derniers changements de prix, vous pouvez trouver plusieurs pièces qui sont évidemment différentes, à savoir LINK, XTZ, BCH, ETH. Expliquez-leur qu'elles peuvent souvent suivre leur propre tendance et que les raccourcir présente un risque plus élevé et doit être exclu de la stratégie.

Tracez une carte thermique du coefficient de corrélation des monnaies restantes et découvrez que la tendance de l'ETC et de l'ATOM est également relativement spéciale et peut être exclue.

price_btc_norm.iloc[-1,].sort_values()[-5:]

Résultats:

ETH     0.600417
ETC     0.661616
BCH     1.141961
XTZ     2.512195
LINK    2.764495
Name: 2020-03-25 00:00:00, dtype: float64
trade_symbols = list(set(symbols)-set(['LINK','XTZ','BCH', 'ETH'])) # Remaining currencies
plt.subplots(figsize=(12, 12)) # Set the screen size
sns.heatmap(price_btc[trade_symbols].corr(), annot=True, vmax=1, square=True, cmap="Blues");

img

La dernière devise restante a chuté en moyenne de 66% par an, il y a évidemment beaucoup de marge de manœuvre pour le shorting. En synthétisant la tendance de ces pièces dans l'indice de prix des altcoins, il a été constaté qu'elle a fondamentalement chuté tout le chemin, elle était plus stable au deuxième semestre de l'année dernière, et a commencé à chuter tout le chemin cette année.

Il convient de noter que l'indice altcoin actuel est au plus bas de l'année dernière.

trade_symbols = list(set(symbols)-set(['LINK','XTZ','BCH', 'ETH', 'ETC','ATOM','BNB','EOS','LTC'])) # You can set the remaining currencies, which you want to subtract.
1-price_btc_norm[trade_symbols].iloc[-1,].mean()

Résultats:

0.6714306758250285
price_btc_norm[trade_symbols].mean(axis=1).plot(figsize=(16,6),grid = True,legend=False);

img

Données sur la durabilité de Binance

De même, les données sur la durabilité de Binance ont été compilées, vous pouvez également les citer directement dans votre cahier, les données sont la ligne K du marché de 1h du 28 janvier au 31 mars 2020, car la plupart des contrats perpétuels de Binance ont été déjeunés seulement deux mois, donc les données sont suffisantes pour le backtest.

price_usdt = pd.read_csv('https://www.fmz.com/upload/asset/20227de6c1d10cb9dd1.csv ', index_col = 0)
price_usdt.index = pd.to_datetime(price_usdt.index)
price_usdt.tail()

Résultats:

img img

La tendance globale avec les données normalisées. Dans la chute de mars, par rapport au prix au début de février, le prix a été généralement réduit, montrant que le risque de contrat perpétuel est également très élevé. Cette vague de déclin est également un grand défi pour la stratégie.

price_usdt_norm = price_usdt/price_usdt.fillna(method='bfill').iloc[0,]
price_usdt_norm.plot(figsize=(16,6),grid = True,legend=False);

img

Dessinez le prix de l'indice de la pièce que nous voulons vendre contre Bitcoin, le principe de la stratégie est de court-circuiter cette courbe, et le rendement est essentiellement l'inverse de cette courbe.

price_usdt_btc = price_usdt.divide(price_usdt['BTC'],axis=0)
price_usdt_btc_norm = price_usdt_btc/price_usdt_btc.fillna(method='bfill').iloc[0,]
price_usdt_btc_norm[trade_symbols].mean(axis=1).plot(figsize=(16,6),grid = True);
#price_usdt_btc_norm.mean(axis=1).plot(figsize=(16,6),grid = True,legend=False);

img

Moteur de contre-essai

Parce que le backtest local FMZ n'a pas de données pour toutes les devises et ne prend pas en charge le backtest multi-values, il est nécessaire de réimplémenter un moteur de backtest. J'ai donc écrit un nouveau moteur de backtest, il est relativement simple, mais fondamentalement suffisant. En tenant compte des frais de transaction, mais en ignorant fondamentalement le taux de capital, n'a pas pris en compte la situation du maintien du capital de marge. Le capital total, la marge occupée et le levier ont été enregistrés. Puisque cette stratégie a l'attribut que la position longue égale la position courte, l'impact des taux de capital n'est donc pas significatif.

Le backtest ne prend pas en compte la situation de glissement de prix, vous pouvez augmenter la simulation des frais de transaction par vous-même, compte tenu des faibles frais de transaction du fabricant Binance, même la différence de prix dans le marché de la monnaie impopulaire est très faible, vous pouvez utiliser la méthode de commission de l'iceberg sur le marché réel lors de la passation d'une commande, l'impact ne devrait pas être significatif.

Lors de la création d'un objet d'échange, vous devez spécifier la devise à échanger. L'achat est long et la vente est courte. En raison de la limitation perpétuelle du contrat, lors de l'ouverture de la position, les positions longues et courtes sont automatiquement fermées ensemble. Lors de la vente de la position courte et le nombre de devises sont négatifs. Les paramètres sont les suivants:

  • trade_symbols: liste des monnaies à échanger
  • effet de levier: effet de levier, marge d'effet,
  • commissions: frais de transaction, défaut 0,00005
  • initial_balance: actif initial, évaluation en USDT
  • journaux: imprimer ou non les enregistrements des transactions
class Exchange:
    
    def __init__(self, trade_symbols, leverage=20, commission=0.00005,  initial_balance=10000, log=False):
        self.initial_balance = initial_balance # Initial asset
        self.commission = commission
        self.leverage = leverage
        self.trade_symbols = trade_symbols
        self.date = ''
        self.log = log
        self.df = pd.DataFrame(columns=['margin','total','leverage','realised_profit','unrealised_profit'])
        self.account = {'USDT':{'realised_profit':0, 'margin':0, 'unrealised_profit':0, 'total':initial_balance, 'leverage':0}}
        for symbol in trade_symbols:
            self.account[symbol] = {'amount':0, 'hold_price':0, 'value':0, 'price':0, 'realised_profit':0, 'margin':0, 'unrealised_profit':0}
            
    def Trade(self, symbol, direction, price, amount, msg=''):
        if self.date and self.log:
            print('%-20s%-5s%-5s%-10.8s%-8.6s %s'%(str(self.date), symbol, 'buy' if direction == 1 else 'sell', price, amount, msg))
            
        cover_amount = 0 if direction*self.account[symbol]['amount'] >=0 else min(abs(self.account[symbol]['amount']), amount)
        open_amount = amount - cover_amount
        
        self.account['USDT']['realised_profit'] -= price*amount*self.commission # Minus transaction fee
        
        if cover_amount > 0: # close position first
            self.account['USDT']['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount  # profit
            self.account['USDT']['margin'] -= cover_amount*self.account[symbol]['hold_price']/self.leverage # Free the margin
            
            self.account[symbol]['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount
            self.account[symbol]['amount'] -= -direction*cover_amount
            self.account[symbol]['margin'] -=  cover_amount*self.account[symbol]['hold_price']/self.leverage
            self.account[symbol]['hold_price'] = 0 if self.account[symbol]['amount'] == 0 else self.account[symbol]['hold_price']
            
        if open_amount > 0:
            total_cost = self.account[symbol]['hold_price']*direction*self.account[symbol]['amount'] + price*open_amount
            total_amount = direction*self.account[symbol]['amount']+open_amount
            
            self.account['USDT']['margin'] +=  open_amount*price/self.leverage            
            self.account[symbol]['hold_price'] = total_cost/total_amount
            self.account[symbol]['amount'] += direction*open_amount
            self.account[symbol]['margin'] +=  open_amount*price/self.leverage
            
        self.account[symbol]['unrealised_profit'] = (price - self.account[symbol]['hold_price'])*self.account[symbol]['amount']
        self.account[symbol]['price'] = price
        self.account[symbol]['value'] = abs(self.account[symbol]['amount'])*price
        
        return True
    
    def Buy(self, symbol, price, amount, msg=''):
        self.Trade(symbol, 1, price, amount, msg)
        
    def Sell(self, symbol, price, amount, msg=''):
        self.Trade(symbol, -1, price, amount, msg)
        
    def Update(self, date, close_price): # Update assets
        self.date = date
        self.close = close_price
        self.account['USDT']['unrealised_profit'] = 0
        for symbol in self.trade_symbols:
            if np.isnan(close_price[symbol]):
                continue
            self.account[symbol]['unrealised_profit'] = (close_price[symbol] - self.account[symbol]['hold_price'])*self.account[symbol]['amount']
            self.account[symbol]['price'] = close_price[symbol]
            self.account[symbol]['value'] = abs(self.account[symbol]['amount'])*close_price[symbol]
            self.account['USDT']['unrealised_profit'] += self.account[symbol]['unrealised_profit']
            if self.date.hour in [0,8,16]:
                pass
                self.account['USDT']['realised_profit'] += -self.account[symbol]['amount']*close_price[symbol]*0.01/100
        
        self.account['USDT']['total'] = round(self.account['USDT']['realised_profit'] + self.initial_balance + self.account['USDT']['unrealised_profit'],6)
        self.account['USDT']['leverage'] = round(self.account['USDT']['margin']/self.account['USDT']['total'],4)*self.leverage
        self.df.loc[self.date] = [self.account['USDT']['margin'],self.account['USDT']['total'],self.account['USDT']['leverage'],self.account['USDT']['realised_profit'],self.account['USDT']['unrealised_profit']]
# First test the backtest engine
e = Exchange(['BTC','XRP'],initial_balance=10000,commission=0,log=True)

e.Buy('BTC',100, 5)
e.Sell('XRP',10, 50)

e.Sell('BTC',105,e.account['BTC']['amount'])
e.Buy('XRP',9,-e.account['XRP']['amount'])

round(e.account['USDT']['realised_profit'],4)
75.0

Le premier code de stratégie

La logique de la stratégie:

  • Vérifiez le prix de la devise, si ce n'est pas nan, vous pouvez échanger
  • Vérifiez la valeur du contrat altcoin. Si elle est inférieure à la valeur cible trade_value, la différence correspondante sera vendue à découvert, et si elle est supérieure, le montant correspondant sera acheté pour fermer la position.
  • Ajoutez la valeur courte de tous les altcoins et ajustez la position BTC pour vous protéger contre elle.

La position short trade_value détermine la taille de la position.

# Need to hedge with BTC
trade_symbols = list(set(symbols)-set(['LINK','XTZ','BCH', 'ETH', 'ETC','ATOM','BNB','EOS','LTC'])) # Remaining currencies
e = Exchange(trade_symbols+['BTC'],initial_balance=10000,commission=0.0005,log=False)
trade_value = 2000
for row in price_usdt.iloc[:].iterrows():
    e.Update(row[0], row[1])
    empty_value = 0
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        if e.account[symbol]['value'] - trade_value  < -20 :
            e.Sell(symbol, price, round((trade_value-e.account[symbol]['value'])/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        if e.account[symbol]['value'] - trade_value > 20 :
            e.Buy(symbol, price, round((e.account[symbol]['value']-trade_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        empty_value += e.account[symbol]['value']
    price = row[1]['BTC']
    if e.account['BTC']['value'] - empty_value < -20:
        e.Buy('BTC', price, round((empty_value-e.account['BTC']['value'])/price,6),round(e.account['BTC']['realised_profit']+e.account['BTC']['unrealised_profit'],2))
    if e.account['BTC']['value'] - empty_value > 20:
        e.Sell('BTC', price, round((e.account['BTC']['value']-empty_value)/price,6),round(e.account['BTC']['realised_profit']+e.account['BTC']['unrealised_profit'],2))
stragey_1 = e

Le bénéfice final de chaque monnaie est le suivant:

pd.DataFrame(stragey_1.account).T.apply(lambda x:round(x,3))

img

Les deux graphiques ci-dessous représentent la courbe de la valeur nette et l'effet de levier utilisé.

Le jaune de la courbe de valeur nette est l'effet d'un effet de levier 1x sur l'indice altcoin. On peut voir que la stratégie amplifie fondamentalement la fluctuation de l'indice, ce qui est conforme aux attentes. Le rendement final de deux mois est de 60%, le retracement maximum est de 20% et l'effet de levier maximum est d'environ 8 fois. La plupart du temps, il est inférieur à 6 fois. Il est toujours sûr. Plus important encore, la couverture complète a fait perdre peu de la stratégie dans la chute du 12 mars.

Lorsque le prix de la monnaie de vente à découvert augmente et que la valeur du contrat augmente, la position est réduite, en revanche, lorsque le profit est réalisé, la position est augmentée.

Mais les risques ont également été mentionnés plus tôt, les altcoins sont très susceptibles de courir leur propre tendance, et peuvent augmenter beaucoup du bas. Cela dépend de la façon dont vous l'utilisez. Si vous êtes optimiste sur l'altcoin et pensez qu'il a atteint le bas, vous pouvez opérer dans la direction et acheter long cet indice. Ou si vous êtes optimiste sur certaines devises, vous pouvez vous protéger avec eux.

(stragey_1.df['total']/stragey_1.initial_balance).plot(figsize=(18,6),grid = True); # Net worth curve
#(2-price_usdt_btc_norm[trade_symbols].mean(axis=1)).plot(figsize=(18,6),grid = True);

img

# Strategy leverage
stragey_1.df['leverage'].plot(figsize=(18,6),grid = True);

img

En outre, comme le prix de l'altcoin contre l'USDT a également chuté, le plan extrême n'est pas couvert, vendant directement à découvert, mais la fluctuation est très importante et le retracement est élevé.

trade_symbols = list(set(symbols)-set(['LINK','XTZ','BCH', 'ETH', 'ETC','ATOM','BNB','EOS','LTC'])) # Remaining currencies
e = Exchange(trade_symbols+['BTC'],initial_balance=10000,commission=0.0005,log=False)
trade_value = 2000
for row in price_usdt.iloc[:].iterrows():
    e.Update(row[0], row[1])
    empty_value = 0
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        if e.account[symbol]['value'] - trade_value  < -20 :
            e.Sell(symbol, price, round((trade_value-e.account[symbol]['value'])/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        if e.account[symbol]['value'] - trade_value > 20 :
            pass
            #e.Buy(symbol, price, round((e.account[symbol]['value']-trade_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        empty_value += e.account[symbol]['value']
stragey_1b = e
(stragey_1b.df['total']/stragey_1.initial_balance).plot(figsize=(18,6),grid = True); # Net worth curve
(2-price_usdt_btc_norm[trade_symbols].mean(axis=1)).plot(figsize=(18,6),grid = True);

img

Le deuxième code de stratégie

La logique de la stratégie:

  • Vérifiez s'il y a un prix ou s'il y a un prix à échanger
  • Vérifiez l'écart du prix de la devise par rapport à l'indice
  • Allez long et court basé sur le jugement de l'écart, et de juger la position en fonction de la taille de l'écart
  • Calcul des positions non couvertes et couverture par BTC

Trade_value contrôle également la taille des positions ouvertes. Vous pouvez également modifier le facteur de conversion de diff/0.001

trade_symbols = list(set(symbols)-set(['LINK','XTZ','BCH', 'ETH'])) # Remaining currencies
price_usdt_btc_norm_mean = price_usdt_btc_norm[trade_symbols].mean(axis=1)
e = Exchange(trade_symbols+['BTC'],initial_balance=10000,commission=0.0005,log=False)
trade_value = 300
for row in price_usdt.iloc[:].iterrows():
    e.Update(row[0], row[1])
    empty_value = 0
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        diff = price_usdt_btc_norm.loc[row[0],symbol] - price_usdt_btc_norm_mean[row[0]]
        aim_value = -trade_value*round(diff/0.01,0)
        now_value = e.account[symbol]['value']*np.sign(e.account[symbol]['amount'])
        empty_value += now_value
        if aim_value - now_value > 50:
            e.Buy(symbol, price, round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        if aim_value - now_value < -50:
            e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
    price = row[1]['BTC']
    aim_value = -empty_value
    now_value = e.account['BTC']['value']*np.sign(e.account['BTC']['amount'])
    if aim_value - now_value > 50:
        e.Buy('BTC', price, round((aim_value - now_value)/price, 6),round(e.account['BTC']['realised_profit']+e.account['BTC']['unrealised_profit'],2))
    if aim_value - now_value < -50:
        e.Sell('BTC', price, -round((aim_value - now_value)/price, 6),round(e.account['BTC']['realised_profit']+e.account['BTC']['unrealised_profit'],2))
stragey_2 = e

Le rendement de la deuxième stratégie est bien meilleur que celui de la première stratégie. Au cours des deux derniers mois, il a un rendement de 100%, mais a toujours un retracement de 20%. Au cours de la dernière semaine, en raison des petites fluctuations du marché, le rendement n'est pas évident. Le levier global n'est pas grand. Cette stratégie vaut la peine d'être essayée. Selon le degré d'écart, plus de 7800 positions USDT ont été ouvertes au maximum.

Notez que si une devise exécute une tendance indépendante, par exemple, elle a augmenté plusieurs fois par rapport à l'indice, elle accumulera un grand nombre de positions courtes dans la devise, et la même baisse nette rendra également la stratégie d'achat longue, ce qui peut limiter la position d'ouverture maximale.

(stragey_2.df['total']/stragey_2.initial_balance).plot(figsize=(18,6),grid = True);

img

# Summary results by currency
pd.DataFrame(e.account).T.apply(lambda x:round(x,3))

img

e.df['leverage'].plot(figsize=(18,6),grid = True);

img

Si le résultat de la non couverture est le suivant, la différence n'est en fait pas grande.

trade_symbols = list(set(symbols)-set(['LINK','XTZ','BCH', 'ETH'])) # Remaining currencies
price_usdt_btc_norm_mean = price_usdt_btc_norm[trade_symbols].mean(axis=1)
e = Exchange(trade_symbols,initial_balance=10000,commission=0.0005,log=False)
trade_value = 300
for row in price_usdt.iloc[:].iterrows():
    e.Update(row[0], row[1])
    empty_value = 0
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        diff = price_usdt_btc_norm.loc[row[0],symbol] - price_usdt_btc_norm_mean[row[0]]
        aim_value = -trade_value*round(diff/0.01,1)
        now_value = e.account[symbol]['value']*np.sign(e.account[symbol]['amount'])
        empty_value += now_value
        if aim_value - now_value > 20:
            e.Buy(symbol, price, round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        if aim_value - now_value < -20:
            e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
stragey_2b = e
(stragey_2b.df['total']/stragey_2.initial_balance).plot(figsize=(18,6),grid = True);
#(stragey_2.df['total']/stragey_2.initial_balance).plot(figsize=(18,6),grid = True); # Can be stacked together

img

Si vous faites référence à la régression des prix USDT, l'effet sera beaucoup pire

trade_symbols = list(set(symbols)-set(['LINK','XTZ','BCH', 'ETH']))+['BTC'] #Remaining currencies
price_usdt_norm_mean = price_usdt_norm[trade_symbols].mean(axis=1)
e = Exchange(trade_symbols,initial_balance=10000,commission=0.0005,log=False)
trade_value = 300
for row in price_usdt.iloc[:].iterrows():
    e.Update(row[0], row[1])
    empty_value = 0
    for symbol in trade_symbols+['BTC']:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        diff = price_usdt_norm.loc[row[0],symbol] - price_usdt_norm_mean[row[0]]
        aim_value = -trade_value*round(diff/0.01,1)
        now_value = e.account[symbol]['value']*np.sign(e.account[symbol]['amount'])
        empty_value += now_value
        if aim_value - now_value > 20:
            e.Buy(symbol, price, round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        if aim_value - now_value < -20:
            e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
stragey_2c = e
(stragey_2c.df['total']/stragey_2.initial_balance).plot(figsize=(18,6),grid = True);
(stragey_2b.df['total']/stragey_2.initial_balance).plot(figsize=(18,6),grid = True);

img

Si vous limitez la valeur de position maximale, la performance sera pire

trade_symbols = list(set(symbols)-set(['LINK','XTZ','BCH', 'ETH'])) #Remaining currencies
price_usdt_btc_norm_mean = price_usdt_btc_norm[trade_symbols].mean(axis=1)
e = Exchange(trade_symbols+['BTC'],initial_balance=10000,commission=0.0005,log=False)
trade_value = 300
for row in price_usdt.iloc[:].iterrows():
    e.Update(row[0], row[1])
    empty_value = 0
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        diff = price_usdt_btc_norm.loc[row[0],symbol] - price_usdt_btc_norm_mean[row[0]]
        aim_value = -trade_value*round(diff/0.01,1)
        now_value = e.account[symbol]['value']*np.sign(e.account[symbol]['amount'])
        empty_value += now_value
        if aim_value - now_value > 20 and abs(aim_value)<3000:
            e.Buy(symbol, price, round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        if aim_value - now_value < -20 and abs(aim_value)<3000:
            e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
    price = row[1]['BTC']
    aim_value = -empty_value
    now_value = e.account['BTC']['value']*np.sign(e.account['BTC']['amount'])
    if aim_value - now_value > 20:
        e.Buy('BTC', price, round((aim_value - now_value)/price, 6),round(e.account['BTC']['realised_profit']+e.account['BTC']['unrealised_profit'],2))
    if aim_value - now_value < -20:
        e.Sell('BTC', price, -round((aim_value - now_value)/price, 6),round(e.account['BTC']['realised_profit']+e.account['BTC']['unrealised_profit'],2))
stragey_2d = e
(stragey_2d.df['total']/stragey_2.initial_balance).plot(figsize=(17,6),grid = True);

img

Résumé et risque

La première stratégie profite du fait que la valeur globale des altcoins n'est pas aussi bonne que celle du bitcoin. Si vous achetez des longs bitcoins, vous voudrez peut-être vous en tenir à cette stratégie pendant longtemps. En raison de l'équivalence des positions longues et courtes, vous n'avez pratiquement pas peur du taux de financement de 8h. À long terme, le taux de gain est relativement élevé. Mais je m'inquiète aussi du fait que l'altcoin est actuellement au bas, et qu'il pourrait s'épuiser d'une tendance haussière et causer une perte de cette stratégie.

La deuxième stratégie utilise la caractéristique de régression des prix de l'altcoin, qui augmente plus que l'indice et a une forte probabilité de reculer.

En raison de la différence de temps de démarrage de la stratégie et des paramètres spécifiques, l'impact des personnes qui utilisent cette stratégie pendant une longue période ne devrait pas être grand.

En bref, il n'existe pas de stratégie parfaite, seulement une attitude correcte à l'égard de la stratégie, elle dépend en fin de compte de la compréhension des risques et du jugement de l'utilisateur sur l'avenir.


Relationnée

Plus de