डिजिटल मुद्रा जोड़ी ट्रेडिंग रणनीति का विस्तृत विवरण
परिचय
हाल ही में मैंने बुउ की मात्रात्मक डायरी देखी, जिसमें बताया गया था कि आप मुद्राओं का चयन करने के लिए नकारात्मक रूप से सहसंबद्ध मुद्राओं का उपयोग कर सकते हैं, और मूल्य अंतर सफलताओं के आधार पर लाभ कमाने के लिए पोजीशन खोल सकते हैं। डिजिटल मुद्राएँ मूल रूप से सकारात्मक रूप से सहसंबद्ध होती हैं, और केवल कुछ मुद्राएँ नकारात्मक रूप से सहसंबद्ध होती हैं। उनके पास अक्सर विशेष बाजार स्थितियाँ होती हैं, जैसे कि कुछ समय पहले MEME सिक्कों की स्वतंत्र बाजार स्थितियाँ, जो बाजार की प्रवृत्ति का बिल्कुल भी पालन नहीं करती हैं। फ़िल्टर करें इन मुद्राओं और सफलता के बाद लंबे समय तक चलते हैं, यह विधि कुछ बाजार स्थितियों के तहत लाभ कमा सकती है। हालांकि, मात्रात्मक व्यापार के क्षेत्र में सबसे आम तरीका जोड़ी व्यापार के लिए सकारात्मक सहसंबंध का उपयोग करना है। यह लेख संक्षेप में इस रणनीति का परिचय देगा।
क्रिप्टोकरेंसी जोड़ी ट्रेडिंग सांख्यिकीय मध्यस्थता पर आधारित एक ट्रेडिंग रणनीति है, जो दो अत्यधिक सहसंबद्ध क्रिप्टोकरेंसी स्थायी अनुबंधों को एक साथ खरीद और बेचकर मूल्य विचलन से लाभ प्राप्त करने का प्रयास करती है। यह लेख रणनीति के सिद्धांतों, लाभ तंत्र, मुद्राओं की स्क्रीनिंग की विधि, संभावित जोखिमों और इसे सुधारने के तरीकों का परिचय देगा और कुछ व्यावहारिक पायथन कोड उदाहरण प्रदान करेगा।
रणनीति सिद्धांत
जोड़ी ट्रेडिंग रणनीतियाँ दो क्रिप्टोकरेंसी की कीमतों के बीच ऐतिहासिक सहसंबंध पर निर्भर करती हैं। जब दो मुद्राएं आपस में दृढ़तापूर्वक सहसम्बन्धित होती हैं, तो उनकी कीमतें लगभग एक समान चलती हैं। यदि किसी निश्चित समय पर दोनों का मूल्य अनुपात काफी हद तक विचलित हो जाता है, तो यह माना जा सकता है कि यह एक अस्थायी विसंगति है और कीमतें सामान्य स्तर पर वापस आ जाएंगी। डिजिटल मुद्रा बाजार आपस में बहुत जुड़ा हुआ है। जब कोई प्रमुख डिजिटल मुद्रा (जैसे बिटकॉइन) महत्वपूर्ण उतार-चढ़ाव का अनुभव करती है, तो यह आमतौर पर अन्य डिजिटल मुद्राओं के बीच एक श्रृंखला प्रतिक्रिया को ट्रिगर करती है। कुछ मुद्राओं में बहुत स्पष्ट सकारात्मक सहसंबंध हो सकता है, और यह सहसंबंध कायम भी रह सकता है, क्योंकि वे एक ही निवेश संस्थाओं, एक ही बाजार निर्माताओं और एक ही ट्रैक से संबंधित हैं। कुछ मुद्राएं नकारात्मक रूप से सहसंबद्ध होती हैं, लेकिन नकारात्मक रूप से सहसंबद्ध मुद्राएं कम होती हैं, और क्योंकि वे सभी समग्र बाजार प्रवृत्ति से प्रभावित होती हैं, वे अक्सर सुसंगत बाजार प्रवृत्तियां दर्शाती हैं।
मान लीजिए कि सिक्का A और सिक्का B का मूल्य सहसंबंध उच्च है। एक निश्चित समय पर, A/B मूल्य अनुपात का औसत मूल्य 1 होता है। यदि किसी निश्चित समय पर, A/B मूल्य अनुपात 0.001 से अधिक, अर्थात 1.001 से अधिक की वृद्धि से विचलित होता है, तो आप निम्न तरीकों से व्यापार कर सकते हैं: B पर एक लंबी स्थिति खोलें और A पर एक छोटी स्थिति खोलें . इसके विपरीत, जब A/B मूल्य अनुपात 0.999 से कम हो: A पर लंबी स्थिति और B पर छोटी स्थिति खोलें।
लाभप्रदता की कुंजी मूल्य अंतर लाभ में निहित है, जब कीमतें विचलित होती हैं और सामान्य स्तर पर लौट आती हैं। चूंकि मूल्य विचलन आमतौर पर अल्पकालिक होते हैं, इसलिए जब कीमतें औसत पर वापस आ जाती हैं तो व्यापारी अपनी स्थिति को बंद कर सकते हैं और अंतर से लाभ कमा सकते हैं।
डेटा तैयार करें
संबंधित लाइब्रेरी आयात करें
इन कोडों का सीधे उपयोग किया जा सकता है, लेकिन सबसे अच्छा यह होगा कि आप एनानकोडा को डाउनलोड करें और उसे ज्यूपियर नोटबुक में डीबग करें। इसमें आमतौर पर प्रयुक्त डेटा विश्लेषण के लिए सीधे पैकेज शामिल हैं।
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
सभी ट्रेडिंग जोड़े प्राप्त करें जिनका व्यापार किया जा रहा है
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-लाइन फ़ंक्शन डाउनलोड करें
GetKlines फ़ंक्शन का मुख्य कार्य बिनेंस एक्सचेंज से निर्दिष्ट ट्रेडिंग जोड़ी के सतत अनुबंध का ऐतिहासिक K-लाइन डेटा प्राप्त करना और इस डेटा को पांडा डेटाफ़्रेम में संग्रहीत करना है। के-लाइन डेटा में प्रारंभिक मूल्य, उच्चतम मूल्य, निम्नतम मूल्य, समापन मूल्य, ट्रेडिंग वॉल्यूम और अन्य जानकारी शामिल होती है। इस बार हम मुख्य रूप से समापन मूल्य डेटा का उपयोग करते हैं।
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
डेटा डाउनलोड करें
डेटा की मात्रा अपेक्षाकृत बड़ी है। तेजी से डाउनलोड करने के लिए, पिछले तीन महीनों का केवल प्रति घंटा K-लाइन डेटा प्राप्त किया गया था। df_close में सभी मुद्राओं के लिए समापन मूल्य डेटा शामिल है
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')
बैकटेस्टिंग इंजन
निम्नलिखित बैकटेस्ट के लिए Exchange ऑब्जेक्ट को परिभाषित करता है
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)
मुद्राओं को फ़िल्टर करने के लिए सहसंबंध विश्लेषण
सहसंबंध गणना सांख्यिकी में एक विधि है जिसका उपयोग दो चरों के बीच रैखिक संबंध को मापने के लिए किया जाता है। सबसे अधिक प्रयुक्त सहसंबंध गणना पद्धति पियर्सन सहसंबंध गुणांक है। नीचे सहसंबंध गणना के सिद्धांत, सूत्र और कार्यान्वयन विधियां दी गई हैं। पियर्सन सहसंबंध गुणांक का उपयोग दो चरों के बीच रैखिक संबंध को मापने के लिए किया जाता है, और इसका मान रेंज -1 और 1 के बीच होता है:
- 1 यह एक पूर्ण सकारात्मक सहसंबंध को इंगित करता है, जहां दो चर सदैव समकालिक रूप से बदलते रहते हैं। जब एक चर बढ़ता है, तो दूसरा चर भी आनुपातिक रूप से बढ़ता है। यह 1 के जितना करीब होगा, सहसंबंध उतना ही मजबूत होगा।
- -1 यह पूर्णतः नकारात्मक सहसंबंध को दर्शाता है, जहां दो चर सदैव विपरीत दिशाओं में बदलते हैं। यह -1 के जितना करीब होगा, नकारात्मक सहसंबंध उतना ही मजबूत होगा।
- 0 यह किसी रैखिक सहसंबंध को नहीं दर्शाता है, दो चरों के बीच कोई सीधी रेखा संबंध नहीं है।
पियर्सन सहसंबंध गुणांक दो चरों के बीच उनके सहप्रसरण और मानक विचलन की गणना करके उनके बीच सहसंबंध निर्धारित करता है। सूत्र इस प्रकार है:
[ \rho_{X,Y} = \frac{\text{cov}(X,Y)}{\sigma_X \sigma_Y} ]
में:
- ( \rho_{X,Y} ) एक चर है( X ) और ( Y ) पियर्सन सहसंबंध गुणांक.
- ( \text{cov}(X,Y) ) हाँ ( X ) और ( Y ) का सहप्रसरण.
- ( \sigma_X ) और ( \sigma_Y ) वे हैं( X ) और ( Y ) का मानक विचलन.
बेशक, आपको इस बारे में ज़्यादा चिंता करने की ज़रूरत नहीं है कि इसकी गणना कैसे की जाती है। आप पायथन कोड की सिर्फ़ एक लाइन का इस्तेमाल करके सभी मुद्राओं के सहसंबंध की गणना कर सकते हैं। चित्र में सहसंबंध हीट मैप दिखाया गया है। लाल रंग सकारात्मक सहसंबंध को दर्शाता है, नीला रंग नकारात्मक सहसंबंध को दर्शाता है, और रंग जितना गहरा होगा, सहसंबंध उतना ही मजबूत होगा। यह देखा जा सकता है कि बड़े क्षेत्र गहरे लाल हैं, इसलिए डिजिटल मुद्रा का सकारात्मक सहसंबंध बहुत मजबूत है।
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);
सहसंबंध के आधार पर, शीर्ष 20 सर्वाधिक प्रासंगिक मुद्रा जोड़े चुने जाते हैं। परिणाम इस प्रकार हैं। इनका सहसंबंध बहुत मजबूत है, सभी 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
संबंधित कोड इस प्रकार है:
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)
बैकटेस्टिंग सत्यापन
विशिष्ट बैकटेस्ट कोड इस प्रकार है। डेमो रणनीति दो क्रिप्टोकरेंसी (IOTA और ZIL) के मूल्य अनुपात को देखने और इस अनुपात में परिवर्तन के आधार पर व्यापार करने पर केंद्रित है। विशिष्ट चरण इस प्रकार हैं:
-
प्रारंभ:
- व्यापारिक जोड़े परिभाषित करें (pair_a = 'IOTA', pair_b = 'ZIL').
- एक एक्सचेंज ऑब्जेक्ट बनाएँ
eप्रारंभिक शेष राशि $10,000 है और लेनदेन शुल्क 0.02% है। - प्रारंभिक औसत मूल्य अनुपात की गणना
avg。 - प्रारंभिक लेनदेन मूल्य निर्धारित करें
value = 1000。
-
मूल्य डेटा को पुनरावृत्त रूप से संसाधित करें:
- प्रत्येक समय बिंदु पर मूल्य डेटा को पार करें
df_close。 - वर्तमान मूल्य अनुपात के माध्य से विचलन की गणना करता है
diff。 - विचलन के आधार पर लक्ष्य लेनदेन मूल्य की गणना करें
aim_value, 0.01 के प्रत्येक विचलन के लिए, एक मान का व्यापार करें। और चालू खाते की स्थिति और मूल्य स्थितियों के आधार पर खरीद और बिक्री कार्यों पर निर्णय लें। - यदि विचलन बहुत बड़ा है, तो बिक्री निष्पादित करें
pair_aऔर खरीदेंpair_bसंचालित. - यदि विचलन बहुत छोटा है, तो खरीदारी करें
pair_aऔर बेचेंpair_bसंचालित.
- प्रत्येक समय बिंदु पर मूल्य डेटा को पार करें
-
समायोजित माध्य:
- अद्यतन औसत मूल्य अनुपात
avg, नवीनतम मूल्य अनुपात को प्रतिबिंबित करने के लिए।
- अद्यतन औसत मूल्य अनुपात
-
खाते और रिकॉर्ड अपडेट करना:
- एक्सचेंज खाते की स्थिति और शेष राशि की जानकारी अद्यतन करें।
- प्रत्येक चरण पर खाते की स्थिति रिकॉर्ड करें (कुल परिसंपत्तियां, होल्डिंग्स, लेनदेन शुल्क, लंबी और छोटी स्थिति)
res_list。
-
परिणाम आउटपुट:
- इच्छा
res_listडेटाफ़्रेम में कनवर्ट करेंres, आगे के विश्लेषण और प्रस्तुति के लिए।
- इच्छा
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);
कुल 4 मुद्रा समूहों का बैकटेस्ट किया गया, और परिणाम अपेक्षाकृत आदर्श थे। वर्तमान सहसंबंध गणनाएं भविष्य के डेटा का उपयोग करती हैं, इसलिए वे बहुत सटीक नहीं हैं। यह आलेख भी डेटा को दो भागों में विभाजित करता है, जो आगे की ओर गणना किए गए सहसंबंध और पीछे की ओर बैक-टेस्टेड लेनदेन पर आधारित है। परिणाम थोड़े खराब थे लेकिन फिर भी काफी अच्छे थे। सत्यापन का कार्य उपयोगकर्ता पर छोड़ दिया गया है।
संभावित जोखिम और सुधार के तरीके
यद्यपि जोड़ी ट्रेडिंग रणनीति सिद्धांत रूप में लाभदायक हो सकती है, फिर भी वास्तविक संचालन में कुछ जोखिम हैं: समय के साथ मुद्राओं के बीच संबंध बदल सकता है, जिससे रणनीति विफल हो सकती है; चरम बाजार स्थितियों के तहत, मूल्य विचलन बढ़ सकता है, जिसके परिणामस्वरूप बड़े नुकसान हो सकते हैं; कुछ मुद्राओं की कम तरलता के कारण लेनदेन करना कठिन हो सकता है या लागत बढ़ सकती है; बार-बार होने वाले लेनदेन से उत्पन्न शुल्क से लाभ कम हो सकता है।
जोखिम को कम करने और रणनीति की स्थिरता में सुधार करने के लिए, निम्नलिखित सुधार उपायों पर विचार किया जा सकता है: नियमित रूप से मुद्राओं के बीच सहसंबंध की पुनर्गणना करें और समय में व्यापारिक जोड़े को समायोजित करें; एकल लेनदेन के अधिकतम नुकसान को नियंत्रित करने के लिए स्टॉप लॉस और लाभ बिंदु निर्धारित करें; जोखिम को विविधता प्रदान करने के लिए कई मुद्रा जोड़ों में व्यापार करें।
निष्कर्ष के तौर पर
डिजिटल मुद्रा जोड़ी ट्रेडिंग रणनीति मुद्रा की कीमतों के बीच सहसंबंध का लाभ उठाकर और कीमतों में विचलन होने पर मध्यस्थता संचालन करके लाभ प्राप्त करती है। इस रणनीति की सैद्धांतिक व्यवहार्यता बहुत अधिक है। इस रणनीति पर आधारित एक सरल वास्तविक समय रणनीति स्रोत कोड बाद में जारी किया जाएगा। यदि आपके पास और प्रश्न हों या आगे चर्चा की आवश्यकता हो, तो कृपया निःसंकोच संवाद करें।



