Revisión del mercado de divisas digitales en 2021 y la estrategia más simple 10 veces perdida

El autor:- ¿ Por qué?, Creado: 2022-10-26 16:12:49, Actualizado: 2023-09-15 20:41:17

img

Resumen para 2021 y estrategias futuras

2021 está llegando a su fin, y los puntos calientes de DEFI a GAMEFI están surgiendo en una corriente interminable, y el mercado general sigue siendo un mercado alcista. Ahora mire hacia atrás y resuma, ¿cuánto ganó en 2021? ¿Qué oportunidades perdió? ¿Cuáles fueron algunas inversiones exitosas? Recientemente, eché un vistazo al mercado histórico del año pasado y encontré una estrategia de lucro inesperada y simple, que es un índice multidivisas.

Hay tantas monedas en el intercambio, muchas de las cuales están destinadas a ser desconocidas e incluso pueden retirarse del comercio. Aquí elegimos la moneda de Binance perpetual contract que se han utilizado en el mercado. Generalmente se prueban y reconocen como monedas convencionales, que son relativamente seguras. Después de una simple detección, se eliminaron algunas monedas de índice y finalmente se obtuvieron 134 monedas.

En [1]:

import requests
from datetime import date,datetime
import time
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

En [144]:

## Current trading pairs
Info = requests.get('https://fapi.binance.com/fapi/v1/exchangeInfo')
symbols = [s['symbol'] for s in Info.json()['symbols']]

En [154]:

symbols_f = list(set(filter(lambda x: x[-4:] == 'USDT', [s.split('_')[0] for s in symbols]))-
                 set(['1000SHIBUSDT','1000XECUSDT','BTCDOMUSDT','DEFIUSDT','BTCSTUSDT'])) + ['SHIBUSDT','XECUSDT']
print(symbols_f)

En [155]:

print(len(symbols_f))

Mercado en el último año

Luego obtenemos sus precios de cierre diarios para el año pasado, observando que algunas monedas han estado en el estante durante un corto período de tiempo, por lo que necesitamos rellenar los datos.

El rendimiento del índice final es de aproximadamente 12 veces, es decir, si usted compra las 134 monedas el 1 de enero de 2021 en promedio, el rendimiento final de no hacer nada será de 12 veces. Se estima que más del 90% de los comerciantes no superan el índice promedio. Entre ellos, las monedas con la mayor caída son: ICP cayó en 93%, DODO cayó en 85% y LINA cayó en 75%. Mientras que SOL, FTM, LUNA, MATIC, SAND y AXS han aumentado casi 100 veces. Entre ellos, AXS subió 168 veces, convirtiéndose en el caballo oscuro más grande. La mediana aumentó 3 veces, lo que fue impulsado principalmente por la cadena pública y los juegos. Para evitar el sesgo de supervivencia, excluimos la nueva moneda perpetua durante el período, y también logramos casi 11 veces los beneficios. Es 7 veces los beneficios de BTC para sobrevivir.

Esta es una tasa de rendimiento desesperada. He trabajado duro para hacer todo tipo de estrategias, pero estaba lejos de las ganancias de no hacer nada en un año. Sin embargo, debe tenerse en cuenta que algunos de los aumentos específicos son demasiado grandes y se desvió del índice obviamente. Si estas monedas no se seleccionan al principio del año, las ganancias estarán cerca de la mediana, que es mucho menos rentable.

En [157]:

#Obtain the function of K-line in any period
def GetKlines(symbol='BTCUSDT',start='2020-8-10',end='2021-8-10',period='1h',base='fapi',v = 'v1'):
    Klines = []
    start_time = int(time.mktime(datetime.strptime(start, "%Y-%m-%d").timetuple()))*1000 + 8*60*60*1000
    end_time = int(time.mktime(datetime.strptime(end, "%Y-%m-%d").timetuple()))*1000 + 8*60*60*1000
    intervel_map = {'m':60*1000,'h':60*60*1000,'d':24*60*60*1000}
    while start_time < end_time:
        mid_time = min(start_time+1000*int(period[:-1])*intervel_map[period[-1]],end_time)
        url = 'https://'+base+'.binance.com/'+base+'/'+v+'/klines?symbol=%s&interval=%s&startTime=%s&endTime=%s&limit=1000'%(symbol,period,start_time,mid_time)
        res = requests.get(url)
        res_list = res.json()
        if type(res_list) == list and len(res_list) > 0:
            start_time = res_list[-1][0]
            Klines += res_list
        elif type(res_list) == list:
            start_time = start_time+1000*int(period[:-1])*intervel_map[period[-1]]
        else:
            break

    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')
    return df

En [164]:

df_all_s = pd.DataFrame(index=pd.date_range(start='2021-1-1', end='2021-12-28', freq='1d'),columns=symbols_s)
for i in range(len(symbols_f)):
    #print(symbols_s[i])
    symbol_s = symbols_f[i]
    df_s = GetKlines(symbol=symbol_s,start='2021-1-1',end='2021-12-28',period='1d',base='api',v='v3')
    df_all_s[symbol_s] = df_s[~df_s.index.duplicated(keep='first')].close

En el [165]:

df_all_s.tail() #data structure

Fuera [1]:

En [174]:

df_all = df_all_s.fillna(method='bfill')#filled data
df_norm = df_all/df_all.iloc[0] #normalization
df_norm.mean(axis=1).plot(figsize=(12,4),grid=True);
#The final index return chart

Fuera [1]:

img

En el [175]:

#The median increase
df_norm.median(axis=1).plot(figsize=(12,4),grid=True);

Fuera [1]:

img

En [168]:

#Ranking for increase/decrease
print(df_norm.iloc[-1].round(2).sort_values().to_dict())

En [317]:

#Maximum rollback of current price compared with the highest point in the year
print((1-df_norm.iloc[-1]/df_norm.max()).round(2).sort_values().to_dict())

En [177]:

df_all_f = pd.DataFrame(index=pd.date_range(start='2021-1-1', end='2021-12-28', freq='1d'),columns=symbols_s)
for i in range(len(symbols_f)):
    #print(symbols_s[i])
    symbol_f = symbols_f[i]
    df_f = GetKlines(symbol=symbol_f,start='2021-1-1',end='2021-12-28',period='1d',base='fapi',v='v1')
    df_all_f[symbol_f] = df_f[~df_f.index.duplicated(keep='first')].close

En [208]:

#Excluding new currency
df = df_all_s[df_all_s.columns[~df_all_f.iloc[0].isnull()]]
df = df.fillna(method='bfill')
df = df/df.iloc[0]
df.mean(axis=1).plot(figsize=(12,4),grid=True);

Fuera[208]:

img

En [212]:

#Compared with Bitcoin
(df.mean(axis=1)/df.BTCUSDT).plot(figsize=(12,4),grid=True);

Fuera [1]:

img

En [213]:

#Use the original backtest engine
class Exchange:
    
    def __init__(self, trade_symbols, fee=0.0004, initial_balance=10000):
        self.initial_balance = initial_balance #Initial assets
        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 the handling fee
        self.account['USDT']['fee'] += price*amount*self.fee
        self.account[symbol]['fee'] += price*amount*self.fee

        if cover_amount > 0: #Close the position first
            self.account['USDT']['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount  #Profits
            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 the assets
        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)

En el [418]:

#The hourly K-line was taken to make the backtest more accurate
df_all_s = pd.DataFrame(index=pd.date_range(start='2021-1-1', end='2021-12-28', freq='1h'),columns=symbols_s)
for i in range(len(symbols_f)):
    #print(symbols_s[i])
    symbol_s = symbols_f[i]
    df_s = GetKlines(symbol=symbol_s,start='2021-1-1',end='2021-12-28',period='1h',base='api',v='v3')
    df_all_s[symbol_s] = df_s[~df_s.index.duplicated(keep='first')].close

En el [419]:

df = df_all_s[df_all_s.columns[~df_all_f.iloc[0].isnull()]]
df = df.fillna(method='bfill')
df = df/df.iloc[0]
df.mean(axis=1).plot(figsize=(12,4),grid=True);

Fuera[419]:

img

Ejecución de las estrategias equilibradas

En el backtest, se seleccionaron todas las monedas del contrato perpetuo Binance en línea el 1 de enero de 2021. El período de la línea K fue de 1h. El parámetro comenzó a escalar en posiciones cuando la posición era un 5% inferior al promedio, y las vendió cuando la posición era más del 5%. Cuando el backtest es todas las monedas, el rendimiento estratégico final es de 7.7 veces. Obviamente no es tan bueno como el rendimiento promedio de 13 veces. Esto también se espera. Después de todo, varias monedas que subieron cien veces son demasiado especiales, y la estrategia de equilibrio las venderá a todas.

Si se eliminan de la prueba de retroceso las 10 monedas con mayor aumento, sólo se considerarán las monedas relativamente mediocres, y el ingreso final será de 4,8 veces, muy superior al rendimiento promedio de 3,4 veces.

Si solo se rotan las 3 monedas con mayor aumento, las ganancias finales serán 373 veces, lo que es mucho más que el rendimiento promedio de 160 veces. Esto muestra que si la tendencia y el aumento de la moneda rotada seleccionada tienden a ser consistentes, el resultado de rotar será mucho mejor que el de no hacer nada.

En el [494]:

#Full currency backtest
symbols = list(df.iloc[-1].sort_values()[:].index)
e = Exchange(symbols, fee=0.001, initial_balance=10000)
res_list = []
avg_pct = 1/len(symbols)
for row in df[symbols].iterrows():
    prices = row[1]
    total = e.account['USDT']['total']
    e.Update(prices)
    for symbol in symbols:
        pct = e.account[symbol]['value']/total
        if pct < 0.95*avg_pct:
            e.Buy(symbol,prices[symbol],(avg_pct-pct)*total/prices[symbol])
        if pct > 1.05*avg_pct:
            e.Sell(symbol,prices[symbol],(pct-avg_pct)*total/prices[symbol])
    res_list.append([e.account[symbol]['value'] for symbol in symbols] + [e.account['USDT']['total']])
res = pd.DataFrame(data=res_list, columns=symbols+['total'],index = df.index)

En el [495]:

e.account['USDT']

Fuera[495]:

En el [496]:

# Backtest performance of full currencies
(res.total/10000).plot(figsize=(12,4),grid = True); 
df[symbols].mean(axis=1).plot(figsize=(12,4),grid=True);

Fuera[496]:

img

En el [498]:

#Remove currencies with huge growth
symbols = list(df.iloc[-1].sort_values()[:-10].index)
e = Exchange(symbols, fee=0.001, initial_balance=10000)
res_list = []
avg_pct = 1/len(symbols)
for row in df[symbols].iterrows():
    prices = row[1]
    total = e.account['USDT']['total']
    e.Update(prices)
    for symbol in symbols:
        pct = e.account[symbol]['value']/total
        if pct < 0.95*avg_pct:
            e.Buy(symbol,prices[symbol],(avg_pct-pct)*total/prices[symbol])
        if pct > 1.05*avg_pct:
            e.Sell(symbol,prices[symbol],(pct-avg_pct)*total/prices[symbol])
    res_list.append([e.account[symbol]['value'] for symbol in symbols] + [e.account['USDT']['total']])
res = pd.DataFrame(data=res_list, columns=symbols+['total'],index = df.index)

En el [501]:

e.account['USDT']

Fuera[501]:

En [499]:

(res.total/10000).plot(figsize=(12,4),grid = True); 
df[symbols].mean(axis=1).plot(figsize=(12,4),grid=True);

En el caso de las empresas de servicios de telecomunicaciones:

img

En el [503]:

#Only the currency with the highest increase is tested
symbols = list(df.iloc[-1].sort_values()[-3:].index)
e = Exchange(symbols, fee=0.001, initial_balance=10000)
res_list = []
avg_pct = 1/len(symbols)
for row in df[symbols].iterrows():
    prices = row[1]
    total = e.account['USDT']['total']
    e.Update(prices)
    for symbol in symbols:
        pct = e.account[symbol]['value']/total
        if pct < 0.95*avg_pct:
            e.Buy(symbol,prices[symbol],(avg_pct-pct)*total/prices[symbol])
        if pct > 1.05*avg_pct:
            e.Sell(symbol,prices[symbol],(pct-avg_pct)*total/prices[symbol])
    res_list.append([e.account[symbol]['value'] for symbol in symbols] + [e.account['USDT']['total']])
res = pd.DataFrame(data=res_list, columns=symbols+['total'],index = df.index)

En el [504]:

e.account['USDT']

Fuera[504]:

En el [505]:

(res.total/10000).plot(figsize=(12,4),grid = True); 
df[symbols].mean(axis=1).plot(figsize=(12,4),grid=True);

Fuera[505]:

img

Resumen de las actividades

En general, 2021 será un mercado alcista para las monedas falsificadas y un año a la baja para Bitcoin. El valor de mercado de Bitcoin ha caído al 40% ahora desde el 70% al comienzo del año, que es el nivel más bajo de la historia. Por lo tanto, las ganancias promedio de comprar y mantener bienes falsificados en el año pasado son mucho más altas que las de mantener Bitcoin. Mirando hacia adelante a 2022, si considera que todavía habrá varias monedas centenarias en el mercado actual en el futuro, puede diversificar sus posiciones con audacia y esperar pacientemente. Si es particularmente optimista sobre algunas monedas o el mercado promedio, puede usar la estrategia rotativa para obtener rendimientos excesivos sin pensar. Si piensa que las cosas llegarán una contra otra cuando se vuelvan al extremo, puede cazar Bitcoin para obtener mejores rendimientos y seguridad.


Relacionados

Más.