Sumber daya yang dimuat... Pemuatan...

Berpikir tentang strategi perdagangan frekuensi tinggi (2)

Penulis:Rumput, Dibuat: 2023-08-04 16:14:27, Diperbarui: 2023-09-19 09:08:17

img

Artikel ini membahas strategi perdagangan frekuensi tinggi, dengan penelitian fokus pada pemodelan volume perdagangan dan kejutan harga. Artikel ini mengusulkan model awal posisi paling optimal yang tergantung dengan menganalisis transaksi tunggal, kejutan harga interval tetap, dan efek transaksi pada harga. Model ini didasarkan pada pemahaman volume perdagangan dan kejutan harga, mencoba untuk menemukan posisi perdagangan optimal.

Pemodelan transaksi yang akumulasi

Pada artikel sebelumnya, kami menghasilkan ekspresi kemungkinan transaksi tunggal lebih besar dari nilai tertentu:

img

Kami juga peduli dengan distribusi volume transaksi dalam jangka waktu tertentu, yang secara intuitif harus terkait dengan jumlah transaksi dan frekuensi pesanan per transaksi. Di bawah ini data diproses dengan interval yang tetap.

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 satuan dengan interval 1s menjadi jumlah transaksi, menghilangkan bagian yang tidak terjadi, dan menyesuaikan dengan distribusi transaksi tunggal di atas, hasil yang terlihat lebih baik, menganggap semua transaksi dalam 1s sebagai satuan, masalah ini menjadi masalah yang telah diselesaikan. Tetapi ketika siklus diperpanjang (relatif terhadap frekuensi transaksi), kesalahan meningkat, dan penelitian menemukan bahwa kesalahan ini disebabkan oleh perbaikan distribusi Pareto sebelumnya. Ini menunjukkan bahwa ketika siklus diperpanjang, yang berisi lebih banyak transaksi tunggal, semakin banyak transaksi bergabung dan semakin dekat dengan distribusi Pareto, situasi ini harus dihapus.

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 jumlah first_trade_id last_trade_id adalah_pembeli_pembuat tanggal waktu transaksi interval berbeda
2023-01-27 00:00:00.161 1138369 2.901 54.3 3806199 3806201 Tidak benar 2023-01-27 00:00:00.161 1674777600161 Tidak 0.001
2023-01-27 00:00:04.140 1138370 2.901 291.3 3806202 3806203 Tidak benar 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 benar 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 benar 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 benar 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 benar 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 benar 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 benar 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 benar 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 benar 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)

png

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)

png

Sekarang untuk distribusi jumlah transaksi yang terakumulasi dalam waktu yang berbeda, simpulkan rumus umum, dan sesuaikan dengan distribusi transaksi tunggal, tanpa menggunakan statistik terpisah setiap kali.

img

Di mana avg_interval menunjukkan interval rata-rata transaksi tunggal, dan avg_interval_T menunjukkan interval rata-rata interval yang perlu diperkirakan, yang dikatakan agak menyimpang. Jika kita ingin memperkirakan transaksi 1s, perlu memperkirakan interval rata-rata peristiwa transaksi yang terkandung dalam statistik 1s. Jika probabilitas pesanan yang tiba sesuai dengan distribusi Parsons, ini seharusnya dapat diperkirakan secara langsung, tetapi penyimpangan sebenarnya sangat besar, tidak dijelaskan di sini.

Perhatikan bahwa kemungkinan transaksi yang lebih besar dari nilai tertentu dalam interval waktu di sini dan kemungkinan transaksi yang sebenarnya berada di lokasi dalam kedalaman harus berbeda jauh, karena semakin lama waktu tunggu, semakin besar kemungkinan perubahan buku pesanan, dan transaksi juga menyebabkan perubahan kedalaman, sehingga kemungkinan transaksi di lokasi kedalaman yang sama berubah secara real-time seiring dengan pembaruan 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)

png

Kejutan harga transaksi tunggal

Data transaksi adalah harta karun, dan masih banyak data yang dapat digali. Kita harus sangat memperhatikan dampak pesanan terhadap harga, yang mempengaruhi posisi daftar strategi. Juga berdasarkan data agregat transact_time, perhitungkan selisih harga terakhir dan harga pertama, jika hanya ada satu pesanan, selisihnya adalah 0. Anehnya, ada juga sejumlah kecil hasil data negatif, seharusnya masalah urutan urutan data, tidak masuk ke dalam di sini.

Hasilnya menunjukkan bahwa persentase tidak menimbulkan benturan mencapai 77%, persentase 1 tik adalah 16,5%, 2 tik adalah 3,7%, 3 tik adalah 1,2%, dan lebih dari 4 tik adalah kurang dari 1%.

Jumlah transaksi yang menyebabkan perbedaan harga yang sesuai dihitung, menghilangkan kebohongan yang terlalu besar, dan pada dasarnya sesuai dengan hubungan linier, sekitar 1 tik untuk setiap 1000 volume yang menghasilkan fluktuasi harga.

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);

png

Shock harga dengan interval tetap

Harga shock dalam statistik 2s, yang berbeda adalah bahwa di sini akan ada negatif, tentu saja karena di sini hanya statistik pembayaran, posisi simetris akan lebih besar satu tik. Lanjutkan untuk mengamati hubungan antara transaksi dan shock, hanya statistik yang lebih besar dari 0 hasil, kesimpulan dan pesanan tunggal hampir sama, juga hubungan linear yang mendekati, setiap tik membutuhkan sekitar 2000 jumlah.

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));

png

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);

png

Kejutan harga transaksi

Sebelumnya mencari volume transaksi yang diperlukan untuk perubahan tik, tetapi tidak akurat karena dibangun pada kasus yang mengasumsikan bahwa kejutan telah terjadi. Sekarang sebaliknya melihat kejutan harga yang disebabkan oleh perubahan perdagangan.

Di sini data disampel dalam 1s, satu langkah per 100 kuantitas, dan statistik perubahan harga dalam kisaran kuantitas ini; membuat beberapa kesimpulan yang lebih berharga:

  1. Ketika jumlah transaksi order di bawah 500, perubahan harga yang diharapkan adalah penurunan, yang sesuai dengan harapan, setelah semua, juga order jual mempengaruhi harga.
  2. Ketika volume transaksi rendah, maka hubungan linear sesuai, yaitu semakin besar volume transaksi, semakin besar kenaikan harga.
  3. Semakin besar volume transaksi, semakin besar perubahan harga, yang seringkali mewakili harga terobosan, harga terobosan dapat kembali, ditambah dengan pengambilan sampel interval tetap, yang menyebabkan ketidakstabilan data.
  4. Perhatian harus diberikan pada bagian atas grafik titik-titik, yaitu bagian di mana volume transaksi sesuai dengan kenaikan harga.
  5. Hanya untuk pasangan transaksi ini, berikan hubungan antara volume transaksi yang dibuat dan perubahan harga dalam versi kasar:

img

Di antaranya, C menunjukkan perubahan harga, dan Q mewakili volume transaksi pembelian.

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)

png

grouped_df.head(10)
jumlah_kelompok harga_perbedaan jumlah_kelompok_pusat
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

Posisi pertama yang paling menguntungkan

Dengan pemodelan volume transaksi dan model kasar dari volume transaksi yang sesuai dengan dampak harga, tampaknya dapat dihitung posisi optimum untuk daftar.

  1. Misalkan harga kembali ke nilai awal setelah kejutan (yang tentu saja tidak mungkin, perlu analisis ulang perubahan harga setelah kejutan)
  2. Asumsikan bahwa distribusi volume transaksi dan frekuensi pesanan selama periode ini sesuai dengan perkiraan (ini juga tidak akurat, di sini perkiraan dilakukan dengan nilai sehari, dan transaksi memiliki fenomena pengumpulan yang jelas).
  3. Dengan asumsi bahwa hanya ada satu penjualan dalam waktu simulasi, maka akan terjadi penarikan.
  4. Dengan asumsi bahwa setelah pesanan selesai, ada pembayaran lain yang terus mendorong harga lebih tinggi, terutama ketika jumlahnya sangat rendah, efek ini diabaikan di sini, dengan alasan bahwa itu akan kembali.

Pertama, tulislah pengembalian yang diharapkan yang sederhana, yaitu probabilitas pembayaran yang terkumpul lebih besar dari Q dalam 1s, dikalikan dengan pengembalian yang diharapkan (yaitu harga yang terjatuh):

img

Berdasarkan gambar, diharapkan hasil maksimal sekitar 2500 dan sekitar 2,5 kali lipat dari volume rata-rata transaksi. Artinya, pesanan jual harus tergantung di posisi 2500. Perlu ditekankan lagi bahwa volume transaksi dalam garis lintang mewakili 1s, tidak dapat secara sederhana sama dengan posisi kedalaman. Dan ini saat ini masih kekurangan data kedalaman yang penting, hanya berdasarkan spekulasi perdagangan.

Pengamatan

Penemuan bahwa distribusi transaksi pada interval waktu yang berbeda adalah skala sederhana tentang distribusi transaksi tunggal. Juga berdasarkan kejutan harga dan probabilitas transaksi, model pengharapan pendapatan sederhana dibuat, dan hasilnya sesuai dengan harapan kami, jika jumlah transaksi yang dijual kecil, yang menunjukkan penurunan harga, diperlukan jumlah tertentu untuk ruang keuntungan, dan semakin besar volume transaksi, semakin rendah probabilitasnya, ada ukuran optimal di tengah, dan juga posisi yang strategis untuk mencari. Tentu saja, model ini masih terlalu sederhana, dan saya akan terus membahasnya di artikel berikutnya.

#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)

png


Lebih banyak

Ukuran ok 🐂🍺