उच्च आवृत्ति व्यापार रणनीतियों पर विचार (2)

लेखक:लिडिया, बनाया गयाः 2023-08-04 17:17:30, अद्यतन किया गयाः 2023-09-12 15:50:31

img

उच्च आवृत्ति व्यापार रणनीतियों पर विचार (2)

संचयी व्यापारिक राशि का मॉडलिंग

पिछले लेख में, हमने एक एकल व्यापार राशि के एक निश्चित मूल्य से अधिक होने की संभावना के लिए एक अभिव्यक्ति प्राप्त की।

img

हम समय की अवधि के दौरान व्यापार राशि के वितरण में भी रुचि रखते हैं, जो सहज रूप से व्यक्तिगत व्यापार राशि और आदेश आवृत्ति से संबंधित होना चाहिए। नीचे, हम निश्चित अंतराल में डेटा को संसाधित करते हैं और इसके वितरण को ग्राफ करते हैं, जैसा कि पिछले खंड में किया गया था।

में [1]:

from datetime import date,datetime
import time
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

[2] मेंः

trades = pd.read_csv('HOOKUSDT-aggTrades-2023-01-27.csv')
trades['date'] = pd.to_datetime(trades['transact_time'], unit='ms')
trades.index = trades['date']
buy_trades = trades[trades['is_buyer_maker']==False].copy()
buy_trades = buy_trades.groupby('transact_time').agg({
    'agg_trade_id': 'last',
    'price': 'last',
    'quantity': 'sum',
    'first_trade_id': 'first',
    'last_trade_id': 'last',
    'is_buyer_maker': 'last',
    'date': 'last',
    'transact_time':'last'
})
buy_trades['interval']=buy_trades['transact_time'] - buy_trades['transact_time'].shift()
buy_trades.index = buy_trades['date']

हम किसी भी ट्रेडिंग गतिविधि के बिना अवधि को छोड़कर, 1 सेकंड के अंतराल पर व्यक्तिगत ट्रेड राशि को मिलाकर एकत्रित ट्रेडिंग राशि प्राप्त करते हैं। फिर हम पहले बताए गए एकल ट्रेड राशि विश्लेषण से व्युत्पन्न वितरण का उपयोग करके इस एकत्रित राशि को फिट करते हैं। 1 सेकंड के अंतराल के भीतर प्रत्येक व्यापार को एक एकल व्यापार के रूप में मानते समय परिणाम एक अच्छा फिट दिखाते हैं, प्रभावी रूप से समस्या को हल करते हैं। हालांकि, जब समय अंतराल को ट्रेडिंग आवृत्ति के सापेक्ष बढ़ाया जाता है, तो हम त्रुटियों में वृद्धि का निरीक्षण करते हैं। आगे के शोध से पता चलता है कि यह त्रुटि पैरेटो वितरण द्वारा पेश किए गए सुधार शब्द के कारण होती है। इससे पता चलता है कि जैसे-जैसे समय बढ़ता है और अधिक व्यक्तिगत ट्रेड शामिल होते हैं, कई ट्रेडों का अंतराल संचय पैरेटो वितरण के करीब आता है, जिससे सुधार शब्द को हटाने की आवश्यकता होती है।

[3] मेंः

df_resampled = buy_trades['quantity'].resample('1S').sum()
df_resampled = df_resampled.to_frame(name='quantity')
df_resampled = df_resampled[df_resampled['quantity']>0]

[4] मेंः

# Cumulative distribution in 1s
depths = np.array(range(0, 3000, 5))
probabilities = np.array([np.mean(df_resampled['quantity'] > depth) for depth in depths])
mean = df_resampled['quantity'].mean()
alpha = np.log(np.mean(df_resampled['quantity'] > mean))/np.log(2.05)
probabilities_s = np.array([((1+20**(-depth/mean))*depth/mean+1)**(alpha) for depth in depths])

plt.figure(figsize=(10, 5))
plt.plot(depths, probabilities)
plt.plot(depths, probabilities_s)
plt.xlabel('Depth')
plt.ylabel('Probability of execution')
plt.title('Execution probability at different depths')
plt.grid(True)

बाहर[4]:

img

[5] मेंः

df_resampled = buy_trades['quantity'].resample('30S').sum()
df_resampled = df_resampled.to_frame(name='quantity')
df_resampled = df_resampled[df_resampled['quantity']>0]
depths = np.array(range(0, 12000, 20))
probabilities = np.array([np.mean(df_resampled['quantity'] > depth) for depth in depths])
mean = df_resampled['quantity'].mean()
alpha = np.log(np.mean(df_resampled['quantity'] > mean))/np.log(2.05)
probabilities_s = np.array([((1+20**(-depth/mean))*depth/mean+1)**(alpha) for depth in depths])
alpha = np.log(np.mean(df_resampled['quantity'] > mean))/np.log(2)
probabilities_s_2 = np.array([(depth/mean+1)**alpha for depth in depths]) # No amendment

plt.figure(figsize=(10, 5))
plt.plot(depths, probabilities,label='Probabilities (True)')
plt.plot(depths, probabilities_s, label='Probabilities (Simulation 1)')
plt.plot(depths, probabilities_s_2, label='Probabilities (Simulation 2)')
plt.xlabel('Depth')
plt.ylabel('Probability of execution')
plt.title('Execution probability at different depths')
plt.legend() 
plt.grid(True)

बाहर[5]:

img

अब विभिन्न समय अवधि के लिए संचित व्यापार राशि के वितरण के लिए एक सामान्य सूत्र का सारांश, प्रत्येक बार अलग से गणना करने के बजाय फिट करने के लिए एकल लेनदेन राशि के वितरण का उपयोग करके। यहाँ सूत्र हैः

img

यहाँ, avg_interval एकल लेनदेन के औसत अंतराल का प्रतिनिधित्व करता है, और avg_interval_T उस अंतराल के औसत अंतराल का प्रतिनिधित्व करता है जिसका अनुमान लगाया जाना है। यह थोड़ा भ्रमित करने वाला लग सकता है। यदि हम 1 सेकंड के लिए ट्रेडिंग राशि का अनुमान लगाना चाहते हैं, तो हमें 1 सेकंड के भीतर लेनदेन वाले घटनाओं के बीच औसत अंतराल की गणना करने की आवश्यकता है। यदि ऑर्डर की आगमन संभावना पोइसन वितरण का पालन करती है, तो यह सीधे अनुमानित होनी चाहिए। हालांकि, वास्तव में, एक महत्वपूर्ण विचलन है, लेकिन मैं इसे यहां विस्तार से नहीं बताऊंगा।

ध्यान दें कि समय के एक निश्चित अंतराल के भीतर एक विशिष्ट मूल्य से अधिक व्यापार राशि की संभावना और गहराई में उस स्थिति पर व्यापार की वास्तविक संभावना काफी अलग होनी चाहिए। जैसे-जैसे प्रतीक्षा समय बढ़ता है, ऑर्डर बुक में परिवर्तन की संभावना बढ़ जाती है, और व्यापार भी गहराई में परिवर्तन की ओर जाता है। इसलिए, डेटा अपडेट के रूप में वास्तविक समय में एक ही गहराई की स्थिति पर व्यापार की संभावना बदलती है।

[6] मेंः

df_resampled = buy_trades['quantity'].resample('2S').sum()
df_resampled = df_resampled.to_frame(name='quantity')
df_resampled = df_resampled[df_resampled['quantity']>0]
depths = np.array(range(0, 6500, 10))
probabilities = np.array([np.mean(df_resampled['quantity'] > depth) for depth in depths])
mean = buy_trades['quantity'].mean()
adjust = buy_trades['interval'].mean() / 2620
alpha = np.log(np.mean(buy_trades['quantity'] > mean))/0.7178397931503168
probabilities_s = np.array([((1+20**(-depth*adjust/mean))*depth*adjust/mean+1)**(alpha) for depth in depths])

plt.figure(figsize=(10, 5))
plt.plot(depths, probabilities)
plt.plot(depths, probabilities_s)
plt.xlabel('Depth')
plt.ylabel('Probability of execution')
plt.title('Execution probability at different depths')
plt.grid(True)

बाहर[6]:

img

एकल व्यापार मूल्य पर प्रभाव

ट्रेड डेटा मूल्यवान है, और अभी भी बहुत सारे डेटा हैं जिन्हें खनन किया जा सकता है। हमें कीमतों पर ऑर्डर के प्रभाव पर ध्यान देना चाहिए, क्योंकि यह रणनीतियों की स्थिति को प्रभावित करता है। इसी तरह, transact_time के आधार पर डेटा को एकत्र करते हुए, हम अंतिम मूल्य और पहली कीमत के बीच अंतर की गणना करते हैं। यदि केवल एक ऑर्डर है, तो मूल्य अंतर 0 है। दिलचस्प बात यह है कि कुछ डेटा परिणाम नकारात्मक हैं, जो डेटा के क्रम के कारण हो सकते हैं, लेकिन हम यहां इसमें गहराई से नहीं जाएंगे।

परिणामों से पता चलता है कि व्यापारों का अनुपात जो किसी भी प्रभाव का कारण नहीं बनता है वह 77% तक है, जबकि व्यापारों का अनुपात जो 1 टिक के मूल्य आंदोलन का कारण बनता है, 16.5% है, 2 टिक 3.7% है, 3 टिक 1.2% है, और 4 से अधिक टिक 1% से कम है। यह मूल रूप से एक घातीय फ़ंक्शन की विशेषताओं का पालन करता है, लेकिन फिटिंग सटीक नहीं है।

संबंधित मूल्य अंतर का कारण बनने वाली व्यापार राशि का भी विश्लेषण किया गया, जिसमें अत्यधिक प्रभाव के कारण होने वाले विकृतियों को शामिल नहीं किया गया। यह एक रैखिक संबंध दिखाता है, जिसमें प्रत्येक 1000 यूनिट की राशि के कारण लगभग 1 टिक मूल्य उतार-चढ़ाव होता है। इसे ऑर्डर बुक में प्रत्येक मूल्य स्तर के पास रखे गए लगभग 1000 यूनिट के ऑर्डर के औसत के रूप में भी समझा जा सकता है।

[7] मेंः

diff_df = trades[trades['is_buyer_maker']==False].groupby('transact_time')['price'].agg(lambda x: abs(round(x.iloc[-1] - x.iloc[0],3)) if len(x) > 1 else 0)
buy_trades['diff'] = buy_trades['transact_time'].map(diff_df)

[8] मेंः

diff_counts = buy_trades['diff'].value_counts()
diff_counts[diff_counts>10]/diff_counts.sum()

बाहर[8]:

img

[9] मेंः

diff_group = buy_trades.groupby('diff').agg({
    'quantity': 'mean',
    'diff': 'last',
})

[10] मेंः

diff_group['quantity'][diff_group['diff']>0][diff_group['diff']<0.01].plot(figsize=(10,5),grid=True);

बाहर[10]:

img

फिक्स्ड इंटरवल प्राइस इफेक्ट

आइए 2 सेकंड के अंतराल के भीतर मूल्य प्रभाव का विश्लेषण करें। यहाँ अंतर यह है कि नकारात्मक मान हो सकते हैं। हालांकि, चूंकि हम केवल खरीद आदेशों पर विचार कर रहे हैं, इसलिए सममित स्थिति पर प्रभाव एक टिक अधिक होगा। व्यापार राशि और प्रभाव के बीच संबंध का निरीक्षण करना जारी रखते हुए, हम केवल 0 से अधिक परिणामों पर विचार करते हैं। निष्कर्ष एक एकल आदेश के समान है, जो एक अनुमानित रैखिक संबंध दिखाता है, प्रत्येक टिक के लिए लगभग 2000 इकाइयों की मात्रा की आवश्यकता होती है।

[11] मेंः

df_resampled = buy_trades.resample('2S').agg({ 
    'price': ['first', 'last', 'count'],
    'quantity': 'sum'
})
df_resampled['price_diff'] = round(df_resampled[('price', 'last')] - df_resampled[('price', 'first')],3)
df_resampled['price_diff'] = df_resampled['price_diff'].fillna(0)
result_df_raw = pd.DataFrame({
    'price_diff': df_resampled['price_diff'],
    'quantity_sum': df_resampled[('quantity', 'sum')],
    'data_count': df_resampled[('price', 'count')]
})
result_df = result_df_raw[result_df_raw['price_diff'] != 0]

[12] मेंः

result_df['price_diff'][abs(result_df['price_diff'])<0.016].value_counts().sort_index().plot.bar(figsize=(10,5));

बाहर[12]:

img

[23] मेंः

result_df['price_diff'].value_counts()[result_df['price_diff'].value_counts()>30]

बाहर[23]:

img

[14] मेंः

diff_group = result_df.groupby('price_diff').agg({ 'quantity_sum': 'mean'})

[15] मेंः

diff_group[(diff_group.index>0) & (diff_group.index<0.015)].plot(figsize=(10,5),grid=True);

बाहर[15]:

img

व्यापार राशि का मूल्य प्रभाव

पहले, हमने एक टिक परिवर्तन के लिए आवश्यक व्यापार राशि निर्धारित की थी, लेकिन यह सटीक नहीं थी क्योंकि यह इस धारणा पर आधारित थी कि प्रभाव पहले ही हुआ था। अब, आइए परिप्रेक्ष्य को उलट दें और व्यापार राशि के कारण होने वाले मूल्य प्रभाव की जांच करें।

इस विश्लेषण में, डेटा को प्रत्येक 1 सेकंड में नमूना किया जाता है, प्रत्येक चरण राशि की 100 इकाइयों का प्रतिनिधित्व करता है। फिर हमने इस राशि सीमा के भीतर मूल्य परिवर्तन की गणना की। यहां कुछ मूल्यवान निष्कर्ष दिए गए हैंः

  1. जब खरीद आदेश की राशि 500 से कम होती है, तो अपेक्षित मूल्य परिवर्तन में कमी होती है, जो अपेक्षित है क्योंकि मूल्य को प्रभावित करने वाले बिक्री आदेश भी होते हैं।
  2. कम व्यापार राशि पर, एक रैखिक संबंध है, जिसका अर्थ है कि व्यापार राशि जितनी बड़ी होगी, कीमत में वृद्धि उतनी ही अधिक होगी।
  3. जैसे-जैसे खरीद ऑर्डर की राशि बढ़ती है, मूल्य परिवर्तन अधिक महत्वपूर्ण हो जाता है। यह अक्सर एक मूल्य सफलता का संकेत देता है, जो बाद में पीछे हट सकता है। इसके अतिरिक्त, निश्चित अंतराल नमूनाकरण डेटा अस्थिरता में जोड़ता है।
  4. बिखराव ग्राफ के ऊपरी भाग पर ध्यान देना महत्वपूर्ण है, जो व्यापार राशि के साथ मूल्य में वृद्धि से मेल खाता है।
  5. इस विशेष व्यापारिक जोड़ी के लिए, हम व्यापार राशि और मूल्य परिवर्तन के बीच संबंध का एक मोटा संस्करण प्रदान करते हैं।

img

जहां C मूल्य में परिवर्तन को दर्शाता है और Q खरीद आदेशों की मात्रा को दर्शाता है।

[16] मेंः

df_resampled = buy_trades.resample('1S').agg({ 
    'price': ['first', 'last', 'count'],
    'quantity': 'sum'
})
df_resampled['price_diff'] = round(df_resampled[('price', 'last')] - df_resampled[('price', 'first')],3)
df_resampled['price_diff'] = df_resampled['price_diff'].fillna(0)
result_df_raw = pd.DataFrame({
    'price_diff': df_resampled['price_diff'],
    'quantity_sum': df_resampled[('quantity', 'sum')],
    'data_count': df_resampled[('price', 'count')]
})
result_df = result_df_raw[result_df_raw['price_diff'] != 0]

[24] मेंः

df = result_df.copy()
bins = np.arange(0, 30000, 100)  # 
labels = [f'{i}-{i+100-1}' for i in bins[:-1]]  
df.loc[:, 'quantity_group'] = pd.cut(df['quantity_sum'], bins=bins, labels=labels)
grouped = df.groupby('quantity_group')['price_diff'].mean()

[25] मेंः

grouped_df = pd.DataFrame(grouped).reset_index()
grouped_df['quantity_group_center'] = grouped_df['quantity_group'].apply(lambda x: (float(x.split('-')[0]) + float(x.split('-')[1])) / 2)

plt.figure(figsize=(10,5))
plt.scatter(grouped_df['quantity_group_center'], grouped_df['price_diff'],s=10)
plt.plot(grouped_df['quantity_group_center'], np.array(grouped_df['quantity_group_center'].values)/2e6-0.000352,color='red')
plt.xlabel('quantity_group_center')
plt.ylabel('average price_diff')
plt.title('Scatter plot of average price_diff by quantity_group')
plt.grid(True)

बाहर[1]:

img

[19] मेंः

grouped_df.head(10)

बाहर[19]: ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

img

प्रारंभिक इष्टतम आदेश स्थान

व्यापार राशि के मॉडलिंग और व्यापार राशि के अनुरूप मूल्य प्रभाव के मोटे मॉडल के साथ, इष्टतम ऑर्डर प्लेसमेंट की गणना करना संभव प्रतीत होता है। आइए कुछ धारणाएं बनाएं और एक गैरजिम्मेदार इष्टतम मूल्य स्थिति प्रदान करें।

  1. मान लीजिए कि प्रभाव के बाद कीमत अपने मूल मूल्य पर लौटती है (जो अत्यधिक संभावना नहीं है और प्रभाव के बाद मूल्य परिवर्तन का आगे विश्लेषण की आवश्यकता होगी) ।
  2. मान लीजिए कि इस अवधि के दौरान व्यापार की मात्रा और आदेशों की आवृत्ति का वितरण पूर्व निर्धारित पैटर्न का पालन करता है (जो कि भी गलत है, क्योंकि हम एक दिन के आंकड़ों के आधार पर अनुमान लगा रहे हैं और व्यापार में स्पष्ट क्लस्टरिंग घटनाएं दिखाई देती हैं) ।
  3. मान लीजिए कि सिमुलेटेड समय के दौरान केवल एक बिक्री आदेश होता है और फिर बंद हो जाता है।
  4. मान लीजिए कि ऑर्डर निष्पादित होने के बाद, अन्य खरीद ऑर्डर हैं जो कीमत को ऊपर धकेलते रहते हैं, खासकर जब राशि बहुत कम होती है। इस प्रभाव को यहां नजरअंदाज कर दिया जाता है, और यह केवल यह माना जाता है कि कीमत पीछे हट जाएगी।

चलो एक सरल अपेक्षित रिटर्न लिखकर शुरू करते हैं, जो कि 1 सेकंड के भीतर Q से अधिक संचयी खरीद आदेशों की संभावना है, अपेक्षित रिटर्न दर से गुणा (यानी, मूल्य प्रभाव) ।

img

ग्राफ के आधार पर, अधिकतम अपेक्षित रिटर्न लगभग 2500 है, जो औसत व्यापार राशि का लगभग 2.5 गुना है। इससे पता चलता है कि बिक्री आदेश को 2500 की मूल्य स्थिति पर रखा जाना चाहिए। यह रेखांकित करना महत्वपूर्ण है कि क्षैतिज अक्ष 1 सेकंड के भीतर व्यापार राशि का प्रतिनिधित्व करता है और इसे गहराई स्थिति के बराबर नहीं किया जाना चाहिए। इसके अलावा, यह विश्लेषण ट्रेड डेटा पर आधारित है और इसमें महत्वपूर्ण गहराई डेटा की कमी है।

सारांश

हमने पाया है कि अलग-अलग समय अंतराल पर व्यापार राशि का वितरण व्यक्तिगत व्यापार राशि के वितरण का एक सरल स्केलिंग है। हमने मूल्य प्रभाव और व्यापार संभावना के आधार पर एक सरल अपेक्षित रिटर्न मॉडल भी विकसित किया है। इस मॉडल के परिणाम हमारी उम्मीदों के अनुरूप हैं, यह दिखाते हुए कि यदि बिक्री आदेश राशि कम है, तो यह मूल्य में कमी का संकेत देता है, और लाभ क्षमता के लिए एक निश्चित राशि की आवश्यकता होती है। व्यापार राशि बढ़ने के साथ संभावना कम हो जाती है, बीच में इष्टतम आकार के साथ, जो इष्टतम आदेश प्लेसमेंट रणनीति का प्रतिनिधित्व करता है। हालांकि, यह मॉडल अभी भी बहुत सरल है। अगले लेख में, मैं इस विषय में गहराई से गहराई से जाऊंगा।

[20] मेंः

# Cumulative distribution in 1s
df_resampled = buy_trades['quantity'].resample('1S').sum()
df_resampled = df_resampled.to_frame(name='quantity')
df_resampled = df_resampled[df_resampled['quantity']>0]

depths = np.array(range(0, 15000, 10))
mean = df_resampled['quantity'].mean()
alpha = np.log(np.mean(df_resampled['quantity'] > mean))/np.log(2.05)
probabilities_s = np.array([((1+20**(-depth/mean))*depth/mean+1)**(alpha) for depth in depths])
profit_s = np.array([depth/2e6-0.000352 for depth in depths])
plt.figure(figsize=(10, 5))
plt.plot(depths, probabilities_s*profit_s)
plt.xlabel('Q')
plt.ylabel('Excpet profit')
plt.grid(True)

बाहर[20]:

img


अधिक