Berpikir tentang strategi perdagangan frekuensi tinggi (5)

Penulis:Rumput, Dibuat: 2023-08-09 18:13:16, Diperbarui: 2023-09-18 19:51:59

img

Artikel sebelumnya memberikan perkenalan awal tentang berbagai metode perhitungan harga tengah dan memberikan revisi harga tengah, yang akan kita lanjutkan di artikel ini.

Data yang dibutuhkan

Data aliran pesanan dan data kedalaman sepuluh file, berasal dari koleksi real disk, dan frekuensi pembaruan adalah 100ms.

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]]

Pertama-tama lihatlah distribusi pasar 20 file ini, sesuai dengan yang diharapkan, semakin jauh dari transaksi, biasanya ada lebih banyak daftar, dan daftar pembelian dan daftar penjualan hampir simetris.

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

Menggabungkan data kedalaman dan data transaksi untuk memudahkan evaluasi keakuratan prediksi. Di sini, data transaksi dijamin lebih lambat dari data kedalaman, tanpa memperhitungkan keterlambatan, secara langsung menghitung nilai prediksi dengan rata-rata kesalahan sisi dari harga transaksi yang sebenarnya.

Hasilnya, kesalahan harga jual beli rata-rata adalah yang terbesar, setelah diubah menjadi weight_mid_price, kesalahan itu segera menjadi jauh lebih kecil, dan sedikit lebih baik lagi dengan menyesuaikan harga tengah ditimbang. Setelah artikel kemarin diterbitkan, ada yang memberikan umpan balik hanya dengan I ^ 3 / 2, di sini diperiksa, dan menemukan hasil yang lebih baik.

img

Hasilnya juga sedikit lebih baik. Artikel sebelumnya mengatakan bahwa strategi harus diprediksi dengan data yang lebih banyak, dan dengan data yang lebih dalam dan transaksi pesanan, keterikatan dan peningkatan yang dapat diperoleh sudah sangat lemah.

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

Pertimbangkan kedalaman kedua.

Di sini, dengan menggunakan ide yang sama, kita akan melihat berbagai rentang nilai yang mempengaruhi suatu parameter, perubahan harga transaksi untuk mengukur kontribusi parameter ini terhadap harga tengah. Seperti gambar dalam garis pertama, dengan peningkatan harga transaksi, harga transaksi selanjutnya semakin mungkin berubah, ini menunjukkan bahwa saya telah memberikan kontribusi positif.

Garis kedua ditangani dengan cara yang sama, dan ditemukan bahwa meskipun efeknya sedikit lebih kecil dari yang pertama, namun tidak boleh diabaikan. Garis ketiga juga memberikan kontribusi yang lemah, tetapi monotonnya jauh lebih buruk, dan kedalaman yang lebih dalam hampir tidak memiliki nilai referensi.

Menurut tingkat kontribusi yang berbeda, parameter ketidakseimbangan dari ketiga kelas ini, yang diberikan bobot yang berbeda, diperiksa secara aktual untuk berbagai metode perhitungan, dan kesalahan prediksi menurun lebih lanjut.

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

Pertimbangkan data transaksi

Data transaksi secara langsung mencerminkan tingkat kekosongan, setelah semua ini adalah pilihan untuk berpartisipasi dalam emas asli dan perak, sedangkan biaya pengunggahan yang jauh lebih rendah, bahkan ada kasus penipuan pengunggahan yang disengaja. Oleh karena itu, memprediksi harga tengah, strategi harus mempertimbangkan data transaksi.

Mengingat bentuknya, definisi jumlah pesanan yang mencapai rata-rata tidak seimbang VI, Vb, VS masing-masing menunjukkan jumlah rata-rata dalam peristiwa unit pesanan dan pesanan penjualan.

img

Hasilnya menemukan bahwa jumlah pendaratan dalam waktu singkat paling signifikan terhadap perkiraan perubahan harga, ketika VI berada di antara (< 0.1-0.9) negatif terkait dengan harga, sedangkan di luar kisaran, sebaliknya positif terkait dengan harga cepat. Ini menunjukkan bahwa harga akan kembali rata ketika pasar tidak ekstrem, yang didominasi oleh gejolak, dan ketika pasar ekstrim muncul, seperti ketika banyak pembelian oversold, saat ini akan keluar dari tren. Bahkan tanpa mempertimbangkan situasi kemungkinan rendah ini, asumsi sederhana bahwa tren dan VI memenuhi hubungan linier negatif, perbedaan kesalahan perkiraan harga tengah juga menurun secara signifikan.

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

Harga Intermediate yang Komprehensif

Dengan mempertimbangkan bahwa kedua jumlah pesanan dan data transaksi membantu dalam memprediksi harga tengah, maka kedua parameter ini dapat dikombinasikan, di mana pemberian bobot agak acak, dan tidak mempertimbangkan kondisi perbatasan. Dalam kasus yang ekstrem, harga tengah yang diprediksi mungkin tidak berada di antara satu beli dan satu jual, tetapi selama kesalahan dapat dikurangi, tidak peduli dengan detail ini.

Kesalahan yang diprediksi akhirnya turun dari awal 0.00487 menjadi 0.0043, dan di sini tidak lebih dalam lagi, harga tengah masih banyak yang dapat digali, setelah semua, harga tengah diprediksi adalah harga yang diprediksi, Anda dapat mencobanya sendiri.

#注意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

Pengamatan

Dengan menggabungkan data mendalam dan data transaksi, metode perhitungan harga tengah disempurnakan lebih lanjut, metode pengukuran akurasi diberikan, peningkatan akurasi peramalan perubahan harga. Secara keseluruhan, berbagai parameter tidak terlalu ketat, hanya untuk referensi. Ada harga tengah yang lebih akurat, kemudian harga tengah diterapkan secara praktis untuk di-re-measurement, bagian ini juga memiliki banyak konten, sebelum menunda pembaruan untuk sementara waktu.


Lebih banyak

mztcoin"Mengharukan" karena diselingi isak tangis (khususnya pada orang dewasa).

LouisSiapa yang mengerti?

xukittyYang tinggi dan yang rendah.