Artikel ini membincangkan strategi dagangan frekuensi tinggi, dengan tumpuan kepada pemodelan jumlah dagangan yang terkumpul dan kejutan harga. Artikel ini mengemukakan model kedudukan tunggal yang paling optimal berdasarkan analisis transaksi tunggal, kejutan harga selang tetap dan kesan dagangan pada harga. Model ini berdasarkan pemahaman mengenai jumlah dagangan dan kejutan harga untuk mencari kedudukan dagangan yang paling optimum.
Artikel sebelumnya menghasilkan ungkapan kebarangkalian transaksi tunggal yang lebih besar daripada nilai tertentu:
Kami juga mengambil berat tentang pembahagian jumlah transaksi dalam jangka masa tertentu, yang secara intuitif harus berkaitan dengan jumlah transaksi dan kekerapan pesanan setiap kali; di bawah ini, data diproses mengikut selang masa yang tetap; dan seperti di atas, gambarkan pembahagian itu.
from datetime import date,datetime
import time
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
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']
Menggabungkan transaksi setiap selang 1s menjadi jumlah transaksi, membuang bahagian yang tidak berlaku, dan menyesuaikan dengan peredaran transaksi tunggal di atas, hasil yang lebih baik dapat dilihat, menganggap semua transaksi dalam 1s sebagai satu, masalah ini menjadi masalah yang telah diselesaikan. Tetapi apabila kitaran ditarik (berbanding dengan kekerapan urus niaga), kesalahan meningkat, dan kajian mendapati bahawa kesalahan ini disebabkan oleh penyempurnaan pembahagian Pareto sebelumnya. Ini menunjukkan bahawa apabila kitaran ditarik, yang mengandungi lebih banyak transaksi tunggal, semakin banyak gabungan transaksi yang semakin mendekati pembahagian Pareto, keadaan ini perlu dikeluarkan penyempurnaan.
df_resampled = buy_trades['quantity'].resample('1S').sum()
df_resampled = df_resampled.to_frame(name='quantity')
df_resampled = df_resampled[df_resampled['quantity']>0]
buy_trades
agg_trade_id | harga | kuantiti | first_trade_id | last_trade_id | is_buyer_maker | tarikh | masa urus niaga | Jangkaan | berbeza | |
---|---|---|---|---|---|---|---|---|---|---|
2023-01-27 00:00:00.161 | 1138369 | 2.901 | 54.3 | 3806199 | 3806201 | Tidak betul | 2023-01-27 00:00:00.161 | 1674777600161 | NaN | 0.001 |
2023-01-27 00:00:04.140 | 1138370 | 2.901 | 291.3 | 3806202 | 3806203 | Tidak betul | 2023-01-27 00:00:04.140 | 1674777604140 | 3979.0 | 0.000 |
2023-01-27 00:00:04.339 | 1138373 | 2.902 | 55.1 | 3806205 | 3806207 | Tidak betul | 2023-01-27 00:00:04.339 | 1674777604339 | 199.0 | 0.001 |
2023-01-27 00:00:04.772 | 1138374 | 2.902 | 1032.7 | 3806208 | 3806223 | Tidak betul | 2023-01-27 00:00:04.772 | 1674777604772 | 433.0 | 0.000 |
2023-01-27 00:00:05.562 | 1138375 | 2.901 | 3.5 | 3806224 | 3806224 | Tidak betul | 2023-01-27 00:00:05.562 | 1674777605562 | 790.0 | 0.000 |
… | … | … | … | … | … | … | … | … | … | … |
2023-01-27 23:59:57.739 | 1544370 | 3.572 | 394.8 | 5074645 | 5074651 | Tidak betul | 2023-01-27 23:59:57.739 | 1674863997739 | 1224.0 | 0.002 |
2023-01-27 23:59:57.902 | 1544372 | 3.573 | 177.6 | 5074652 | 5074655 | Tidak betul | 2023-01-27 23:59:57.902 | 1674863997902 | 163.0 | 0.001 |
2023-01-27 23:59:58.107 | 1544373 | 3.573 | 139.8 | 5074656 | 5074656 | Tidak betul | 2023-01-27 23:59:58.107 | 1674863998107 | 205.0 | 0.000 |
2023-01-27 23:59:58.302 | 1544374 | 3.573 | 60.5 | 5074657 | 5074657 | Tidak betul | 2023-01-27 23:59:58.302 | 1674863998302 | 195.0 | 0.000 |
2023-01-27 23:59:59.894 | 1544376 | 3.571 | 12.1 | 5074662 | 5074664 | Tidak betul | 2023-01-27 23:59:59.894 | 1674863999894 | 1592.0 | 0.000 |
#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)
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]) # 无修正
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)
Sekarang untuk pembahagian jumlah urus niaga yang terkumpul dalam masa yang berbeza, ringkasan formula umum, yang disesuaikan dengan pembahagian urus niaga tunggal, tanpa menggunakan statistik yang berasingan setiap kali.
Di mana avg_interval menunjukkan selang purata transaksi tunggal, dan avg_interval_T menunjukkan selang purata selang yang diperlukan untuk dianggarkan, dikatakan agak melingkar. Jika kita mahu menganggarkan selang 1s, kita perlu menganggarkan selang purata peristiwa yang terkandung dalam selang 1s. Jika kemungkinan pesanan tiba sesuai dengan pembahagian Parsons, ini sepatutnya dapat dianggarkan secara langsung, tetapi kesesuaian sebenar sangat besar, tidak dijelaskan di sini.
Perhatikan di sini bahawa kebarangkalian transaksi yang lebih besar daripada nilai tertentu dalam satu selang masa dan kebarangkalian transaksi yang sebenarnya berada di lokasi dalam kedalaman harus berbeza jauh, kerana semakin lama masa menunggu, semakin besar kemungkinan perubahan buku pesanan, dan transaksi juga menyebabkan perubahan kedalaman, jadi kebarangkalian transaksi di lokasi yang sama dalam kedalaman berubah secara langsung dengan kemas kini data.
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)
Data urus niaga adalah harta karun, dan masih banyak data yang boleh digali. Kita harus sangat memperhatikan kesan pesanan terhadap harga, yang mempengaruhi kedudukan senarai strategi. Juga berdasarkan data agregat transact_time, mengira perbezaan harga terakhir dan harga pertama, jika hanya ada satu pesanan, perbezaannya adalah 0.
Hasilnya menunjukkan peratusan tidak menyebabkan kejutan sebanyak 77%, peratusan 1 tik adalah 16.5%, 2 tik adalah 3.7%, 3 tik adalah 1.2%, dan lebih daripada 4 tik adalah kurang daripada 1%.
Jumlah dagangan yang menyebabkan perbezaan harga yang sepadan telah dikira, menghilangkan kepalsuan yang terlalu besar, dan pada dasarnya sesuai dengan hubungan linear, kira-kira satu pergerakan harga bagi setiap 1000 jumlah yang menyebabkan 1 tik.
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)
diff_counts = buy_trades['diff'].value_counts()
diff_counts[diff_counts>10]/diff_counts.sum()
0.000 0.769965
0.001 0.165527
0.002 0.037826
0.003 0.012546
0.004 0.005986
0.005 0.003173
0.006 0.001964
0.007 0.001036
0.008 0.000795
0.009 0.000474
0.010 0.000227
0.011 0.000187
0.012 0.000087
0.013 0.000080
Name: diff, dtype: float64
diff_group = buy_trades.groupby('diff').agg({
'quantity': 'mean',
'diff': 'last',
})
diff_group['quantity'][diff_group['diff']>0][diff_group['diff']<0.01].plot(figsize=(10,5),grid=True);
Harga kejutan dalam statistik 2s, yang berbeza di sini adalah bahawa akan ada negatif, tentu saja kerana di sini hanya statistik pembayaran, kedudukan simetris akan lebih besar daripada satu tik. Teruskan melihat hubungan perdagangan dan kejutan, hanya statistik yang lebih besar daripada 0 hasil, kesimpulan dan pesanan tunggal hampir sama, juga hubungan linear yang hampir, setiap tik memerlukan jumlah sekitar 2000.
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]
result_df['price_diff'][abs(result_df['price_diff'])<0.016].value_counts().sort_index().plot.bar(figsize=(10,5));
result_df['price_diff'].value_counts()[result_df['price_diff'].value_counts()>30]
0.001 7176
-0.001 3665
0.002 3069
-0.002 1536
0.003 1260
0.004 692
-0.003 608
0.005 391
-0.004 322
0.006 259
-0.005 192
0.007 146
-0.006 112
0.008 82
0.009 75
-0.007 75
-0.008 65
0.010 51
0.011 41
-0.010 31
Name: price_diff, dtype: int64
diff_group = result_df.groupby('price_diff').agg({ 'quantity_sum': 'mean'})
diff_group[(diff_group.index>0) & (diff_group.index<0.015)].plot(figsize=(10,5),grid=True);
Sebelum ini, jumlah transaksi yang diperlukan untuk perubahan tik dikehendaki, tetapi tidak tepat kerana ia dibina pada keadaan yang menganggap kejutan telah berlaku; kini sebaliknya melihat kejutan harga yang disebabkan oleh pertukaran.
Di sini, data disampel mengikut 1s, satu langkah setiap 100 kuantiti, dan perubahan harga dalam jumlah ini dikira; membuat beberapa kesimpulan yang agak berharga:
Di antaranya,
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]
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()
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)
grouped_df.head(10)
kuantiti_kumpulan | harga_perbezaan | quantity_group_center | |
---|---|---|---|
0 | 0-199 | -0.000302 | 99.5 |
1 | 100-299 | -0.000124 | 199.5 |
2 | 200-399 | -0.000068 | 299.5 |
3 | 300-499 | -0.000017 | 399.5 |
4 | 400-599 | -0.000048 | 499.5 |
5 | 500-699 | 0.000098 | 599.5 |
6 | 600-799 | 0.000006 | 699.5 |
7 | 700-899 | 0.000261 | 799.5 |
8 | 800-999 | 0.000186 | 899.5 |
9 | 900-1099 | 0.000299 | 999.5 |
Dengan pemodelan yang kasar terhadap jumlah urus niaga dan jumlah urus niaga yang sepadan dengan kejutan harga, nampaknya boleh dihitung kedudukan yang paling optimum.
Pertama, tulis hasil yang dijangkakan yang mudah, iaitu kebarangkalian pembayaran yang terkumpul lebih besar daripada Q dalam 1s, dikalikan dengan kadar pulangan yang dijangkakan (iaitu harga kejutan):
Berdasarkan imej, jangkaan keuntungan maksimum adalah kira-kira 2500 dan kira-kira 2.5 kali ganda jumlah purata dagangan. Maksudnya, pesanan jual harus digantung di kedudukan 2500. Perlu ditekankan sekali lagi bahawa jumlah dagangan dalam kisaran 1s tidak dapat disamakan dengan kedudukan kedalaman. Dan ini pada masa ini masih kekurangan data kedalaman yang penting, hanya berdasarkan spekulasi dagangan.
Dijumpai bahawa pembahagian jumlah dagangan pada selang masa yang berbeza adalah skala sederhana mengenai pembahagian jumlah dagangan tunggal. Juga berdasarkan kejutan harga dan kebarangkalian dagangan, model pendapatan yang diharapkan sederhana dibuat. Hasil model ini sesuai dengan jangkaan kami, jika jumlah dagangan yang dijual kecil, yang menunjukkan penurunan harga, ruang keuntungan diperlukan untuk jumlah tertentu, dan jumlah dagangan yang lebih besar semakin rendah kebarangkalian, terdapat saiz yang paling baik di tengah-tengah, dan juga strategi mencari kedudukan gantung. Sudah tentu, model ini masih terlalu mudah, artikel seterusnya, saya akan terus membincangkannya.
#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)
Ukuran ok 🐂🍺