Sumber dimuat naik... memuat...

Penjelasan terperinci mengenai Strategi Perdagangan Pasangan Mata Wang Digital

Penulis:FMZ~Lydia, Dicipta: 2024-07-08 11:41:23, Dikemas kini: 2024-07-12 15:54:35

img

Pengantar

Baru-baru ini, saya melihat BuOu's Quantitative Diary menyebut bahawa anda boleh menggunakan mata wang yang berkorelasi negatif untuk memilih mata wang, dan membuka kedudukan untuk membuat keuntungan berdasarkan kejayaan perbezaan harga. Mata wang digital pada dasarnya berkorelasi positif, dan hanya beberapa mata wang berkorelasi negatif, sering dengan keadaan pasaran khas, seperti keadaan pasaran bebas duit syiling MEME, yang sama sekali berbeza dari trend pasaran. Mata wang ini boleh dipilih 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 berpasangan.

Perdagangan pasangan mata wang digital adalah strategi perdagangan berdasarkan arbitraj statistik, yang pada masa yang sama membeli dan menjual dua mata wang kripto yang sangat berkaitan untuk memperoleh keuntungan dari penyimpangan harga.

Prinsip Strategi

Strategi perdagangan pasangan bergantung pada korelasi sejarah antara harga dua mata wang digital. Apabila harga dua mata wang menunjukkan korelasi yang kuat, trend harga mereka umumnya selaras. Jika nisbah harga antara kedua-dua menyimpang dengan ketara pada saat tertentu, ia boleh dianggap sebagai kelainan sementara dan harga akan cenderung kembali ke tahap normal. Pasaran mata wang digital sangat saling berkaitan. Apabila mata wang digital utama (seperti Bitcoin) turun naik dengan ketara, ia biasanya akan mencetuskan tindak balas yang diselaraskan dalam mata wang digital lain. Sesetengah mata wang mungkin mempunyai korelasi positif yang sangat jelas yang boleh berlangsung kerana institusi pelaburan yang sama, pembuat pasaran yang sama, dan trek yang sama. Sesetengah mata wang berkorelasi negatif, tetapi terdapat lebih sedikit mata wang yang berkorelasi negatif, dan kerana mereka semua dipengaruhi oleh trend pasaran, mereka sering akan mempunyai trend pasaran yang konsisten.

Misalkan mata wang A dan mata wang B mempunyai korelasi harga yang tinggi. Pada masa tertentu, nilai purata nisbah harga A / B adalah 1. Jika pada masa tertentu, nisbah harga A / B menyimpang lebih daripada 0.001, iaitu lebih daripada 1.001, maka anda boleh berdagang dengan cara berikut: Buka kedudukan panjang pada B dan buka kedudukan pendek pada A. Sebaliknya, apabila nisbah harga A / B lebih rendah daripada 0.999: Buka kedudukan panjang pada A dan buka kedudukan pendek pada B.

Kunci keuntungan terletak pada keuntungan spread apabila harga menyimpang dari purata dan kembali normal.

Sediakan Data

Memimport perpustakaan yang sepadan

Kod ini boleh digunakan secara langsung. Adalah lebih baik untuk memuat turun Anancoda dan debugnya di buku nota Jupyer. Ia termasuk pakej untuk analisis data yang biasa digunakan secara langsung.

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

Dapatkan semua pasangan dagangan yang didagangkan

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) # Get all trading pairs being traded

Muat turun fungsi K-line

Fungsi utama fungsi GetKlines adalah untuk mendapatkan data K-line sejarah kontrak kekal pasangan dagangan yang ditentukan dari bursa Binance dan menyimpan data dalam Pandas DataFrame. Data K-line termasuk maklumat seperti harga pembukaan, harga tertinggi, harga terendah, harga penutupan, dan jumlah dagangan. Kali ini kami terutamanya 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

Muat turun data

Volume data agak besar. Untuk memuat turun lebih cepat, hanya data K-line sejam tiga bulan yang lalu diperoleh. df_close mengandungi data harga penutupan 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')

Enjin Ujian Kembali

Kita tentukan objek pertukaran untuk backtest berikut.

class Exchange:
    def __init__(self, trade_symbols, fee=0.0002, 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, '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 #Deduction 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  #profit
            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
        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)

Analisis korelasi dengan mata wang penapis

Pengiraan korelasi adalah kaedah dalam statistik yang digunakan untuk mengukur hubungan linear antara dua pembolehubah. Kaedah pengiraan korelasi yang paling biasa digunakan adalah pekali korelasi Pearson. Berikut adalah prinsip, formula dan kaedah pelaksanaan pengiraan korelasi. Pekali korelasi Pearson digunakan untuk mengukur hubungan linear antara dua pembolehubah dan julat nilainya adalah antara -1 dan 1:

  • 1 menunjukkan korelasi positif sempurna, di mana kedua-dua pembolehubah sentiasa berubah secara serentak. Apabila satu pembolehubah meningkat, yang lain juga meningkat secara proporsional. Semakin dekat dengan 1, semakin kuat korelasi.
  • -1 menunjukkan korelasi negatif sempurna, di mana kedua-dua pembolehubah sentiasa berubah dalam arah yang bertentangan.
  • 0 bermaksud tiada korelasi linear, tidak ada hubungan garis lurus antara kedua-dua pembolehubah.

Gabungan korelasi Pearson menentukan korelasi antara dua pembolehubah dengan mengira kovarian dan penyimpangan standard mereka. Rumusnya adalah seperti berikut:

img

di mana:

  • imgialah pekali korelasi Pearson antara pembolehubah X dan Y.
  • imgadalah kovariansi X dan Y.
  • imgdanimgadalah penyimpangan standard X dan Y masing-masing.

Sudah tentu, anda tidak perlu terlalu bimbang tentang bagaimana ia dikira. Anda boleh menggunakan 1 baris kod di Python untuk mengira korelasi semua mata wang. Rajah menunjukkan peta haba korelasi. Merah mewakili korelasi positif, biru mewakili korelasi negatif, dan semakin gelap warnanya, semakin kuat korelasinya. Anda dapat melihat bahawa sebahagian besar kawasan adalah merah gelap, jadi korelasi positif mata wang digital sangat kuat.

img

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 wang teratas yang paling berkorelasi dipilih. Hasilnya adalah seperti berikut. Korelasi mereka sangat kuat, semua 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

Kod yang sepadan adalah seperti berikut:

corr_pairs = corr.unstack()

# Remove self-correlation (i.e. values ​​on the diagonal)
corr_pairs = corr_pairs[corr_pairs != 1]

sorted_corr_pairs = corr_pairs.sort_values(kind="quicksort")

# Extract the top 20 most and least correlated currency pairs
most_correlated = sorted_corr_pairs.tail(40)[::-2]

print("The top 20 most correlated currency pairs are:")
print(most_correlated)

Pengesahan Backtest

Kod backtest khusus adalah seperti berikut. Strategi demonstrasi terutamanya memerhatikan nisbah harga dua mata wang kripto (IOTA dan ZIL) dan berdagang mengikut perubahan dalam nisbah ini. Langkah-langkah tertentu adalah seperti berikut:

  1. Permulaan:
  • Menentukan pasangan dagangan (pair_a = IOTA, pair_b = ZIL).
  • Buat objek pertukaranedengan baki awal $ 10,000 dan yuran transaksi 0.02%.
  • Mengira nisbah harga purata awalavg.
  • Tetapkan nilai urus niaga awalvalue = 1000.
  1. Mengulang data harga:
  • Melalui data harga pada setiap titik masadf_close.
  • Mengira penyimpangan nisbah harga semasa daripada puratadiff.
  • Nilai transaksi sasaran dikira berdasarkan penyimpanganaim_value, dan satu nilai diperdagangkan untuk setiap penyimpangan 0.01.
  • Jika penyimpangan terlalu besar, melaksanakan jualpair_adan belipair_b operations.
  • Jika penyimpangan terlalu kecil, belipair_adan jualpair_boperasi dilakukan.
  1. Sesuaikan purata:
  • Mengemas kini nisbah harga purataavguntuk mencerminkan nisbah harga terkini.
  1. Mengemas kini akaun dan rekod:
  • Mengemas kini kedudukan dan maklumat baki akaun pertukaran.
  • Mencatatkan status akaun pada setiap langkah (jumlah aset, aset yang dipegang, yuran urus niaga, kedudukan panjang dan pendek) kepadares_list.
  1. Hasil output:
  • Mengubahres_listkepada bingkai dataresuntuk analisis dan persembahan lanjut.
pair_a = 'IOTA'
pair_b = "ZIL"
e = Exchange([pair_a,pair_b], fee=0.0002, initial_balance=10000) #Exchange definition is placed in the comments section
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);

Secara keseluruhan 4 kumpulan mata wang telah diuji semula, dan hasilnya adalah ideal. Pengiraan korelasi semasa menggunakan data masa depan, jadi ia tidak sangat tepat. Artikel ini juga membahagikan data kepada dua bahagian, berdasarkan pengiraan korelasi sebelumnya dan perdagangan backtest berikutnya. Hasilnya sedikit berbeza tetapi tidak buruk. Kami biarkan pengguna untuk berlatih dan mengesahkan.

img

Potensi Risiko dan Cara Untuk Memperbaiki

Walaupun strategi perdagangan pasangan boleh menguntungkan dalam teori, masih ada beberapa risiko dalam operasi sebenar: korelasi antara mata wang boleh berubah dari masa ke masa, menyebabkan strategi gagal; di bawah keadaan pasaran yang melampau, penyimpangan harga boleh meningkat, mengakibatkan kerugian yang lebih besar; kecairan yang rendah dari mata wang tertentu boleh membuat transaksi sukar untuk dilaksanakan atau meningkatkan kos; dan yuran yang dihasilkan oleh transaksi yang kerap boleh mengikis keuntungan.

Untuk mengurangkan risiko dan meningkatkan kestabilan strategi, langkah-langkah penambahbaikan berikut boleh dipertimbangkan: mengira semula korelasi antara mata wang dan menyesuaikan pasangan dagangan dengan tepat pada masanya; menetapkan titik stop loss dan mengambil keuntungan untuk mengawal kerugian maksimum satu transaksi; berdagang beberapa pasangan mata wang pada masa yang sama untuk mempelbagaikan risiko.

Kesimpulan

Strategi perdagangan pasangan mata wang digital mencapai keuntungan dengan memanfaatkan korelasi harga mata wang dan melakukan operasi arbitrase apabila harga menyimpang. Strategi ini mempunyai kelayakan teori yang tinggi. Kod sumber strategi perdagangan langsung yang mudah berdasarkan strategi ini akan dikeluarkan kemudian. Jika anda mempunyai lebih banyak soalan atau memerlukan perbincangan lanjut, sila hubungi kami.


Lebih lanjut