Type/to search
3
Follow
1505
Followers
Detaillierte Erklärung der Handelsstrategie für digitale Währungspaare
Discussions
Created 2024-07-05 16:23:42  Updated 2024-11-05 17:42:06
 3
 6566

img

Detaillierte Erklärung der Handelsstrategie für digitale Währungspaare

Einführung

Kürzlich habe ich Buus quantitatives Tagebuch gesehen, in dem erwähnt wurde, dass man negativ korrelierte Währungen zur Auswahl von Währungen verwenden und Positionen eröffnen kann, um auf der Grundlage von Preisunterschieden Gewinne zu erzielen. Digitale Währungen sind grundsätzlich positiv korreliert, und nur wenige Währungen sind negativ korreliert. Sie haben oft besondere Marktbedingungen, wie beispielsweise die unabhängigen Marktbedingungen der MEME-Münze vor einiger Zeit, die dem Trend des Marktes überhaupt nicht folgten. Herausfiltern und bleiben Sie auch nach dem Durchbruch noch lange auf diesen Währungen, mit dieser Methode können unter bestimmten Marktbedingungen Gewinne erzielt werden. Die gängigste Methode im Bereich des quantitativen Handels ist jedoch die Verwendung einer positiven Korrelation für den Paarhandel. In diesem Artikel wird diese Strategie kurz vorgestellt.

Beim Handel mit Kryptowährungspaaren handelt es sich um eine auf statistischer Arbitrage basierende Handelsstrategie, die darauf abzielt, durch den gleichzeitigen Kauf und Verkauf von zwei zeitlich unbefristeten Kontrakten mit hoher Korrelation zwischen zwei Kryptowährungen Gewinne aus Preisabweichungen zu erzielen. Dieser Artikel stellt die Grundsätze der Strategie, den Gewinnmechanismus, die Methode zur Währungsprüfung, potenzielle Risiken und Verbesserungsmöglichkeiten vor und bietet einige praktische Python-Codebeispiele.

Strategieprinzip

Paarhandelsstrategien basieren auf der historischen Korrelation zwischen den Preisen zweier Kryptowährungen. Wenn zwei Währungen stark korreliert sind, bewegen sich ihre Preise ungefähr synchron. Weicht das Preisverhältnis zwischen den beiden zu einem bestimmten Zeitpunkt erheblich ab, kann davon ausgegangen werden, dass es sich um eine vorübergehende Anomalie handelt und die Preise tendenziell wieder auf ein normales Niveau zurückkehren. Der Markt für digitale Währungen ist stark vernetzt. Wenn eine wichtige digitale Währung (wie Bitcoin) erheblichen Schwankungen unterliegt, löst dies normalerweise eine Kettenreaktion unter anderen digitalen Währungen aus. Einige Währungen weisen möglicherweise eine sehr offensichtliche positive Korrelation auf, und diese Korrelation kann auch anhalten, weil sie zu denselben Investmentinstituten, denselben Market Makern und demselben Kurs gehören. Einige Währungen sind negativ korreliert, es gibt jedoch weniger negativ korrelierte Währungen, und da sie alle vom allgemeinen Markttrend beeinflusst werden, zeigen sie häufig konsistente Markttrends.

Nehmen wir an, dass Münze A und Münze B eine hohe Preiskorrelation aufweisen. Zu einem bestimmten Zeitpunkt beträgt der Durchschnittswert des A/B-Preisverhältnisses 1. Wenn das Preisverhältnis A/B zu einem bestimmten Zeitpunkt um mehr als 0,001, also mehr als 1,001, vom Anstieg abweicht, können Sie auf folgende Weise handeln: Öffnen Sie eine Long-Position auf B und eine Short-Position auf A. . Im Gegenteil, wenn das A/B-Preisverhältnis niedriger als 0,999 ist: Eröffnen Sie eine Long-Position auf A und eine Short-Position auf B.

Der Schlüssel zur Rentabilität liegt in den Preisdifferenzgewinnen, die sich ergeben, wenn die Preise abweichen und sich wieder normalisieren. Da Preisabweichungen in der Regel nur von kurzer Dauer sind, können Händler ihre Positionen schließen, wenn die Preise zum Mittelwert zurückkehren, und von der Differenz profitieren.

Vorbereiten der Daten

Importieren Sie die entsprechende Bibliothek

Diese Codes können direkt verwendet werden, am besten laden Sie jedoch Anancoda herunter und debuggen es in einem Jupyer-Notebook. Enthält direkt Pakete für häufig verwendete Datenanalysen.

python
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

Alle gehandelten Handelspaare abrufen

python
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) # 获取所有的正在交易的交易对

K-Line-Funktion herunterladen

Die Hauptfunktion der GetKlines-Funktion besteht darin, die historischen K-Line-Daten des unbefristeten Vertrags des angegebenen Handelspaares von der Binance-Börse abzurufen und diese Daten in einem Pandas DataFrame zu speichern. Zu den K-Line-Daten zählen Eröffnungskurs, Höchstkurs, Tiefstkurs, Schlusskurs, Handelsvolumen und weitere Informationen. Dieses Mal verwenden wir hauptsächlich Schlusskursdaten.

python
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

Daten herunterladen

Die Datenmenge ist relativ groß. Um den Download zu beschleunigen, wurden nur die stündlichen K-Line-Daten der letzten drei Monate abgerufen. df_close enthält Schlusskursdaten für alle Währungen

python
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')

Backtesting-Engine

Definiert ein Exchange-Objekt für den folgenden Backtest

python
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)

Korrelationsanalyse zum Filtern von Währungen

Die Korrelationsrechnung ist ein Verfahren der Statistik, mit dem der lineare Zusammenhang zwischen zwei Variablen gemessen wird. Die am häufigsten verwendete Methode zur Korrelationsberechnung ist der Korrelationskoeffizient nach Pearson. Nachfolgend finden Sie die Prinzipien, Formeln und Implementierungsmethoden zur Korrelationsberechnung. Der Korrelationskoeffizient nach Pearson dient zur Messung der linearen Beziehung zwischen zwei Variablen und sein Wertebereich liegt zwischen -1 und 1:

  • 1 Zeigt eine perfekte positive Korrelation an, bei der sich die beiden Variablen immer synchron ändern. Wenn eine Variable zunimmt, nimmt auch die andere Variable proportional zu. Je näher der Wert bei 1 liegt, desto stärker ist die Korrelation.
  • -1 Zeigt eine perfekte negative Korrelation an, bei der sich die beiden Variablen immer in entgegengesetzte Richtungen ändern. Je näher der Wert bei -1 liegt, desto stärker ist die negative Korrelation.
  • 0 Zeigt an, dass keine lineare Korrelation vorliegt; zwischen den beiden Variablen besteht keine geradlinige Beziehung.

Der Pearson-Korrelationskoeffizient bestimmt die Korrelation zwischen zwei Variablen, indem er ihre Kovarianz und Standardabweichung berechnet. Die Formel lautet wie folgt:

[ \rho_{X,Y} = \frac{\text{cov}(X,Y)}{\sigma_X \sigma_Y} ]

In:

  • ( \rho_{X,Y} ) ist eine Variable( X ) Und ( Y ) Der Pearson-Korrelationskoeffizient.
  • ( \text{cov}(X,Y) ) Ja ( X ) Und ( Y ) Die Kovarianz von .
  • ( \sigma_X ) Und ( \sigma_Y ) Sie sind( X ) Und ( Y ) Die Standardabweichung von .

Über die Berechnung müssen Sie sich natürlich keine großen Gedanken machen. Sie können die Korrelation aller Währungen mit nur einer Zeile Python-Code berechnen. Die Abbildung zeigt eine Korrelations-Heatmap. Rot steht für positive Korrelation, Blau für negative Korrelation und je dunkler die Farbe, desto stärker die Korrelation. Es ist ersichtlich, dass große Bereiche dunkelrot sind, was bedeutet, dass die positive Korrelation der digitalen Währung sehr stark ist.

img

python
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);

Basierend auf der Korrelation werden die 20 relevantesten Währungspaare ausgewählt. Die Ergebnisse sind wie folgt. Ihre Korrelationen sind sehr stark, alle über 0,99.

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 wie folgt:

python
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)

Backtesting-Verifizierung

Der spezifische Backtest-Code lautet wie folgt. Die Demo-Strategie konzentriert sich auf die Beobachtung des Preisverhältnisses zweier Kryptowährungen (IOTA und ZIL) und den Handel basierend auf Änderungen dieses Verhältnisses. Die einzelnen Schritte sind wie folgt:

  1. Initialisierung

    • Definieren Sie Handelspaare (pair_a = ‚IOTA‘, pair_b = ‚ZIL‘).
    • Erstellen eines Austauschobjektse, der Anfangssaldo beträgt 10.000 $ und die Transaktionsgebühr beträgt 0,02 %.
    • Berechnung des anfänglichen Durchschnittspreisverhältnissesavg
    • Legen Sie einen anfänglichen Transaktionswert festvalue = 1000
  2. Preisdaten iterativ verarbeiten

    • Durchlaufen Sie die Preisdaten zu jedem Zeitpunktdf_close
    • Berechnet die Abweichung des aktuellen Preisverhältnisses vom Mittelwertdiff
    • Berechnen Sie den Zieltransaktionswert basierend auf der Abweichungaim_value, für jede Abweichung von 0,01 wird ein Wert gehandelt. Und entscheiden Sie auf Basis der aktuellen Kontopositionen und Preisbedingungen über Kauf- und Verkaufstransaktionen.
    • Wenn die Abweichung zu groß ist, führen Sie einen Verkauf durchpair_a und kaufenpair_b arbeiten.
    • Wenn die Abweichung zu gering ist, führen Sie einen Kauf auspair_a und verkaufenpair_b arbeiten.
  3. Angepasster Mittelwert

    • Aktualisiertes durchschnittliches Preisverhältnisavg, um das aktuelle Preisverhältnis widerzuspiegeln.
  4. Aktualisieren von Konten und Datensätzen

    • Aktualisieren Sie die Positions- und Saldeninformationen des Börsenkontos.
    • Notieren Sie den Kontostatus bei jedem Schritt (Gesamtvermögen, Bestände, Transaktionsgebühren, Long- und Short-Positionen), umres_list
  5. Ergebnisausgabe

    • Wille res_list In Datenrahmen konvertierenres, zur weiteren Analyse und Präsentation.
python
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);

Insgesamt wurden vier Währungsgruppen einem Backtesting unterzogen und die Ergebnisse waren relativ optimal. Die aktuellen Korrelationsberechnungen basieren auf zukünftigen Daten und sind daher nicht sehr präzise. Auch dieser Artikel unterteilt die Daten in zwei Teile, basierend auf der berechneten Korrelation im Vordergrund und den Backtesting-Transaktionen im Hintergrund. Die Ergebnisse waren etwas abweichend, aber immer noch ziemlich gut. Die Durchführung der Überprüfung bleibt dem Benutzer überlassen.

img

Mögliche Risiken und Verbesserungsmöglichkeiten

Obwohl die Paarhandelsstrategie theoretisch profitabel sein kann, gibt es im tatsächlichen Betrieb immer noch einige Risiken: Die Korrelation zwischen den Währungen kann sich im Laufe der Zeit ändern, was zum Scheitern der Strategie führt. Unter extremen Marktbedingungen können die Preisabweichungen zunehmen, was zu großen Verlusten führt. Die geringe Liquidität bestimmter Währungen kann die Ausführung von Transaktionen erschweren oder die Kosten erhöhen; die durch häufige Transaktionen entstehenden Gebühren können die Gewinne schmälern.

Um das Risiko zu verringern und die Stabilität der Strategie zu verbessern, können die folgenden Verbesserungsmaßnahmen in Betracht gezogen werden: regelmäßige Neuberechnung der Korrelation zwischen Währungen und rechtzeitige Anpassung der Handelspaare; Festlegung von Stop-Loss- und Take-Profit-Punkten, um den maximalen Verlust einer einzelnen Transaktion zu kontrollieren; Handeln Sie mit mehreren Münzpaaren, um das Risiko zu streuen.

abschließend

Mit der Handelsstrategie für digitale Währungspaare werden Gewinne erzielt, indem die Korrelation zwischen Währungskursen ausgenutzt und bei abweichenden Kursen Arbitragegeschäfte durchgeführt werden. Diese Strategie hat eine hohe theoretische Machbarkeit. Ein einfacher Echtzeitstrategie-Quellcode basierend auf dieser Strategie wird später veröffentlicht. Wenn Sie weitere Fragen haben oder Bedarf für eine weitere Diskussion haben, können Sie sich gerne an uns wenden.

Comment
All comments (2)

    这个值得研究,码源呢?

    2 years ago

    张总加班 - -! 哈哈哈

    2 years ago
  • 1
iPhone Download
Forums
PINE Language
© 2015 - ∞ INVENTOR PTE LTD (SG)