Berfikir tentang strategi perdagangan frekuensi tinggi (5)

Penulis:Rumput, Dicipta: 2023-08-09 18:13:16, Dikemas kini: 2023-09-18 19:51:59

img

Artikel sebelum ini telah memperkenalkan perbandingan antara pelbagai kaedah pengiraan harga tengah dan memberikan satu pembaharuan kepada harga tengah, yang akan diteruskan dalam topik ini.

Data yang diperlukan

Data aliran pesanan dan data kedalaman sepuluh rak, berasal dari rak sebenar yang dikumpulkan, dan kekerapan kemas kini adalah 100ms. Rak sebenar hanya mengandungi data beli dan jual satu rak yang diperbaharui secara langsung, untuk ringkas, sementara tidak diperlukan. Mengingat data yang terlalu besar, hanya menyimpan 100,000 baris data kedalaman, dan memisahkan setiap rak sebagai barisan yang berasingan.

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, lihatlah pembahagian pasaran 20 fail ini, sesuai dengan jangkaan, jarak yang lebih jauh dari penyerahan, biasanya ada lebih banyak pesanan, dan pesanan pesanan dan pesanan 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 urus niaga untuk menilai ketepatan ramalan. Di sini, data urus niaga dijamin lebih lambat daripada data kedalaman, tanpa mengambil kira kelewatan, secara langsung mengira nilai ramalan dan kesesuaian rata-rata harga urus niaga sebenar. Untuk mengukur ketepatan ramalan.

Hasilnya, kesilapan harga pertengahan jual beli adalah yang terbesar, dan selepas diubah menjadi weight_mid_price, kesilapan itu segera menjadi lebih kecil, dengan penyesuaian harga pertengahan yang ditimbang. Selepas artikel semalam dikeluarkan, ada yang memberi maklum balas hanya dengan I ^ 3 / 2, di sini diperiksa dan mendapati keputusan yang lebih baik.

img

Hasilnya sedikit lebih baik. Artikel sebelumnya mengatakan bahawa strategi harus membuat ramalan dengan lebih banyak data, dan peningkatan yang dapat dicapai dengan peredaran sudah lemah dengan lebih banyak kedalaman dan data transaksi pesanan.

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 idea yang sama, kita melihat pelbagai nilai yang diambil untuk parameter yang mempengaruhi, perubahan harga urus niaga untuk mengukur sumbangan parameter ini kepada harga pertengahan. Sebagai contoh, grafik kedalaman baris pertama menunjukkan bahawa apabila harga urus niaga meningkat, harga urus niaga seterusnya semakin cenderung untuk berubah, ini menunjukkan bahawa saya telah memberikan sumbangan positif.

Garis kedua diproses dengan cara yang sama dan mendapati walaupun kesannya sedikit lebih kecil daripada Garis Pertama, tetapi tidak boleh diabaikan. Garis Ketiga juga memberikan sumbangan yang lemah, tetapi monotonnya jauh lebih buruk, dan kedalaman yang lebih dalam hampir tidak mempunyai nilai rujukan.

Menurut tahap sumbangan yang berbeza, tiga parameter ketidakseimbangan ini diberikan berat yang berbeza, dan kesalahan ramalan dikurangkan lebih lanjut untuk ujian sebenar yang berbeza.

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 urus niaga secara langsung mencerminkan tahap kekosongan, selepas semua ini adalah pilihan untuk melibatkan emas tulen perak, dan kos penyambungan yang jauh lebih rendah, bahkan terdapat kes penipuan penyambungan yang disengajakan. Oleh itu, ramalan harga pertengahan, strategi harus memberi tumpuan kepada data urus niaga.

Memandangkan bentuknya, jumlah pesanan yang mencapai purata tidak seimbang VI, Vb, dan Vs yang dinyatakan sebagai purata dalam kejadian unit pesanan dan pesanan jualan.

img

Hasilnya mendapati bahawa jumlah kedatangan dalam masa yang singkat adalah yang paling ketara terhadap ramalan perubahan harga, apabila VI berada di antara 0.1-0.9, ia berkaitan negatif dengan harga, tetapi di luar julat ia berkaitan positif dengan harga dengan cepat. Ini menunjukkan bahawa harga akan kembali rata apabila pasaran tidak melampau, yang didominasi oleh pergolakan, dan apabila pasaran melampau berlaku, seperti banyak pembelian yang terlalu banyak, ketika ini keluar dari trend. Walaupun tidak mengambil kira keadaan kemungkinan rendah ini, andaian sederhana bahawa trend dan VI memenuhi hubungan linear negatif, perbezaan ramalan terhadap harga pertengahan juga menurun dengan ketara.

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 Pertengahan Kompleks

Memandangkan kedua-dua jumlah pesanan dan data urus niaga membantu untuk meramalkan harga tengah, maka kedua-dua parameter ini boleh digabungkan bersama, di mana pemberian berat badan agak rawak dan tidak mengambil kira keadaan sempadan. Dalam keadaan yang melampau, harga tengah yang diramalkan mungkin tidak antara satu membeli dan satu menjual, tetapi selagi kesilapan dapat dikurangkan, tidak peduli dengan butiran ini.

Kesalahan ramalan akhir turun dari 0.00487 pada mulanya kepada 0.0043, dan di sini tidak boleh terus mendalam, harga pertengahan masih banyak yang boleh digali, selepas semua ramalan harga pertengahan adalah dalam harga ramalan, anda boleh mencuba 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

Ringkasan

Dengan menggabungkan data mendalam dan data transaksi, kaedah pengiraan harga tengah dipertingkatkan lagi, kaedah pengukuran ketepatan diberikan, peningkatan ketepatan ramalan perubahan harga. Secara keseluruhan, pelbagai parameter tidak terlalu ketat, hanya untuk rujukan. Terdapat harga tengah yang lebih tepat, kemudian harga tengah digunakan secara praktikal untuk diukur semula.


Lebih lanjut

mztcoinTerlalu lembu dan menunggu pembaruan seterusnya

LouisSiapa yang faham?

xukitty"Dan tidak pula perempuan-perempuan yang tidak mempunyai anak, melainkan mereka yang memuji".