2021 Cryptocurrency TAQ Review & Stratégie manquée la plus simple d'augmentation de 10 fois

Auteur:Je suis désolée., Créé: 2022-04-07 11:36:32, Mis à jour: 2022-04-13 09:25:23

2021 Cryptocurrency TAQ Review & Stratégie manquée la plus simple d'augmentation de 10 fois

Conclusion 2021 et stratégie future.ipynb

2021 touche à sa fin, et des points chauds de DEFI à GAMEFI émergent l'un après l'autre, et le marché global est toujours dans un marché haussier. En regardant en arrière maintenant, combien avez-vous gagné en 2021? Quelle opportunité avez-vous manquée? Y a-t-il des investissements réussis? Récemment, j'ai tiré les cotations historiques du marché de l'année dernière et j'ai trouvé une stratégie de profiteur inattendue, mais c'est un indice multi-monnaies.

Il y a trop de symboles de devises répertoriés sur les plateformes, et beaucoup sont destinés à être inconnus et peuvent même être retirés du commerce. Ici, nous choisissons les symboles de devises qui ont été répertoriés sur Binance Perpetual Swap. Ils ont généralement été testés et sont reconnus comme des devises grand public, qui sont relativement sûres. Après un simple criblage, certaines devises de l'indice ont été supprimées et 134 devises ont finalement survécu.

Dans [1]: demandes d'importation à partir de la date/heure date d'importation, date/heure Temps d'importation Importation de pandas comme pd Importation de numéros comme np Importer matplotlib.pyplot comme plt % de matplotlib en ligne

Dans [144]: ##paire de négociation courante Les informations fournies par les autorités compétentes sont les suivantes:https://fapi.binance.com/fapi/v1/exchangeInfo’) les symboles = [s[symbol] pour s dans Info.json() [symbols]]

Dans [154]: Symbols_f = list(set(filter(lambda x: x[-4:] == USDT, [s.split(_) [0] pour s dans les symboles]))- Le montant de l'impôt sur les sociétés est calculé en fonction de la valeur de l'impôt sur les sociétés et de la valeur de l'impôt sur les sociétés. Print (symbols_f)

En [155]: Le numéro de série est le numéro de série.

Marché au cours de l'année écoulée

Ensuite, nous obtenons leurs prix de clôture quotidiens au cours de l'année écoulée, et nous remarquons que certains symboles de devises n'étaient sur le marché que pendant une courte période, de sorte que les données ont besoin d'un traitement d'unitization.

Le profit final de l'indice est d'environ 12 fois, c'est-à-dire si vous achetez ces 134 symboles de devises en moyenne le 1er janvier 2021, le profit final de ne rien faire est de 12 fois, et on estime que plus de 90% des gens ne dépassent pas l'indice moyen. Parmi eux, les symboles de devises avec la plus grande baisse: ICP a chuté de 93%, DODO a chuté de 85% et LINA a chuté de 75%. L'augmentation de près de cent fois: SOL, FTM, LUNA, MATIC, SAND, AXS. Parmi eux, AXS a augmenté de 168 fois et est le plus grand cheval noir. La médiane a augmenté de 3 fois. On peut dire que l'indice est principalement entraîné par les chaînes publiques et les jeux.

Il s'agit d'un ratio de profit désespéré. J'ai travaillé dur et essayé toutes sortes de stratégies, et je n'ai pas réalisé autant de profit qu'une année où je n'ai fait aucun effort supplémentaire. Cependant, il convient de noter que plusieurs des augmentations du ratio sont trop énormes et s'écartent évidemment de l'indice. Si ces symboles de devises ne sont pas sélectionnés au début de l'année, le profit sera proche de la médiane, qui est beaucoup moins importante.

Dans [157]: # fonction pour obtenir la ligne K dans n'importe quelle période def GetKlines ((symbole=BTCUSDT,début=2020-8-10,fin=2021-8-10,période=1h,base=fapi,v = v1): Les écailles = Le temps de démarrage = int (time.mktime.datetime.strptime.start, %Y-%m-%d).1000 + 860601 000 personnes Le temps de fin = int ((time.mktime ((datetime.strptime ((fin, %Y-%m-%d).temps à deux fois))))1000 + 860601 000 personnes Le nombre de points de contrôle est le nombre de points de contrôle.1000,h:60601000,d:2460601000) pendant que le temps de début < le temps de fin: La période de mise à jour est la période de mise à jour.Le nombre d'heures d'exécution est calculé en fonction de la fréquence d'exécution de l'opération. url = https://+base+.binance.com/+base+/+v+/klines?symbol=%s&interval=%s&startTime=%s&endTime=%s&limit=1000%(symbol,period,start_time,mid_time) rés = requêtes.get (URL) rés_list = res.json() si type ((res_list) == liste et len ((res_list) > 0: le nombre de points de départ est le nombre de points de départ. Klines += rés_list élif type ((res_list) == liste: le nombre de fois où le système est activéint(période[:-1])*intervalle_carte[période[-1]] autres: une pause

df = pd.DataFrame(Klines,columns=['time','open','high','low','close','amount','end_time','volume','count','buy_amount','buy_volume','null']).astype('float')
df.index = pd.to_datetime(df.time,unit='ms')
profit df

Dans [164]: df_all_s = pd.DataFrame ((index=pd.date_range ((début=2021-1-1, fin=2021-12-28, fréquence=1d),colonnes=symbols_s) pour i dans la plage ((len ((symbols_f)): #print ((symbols_s[i]) Le nombre de points de contrôle est le nombre de points de contrôle de l'autorité compétente. df_s = GetKlines ((symbol=symbol_s,start=2021-1-1,end=2021-12-28,période=1d,base=api,v=v3) df_all_s[symbol_s] = df_s[~df_s.index.duplicated(keep=first) ].close

Dans [165]: df_all_s.tail() #structure de données À l'extérieur [1]:

Dans [174]: df_all = df_all_s.fillna ((méthode=bfill) # remplir les données df_norm = df_all/df_all.iloc[0] #unitization df_norm.mean ((axe=1).plot ((figsize=(12,4), grille=Vrai); #graphique du bénéfice final de l'indice À l'extérieur [1]:img

Dans [175]: #augmentation médiane df_norm.median ((axe=1).plot ((figsize=(12,4), grille=Vrai); À l'extérieur [1]:img

Dans [168]: #sortie et chute print ((df_norm.iloc[-1].round ((2).sort_values (().to_dict())

Dans [317]: # retrait maximal du prix actuel par rapport au prix le plus élevé de l'année écoulée print ((((1-df_norm.iloc[-1]/df_norm.max (()))) ronde ((2).sort_values (().à_dict (())

Dans [177]: df_all_f = pd.DataFrame ((index=pd.date_range ((début=2021-1-1, fin=2021-12-28, fréquence=1d),colonnes=symbols_s) pour i dans la plage ((len ((symbols_f)): #print ((symbols_s[i]) Le nombre d'équipements utilisés est le nombre total d'équipements utilisés. df_f = GetKlines ((symbol=symbol_f,start=2021-1-1,end=2021-12-28,période=1d,base=fapi,v=v1) Df_all_f[symbole_f] = df_f[~df_f.index.duplicated ((maintenir=first) ].close

Dans [208]: # pas inclus de nouveaux symboles Le dépôt de la déclaration de conformité est effectué par un opérateur de l'Union européenne. La méthode de remplissage est la suivante: Le nombre d'équipements utilisés est le nombre total d'équipements utilisés. df.mean ((axe=1).plot ((figsize=(12,4), grille=Vrai); Extrait[208]:img

Dans [212]: #comparé à BTC (df.mean(axe=1)/df.BTCUSDT).graphique ((figsize=(12,4), grille=Vrai); À l'extérieur [1]:img

Dans [213]: # Utilise le vieux moteur de backtest classe échange:

def __init__(self, trade_symbols, fee=0.0004, initial_balance=10000):
    self.initial_balance = initial_balance #initial asset  
    self.fee = fee
    self.trade_symbols = trade_symbols
    self.account = {'USDT':{'realised_profit':0, 'unrealised_profit':0, 'total':initial_balance, 'fee':0}}
    for symbol in trade_symbols:
        self.account[symbol] = {'amount':0, 'hold_price':0, 'value':0, 'price':0, 'realised_profit':0,'unrealised_profit':0,'fee':0}
        
def Trade(self, symbol, direction, price, amount):
    
    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.fee #deduct service fee
    self.account['USDT']['fee'] += price*amount*self.fee
    self.account[symbol]['fee'] += price*amount*self.fee

    if cover_amount > 0: #close first 
        self.account['USDT']['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount  #profit
        self.account[symbol]['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount
        
        self.account[symbol]['amount'] -= -direction*cover_amount
        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[symbol]['hold_price'] = total_cost/total_amount
        self.account[symbol]['amount'] += direction*open_amount
                

def Buy(self, symbol, price, amount):
    self.Trade(symbol, 1, price, amount)
    
def Sell(self, symbol, price, amount):
    self.Trade(symbol, -1, price, amount)
    
def Update(self, close_price): #update asset
    self.account['USDT']['unrealised_profit'] = 0
    for symbol in self.trade_symbols:
        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']
    self.account['USDT']['total'] = round(self.account['USDT']['realised_profit'] + self.initial_balance + self.account['USDT']['unrealised_profit'],6)

Dans [418]: #pour un backtest plus précis, parcourez 1 heure de ligne k df_all_s = pd.DataFrame ((index=pd.date_range ((début=2021-1-1, fin=2021-12-28, fréquence=1h),colonnes=symbols_s) pour i dans la plage ((len ((symbols_f)): #print ((symbols_s[i]) Le nombre de points de contrôle est le nombre de points de contrôle de l'autorité compétente. df_s = GetKlines ((symbol=symbol_s,start=2021-1-1,end=2021-12-28,période=1h,base=api,v=v3) df_all_s[symbol_s] = df_s[~df_s.index.duplicated(keep=first) ].close

Dans [419]: Le nombre de colonnes est le nombre de colonnes de la colonne df. La méthode de remplissage est la suivante: Le nombre d'équipements utilisés est le nombre total d'équipements utilisés. df.mean ((axe=1).plot ((figsize=(12,4), grille=Vrai); À l'extérieur[419]:img

Performance équilibrée de la stratégie

Le backtest a sélectionné tous les symboles de devises répertoriés sur les contrats perpétuels Binance le 1er janvier 2021. La période de la ligne K est de 1h, et le paramètre est de commencer à acheter lorsque le montant de la position est inférieur à 5% de la moyenne et de commencer à vendre lorsqu'il est supérieur à 5%. Lorsque le backtest est de tous les symboles de devises, le profit final de la stratégie est de 7,7 fois. Sensiblement pire que le profit moyen de 13 fois. C'est aussi dans mon attente. Après tout, les symboles de devises qui ont augmenté de cent fois sont trop spéciaux, et la stratégie équilibrée les vendra tous.

Si le backtest choisit de supprimer les 10 symboles de devises avec la plus forte augmentation et d'examiner uniquement les symboles de devises relativement médiocres, le profit final est de 4,8 fois, ce qui dépasse de loin la performance moyenne de 3,4 fois.

Si seuls les 3 symboles de monnaie avec la plus forte augmentation sont tournés, le profit final est de 373 fois, ce qui dépasse de loin la performance moyenne de 160 fois.

Dans [494]: #Backtest de tous les symboles les symboles = liste ((df.iloc[-1].sort_values() [:].index) e = échange (symboles, frais = 0,001, solde initial = 10000) rés_list = [] Le nombre d'étoiles est calculé en fonction de la taille de l'étoile. pour la ligne dans df[symboles].iterrows(): prix = rangée [1] le montant total = compte électronique[USDT][total] e.Mise à jour des prix pour le symbole dans les symboles: Le montant de la garantie est calculé à partir du montant de la garantie. si le pct est < 0,95*avg_pct: e. Acheter (symbole, prix (symbole), avg_pct-pct)Total/prix[symbole]) si le pct est supérieur à 1,05Je ne sais pas. e.Vendre (symbole,prix (symbole) = total/prix (symbole)) rés_list.append (([e.account[symbole][value] pour le symbole dans les symboles] + [e.account[USDT][total]]) rés = pd.DataFrame ((data=res_list, colonnes=symboles+[total],index = df.index)

Dans [495]: Compte électronique[USDT] À l'extérieur[495]:

Dans [496]: #backtest performance de tous les symboles (res.total/10000).graphique (figure de taille = 12,4), grille = Vrai); df[symbols].mean ((axe=1).plot ((figsize=(12,4), grille=Vrai); Extrait[496]:img

Dans [498]: # réduire les symboles avec une énorme augmentation les symboles = liste ((df.iloc[-1].sort_values() [:-10].index) e = échange (symboles, frais = 0,001, solde initial = 10000) rés_list = [] Le nombre d'étoiles est calculé en fonction de la taille de l'étoile. pour la ligne dans df[symboles].iterrows(): prix = rangée [1] le montant total = compte électronique[USDT][total] e.Mise à jour des prix pour le symbole dans les symboles: Le montant de la garantie est calculé à partir du montant de la garantie. si le pct est < 0,95*avg_pct: e. Acheter (symbole, prix (symbole), avg_pct-pct)Total/prix[symbole]) si le pct est supérieur à 1,05Je ne sais pas. e.Vendre (symbole,prix (symbole) = total/prix (symbole)) rés_list.append (([e.account[symbole][value] pour le symbole dans les symboles] + [e.account[USDT][total]]) rés = pd.DataFrame ((data=res_list, colonnes=symboles+[total],index = df.index)

Dans [501]: Compte électronique[USDT] Extrait [1]:

Dans [499]: (res.total/10000).graphique (figure de taille = 12,4), grille = Vrai); df[symbols].mean ((axe=1).plot ((figsize=(12,4), grille=Vrai); Extrait [499]:img

Dans [503]: #test seulement les symboles avec la plus grande augmentation les symboles = liste ((df.iloc[-1].sort_values() [-3:].index) e = échange (symboles, frais = 0,001, solde initial = 10000) rés_list = [] Le nombre d'étoiles est calculé en fonction de la taille de l'étoile. pour la ligne dans df[symboles].iterrows(): prix = rangée [1] le montant total = compte électronique[USDT][total] e.Mise à jour des prix pour le symbole dans les symboles: Le montant de la garantie est calculé à partir du montant de la garantie. si le pct est < 0,95*avg_pct: e. Acheter (symbole, prix (symbole), avg_pct-pct)Total/prix[symbole]) si le pct est supérieur à 1,05Je ne sais pas. e.Vendre (symbole,prix (symbole) = total/prix (symbole)) rés_list.append (([e.account[symbole][value] pour le symbole dans les symboles] + [e.account[USDT][total]]) rés = pd.DataFrame ((data=res_list, colonnes=symboles+[total],index = df.index)

Dans [504]: Compte électronique[USDT] Extrait[504]:

Dans [505]: (res.total/10000).graphique (figure de taille = 12,4), grille = Vrai); df[symbols].mean ((axe=1).plot ((figsize=(12,4), grille=Vrai); À l'extérieur[505]:img

Conclusion

En général, 2021 a été un grand marché haussier pour les monnaies copiées et une année désolée pour BTC. La valeur marchande de BTC est passée de 70% au début de l'année à 40% maintenant, ce qui est déjà le niveau le plus bas de l'histoire. Par conséquent, le profit moyen de l'achat de symboles de devises copiées et de leur détention au cours de l'année écoulée était beaucoup plus élevé que celui de la détention de BTC.


Plus de