ہائی فریکوئنسی ٹریڈنگ کی حکمت عملی کے بارے میں سوچنا (5)

مصنف:گھاس, تخلیق: 2023-08-09 18:13:16, تازہ کاری: 2023-09-18 19:51:59

img

پچھلے مضمون میں مختلف درمیانی قیمتوں کے حساب کتاب کے طریقوں کا ابتدائی تعارف کیا گیا تھا اور درمیانی قیمتوں پر ایک نظر ثانی کی گئی تھی ، اس مضمون میں اس موضوع پر مزید گہرائی میں جانا ہے۔

مطلوبہ اعداد و شمار

آرڈر کے بہاؤ کے اعداد و شمار اور دسیوں کی گہرائی کے اعداد و شمار ، حقیقی ڈسک سے جمع کیے گئے ہیں ، اور اپ ڈیٹ کی تعدد 100ms ہے۔ حقیقی ڈسک میں صرف خرید و فروخت کی ایک ڈسک پر مشتمل اعداد و شمار کو حقیقی وقت میں اپ ڈیٹ کیا جاتا ہے ، تاکہ یہ مختصر ہو ، عارضی طور پر استعمال نہ ہو۔ اعداد و شمار کو بہت بڑا سمجھنے کے ل only ، صرف 100،000 لائنوں کی گہرائی کے اعداد و شمار کو برقرار رکھا گیا ہے ، اور ہر ڈسک کو الگ الگ کالموں میں الگ الگ رکھا گیا ہے۔

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

سب سے پہلے ان 20 فائلوں کی مارکیٹ کی تقسیم کو دیکھیں ، جو توقع کے مطابق ہے ، جو فاصلے پر ہیں ، عام طور پر زیادہ سے زیادہ شیڈول ہوتے ہیں ، اور خریداری کی شیڈول اور فروخت کی شیڈول تقریبا متوازن ہیں۔

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

گہرائی کے اعداد و شمار اور لین دین کے اعداد و شمار کو جوڑ کر پیش گوئی کی درستگی کا اندازہ لگانا آسان ہے۔ یہاں اس بات کا یقین کیا جاتا ہے کہ لین دین کے اعداد و شمار گہرائی کے اعداد و شمار سے پیچھے ہیں ، بغیر کسی تاخیر کے ، براہ راست پیش گوئی کی قیمت اور اصل لین دین کی قیمت کے درمیان اوسط غلطی کا حساب لگایا جاتا ہے۔ پیشن گوئی کی درستگی کی پیمائش کے لئے استعمال کیا جاتا ہے۔

نتیجے کے طور پر ، خرید و فروخت کی اوسط قیمت mid_price کی غلطی سب سے بڑی ہے ، weight_mid_price میں تبدیل ہونے کے بعد ، غلطی فوری طور پر بہت چھوٹی ہوگئی ، اور وزن میں اضافے کے ساتھ درمیانی قیمت کو ایڈجسٹ کرنے سے تھوڑا سا بہتر ہوا۔ کل کے مضمون کے بعد ، کسی نے صرف I ^ 3 / 2 کے ساتھ رائے دی ، یہاں چیک کیا ، اور نتیجہ بہتر نکلا ہے۔ اس کی وجہ یہ ہے کہ واقعات کی تعدد میں فرق ہونا چاہئے ، I قریب -1 اور 1 میں کم امکانات کا واقعہ ہے ، تاکہ ان کم امکانات کو درست کیا جاسکے ، لیکن اعلی تعدد کے واقعات کی پیش گوئی کرنے کے لئے کم درست ہے ، لہذا ، اعلی تعدد کے واقعات کی دیکھ بھال کے ساتھ ، میں نے پھر سے ایڈجسٹ کیا:

img

اس کے نتیجے میں کچھ بہتر ہوا ہے۔ پچھلے مضمون میں کہا گیا ہے کہ حکمت عملی کو زیادہ سے زیادہ اعداد و شمار کے ساتھ پیش گوئی کرنی چاہئے ، اور زیادہ گہرائی اور آرڈر ٹرانزیکشن ڈیٹا کے ساتھ ، اس میں الجھن اور ڈسکاؤنٹ سے فائدہ اٹھانا بہت کم ہے۔

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

دوسری گہرائی پر غور کریں

یہاں ایک خیال ہے کہ کسی پیرامیٹر پر اثر انداز ہونے والے مختلف قیمتوں کا جائزہ لینے کے ل the ، تجارت کی قیمت میں تبدیلی اس پیرامیٹر کی انٹرمیڈیٹ قیمت میں شراکت کا اندازہ لگانے کے لئے ہے۔ مثال کے طور پر ، گہرائی کا پہلا گراف ، جیسے ہی I بڑھتا ہے ، تجارت کی قیمت میں اضافہ ہوتا ہے ، اس کے بعد تجارت کی قیمت میں زیادہ امکان ہوتا ہے ، اس سے پتہ چلتا ہے کہ I نے مثبت شراکت کی ہے۔

دوسری گائیڈ کو اسی طرح سے سنبھالا گیا ، اور یہ پتہ چلا کہ اگرچہ اثر پہلے گائیڈ سے تھوڑا سا چھوٹا ہے ، لیکن اس کو نظرانداز نہیں کیا جاسکتا ہے۔ تیسری گائیڈ کی گہرائی میں بھی کمزور شراکت ہے ، لیکن یکسانیت بہت خراب ہے ، اور گہری گہرائی میں بنیادی طور پر کوئی حوالہ قیمت نہیں ہے۔

ان تینوں درجہ بندیوں میں عدم توازن کے پیرامیٹرز کو مختلف وزن میں تقسیم کیا گیا ہے ، جو شراکت کی مختلف سطحوں پر منحصر ہے ، اور اصل جانچ پڑتال مختلف حساب کے طریقوں کے لئے پیش گوئی کی غلطی میں مزید کمی ہے۔

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

ٹرانزیکشن ڈیٹا پر غور کریں

ٹرانزیکشن ڈیٹا براہ راست زیادہ خالی جگہوں کی سطح کی عکاسی کرتا ہے، کیونکہ یہ حقیقی سونے اور چاندی کی شرکت کا انتخاب ہے، اور اس کی لاگت بہت کم ہے، یہاں تک کہ یہاں تک کہ جان بوجھ کر ٹرانزیکشن کی دھوکہ دہی کی صورت حال بھی ہے. لہذا، انٹرمیڈیٹ کی قیمت کی پیشن گوئی، حکمت عملی کو ٹرانزیکشن ڈیٹا پر توجہ دینا چاہئے.

شکل کو مدنظر رکھتے ہوئے ، آرڈر کی اوسط آمد کی تعداد کو غیر متوازن VI ، Vb ، VS کے طور پر بیان کیا گیا ہے جو خرید اور فروخت کے احکامات کے یونٹ واقعات میں اوسط تعداد ہے۔

img

نتائج سے پتہ چلتا ہے کہ مختصر مدت میں آنے والی تعداد قیمتوں میں تبدیلی کی پیشن گوئی پر سب سے زیادہ نمایاں ہے ، جب VI 0.1-0.9 کے درمیان ہے تو ، یہ قیمتوں کے ساتھ منفی سے متعلق ہے ، جبکہ اس کے بجائے اس کی حد سے باہر تیزی سے مثبت ہے۔ اس سے پتہ چلتا ہے کہ جب مارکیٹ انتہائی نہیں ہوتی ہے تو ، اس میں ہلچل ہوتی ہے ، قیمتیں یکساں ہوجاتی ہیں ، جب انتہائی مارکیٹ ہوتی ہے ، جیسے بہت سارے خرید و فروخت کے احکامات ، اس وقت یہ رجحان سے باہر ہوجاتا ہے۔ یہاں تک کہ اگر ان کم امکانات کی صورتحال کو مدنظر نہ رکھا جائے تو ، سادہ مفروضہ یہ ہے کہ رجحان اور VI منفی لکیری تعلقات کو پورا کرتے ہیں تو ، درمیانی قیمت کی پیشن گوئی میں غلطی کا فرق بھی نمایاں طور پر کم ہوجاتا ہے۔

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

جامع درمیانی قیمت

چونکہ منسلک مقدار اور ٹرانزیکشن ڈیٹا دونوں ہی درمیانی قیمت کی پیش گوئی میں مددگار ہیں ، لہذا دونوں پیرامیٹرز کو ایک ساتھ جوڑا جاسکتا ہے ، جہاں وزن کی تفویض نسبتا random بے ترتیب ہے ، اور حدود کی شرائط کو مدنظر نہیں رکھا جاتا ہے۔ انتہائی صورت میں ، پیش گوئی کی جانے والی درمیانی قیمت خرید و فروخت کے درمیان نہیں ہوسکتی ہے ، لیکن جب تک کہ غلطی کو کم کیا جاسکے ، ان تفصیلات کی پرواہ نہیں کی جاسکتی ہے۔

آخر میں پیش گوئی کی غلطی 0.00487 سے 0.0043 تک گر گئی ، یہاں مزید گہرائی میں جانے کی ضرورت نہیں ہے ، درمیانی قیمتوں میں کھدائی کرنے کے لئے بہت کچھ باقی ہے ، آخر میں ، پیش گوئی کی درمیانی قیمت پیش گوئی کی قیمتوں میں ہے ، آپ اپنے آپ کو آزما سکتے ہیں۔

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

خلاصہ

اس مضمون میں گہرائی کے اعداد و شمار اور ٹرانزیکشن کے اعداد و شمار کے ساتھ مل کر ، درمیانی قیمتوں کے حساب کتاب کے طریقہ کار کو مزید بہتر بنایا گیا ہے ، جس میں قیمتوں میں تبدیلی کی پیشن گوئی کی درستگی کو بہتر بنانے کے لئے درستگی کی پیمائش کرنے کا طریقہ دیا گیا ہے۔ مجموعی طور پر مختلف پیرامیٹرز زیادہ سخت نہیں ہیں ، صرف حوالہ کے لئے ہیں۔ زیادہ درست درمیانی قیمتیں ہیں ، اس کے بعد عملی طور پر درمیانی قیمتوں کا استعمال کیا جاتا ہے ، اس حصے میں بھی بہت کچھ ہے ، پہلے کچھ وقت کے لئے اپ ڈیٹ کریں۔


مزید

mztcoinNext articleپاکستان میں ہنگامہ آرائی کا سلسلہ جاری

لوئسکون سمجھتا ہے

چوکٹیاور نہ بیوائیں اور نہ بوڑھے