उच्च आवृत्ति ट्रेडिंग रणनीतियों के बारे में सोचें (5)

लेखक:घास, बनाया गयाः 2023-08-09 18:13:16, अद्यतन किया गयाः 2023-09-18 19:51:59

img

पिछले लेख में मध्यवर्ती कीमतों के गणना के विभिन्न तरीकों का प्रारंभिक परिचय दिया गया है और मध्यवर्ती कीमतों पर एक संशोधन दिया गया है, जो इस विषय पर गहराई से जारी है।

आवश्यक डेटा

ऑर्डर प्रवाह डेटा और दशमलव की गहराई का डेटा, वास्तविक डिस्क संग्रह से आता है, अद्यतन की आवृत्ति 100ms है। वास्तविक डिस्क में केवल खरीदें और बेचें एक डिस्क डेटा शामिल है जो वास्तविक समय में अद्यतन किया जाता है, संक्षिप्तता के लिए, अस्थायी रूप से अनुपयोगी है। डेटा बहुत बड़ा है, केवल 100,000 पंक्तियों की गहराई डेटा को बनाए रखा गया है, और प्रत्येक डिस्क को अलग-अलग कॉलम में अलग रखा गया है।

from datetime import date,datetime
import time
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import ast
%matplotlib inline
tick_size = 0.0001
trades = pd.read_csv('YGGUSDT_aggTrade.csv',names=['type','event_time', 'agg_trade_id','symbol', 'price', 'quantity', 'first_trade_id', 'last_trade_id',
       'transact_time', 'is_buyer_maker'])
trades = trades.groupby(['transact_time','is_buyer_maker']).agg({
    'transact_time':'last',
    'agg_trade_id': 'last',
    'price': 'first',
    'quantity': 'sum',
    'first_trade_id': 'first',
    'last_trade_id': 'last',
    'is_buyer_maker': 'last',
})
trades.index = pd.to_datetime(trades['transact_time'], unit='ms')
trades.index.rename('time', inplace=True)
trades['interval'] = trades['transact_time'] - trades['transact_time'].shift()
depths = pd.read_csv('YGGUSDT_depth.csv',names=['type','event_time', 'transact_time','symbol', 'u1', 'u2', 'u3', 'bids','asks'])
depths = depths.iloc[:100000]
depths['bids'] = depths['bids'].apply(ast.literal_eval).copy()
depths['asks'] = depths['asks'].apply(ast.literal_eval).copy()
def expand_bid(bid_data):
    expanded = {}
    for j, (price, quantity) in enumerate(bid_data):
        expanded[f'bid_{j}_price'] = float(price)
        expanded[f'bid_{j}_quantity'] = float(quantity)
    return pd.Series(expanded)
def expand_ask(ask_data):
    expanded = {}
    for j, (price, quantity) in enumerate(ask_data):
        expanded[f'ask_{j}_price'] = float(price)
        expanded[f'ask_{j}_quantity'] = float(quantity)
    return pd.Series(expanded)
# 应用到每一行,得到新的df
expanded_df_bid = depths['bids'].apply(expand_bid)
expanded_df_ask = depths['asks'].apply(expand_ask)
# 在原有df上进行扩展
depths = pd.concat([depths, expanded_df_bid, expanded_df_ask], axis=1)
depths.index = pd.to_datetime(depths['transact_time'], unit='ms')
depths.index.rename('time', inplace=True);
trades = trades[trades['transact_time'] < depths['transact_time'].iloc[-1]]

पहले इन 20 फाइलों के बाजारों के वितरण को देखें, जो उम्मीद के अनुरूप है, जितना अधिक दूरी पर होगा, उतना ही अधिक सूचीबद्ध होगा, और खरीद सूची और बिक्री सूची लगभग सममित होगी।

bid_mean_list = []
ask_mean_list = []
for i in range(20):
    bid_mean_list.append(round(depths[f'bid_{i}_quantity'].mean(),0))
    ask_mean_list.append(round(depths[f'ask_{i}_quantity'].mean(),0))
plt.figure(figsize=(10, 5))
plt.plot(bid_mean_list);
plt.plot(ask_mean_list);
plt.grid(True)

img

गहन डेटा और लेन-देन डेटा को जोड़कर, पूर्वानुमान की सटीकता का आकलन करना आसान है। यह सुनिश्चित करता है कि लेनदेन डेटा गहन डेटा से बाद में है, और बिना किसी देरी के, प्रत्यक्ष रूप से पूर्वानुमान मूल्य और वास्तविक लेनदेन मूल्य के बीच औसत त्रुटि की गणना करता है। पूर्वानुमान की सटीकता को मापने के लिए उपयोग किया जाता है।

नतीजतन, खरीदें-बेचें औसत मध्य_मूल्य का त्रुटि सबसे बड़ा है, weight_mid_price में बदलने के बाद, त्रुटि तुरंत बहुत कम हो गई, और भारित मध्य मूल्य को समायोजित करने के साथ थोड़ा सुधार हुआ। कल के लेख के बाद, किसी ने केवल I ^ 3 / 2 के साथ प्रतिक्रिया दी, यहां जाँच की, और परिणाम बेहतर हैं। निम्नलिखित कारणों पर विचार किया, घटना की आवृत्ति में अंतर होना चाहिए, I -1 और 1 के करीब कम संभावना घटना है, इन कम संभावनाओं को ठीक करने के लिए, उच्च आवृत्ति वाली घटनाओं के लिए पूर्वानुमान के बजाय, मैं उच्च आवृत्ति वाली घटनाओं के लिए अधिक सटीक नहीं हूं, इसलिए, उच्च आवृत्ति वाली घटनाओं की देखभाल के मामले में, मैंने फिर से समायोजित किया। यहाँ शुद्ध रूप से संदर्भित पैरामीटर हैं, वास्तविकता बहुत बड़ी नहीं हैः

img

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

df = pd.merge_asof(trades, depths, on='transact_time', direction='backward')
df['spread'] = round(df['ask_0_price'] - df['bid_0_price'],4)
df['mid_price'] = (df['bid_0_price']+ df['ask_0_price']) / 2
df['I'] = (df['bid_0_quantity'] - df['ask_0_quantity']) / (df['bid_0_quantity'] + df['ask_0_quantity'])
df['weight_mid_price'] = df['mid_price'] + df['spread']*df['I']/2
df['adjust_mid_price'] = df['mid_price'] + df['spread']*(df['I'])*(df['I']**8+1)/4
df['adjust_mid_price_2'] = df['mid_price'] + df['spread']*df['I']*(df['I']**2+1)/4
df['adjust_mid_price_3'] = df['mid_price'] + df['spread']*df['I']**3/2
df['adjust_mid_price_4'] = df['mid_price'] + df['spread']*(df['I']+0.3)*(df['I']**4+0.7)/3.8
print('平均值     mid_price的误差:', ((df['price']-df['mid_price'])**2).sum())
print('挂单量加权 mid_price的误差:', ((df['price']-df['weight_mid_price'])**2).sum())
print('调整后的   mid_price的误差:', ((df['price']-df['adjust_mid_price'])**2).sum())
print('调整后的 mid_price_2的误差:', ((df['price']-df['adjust_mid_price_2'])**2).sum())
print('调整后的 mid_price_3的误差:', ((df['price']-df['adjust_mid_price_3'])**2).sum())
print('调整后的 mid_price_4的误差:', ((df['price']-df['adjust_mid_price_4'])**2).sum())
平均值     mid_price的误差: 0.0048751924999999845
挂单量加权 mid_price的误差: 0.0048373440193987035
调整后的   mid_price的误差: 0.004803654771638586
调整后的 mid_price_2的误差: 0.004808216498329721
调整后的 mid_price_3的误差: 0.004794984755260528
调整后的 mid_price_4的误差: 0.0047909595497071375

दूसरे स्तर की गहराई पर विचार करें

यहाँ एक विचार है, एक पैरामीटर को प्रभावित करने वाले विभिन्न मूल्यवर्गों को देखने के लिए, लेन-देन की कीमत में परिवर्तन, जो कि पैरामीटर के मध्य मूल्य में योगदान को मापता है। जैसे कि पहली श्रेणी के गहराई के चित्र में, लेन-देन की कीमत में वृद्धि के साथ, लेन-देन की कीमत में बदलाव होने की अधिक संभावना है, यह दर्शाता है कि I ने सकारात्मक योगदान दिया है।

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

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

bins = np.linspace(-1, 1, 50)
df['change'] = (df['price'].pct_change().shift(-1))/tick_size
df['I_bins'] = pd.cut(df['I'], bins, labels=bins[1:])
df['I_2'] = (df['bid_1_quantity'] - df['ask_1_quantity']) / (df['bid_1_quantity'] + df['ask_1_quantity'])
df['I_2_bins'] = pd.cut(df['I_2'], bins, labels=bins[1:])
df['I_3'] = (df['bid_2_quantity'] - df['ask_2_quantity']) / (df['bid_2_quantity'] + df['ask_2_quantity'])
df['I_3_bins'] = pd.cut(df['I_3'], bins, labels=bins[1:])
df['I_4'] = (df['bid_3_quantity'] - df['ask_3_quantity']) / (df['bid_3_quantity'] + df['ask_3_quantity'])
df['I_4_bins'] = pd.cut(df['I_4'], bins, labels=bins[1:])
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(8, 5))


axes[0][0].plot(df.groupby('I_bins')['change'].mean())
axes[0][0].set_title('I')
axes[0][0].grid(True)

axes[0][1].plot(df.groupby('I_2_bins')['change'].mean())
axes[0][1].set_title('I 2')
axes[0][1].grid(True)

axes[1][0].plot(df.groupby('I_3_bins')['change'].mean())
axes[1][0].set_title('I 3')
axes[1][0].grid(True)

axes[1][1].plot(df.groupby('I_4_bins')['change'].mean())
axes[1][1].set_title('I 4')
axes[1][1].grid(True)
plt.tight_layout();

img

df['adjust_mid_price_4'] = df['mid_price'] + df['spread']*(df['I']+0.3)*(df['I']**4+0.7)/3.8
df['adjust_mid_price_5'] = df['mid_price'] + df['spread']*(0.7*df['I']+0.3*df['I_2'])/2
df['adjust_mid_price_6'] = df['mid_price'] + df['spread']*(0.7*df['I']+0.3*df['I_2'])**3/2
df['adjust_mid_price_7'] = df['mid_price'] + df['spread']*(0.7*df['I']+0.3*df['I_2']+0.3)*((0.7*df['I']+0.3*df['I_2'])**4+0.7)/3.8
df['adjust_mid_price_8'] = df['mid_price'] + df['spread']*(0.7*df['I']+0.2*df['I_2']+0.1*df['I_3']+0.3)*((0.7*df['I']+0.3*df['I_2']+0.1*df['I_3'])**4+0.7)/3.8
print('调整后的 mid_price_4的误差:', ((df['price']-df['adjust_mid_price_4'])**2).sum())
print('调整后的 mid_price_5的误差:', ((df['price']-df['adjust_mid_price_5'])**2).sum())
print('调整后的 mid_price_6的误差:', ((df['price']-df['adjust_mid_price_6'])**2).sum())
print('调整后的 mid_price_7的误差:', ((df['price']-df['adjust_mid_price_7'])**2).sum())
print('调整后的 mid_price_8的误差:', ((df['price']-df['adjust_mid_price_8'])**2).sum())
调整后的 mid_price_4的误差: 0.0047909595497071375
调整后的 mid_price_5的误差: 0.0047884350488318714
调整后的 mid_price_6的误差: 0.0047778319053133735
调整后的 mid_price_7的误差: 0.004773578540592192
调整后的 mid_price_8的误差: 0.004771415189297518

लेनदेन के आंकड़ों पर विचार करें

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

फॉर्म को ध्यान में रखते हुए, ऑर्डर की औसत आगमन संख्या को परिभाषित किया गया है असंतुलित VI, Vb, और Vs क्रमशः खरीद और बिक्री के आदेश के इकाई घटनाओं में औसत संख्या का प्रतिनिधित्व करते हैं।

img

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

img

alpha=0.1
df['avg_buy_interval'] = None
df['avg_sell_interval'] = None
df.loc[df['is_buyer_maker'] == True, 'avg_buy_interval'] = df[df['is_buyer_maker'] == True]['transact_time'].diff().ewm(alpha=alpha).mean()
df.loc[df['is_buyer_maker'] == False, 'avg_sell_interval'] = df[df['is_buyer_maker'] == False]['transact_time'].diff().ewm(alpha=alpha).mean()
df['avg_buy_quantity'] = None
df['avg_sell_quantity'] = None
df.loc[df['is_buyer_maker'] == True, 'avg_buy_quantity'] = df[df['is_buyer_maker'] == True]['quantity'].ewm(alpha=alpha).mean()
df.loc[df['is_buyer_maker'] == False, 'avg_sell_quantity'] = df[df['is_buyer_maker'] == False]['quantity'].ewm(alpha=alpha).mean()
df['avg_buy_quantity'] = df['avg_buy_quantity'].fillna(method='ffill')
df['avg_sell_quantity'] = df['avg_sell_quantity'].fillna(method='ffill')
df['avg_buy_interval'] = df['avg_buy_interval'].fillna(method='ffill')
df['avg_sell_interval'] = df['avg_sell_interval'].fillna(method='ffill')

df['avg_buy_rate'] = 1000 / df['avg_buy_interval']
df['avg_sell_rate'] =1000 / df['avg_sell_interval']

df['avg_buy_volume'] = df['avg_buy_rate']*df['avg_buy_quantity']
df['avg_sell_volume'] = df['avg_sell_rate']*df['avg_sell_quantity']
df['I'] = (df['bid_0_quantity']- df['ask_0_quantity']) / (df['bid_0_quantity'] + df['ask_0_quantity'])
df['OI'] = (df['avg_buy_rate']-df['avg_sell_rate']) / (df['avg_buy_rate'] + df['avg_sell_rate'])
df['QI'] = (df['avg_buy_quantity']-df['avg_sell_quantity']) / (df['avg_buy_quantity'] + df['avg_sell_quantity'])
df['VI'] = (df['avg_buy_volume']-df['avg_sell_volume']) / (df['avg_buy_volume'] + df['avg_sell_volume'])
bins = np.linspace(-1, 1, 50)
df['VI_bins'] = pd.cut(df['VI'], bins, labels=bins[1:])
plt.plot(df.groupby('VI_bins')['change'].mean());
plt.grid(True)

img

df['adjust_mid_price'] = df['mid_price'] + df['spread']*df['I']/2
df['adjust_mid_price_9'] = df['mid_price'] + df['spread']*(-df['OI'])*2
df['adjust_mid_price_10'] = df['mid_price'] + df['spread']*(-df['VI'])*1.4
print('调整后的mid_price   的误差:', ((df['price']-df['adjust_mid_price'])**2).sum())
print('调整后的mid_price_9 的误差:', ((df['price']-df['adjust_mid_price_9'])**2).sum())
print('调整后的mid_price_10的误差:', ((df['price']-df['adjust_mid_price_10'])**2).sum())
调整后的mid_price   的误差: 0.0048373440193987035
调整后的mid_price_9 的误差: 0.004629586542840461
调整后的mid_price_10的误差: 0.004401790287167206

समग्र मध्य मूल्य

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

अंत में, पूर्वानुमान की त्रुटि 0.00487 से 0.0043 तक गिर गई है, यहां और गहराई से नहीं जाना है, मध्यवर्ती मूल्य के लिए खनन करने के लिए बहुत कुछ है, आखिरकार, मध्यवर्ती मूल्य पूर्वानुमान मूल्य में है, आप अपने आप को कोशिश कर सकते हैं।

#注意VI需要延后一个使用
df['price_change'] = np.log(df['price']/df['price'].rolling(40).mean())
df['CI'] = -1.5*df['VI'].shift()+0.7*(0.7*df['I']+0.2*df['I_2']+0.1*df['I_3'])**3 + 150*df['price_change'].shift(1)
df['adjust_mid_price_11'] = df['mid_price'] + df['spread']*(df['CI'])
print('调整后的mid_price_11的误差:', ((df['price']-df['adjust_mid_price_11'])**2).sum())
调整后的mid_price_11的误差: 0.00421125960463469

सारांश

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


अधिक

mztcoinNext articleगर्मी के बाद क्या करें?

लुईकौन समझता है?

चुकिटीऔर न ऊँची और न ऊँची