2021 geht zu Ende, und Hotspots von DEFI bis GAMEFI entstehen in einem endlosen Strom, und der Gesamtmarkt ist immer noch ein Bullenmarkt. Jetzt blicken Sie zurück und fassen Sie zusammen, wie viel Sie 2021 gewonnen haben? Welche Chancen haben Sie verpasst? Was waren einige erfolgreiche Investitionen? Vor kurzem habe ich mir den historischen Markt des vergangenen Jahres angesehen und eine unerwartete einfache Profit-Strategie gefunden, die ein Multi-Währungsindex ist.
Es gibt so viele Währungen an der Börse, von denen viele dazu bestimmt sind, unbekannt zu sein und sogar aus dem Handel genommen werden können. Hier wählen wir die Währung von Binance perpetual contract, die auf dem Markt verwendet wurden. Sie werden im Allgemeinen getestet und als Mainstream-Währungen anerkannt, die relativ sicher sind. Nach einem einfachen Screening wurden einige Indexwährungen entfernt und schließlich 134 Währungen erhalten.
In [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
In [144]:
## Current trading pairs
Info = requests.get('https://fapi.binance.com/fapi/v1/exchangeInfo')
symbols = [s['symbol'] for s in Info.json()['symbols']]
In [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)
In [155]:
print(len(symbols_f))
Wir erhalten dann ihre täglichen Schlusskurse für das vergangene Jahr, wobei festgestellt wird, dass einige Währungen für eine kurze Zeit auf dem Regal waren, so dass wir die Daten ausfüllen müssen.
Die endgültige Indexrendite beträgt etwa 12 Mal, d.h. wenn Sie am 1. Januar 2021 im Durchschnitt die 134 Münzen kaufen, beträgt die endgültige Rendite des Nichtstuns 12 Mal. Es wird geschätzt, dass mehr als 90% der Trader die durchschnittliche Indexleistung nicht übertreffen. Unter ihnen sind die Währungen mit dem größten Rückgang: ICP fiel um 93%, DODO fiel um 85% und LINA fiel um 75%. Während SOL, FTM, LUNA, MATIC, SAND und AXS fast 100-mal gestiegen sind. Unter ihnen stieg AXS 168 Mal, was es zum größten dunklen Pferd macht. Der Median stieg um das 3-fache, was hauptsächlich durch die öffentliche Kette und Spiele getrieben wurde. Um die Überlebensverzerrung zu vermeiden, schlossen wir die ewige neue Währung während des Zeitraums aus und erzielten auch fast 11-fachen Gewinn.
Dies ist eine verzweifelte Rate der Rendite. Ich habe hart gearbeitet, um alle Arten von Strategien zu machen, aber es war weit davon entfernt, den Gewinn von nichts in einem Jahr zu tun. Allerdings sollte beachtet werden, dass einige der spezifischen Erhöhungen zu groß sind und es war abweichend von dem Index offensichtlich. Wenn diese Währungen nicht zu Beginn des Jahres ausgewählt werden, werden die Gewinne nahe an der Mediane sein, die viel weniger rentabel ist.
In [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
In [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
In [165]:
df_all_s.tail() #data structure
Ausgeschaltet[1]:
In [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
Ausgeschaltet[1]:
In [175]:
#The median increase
df_norm.median(axis=1).plot(figsize=(12,4),grid=True);
Ausgeschaltet[1]:
In [168]:
#Ranking for increase/decrease
print(df_norm.iloc[-1].round(2).sort_values().to_dict())
In [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())
In [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
In [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);
Ausgeschaltet[208]:
In [212]:
#Compared with Bitcoin
(df.mean(axis=1)/df.BTCUSDT).plot(figsize=(12,4),grid=True);
Ausgeschaltet[212]:
In [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)
In [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
In [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);
Aus[419]:
Im Backtest wurden alle Währungen des Online-Binance-Perpetual Contracts am 1. Januar 2021 ausgewählt. Die K-Linienperiode betrug 1h. Der Parameter begann in Positionen zu skalieren, wenn die Position 5% unter dem Durchschnitt lag, und verkaufte sie, wenn die Position mehr als 5% betrug. Wenn der Backtest alle Währungen umfasst, beträgt die endgültige strategische Rendite 7,7 Mal. Es ist offensichtlich nicht so gut wie die durchschnittliche Rendite von 13 Mal. Dies wird auch erwartet. Schließlich sind mehrere Währungen, die hundertmal gestiegen sind, zu speziell, und die Balance-Strategie wird sie alle verkaufen.
Wenn die 10 Währungen mit dem höchsten Anstieg aus dem Backtest entfernt werden, werden nur die relativ mittelschwachen Währungen berücksichtigt, und das Endertrag wird 4,8 mal betragen, was die durchschnittliche Leistung von 3,4 mal weit übersteigt.
Wenn nur die 3 Währungen mit dem höchsten Anstieg gedreht werden, werden die endgültigen Gewinne 373-mal betragen, was weit über der durchschnittlichen Leistung von 160-mal liegt. Dies zeigt, dass, wenn der Trend und der Anstieg der ausgewählten gedrehte Währung tendenziell konsistent sind, das Ergebnis der Drehung viel besser sein wird als das des Nichtstuns.
In [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)
In [495]:
e.account['USDT']
Ausgeschaltet[495]:
In [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);
Ausgeschaltet[496]:
In [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)
In [501]:
e.account['USDT']
Ausgeschaltet[1]:
In [499]:
(res.total/10000).plot(figsize=(12,4),grid = True);
df[symbols].mean(axis=1).plot(figsize=(12,4),grid=True);
Aus [499]:
In [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)
In [504]:
e.account['USDT']
Außen[504]:
In [505]:
(res.total/10000).plot(figsize=(12,4),grid = True);
df[symbols].mean(axis=1).plot(figsize=(12,4),grid=True);
Außen[505]:
Im Allgemeinen wird 2021 ein Bullenmarkt für gefälschte Münzen und ein rückläufiges Jahr für Bitcoin sein. Der Marktwert von Bitcoin ist jetzt von 70% zu Beginn des Jahres auf 40% gefallen, was das niedrigste Niveau in der Geschichte ist. Daher sind die durchschnittlichen Gewinne aus dem Kauf und Halten von gefälschten Waren im vergangenen Jahr weit höher als aus dem Halten von Bitcoin. Wenn Sie sich 2022 vorstellen, dass es in Zukunft noch mehrere hundertfache Währungen auf dem aktuellen Markt geben wird, können Sie Ihre Positionen mutig diversifizieren und geduldig warten. Wenn Sie besonders optimistisch über ein paar Währungen oder den durchschnittlichen Markt sind, können Sie die rotierende Strategie verwenden, um ohne nachzudenken überschüssige Renditen zu erzielen. Wenn Sie denken, dass sich die Dinge gegeneinander erreichen werden, wenn sie sich gegen das Extreme drehen, können Sie Bitcoin verhandeln, um bessere Renditen und Sicherheit zu erzielen.