
Baru-baru ini saya melihat diari kuantitatif Buu yang menyebut bahawa anda boleh menggunakan mata wang berkorelasi negatif untuk memilih mata wang, dan membuka kedudukan untuk membuat keuntungan berdasarkan penembusan perbezaan harga. Mata wang digital pada asasnya berkorelasi secara positif, dan hanya beberapa mata wang yang berkorelasi secara negatif. Mata wang ini selalunya mempunyai keadaan pasaran yang istimewa, seperti keadaan pasaran bebas syiling MEME suatu ketika dahulu, yang tidak mengikuti aliran pasaran sama sekali mata wang ini dan pergi lama selepas kejayaan , kaedah ini boleh membuat keuntungan di bawah keadaan pasaran tertentu. Walau bagaimanapun, kaedah yang paling biasa dalam bidang perdagangan kuantitatif adalah menggunakan korelasi positif untuk perdagangan pasangan Artikel ini akan memperkenalkan secara ringkas strategi ini.
Perdagangan pasangan mata wang kripto ialah strategi dagangan berdasarkan timbang tara statistik, yang bertujuan untuk mendapatkan keuntungan daripada sisihan harga dengan membeli dan menjual dua kontrak kekal mata wang kripto yang sangat berkorelasi secara serentak. Artikel ini akan memperkenalkan prinsip strategi, mekanisme keuntungan, kaedah menyaring mata wang, potensi risiko dan cara untuk memperbaikinya, dan menyediakan beberapa contoh kod Python praktikal.
Strategi perdagangan pasangan bergantung pada korelasi sejarah antara harga dua mata wang kripto. Apabila dua mata wang berkorelasi kuat, harga mereka bergerak secara kasar. Jika pada masa tertentu nisbah harga kedua-duanya menyimpang dengan ketara, ia boleh dianggap bahawa ini adalah anomali sementara dan harga akan cenderung untuk kembali ke paras normal. Pasaran mata wang digital sangat saling berkaitan Apabila mata wang digital utama (seperti Bitcoin) mengalami turun naik yang ketara, ia biasanya mencetuskan tindak balas berantai antara mata wang digital lain. Sesetengah mata wang mungkin mempunyai korelasi positif yang sangat jelas, dan korelasi itu mungkin dikekalkan, kerana ia tergolong dalam institusi pelaburan yang sama, pembuat pasaran yang sama dan landasan yang sama. Sesetengah mata wang berkorelasi negatif, tetapi terdapat lebih sedikit mata wang berkorelasi negatif, dan kerana kesemuanya dipengaruhi oleh aliran pasaran keseluruhan, mata wang tersebut sering menunjukkan arah aliran pasaran yang konsisten.
Andaikan syiling A dan syiling B mempunyai korelasi harga yang tinggi. Pada masa tertentu, nilai purata nisbah harga A/B ialah 1. Jika pada masa tertentu, nisbah harga A/B menyimpang daripada kenaikan lebih daripada 0.001, iaitu lebih daripada 1.001, maka anda boleh berdagang dengan cara berikut: buka kedudukan beli pada B dan buka kedudukan jual pada A . Sebaliknya, apabila nisbah harga A/B lebih rendah daripada 0.999: buka kedudukan beli pada A dan kedudukan jual pada B.
Kunci kepada keuntungan terletak pada keuntungan perbezaan harga apabila harga menyimpang dan kembali normal. Oleh kerana sisihan harga biasanya berumur pendek, peniaga boleh menutup kedudukan mereka apabila harga kembali kepada min dan mendapat keuntungan daripada perbezaan.
Kod ini boleh digunakan secara terus, tetapi yang terbaik adalah memuat turun Anancoda dan nyahpepijatnya dalam buku nota jupyer. Secara langsung termasuk pakej untuk analisis data yang biasa 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 mendapatkan data K-line sejarah kontrak kekal bagi pasangan dagangan yang ditentukan daripada bursa Binance dan menyimpan data ini dalam Pandas DataFrame. Data K-line termasuk harga pembukaan, harga tertinggi, harga terendah, harga penutupan, volum dagangan dan maklumat lain. Kali ini kami menggunakan data harga penutupan terutamanya.
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 data agak besar Untuk memuat turun dengan lebih pantas, hanya data K-line setiap jam untuk tiga bulan yang lalu diperolehi. df_close mengandungi data harga penutupan untuk semua mata wang
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')
Mentakrifkan objek Exchange untuk ujian belakang 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)
Pengiraan korelasi adalah kaedah dalam statistik yang digunakan untuk mengukur hubungan linear antara dua pembolehubah. Kaedah pengiraan korelasi yang paling biasa digunakan ialah pekali korelasi Pearson. Di bawah ialah prinsip, formula dan kaedah pelaksanaan untuk pengiraan korelasi. Pekali korelasi Pearson digunakan untuk mengukur hubungan linear antara dua pembolehubah, dan julat nilainya adalah antara -1 dan 1:
Pekali korelasi Pearson menentukan korelasi antara dua pembolehubah dengan mengira kovarians dan sisihan piawainya. Formulanya adalah seperti berikut:
[ \rho_{X,Y} = \frac{\text{cov}(X,Y)}{\sigma_X \sigma_Y} ]
dalam:
Sudah tentu, anda tidak perlu terlalu risau tentang cara ia dikira Anda boleh mengira korelasi semua mata wang menggunakan hanya satu baris kod Python. Rajah menunjukkan peta haba korelasi Merah mewakili korelasi positif, biru mewakili korelasi negatif, dan lebih gelap warna, lebih kuat korelasi. Ia boleh dilihat bahawa kawasan besar berwarna merah gelap, jadi korelasi positif mata wang digital adalah 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 teratas pasangan mata wang paling relevan dipilih. Hasilnya adalah seperti berikut. Korelasi mereka sangat kuat, semuanya melebihi 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
Kod yang sepadan adalah seperti 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)
Kod ujian belakang khusus adalah seperti berikut. Strategi demo memberi tumpuan kepada pemerhatian nisbah harga dua mata wang kripto (IOTA dan ZIL) dan perdagangan berdasarkan perubahan dalam nisbah ini. Langkah-langkah khusus adalah seperti berikut:
permulaan:
e, baki awal ialah $10,000 dan yuran transaksi ialah 0.02%.avg。value = 1000。Memproses data harga secara berulang:
df_close。diff。aim_value, untuk setiap sisihan 0.01, dagangan satu nilai. Dan memutuskan operasi jual beli berdasarkan kedudukan akaun semasa dan keadaan harga.pair_a dan belipair_b beroperasi.pair_a dan jualpair_b beroperasi.Min diselaraskan:
avg, untuk mencerminkan nisbah harga terkini.Mengemas kini Akaun dan Rekod:
res_list。Output Keputusan:
res_list Tukar kepada bingkai datares, untuk analisis dan pembentangan 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 kumpulan mata wang telah diuji balik, dan hasilnya agak ideal. Pengiraan korelasi semasa menggunakan data masa hadapan, jadi ia tidak begitu tepat. Artikel ini juga membahagikan data kepada dua bahagian, berdasarkan korelasi yang dikira di hadapan dan urus niaga yang diuji belakang di belakang. Hasilnya agak kurang tetapi masih bagus. Ia diserahkan kepada pengguna untuk melaksanakan pengesahan.

Walaupun strategi perdagangan pasangan boleh menguntungkan secara teori, masih terdapat beberapa risiko dalam operasi sebenar: korelasi antara mata wang mungkin berubah dari semasa ke semasa, menyebabkan strategi gagal dalam keadaan pasaran yang melampau, sisihan harga mungkin meningkat, mengakibatkan kerugian besar; kecairan yang rendah bagi mata wang tertentu boleh menyebabkan urus niaga sukar dilaksanakan atau meningkatkan kos;
Untuk mengurangkan risiko dan meningkatkan kestabilan strategi, langkah-langkah penambahbaikan berikut boleh dipertimbangkan: kerap mengira semula korelasi antara mata wang dan melaraskan pasangan dagangan dalam masa yang ditetapkan untuk menghentikan kerugian dan mengambil mata keuntungan untuk mengawal kerugian maksimum satu transaksi; berdagang berbilang pasangan Syiling untuk mempelbagaikan risiko.
Strategi perdagangan pasangan mata wang digital mencapai keuntungan dengan mengambil kesempatan daripada korelasi antara harga mata wang dan melaksanakan operasi arbitraj apabila harga menyimpang. Strategi ini mempunyai kebolehlaksanaan teori yang tinggi. Kod sumber strategi masa nyata ringkas berdasarkan strategi ini akan dikeluarkan kemudian. Jika anda mempunyai lebih banyak soalan atau memerlukan perbincangan lanjut, sila berasa bebas untuk berkomunikasi.