
Baru-baru ini saya melihat buku harian kuantitatif Buu yang menyebutkan bahwa Anda dapat menggunakan mata uang berkorelasi negatif untuk memilih mata uang, dan membuka posisi untuk menghasilkan keuntungan berdasarkan terobosan perbedaan harga. Mata uang digital pada dasarnya berkorelasi positif, dan hanya beberapa mata uang yang berkorelasi negatif. Mata uang digital sering kali memiliki kondisi pasar khusus, seperti kondisi pasar independen koin MEME beberapa waktu lalu, yang sama sekali tidak mengikuti tren pasar. Saring mata uang ini dan bertahan lama setelah terobosan, metode ini dapat menghasilkan keuntungan dalam kondisi pasar tertentu. Namun, metode yang paling umum di bidang perdagangan kuantitatif adalah menggunakan korelasi positif untuk perdagangan berpasangan. Artikel ini akan memperkenalkan strategi ini secara singkat.
Perdagangan pasangan mata uang kripto adalah strategi perdagangan yang didasarkan pada arbitrase statistik, yang berupaya memperoleh laba dari penyimpangan harga dengan membeli dan menjual dua kontrak berjangka mata uang kripto yang sangat berkorelasi secara bersamaan. Artikel ini akan memperkenalkan prinsip-prinsip strategi, mekanisme keuntungan, metode penyaringan mata uang, potensi risiko dan cara memperbaikinya, serta memberikan beberapa contoh kode Python praktis.
Strategi perdagangan berpasangan bergantung pada korelasi historis antara harga dua mata uang kripto. Ketika dua mata uang berkorelasi kuat, harga-harganya bergerak hampir selaras. Jika pada saat tertentu rasio harga keduanya menyimpang secara signifikan, dapat dianggap bahwa ini adalah anomali sementara dan harga akan cenderung kembali ke tingkat normal. Pasar mata uang digital sangat saling terkait. Ketika mata uang digital utama (seperti Bitcoin) mengalami fluktuasi yang signifikan, hal itu biasanya memicu reaksi berantai di antara mata uang digital lainnya. Beberapa mata uang mungkin memiliki korelasi positif yang sangat jelas, dan korelasi tersebut dapat dipertahankan, karena mata uang tersebut dimiliki oleh lembaga investasi yang sama, pembuat pasar yang sama, dan jalur yang sama. Beberapa mata uang berkorelasi negatif, tetapi jumlah mata uang yang berkorelasi negatif lebih sedikit, dan karena semuanya dipengaruhi oleh tren pasar secara keseluruhan, mata uang tersebut sering kali menunjukkan tren pasar yang konsisten.
Asumsikan koin A dan koin B memiliki korelasi harga yang tinggi. Pada saat tertentu, nilai rata-rata rasio harga A/B adalah 1. Jika pada saat tertentu, rasio harga A/B menyimpang dari kenaikan lebih dari 0,001, yaitu lebih dari 1,001, maka Anda dapat berdagang dengan cara berikut: membuka posisi panjang pada B dan membuka posisi pendek pada A . Sebaliknya, ketika rasio harga A/B lebih rendah dari 0,999: buka posisi panjang pada A dan posisi pendek pada B.
Kunci profitabilitas terletak pada keuntungan selisih harga saat harga menyimpang dan kembali normal. Karena penyimpangan harga biasanya berumur pendek, pedagang dapat menutup posisi mereka ketika harga kembali ke harga rata-rata dan mendapat untung dari selisihnya.
Kode-kode ini dapat digunakan secara langsung, tetapi yang terbaik adalah mengunduh Anancoda dan men-debug-nya di jupyer notebook. Secara langsung mencakup paket untuk analisis data yang umum digunakan.
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) # 获取所有的正在交易的交易对
Fungsi utama fungsi GetKlines adalah untuk memperoleh data K-line historis dari kontrak abadi pasangan perdagangan tertentu dari bursa Binance dan menyimpan data ini dalam Pandas DataFrame. Data K-line meliputi harga pembukaan, harga tertinggi, harga terendah, harga penutupan, volume perdagangan, dan informasi lainnya. Kali ini kami terutama menggunakan data harga penutupan.
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
Jumlah datanya relatif besar. Agar dapat mengunduh lebih cepat, hanya data K-line per jam selama tiga bulan terakhir yang diperoleh. df_close berisi data harga penutupan untuk semua mata uang
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')
Menentukan objek Exchange untuk backtest berikut
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)
Perhitungan korelasi adalah metode dalam statistika yang digunakan untuk mengukur hubungan linear antara dua variabel. Metode perhitungan korelasi yang paling umum digunakan adalah koefisien korelasi Pearson. Berikut adalah prinsip, rumus, dan metode implementasi untuk perhitungan korelasi. Koefisien korelasi Pearson digunakan untuk mengukur hubungan linear antara dua variabel, dan rentang nilainya antara -1 dan 1:
Koefisien korelasi Pearson menentukan korelasi antara dua variabel dengan menghitung kovariansi dan deviasi standarnya. Rumusnya adalah sebagai berikut:
[ \rho_{X,Y} = \frac{\text{cov}(X,Y)}{\sigma_X \sigma_Y} ]
di dalam:
Tentu saja, Anda tidak perlu terlalu khawatir tentang cara penghitungannya. Anda dapat menghitung korelasi semua mata uang hanya dengan menggunakan satu baris kode Python. Gambar tersebut menunjukkan peta panas korelasi. Merah menunjukkan korelasi positif, biru menunjukkan korelasi negatif, dan semakin gelap warnanya, semakin kuat korelasinya. Terlihat bahwa area yang luas berwarna merah tua, sehingga korelasi positif mata uang digital sangat kuat.

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);
Berdasarkan korelasi, 20 pasangan mata uang paling relevan dipilih. Hasilnya adalah sebagai berikut. Korelasinya sangat kuat, semuanya di atas 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
Kode yang sesuai adalah sebagai berikut:
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)
Kode backtest spesifiknya adalah sebagai berikut. Strategi demo berfokus pada pengamatan rasio harga dua mata uang kripto (IOTA dan ZIL) dan perdagangan berdasarkan perubahan rasio ini. Langkah-langkah spesifiknya adalah sebagai berikut:
inisialisasi:
e, saldo awal adalah $10.000 dan biaya transaksi adalah 0,02%.avg。value = 1000。Memproses data harga secara berulang:
df_close。diff。aim_value, untuk setiap deviasi 0,01, perdagangkan satu nilai. Dan memutuskan operasi pembelian dan penjualan berdasarkan posisi akun berjalan dan kondisi harga.pair_a dan membelipair_b beroperasi.pair_a dan menjualpair_b beroperasi.Rata-rata yang disesuaikan:
avg, untuk mencerminkan rasio harga terkini.Memperbarui Akun dan Catatan:
res_list。Hasil Keluaran:
res_list Konversi ke kerangka datares, untuk analisis dan presentasi lebih lanjut.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);
Sebanyak 4 kelompok mata uang diuji kembali, dan hasilnya relatif ideal. Perhitungan korelasi saat ini menggunakan data masa depan, sehingga tidak terlalu akurat. Artikel ini juga membagi data menjadi dua bagian, berdasarkan perhitungan korelasi di bagian depan dan pengujian kembali transaksi di bagian belakang. Hasilnya sedikit mengecewakan, tetapi masih cukup bagus. Terserah kepada pengguna untuk melakukan verifikasi.

Meskipun strategi perdagangan berpasangan dapat menguntungkan secara teori, masih ada beberapa risiko dalam operasi sebenarnya: korelasi antara mata uang dapat berubah seiring waktu, yang menyebabkan strategi gagal; dalam kondisi pasar yang ekstrem, deviasi harga dapat meningkat, yang mengakibatkan kerugian besar; Likuiditas mata uang tertentu yang rendah dapat membuat transaksi sulit dilaksanakan atau meningkatkan biaya; biaya yang dihasilkan oleh transaksi yang sering dilakukan dapat mengikis keuntungan.
Untuk mengurangi risiko dan meningkatkan stabilitas strategi, langkah-langkah perbaikan berikut dapat dipertimbangkan: menghitung ulang korelasi antara mata uang secara berkala dan menyesuaikan pasangan perdagangan tepat waktu; menetapkan titik stop loss dan take profit untuk mengendalikan kerugian maksimum dari satu transaksi; perdagangkan beberapa pasangan Koin untuk mendiversifikasi risiko.
Strategi perdagangan pasangan mata uang digital memperoleh keuntungan dengan memanfaatkan korelasi antara harga mata uang dan melakukan operasi arbitrase ketika harga menyimpang. Strategi ini memiliki kelayakan teoritis yang tinggi. Kode sumber strategi waktu nyata sederhana berdasarkan strategi ini akan dirilis kemudian. Jika Anda memiliki pertanyaan lebih lanjut atau memerlukan diskusi lebih lanjut, jangan ragu untuk berkomunikasi.