Tư duy về chiến lược giao dịch tần số cao (5)

Tác giả:Cỏ nhỏ, Tạo: 2023-08-09 18:13:16, Cập nhật: 2023-09-18 19:51:59

img

Bài trước đã giới thiệu sơ bộ các phương pháp tính toán giá trung gian khác nhau và đưa ra một sửa đổi về giá trung gian, bài này tiếp tục nghiên cứu sâu hơn về chủ đề này.

Dữ liệu cần thiết

Dữ liệu lưu lượng đơn đặt hàng và dữ liệu độ sâu mười đĩa, đến từ thu thập đĩa thực, cập nhật tần suất là 100ms. Các đĩa thực chỉ chứa dữ liệu mua bán một đĩa được cập nhật trong thời gian thực, để ngắn gọn, tạm thời không cần thiết. Nhận xét dữ liệu quá lớn, chỉ giữ lại 100.000 dòng dữ liệu độ sâu và tách từng đĩa thành các cột riêng biệt.

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

Trước tiên, hãy xem sự phân bố của 20 hồ sơ thị trường, phù hợp với dự kiến, khoảng cách giao dịch càng xa, thông thường sẽ có nhiều đơn đặt hàng, và đơn đặt hàng và đơn đặt hàng bán hàng gần như đối xứng.

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

Kết hợp dữ liệu độ sâu và dữ liệu giao dịch để đánh giá độ chính xác của dự đoán. Điều này đảm bảo dữ liệu giao dịch là sau dữ liệu độ sâu, và tính toán trực tiếp giá trị dự đoán với sai số trung bình của giá giao dịch thực tế mà không tính đến sự chậm trễ.

Kết quả cho thấy, sai số trung bình bán mua là lớn nhất, sau khi thay đổi thành weight_mid_price, sai số ngay lập tức nhỏ hơn rất nhiều, cải thiện một chút bằng cách điều chỉnh giá trung bình tăng cân. Sau bài viết hôm qua, một số người đã phản hồi chỉ bằng I ^ 3 / 2, sau khi phát hành bài viết hôm qua, chúng tôi đã kiểm tra và tìm thấy kết quả tốt hơn.

img

Kết quả cũng khá tốt hơn một chút. Bài viết trước đã nói rằng chiến lược nên dự đoán với nhiều dữ liệu hơn, trong khi có nhiều độ sâu hơn và dữ liệu giao dịch đơn hàng, sự phức tạp và sự gia tăng có thể đạt được đã rất yếu.

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

Xem xét độ sâu thứ hai

Một ý tưởng ở đây là xem xét phạm vi giá trị khác nhau ảnh hưởng đến một tham số, thay đổi giá giao dịch để đo sự đóng góp của tham số này vào giá trung gian. Ví dụ như biểu đồ độ sâu lớp một, khi giá giao dịch tăng lên, giá giao dịch sau đó có thể thay đổi theo hướng tích cực, điều này cho thấy I đã đóng góp tích cực.

Giai đoạn thứ hai được xử lý theo cách tương tự và thấy rằng mặc dù hiệu ứng nhỏ hơn một chút so với giai đoạn đầu tiên, nhưng không thể bỏ qua.

Theo mức độ đóng góp khác nhau, các tham số không cân bằng của ba lớp được phân bổ trọng lượng khác nhau, kiểm tra thực tế cho các phương pháp tính toán khác nhau, sai số dự đoán giảm hơn nữa.

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

Xem xét dữ liệu giao dịch

Dữ liệu giao dịch phản ánh trực tiếp mức độ trống rỗng, sau khi tất cả, đây là sự tham gia của vàng và bạc thực sự, trong khi chi phí đặt hàng thấp hơn nhiều, thậm chí còn có tình huống lừa đảo đặt hàng có chủ ý. Do đó, dự đoán giá trung gian, chiến lược phải tập trung vào dữ liệu giao dịch.

Với hình thức, xác định số lượng đến trung bình của đơn đặt hàng không cân bằng VI, Vb và Vs, tương ứng là số lượng trung bình trong các sự kiện đơn vị của đơn đặt hàng mua và bán.

img

Kết quả cho thấy số lượng người đến trong thời gian ngắn có ý nghĩa nhất đối với dự đoán thay đổi giá, khi VI nằm trong khoảng từ 0.1-0.9, có liên quan tiêu cực đến giá, nhưng ngoài phạm vi này là liên quan tích cực nhanh chóng đến giá. Điều này cho thấy giá sẽ trở lại bình đẳng khi thị trường không cực đoan, chủ yếu là biến động, và khi thị trường cực đoan xuất hiện, chẳng hạn như một số lượng lớn đơn đặt hàng quá nhiều, khi đó sẽ ra khỏi xu hướng. Ngay cả khi không tính đến những tình huống có khả năng thấp này, giả định đơn giản rằng xu hướng và VI đáp ứng mối quan hệ tuyến tính tiêu cực, chênh lệch dự đoán giá trung gian giảm đáng kể.

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

Giá trung gian tổng hợp

Vì cả số lượng đơn hàng và dữ liệu giao dịch đều hữu ích cho dự đoán giá trung gian, nên có thể kết hợp hai tham số này với nhau, nơi việc gán trọng lượng là khá ngẫu nhiên và không xem xét các điều kiện biên giới, trong trường hợp cực đoan, giá trung gian dự đoán có thể không nằm giữa mua và bán, nhưng miễn là sai số có thể được giảm thiểu, không quan tâm đến các chi tiết này.

Điều này có nghĩa là giá trung gian có thể được khai thác nhiều hơn, sau khi tất cả các giá trung gian dự đoán là trong giá dự đoán, bạn có thể tự mình thử.

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

Tóm lại

Bài viết này kết hợp dữ liệu sâu và dữ liệu giao dịch, cải thiện thêm phương pháp tính toán giá trung gian, đưa ra phương pháp đo lường độ chính xác, nâng cao độ chính xác của dự đoán thay đổi giá. Nhìn chung, các tham số khác nhau không quá nghiêm ngặt, chỉ để tham khảo. Có giá trung gian chính xác hơn, sau đó là giá trung gian thực tế được sử dụng để đánh giá lại, phần này cũng có nhiều nội dung, trước khi tạm dừng cập nhật một thời gian.


Thêm nữa

mztcoinĐồ cỏ quá lớn, mong đợi bản cập nhật tiếp theo

LouisAi có thể hiểu?

xukittyNhững người cao tuổi và những người nghèo,