یہ مضمون بنیادی طور پر ہائی فریکوئینسی ٹریڈنگ کی حکمت عملیوں کا جائزہ لیتا ہے، جس میں مجموعی طور پر ٹرانزیکشن ماڈلنگ اور قیمت کے جھٹکے پر توجہ دی جاتی ہے۔ یہ مضمون ایک ہی ٹرانزیکشن، مقررہ وقفے پر قیمت کے جھٹکے اور قیمت پر ٹرانزیکشن کے اثرات کا تجزیہ کرتے ہوئے ایک ابتدائی بہترین ہاپنگ پوزیشن ماڈل پیش کرتا ہے۔ یہ ماڈل ٹرانزیکشن کی مقدار اور قیمت کے جھٹکے کی تفہیم پر مبنی ہے اور بہترین ٹرانزیکشن پوزیشن تلاش کرنے کی کوشش کرتا ہے۔ ماڈل کے مفروضوں پر گہرائی سے تبادلہ خیال کیا جاتا ہے اور ماڈل کی پیش گوئی کے ساتھ حقیقی منافع کی توقع کے مقابلے میں بہترین ہاپنگ پوزیشن کا ابتدائی جائزہ لیا جاتا ہے۔
پچھلی پوسٹ میں ہم نے ایک ہی ٹرانزیکشن کے امکان کا اظہار کیا ہے جس کی تعداد کسی قدر سے زیادہ ہے:
ہم ایک وقت کے دوران ٹرانزیکشن کی تعداد کی تقسیم کے بارے میں بھی فکر مند ہیں، اور یہ بدیہی طور پر ہر ٹرانزیکشن اور آرڈر کی تعدد سے متعلق ہونا چاہئے. ذیل میں اعداد و شمار کو مقررہ وقفے کے مطابق عملدرآمد کیا گیا ہے.
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']
ہر 1s کے وقفے کے ساتھ ٹرانزیکشنز کو جمع کرکے ٹرانزیکشنز کی مقدار میں شامل کریں ، غیر منقولہ حصے کو ہٹا دیں ، اور اوپر دیئے گئے ایک ہی ٹرانزیکشن کی تقسیم کے مطابق بنائیں ، آپ کو بہتر نتائج ملتے ہیں ، 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]
buy_trades
agg_trade_id | قیمت | مقدار | پہلا_ٹریڈ_آئی ڈی | last_trade_id | is_buyer_maker | تاریخ | ٹرانزیکشن_ٹائم | وقفہ | مختلف | |
---|---|---|---|---|---|---|---|---|---|---|
2023-01-27 00:00:00.161 | 1138369 | 2.901 | 54.3 | 3806199 | 3806201 | غلط | 2023-01-27 00:00:00.161 | 1674777600161 | NaN | 0.001 |
2023-01-27 00:00:04.140 | 1138370 | 2.901 | 291.3 | 3806202 | 3806203 | غلط | 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 | غلط | 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 | غلط | 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 | غلط | 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 | غلط | 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 | غلط | 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 | غلط | 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 | غلط | 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 | غلط | 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)
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)
اب مختلف وقت کی مجموعی ٹرانزیکشنز کی تقسیم کے لئے ایک عام فارمولا کا خلاصہ کریں ، اور ہر بار الگ الگ اعدادوشمار کے بغیر ایک ہی ٹرانزیکشن کی تقسیم کے ساتھ فٹ بیٹھیں ؛ یہاں عمل کو چھوڑ دیں ، براہ راست فارمولا دیں:
جہاں avg_interval ایک ہی ٹرانزیکشن کے اوسط وقفے کو ظاہر کرتا ہے، اور avg_interval_T اندازہ لگانے کے لئے درکار وقفے کے اوسط وقفے کو ظاہر کرتا ہے، یہ کہتے ہوئے تھوڑا سا گھومتا ہے۔ اگر ہم 1s کی تکمیل کا اندازہ لگانا چاہتے ہیں تو ، اعدادوشمار 1s میں شامل ہونے والے ٹرانزیکشن کے واقعات کے اوسط وقفے کی ضرورت ہوتی ہے۔ اگر آرڈر کی آمد کا امکان پارسن کی تقسیم کے مطابق ہے تو ، یہاں براہ راست اندازہ لگایا جاسکتا ہے ، لیکن اصل انحراف بہت بڑا ہے ، یہاں وضاحت نہیں کی جائے گی۔
نوٹ کریں کہ یہاں کسی وقفے کے دوران تجارت کا امکان ایک مخصوص قیمت سے زیادہ ہے اور حقیقت میں گہرائی میں اس مقام پر تجارت کا امکان بہت زیادہ فرق ہونا چاہئے ، کیونکہ جب انتظار کا وقت زیادہ ہوتا ہے تو ، آرڈر لسٹ میں تبدیلی کا امکان زیادہ ہوتا ہے ، اور تجارت میں بھی گہرائی میں تبدیلی آتی ہے ، لہذا اسی گہرائی کی جگہ پر تجارت کا امکان اعداد و شمار کی تازہ کاری کے ساتھ حقیقی وقت میں بدلتا ہے۔
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)
ٹرانزیکشن ڈیٹا ایک خزانہ ہے ، اور کھودنے کے لئے بہت سارے اعداد و شمار موجود ہیں۔ ہمیں آرڈر کی قیمت پر اثر انداز ہونے پر بہت زیادہ توجہ دینی چاہئے ، جس سے حکمت عملی کی فہرست بندی کی پوزیشن پر اثر پڑتا ہے۔ اسی طرح ٹرانزیکٹ ٹائم کے مجموعی اعداد و شمار کے مطابق ، آخری قیمت اور پہلی قیمت کے فرق کا حساب لگائیں ، اگر صرف ایک ہی آرڈر ہے تو ، فرق 0 ہے۔ عجیب بات یہ ہے کہ اعداد و شمار کی ایک چھوٹی سی تعداد بھی منفی ہے ، جو اعداد و شمار کی ترتیب کے سلسلے کا مسئلہ ہونا چاہئے ، یہاں گہرائی نہیں ہے۔
نتائج سے پتہ چلتا ہے کہ بغیر کسی جھٹکے کا تناسب 77 فیصد تک ہے ، ایک ٹک کا تناسب 16.5 فیصد ، دو ٹک کا تناسب 3.7 فیصد ، تین ٹک کا تناسب 1.2 فیصد ، اور چار سے زیادہ ٹک کا تناسب 1 فیصد سے بھی کم ہے۔ یہ بنیادی طور پر اشاریاتی فنکشن کی خصوصیات کے مطابق ہے ، لیکن فٹ ہونے کی درستگی نہیں ہے۔
اعداد و شمار کے مطابق قیمتوں میں فرق پیدا کرنے والی ٹرانزیکشن کی مقدار کو ہٹا دیا گیا ہے ، جس میں بہت زیادہ جھٹکا ہے ، بنیادی طور پر لکیری تعلقات کے مطابق ، تقریبا ہر 1000 مقدار میں قیمت میں 1 ٹک کی اتار چڑھاؤ پیدا ہوتا ہے۔ یہ بھی سمجھا جاسکتا ہے کہ ہر ڈش کے قریب قیمتوں میں اوسطا تقریبا 1000 کی تعداد ہے۔
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);
اعداد و شمار 2s کے اندر قیمتوں میں جھٹکا ، یہاں مختلف ہے کہ منفی ہو جائے گا ، یقینا یہاں صرف ادائیگیوں کا حساب لگایا گیا ہے ، لہذا ہم آہنگی کی پوزیشن ایک ٹک بڑی ہوگی۔ تجارت اور جھٹکے کے تعلقات کو دیکھتے ہوئے ، صرف اعداد و شمار کا نتیجہ 0 سے زیادہ ہے ، نتیجہ اور انفرادی آرڈر تقریبا ، تقریبا line لکیری تعلقات ہیں ، ہر ٹک کو تقریبا 2000 کی مقدار کی ضرورت ہے۔
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));
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);
اس سے پہلے ایک ٹک تبدیلی کے لئے درکار ٹرانزیکشن کی مقدار کی تلاش کی گئی تھی ، لیکن یہ درست نہیں ہے ، کیونکہ یہ اس صورت میں قائم ہے جب یہ فرض کیا جاتا ہے کہ دھچکا واقع ہوچکا ہے۔ اب اس کے برعکس ، ٹرانزیکشن کے ذریعہ آنے والے قیمت کے دھچکے کو دیکھنا ہے۔
یہاں اعداد و شمار کو 1s کے مطابق نمونہ کیا گیا ہے ، ہر 100 مقدار میں ایک قدم کی لمبائی ، اور اس مقدار میں قیمتوں میں ہونے والے تبدیلیوں کا اعدادوشمار کیا گیا ہے۔ کچھ قابل قدر نتائج اخذ کیے گئے ہیں:
ان میں سے،
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)
grouped_df.head(10)
مقدار_گروپ | قیمت_فرق | quantity_group_center | |
---|---|---|---|
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 |
ٹرانزیکشنز کی مقدار اور ٹرانزیکشنز کے مطابق قیمتوں کے اثرات کے لئے موٹے ماڈل کے ساتھ ، یہ معلوم ہوتا ہے کہ بہترین ہونگ لسٹنگ پوزیشن کا حساب لگایا جاسکتا ہے۔ شاید کچھ مفروضے کیے جائیں ، پہلے ایک غیر ذمہ دارانہ بہترین قیمت کی پوزیشن دی جائے۔
پہلے ایک سادہ متوقع واپسی لکھیں، یعنی 1s میں مجموعی طور پر ادائیگی کا امکان Q سے بڑا ہے، متوقع واپسی کی شرح سے ضرب (یعنی جھٹکا کی قیمت):
تصویر کے مطابق، متوقع منافع زیادہ سے زیادہ تقریباً 2500 میں ہے، جو کہ اوسط ٹرانزیکشن کی تعداد سے 2.5 گنا زیادہ ہے۔ یعنی، فروخت کے احکامات کو 2500 کی پوزیشن پر لٹکا دیا جانا چاہئے۔ ایک بار پھر اس بات پر زور دینا ضروری ہے کہ اسقاط حمل کے اندر تجارت کی مقدار 1s کی نمائندگی کرتی ہے، یہ صرف گہرائی کی پوزیشن کے برابر نہیں ہو سکتی۔ اور یہ اس وقت بھی اہم گہرائی کے اعداد و شمار کی کمی کے وقت ہے، صرف تجارت پر مبنی قیاس آرائیاں۔
مختلف وقت وقفے پر ٹرانزیکشن تقسیم کا پتہ لگانے کے بارے میں ایک ٹرانزیکشن کی تقسیم کا ایک سادہ پیمانہ ہے۔ قیمت کے جھٹکے اور ٹرانزیکشن کی امکانات پر مبنی ایک سادہ متوقع آمدنی کا ماڈل بھی بنایا گیا ہے ، جس کا نتیجہ ہماری توقعات کے مطابق ہے ، اگر فروخت کی تعداد چھوٹی ہے ، جس سے قیمت میں کمی کا اشارہ ہوتا ہے تو ، منافع بخش جگہ کے ل a ایک خاص مقدار کی ضرورت ہوتی ہے ، اور ٹرانزیکشن کی تعداد زیادہ ہے تو ، امکانات کم ہوتے ہیں ، درمیان میں ایک زیادہ سے زیادہ سائز ہوتا ہے ، اور حکمت عملی تلاش کرنے کے لئے ایک لٹکی ہوئی پوزیشن بھی ہوتی ہے۔ یقینا یہ ماڈل بہت آسان ہے ، اگلے مضمون میں ، میں مزید گہرائی میں بات کروں گا۔
#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)
اوک کوانٹائزیشن 🐂🍺