Vor kurzem sah ich in dem Quantifizierungsjournal des Buo, dass man mit negativen Korrelationen handeln kann, um einen Gewinn zu erzielen. Digitale Währungen sind im Wesentlichen positiv korreliert, nur wenige sind negativ korreliert. Es gibt oft spezielle Märkte, wie zum Beispiel die MEME-Münzen, die in der Vergangenheit völlig unabhängig waren.
Der Kryptowährungspaarhandel ist eine auf statistischem Gewinn basierende Handelsstrategie, bei der Profit aus der Preisdifferenz erzielt wird, indem gleichzeitig zwei stark verknüpfte Kryptowährungspermanente gekauft und verkauft werden. In diesem Artikel werden die Grundsätze, die Gewinnmechanismen, die Methoden zur Auswahl von Münzen, die potenziellen Risiken und die Möglichkeiten zur Verbesserung dieser Methode und einige praktische Python-Codebeispiele beschrieben.
Die Pairing-Trading-Strategie beruht auf der historischen Korrelation zwischen den Preisen der beiden digitalen Währungen. Wenn die Preise der beiden Währungen stark korrelieren, sind ihre Kursbewegungen weitgehend synchronisiert. Wenn zu einem bestimmten Zeitpunkt eine signifikante Abweichung des Preisverhältnisses zwischen den beiden auftritt, kann dies als eine temporäre Abweichung angesehen werden, bei der die Preise zu normalen Niveaus zurückkehren.
Nehmen wir an, dass die Währungen A und B eine höhere Preisverknüpfung aufweisen. Zu einem bestimmten Zeitpunkt ist der durchschnittliche Wert der A/B-Preisquote 1. Wenn die A/B-Preisquote zu einem bestimmten Zeitpunkt von mehr als 0.001 abweicht, also mehr als 1.001, kann der Handel in folgender Weise durchgeführt werden:
Der Schlüssel zum Gewinn liegt in der Differenzgewinnung, wenn der Preis abweicht und wieder normal wird. Da der Preis abweicht, ist es normalerweise kurzfristig.
Diese Codes können direkt genutzt werden, vorzugsweise durch das Herunterladen von Anancoda und Debugging in einem Jupyer Notebook.
import requests
from datetime import date,datetime
import time
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import requests, zipfile, io
%matplotlib inline
Info = requests.get('https://fapi.binance.com/fapi/v1/exchangeInfo')
b_symbols = [s['symbol'] for s in Info.json()['symbols'] if s['contractType'] == 'PERPETUAL' and s['status'] == 'TRADING' and s['quoteAsset'] == 'USDT']
b_symbols = list(filter(lambda x: x[-4:] == 'USDT', [s.split('_')[0] for s in b_symbols]))
b_symbols = [x[:-4] for x in b_symbols]
print(b_symbols) # 获取所有的正在交易的交易对
Die Hauptfunktion der GetKlines-Funktion ist es, historische K-Linien-Daten zu bestimmten Transaktionen auf dauerhafte Verträge von Bitcoin-Börsen zu erhalten und diese Daten in einem Pandas-Datensatz zu speichern. Die K-Linien-Daten enthalten Informationen wie Öffnungspreis, Höchstpreis, Mindestpreis, Schließpreis, Volumen der Transaktionen. Diesmal verwenden wir hauptsächlich Daten zum Schließpreis.
def GetKlines(symbol='BTCUSDT',start='2020-8-10',end='2024-7-01',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 = min(int(time.mktime(datetime.strptime(end, "%Y-%m-%d").timetuple()))*1000 + 8*60*60*1000,time.time()*1000)
intervel_map = {'m':60*1000,'h':60*60*1000,'d':24*60*60*1000}
while start_time < end_time:
time.sleep(0.3)
mid_time = start_time+1000*int(period[:-1])*intervel_map[period[-1]]
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]+int(period[:-1])*intervel_map[period[-1]]
Klines += res_list
if type(res_list) == list and len(res_list) == 0:
start_time = start_time+1000*int(period[:-1])*intervel_map[period[-1]]
if mid_time >= end_time:
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
Die Datenmenge ist relativ groß und nur für die letzten 3 Monate wurden K-Stunden-Liniendaten für schnelleres Herunterladen erhalten.
start_date = '2024-04-01'
end_date = '2024-07-05'
period = '1h'
df_dict = {}
for symbol in b_symbols:
print(symbol)
if symbol in df_dict.keys():
continue
df_s = GetKlines(symbol=symbol+'USDT',start=start_date,end=end_date,period=period)
if not df_s.empty:
df_dict[symbol] = df_s
df_close = pd.DataFrame(index=pd.date_range(start=start_date, end=end_date, freq=period),columns=df_dict.keys())
for symbol in symbols:
df_close[symbol] = df_dict[symbol].close
df_close = df_close.dropna(how='all')
Definition eines Exchange-Objekts für die nächste Nachprüfung
class Exchange:
def __init__(self, trade_symbols, fee=0.0002, initial_balance=10000):
self.initial_balance = initial_balance #初始的资产
self.fee = fee
self.trade_symbols = trade_symbols
self.account = {'USDT':{'realised_profit':0, 'unrealised_profit':0, 'total':initial_balance,
'fee':0, 'leverage':0, 'hold':0, 'long':0, 'short':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 #扣除手续费
self.account['USDT']['fee'] += price*amount*self.fee
self.account[symbol]['fee'] += price*amount*self.fee
if cover_amount > 0: #先平仓
self.account['USDT']['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount #利润
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): #对资产进行更新
self.account['USDT']['unrealised_profit'] = 0
self.account['USDT']['hold'] = 0
self.account['USDT']['long'] = 0
self.account['USDT']['short'] = 0
for symbol in self.trade_symbols:
if not np.isnan(close_price[symbol]):
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'] = self.account[symbol]['amount']*close_price[symbol]
if self.account[symbol]['amount'] > 0:
self.account['USDT']['long'] += self.account[symbol]['value']
if self.account[symbol]['amount'] < 0:
self.account['USDT']['short'] += self.account[symbol]['value']
self.account['USDT']['hold'] += abs(self.account[symbol]['value'])
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)
self.account['USDT']['leverage'] = round(self.account['USDT']['hold']/self.account['USDT']['total'],3)
Die Korrelationsrechnung ist eine Methode in der Statistik, die verwendet wird, um die lineare Beziehung zwischen zwei Variablen zu messen. Die am häufigsten verwendeten Korrelationsrechnungsmethoden sind die Pearson-Korrelationskoeffizienten. Hier sind die Grundsätze, Formeln und Implementierungsmethoden für die Korrelationsrechnung.
Die Pearson-Relationschaftskoeffizienten werden durch die Berechnung des Koeffizientenunterschieds und des Standardunterschieds der beiden Variablen ermittelt.
[ \rho_{X,Y} = \frac{\text{cov}(X,Y) } {\sigma_X \sigma_Y}
Sie sind:
Natürlich kann man mit Hilfe von Python 1-Zeile Code die Relevanz aller Währungen berechnen, ohne sich so sehr darum zu kümmern, wie sie berechnet wird. Wie die Relativitätsthermographie zeigt, ist die Vertretung in Rot positiv relevant, die Vertretung in Blau negativ relevant, und je tiefer die Farben sind, desto stärker ist die Relevanz.
import seaborn as sns
corr = df_close.corr()
plt.figure(figsize=(20, 20))
sns.heatmap(corr, annot=False, cmap='coolwarm', vmin=-1, vmax=1)
plt.title('Correlation Heatmap of Cryptocurrency Closing Prices', fontsize=20);
Nach Relevanz wurden die Top-20 der relevantesten Währungspaare ausgewählt.
MANA SAND 0.996562
ICX ZIL 0.996000
STORJ FLOW 0.994193
FLOW SXP 0.993861
STORJ SXP 0.993822
IOTA ZIL 0.993204
SAND 0.993095
KAVA SAND 0.992303
ZIL SXP 0.992285
SAND 0.992103
DYDX ZIL 0.992053
DENT REEF 0.991789
RDNT MANTA 0.991690
STMX STORJ 0.991222
BIGTIME ACE 0.990987
RDNT HOOK 0.990718
IOST GAS 0.990643
ZIL HOOK 0.990576
MATIC FLOW 0.990564
MANTA HOOK 0.990563
Der entsprechende Code lautet:
corr_pairs = corr.unstack()
# 移除自身相关性(即对角线上的值)
corr_pairs = corr_pairs[corr_pairs != 1]
sorted_corr_pairs = corr_pairs.sort_values(kind="quicksort")
# 提取最相关和最不相关的前20个币种对
most_correlated = sorted_corr_pairs.tail(40)[::-2]
print("最相关的前20个币种对:")
print(most_correlated)
Der spezifische Rückrufcode ist folgender: Die Hauptbeobachtung der Demonstrationsstrategie ist der Preisverhältnis der beiden Kryptowährungen (IOTA und ZIL) und die Transaktionen werden nach Veränderungen dieses Verhältnisses durchgeführt. Die spezifischen Schritte sind folgende:
Einführung:
e
Der Anfangsbetrag beträgt 10.000 US-Dollar und die Transaktionsgebühr beträgt 0,02%.avg
。value = 1000
。Iderative Bearbeitung von Preisdaten:
df_close
。diff
。aim_value
Für jede Abweichung von 0.01 wird ein Wert gehandelt.pair_a
und kaufenpair_b
Sie ist ein guter Freund.pair_a
und verkaufenpair_b
Sie ist ein guter Freund.Anpassung der Durchschnitte:
avg
Der Preis wird von den Kunden angezeigt, um den aktuellen Preisverhältnis zu reflektieren.Akten und Aufzeichnungen aktualisieren:
res_list
。Ausgabe der Ergebnisse:
res_list
Umgewandelt in einen Datenschaltflächenres
Das ist ein großes Problem, das wir uns stellen müssen, um es zu analysieren und zu zeigen.pair_a = 'IOTA'
pair_b = "ZIL"
e = Exchange([pair_a,pair_b], fee=0.0002, initial_balance=10000) #Exchange定义放在评论区
res_list = []
index_list = []
avg = df_close[pair_a][0] / df_close[pair_b][0]
value = 1000
for idx, row in df_close.iterrows():
diff = (row[pair_a] / row[pair_b] - avg)/avg
aim_value = -value * diff / 0.01
if -aim_value + e.account[pair_a]['amount']*row[pair_a] > 0.5*value:
e.Sell(pair_a,row[pair_a],(-aim_value + e.account[pair_a]['amount']*row[pair_a])/row[pair_a])
e.Buy(pair_b,row[pair_b],(-aim_value - e.account[pair_b]['amount']*row[pair_b])/row[pair_b])
if -aim_value + e.account[pair_a]['amount']*row[pair_a] < -0.5*value:
e.Buy(pair_a, row[pair_a],(aim_value - e.account[pair_a]['amount']*row[pair_a])/row[pair_a])
e.Sell(pair_b, row[pair_b],(aim_value + e.account[pair_b]['amount']*row[pair_b])/row[pair_b])
avg = 0.99*avg + 0.01*row[pair_a] / row[pair_b]
index_list.append(idx)
e.Update(row)
res_list.append([e.account['USDT']['total'],e.account['USDT']['hold'],
e.account['USDT']['fee'],e.account['USDT']['long'],e.account['USDT']['short']])
res = pd.DataFrame(data=res_list, columns=['total','hold', 'fee', 'long', 'short'],index = index_list)
res['total'].plot(grid=True);
Es wurden insgesamt vier Gruppen von Währungen getestet, und das Ergebnis ist relativ ideal. Die Berechnung der aktuellen Korrelation wird mit Zukunftsdaten durchgeführt, so dass sie nicht sehr genau ist.
Obwohl die Pairing-Handelsstrategie theoretisch profitabel ist, bestehen in der Praxis Risiken: Die Wechselbeziehungen zwischen den Währungen können sich mit der Zeit ändern und die Strategie versagen; bei extremen Marktbedingungen können die Preisverzerrungen sich verschärfen und zu größeren Verlusten führen; die geringe Liquidität bestimmter Währungen kann dazu führen, dass die Transaktionen schwierig sind oder die Kosten steigen; die Aufwandsgebühren, die durch häufige Transaktionen entstehen, können die Gewinne erodieren.
Um Risiken zu reduzieren und die Stabilität der Strategie zu verbessern, können folgende Verbesserungsmaßnahmen in Betracht gezogen werden: regelmäßige Umrechnung der Korrelation zwischen den Währungen, rechtzeitige Anpassung der Paare; Einstellung von Stop-Loss und Stop-Spotpunkten, um den maximalen Verlust eines einzelnen Handels zu kontrollieren; gleichzeitige Handel von mehreren Währungspaaren, um das Risiko zu verteilen.
Die Kryptowährungspaarungs-Handelsstrategie erzielt einen Gewinn, indem sie die Korrelation der Preise der Währungen nutzt, um bei einer Abweichung der Preise zu profitieren. Die Strategie hat eine hohe theoretische Durchführbarkeit. Ein einfacher, realer Strategie-Sourcecode basierend auf der Strategie wird dann veröffentlicht.
77924998Was ist mit den Quellen, die es wert sind?
Weizen 888Zhang, der Chef der Überstunden - Ha-ha-ha!