Type/to search
3
Follow
1505
Followers
Мысли о стратегиях высокочастотной торговли (4)
HFT
Created 2023-08-08 22:31:47  Updated 2023-09-18 19:51:25
 3
 3172

img

В предыдущей статье был изучен интервал поступления заказов и показано, почему нам необходимо динамически корректировать параметры и как оценить качество оценки. В этой статье основное внимание будет уделено подробным данным и изучению средней цены (также называемой справедливой ценой, микроценой и т. д.).

Данные о глубине

Binance предоставляет возможность загрузки исторических данных о лучших котировках, включая best_bid_price: лучшую цену спроса, т. е. максимальную цену спроса, best_bid_qty: номер лучшей цены спроса, best_ask_price: лучшую цену спроса, best_ask_qty: номер лучшей цены спроса , transaction_time: временная метка. Эти данные не включают в себя отложенные ордера второго уровня и более глубокие. Анализируемая здесь рыночная ситуация относится к YGG на 7 августа. Колебания рынка в тот день были очень резкими, а объем данных достиг более 9 миллионов.

Сначала давайте посмотрим на рынок дня. Он имеет большие взлеты и падения. Кроме того, количество отложенных ордеров в день также сильно изменилось с колебаниями рынка. В частности, спред (разница между цена продажи и цена покупки) в значительной степени продемонстрировали колебательную ситуацию на рынке. Согласно статистике рынка YGG в тот день, в 20% случаев спред был больше 1 тика. В эту эпоху, когда на рынке конкурируют различные роботы, такая ситуация встречается редко.

python
from datetime import date,datetime import time import pandas as pd import numpy as np import matplotlib.pyplot as plt %matplotlib inline
python
books = pd.read_csv('YGGUSDT-bookTicker-2023-08-07.csv')
python
tick_size = 0.0001
python
books['date'] = pd.to_datetime(books['transaction_time'], unit='ms') books.index = books['date']
python
books['spread'] = round(books['best_ask_price'] - books['best_bid_price'],4)
python
books['best_bid_price'][::10].plot(figsize=(10,5),grid=True);

img

python
books['best_bid_qty'][::10].rolling(10000).mean().plot(figsize=(10,5),grid=True); books['best_ask_qty'][::10].rolling(10000).mean().plot(figsize=(10,5),grid=True);

img

python
(books['spread'][::10]/tick_size).rolling(10000).mean().plot(figsize=(10,5),grid=True);

img

python
books['spread'].value_counts()[books['spread'].value_counts()>500]/books['spread'].value_counts().sum()
0.0001 0.799169 0.0002 0.102750 0.0003 0.042472 0.0004 0.022821 0.0005 0.012792 0.0006 0.007350 0.0007 0.004376 0.0008 0.002712 0.0009 0.001657 0.0010 0.001089 0.0011 0.000740 0.0012 0.000496 0.0013 0.000380 0.0014 0.000258 0.0015 0.000197 0.0016 0.000140 0.0017 0.000112 0.0018 0.000088 0.0019 0.000063 Name: spread, dtype: float64

Несбалансированные котировки

Из вышесказанного видно, что объемы заказов на покупку и продажу в большинстве случаев сильно различаются. Эта разница имеет сильный предсказательный эффект на краткосрочные рыночные условия. Причина аналогична причине, упомянутой в предыдущей статье: небольшие ордера на покупку часто приводят к снижению. Если отложенные ордера на одной стороне значительно меньше, чем на другой стороне, и если предположить, что объемы активных ордеров на покупку и продажу близки, то сторона с меньшими отложенными ордерами, скорее всего, будет поглощена, тем самым двигая цену. изменения. Несбалансированные котировки обозначены как I:
img
Где Q_b представляет собой объем ордера на покупку (best_bid_qty), а Q_a представляет собой объем ордера на продажу (best_ask_qty).

Определить среднюю цену: img

На следующем рисунке показана взаимосвязь между скоростью изменения средней цены в следующем интервале и дисбалансом I. Как и ожидалось, по мере увеличения I цена, скорее всего, вырастет, и чем ближе она к 1, тем больше величина дисбаланса. Изменение цен также ускоряется. В высокочастотной торговле целью введения средней цены является лучшее прогнозирование будущих изменений цен. Другими словами, чем меньше разница с будущей ценой, тем лучше определяется средняя цена. Очевидно, что дисбаланс отложенных ордеров дает дополнительную информацию для прогноза стратегии. Учитывая это, определяем средневзвешенную цену:
img

python
books['I'] = books['best_bid_qty'] / (books['best_bid_qty'] + books['best_ask_qty'])
python
books['mid_price'] = (books['best_ask_price'] + books['best_bid_price'])/2
python
bins = np.linspace(0, 1, 51) books['I_bins'] = pd.cut(books['I'], bins, labels=bins[1:]) books['price_change'] = (books['mid_price'].pct_change()/tick_size).shift(-1) avg_change = books.groupby('I_bins')['price_change'].mean() plt.figure(figsize=(8,5)) plt.plot(avg_change) plt.xlabel('I Value Range') plt.ylabel('Average Mid Price Change Rate'); plt.grid(True)

img

python
books['weighted_mid_price'] = books['mid_price'] + books['spread']*books['I']/2 bins = np.linspace(-1, 1, 51) books['I_bins'] = pd.cut(books['I'], bins, labels=bins[1:]) books['weighted_price_change'] = (books['weighted_mid_price'].pct_change()/tick_size).shift(-1) avg_change = books.groupby('I_bins')['weighted_price_change'].mean() plt.figure(figsize=(8,5)) plt.plot(avg_change) plt.xlabel('I Value Range') plt.ylabel('Weighted Average Mid Price Change Rate'); plt.grid(True)

img

Скорректировать средневзвешенную цену

Из рисунка видно, что средневзвешенная цена изменяется гораздо меньше, чем разность I, а это значит, что средневзвешенная цена подходит лучше. Но все же есть некоторые закономерности, например, около 0,2 и 0,8, где отклонения относительно велики. Это показывает, что я все еще могу предоставить дополнительную информацию. Поскольку взвешенная средняя цена предполагает, что срок коррекции цены полностью линейный с I, это, очевидно, не так. Как видно из приведенного выше рисунка, когда I близко к 0 и 1, отклонение происходит быстрее и это не линейная зависимость.

Для более интуитивного взгляда I переопределено здесь:

img

в это время:

img

Наблюдая эту форму, мы можем обнаружить, что взвешенная средняя цена является поправкой к средней средней цене. Коэффициент поправочного члена — это Spread, а поправочный член является функцией I. Взвешенная средняя цена просто предполагает, что это отношение равно I/2. В это время проявляется преимущество скорректированного распределения I (-1,1). I симметрично относительно начала координат, что делает удобным для нас поиск подходящего соотношения функции. Обратите внимание на график, эта функция должна удовлетворять отношению нечетной степени I, что согласуется с быстрым ростом с обеих сторон и симметрией относительно начала координат. Кроме того, можно заметить, что значение вблизи начала координат близко к линейному, и когда I равно 0, результат функции равен 0, а когда I равно 1, результат функции равен 0,5. Итак, предположим, эта функция выглядит так:

img

Здесь N — положительное четное число. После реальных испытаний лучше, когда N равно 8. На данный момент в данной статье предлагается пересмотренная средневзвешенная цена:

img

На данный момент изменение прогнозируемой средней цены по сути не имеет ничего общего с I. Хотя этот результат лучше, чем простая взвешенная средняя цена, его нельзя применять в реальной торговле. Это всего лишь идея, приведенная здесь. В статье С. Стойкова 2017 года был представлен метод цепей Маркова.Micro-Price, и дает соответствующий код, вы также можете его изучить.

python
books['I'] = (books['best_bid_qty'] - books['best_ask_qty']) / (books['best_bid_qty'] + books['best_ask_qty'])
python
books['weighted_mid_price'] = books['mid_price'] + books['spread']*books['I']/2 bins = np.linspace(-1, 1, 51) books['I_bins'] = pd.cut(books['I'], bins, labels=bins[1:]) books['weighted_price_change'] = (books['weighted_mid_price'].pct_change()/tick_size).shift(-1) avg_change = books.groupby('I_bins')['weighted_price_change'].sum() plt.figure(figsize=(8,5)) plt.plot(avg_change) plt.xlabel('I Value Range') plt.ylabel('Weighted Average Mid Price Change Rate'); plt.grid(True)

img

python
books['adjust_mid_price'] = books['mid_price'] + books['spread']*(books['I'])*(books['I']**8+1)/4 bins = np.linspace(-1, 1, 51) books['I_bins'] = pd.cut(books['I'], bins, labels=bins[1:]) books['adjust_mid_price'] = (books['adjust_mid_price'].pct_change()/tick_size).shift(-1) avg_change = books.groupby('I_bins')['adjust_mid_price'].sum() plt.figure(figsize=(8,5)) plt.plot(avg_change) plt.xlabel('I Value Range') plt.ylabel('Weighted Average Mid Price Change Rate'); plt.grid(True)

img

python
books['adjust_mid_price'] = books['mid_price'] + books['spread']*(books['I']**3)/2 bins = np.linspace(-1, 1, 51) books['I_bins'] = pd.cut(books['I'], bins, labels=bins[1:]) books['adjust_mid_price'] = (books['adjust_mid_price'].pct_change()/tick_size).shift(-1) avg_change = books.groupby('I_bins')['adjust_mid_price'].sum() plt.figure(figsize=(8,5)) plt.plot(avg_change) plt.xlabel('I Value Range') plt.ylabel('Weighted Average Mid Price Change Rate'); plt.grid(True)

img

Подвести итог

Средняя цена очень важна для высокочастотных стратегий. Это прогноз будущих краткосрочных цен, поэтому средняя цена должна быть максимально точной. Все представленные выше средние цены основаны на рыночных данных, поскольку в анализе используется только одна рыночная цена. В реальной торговле стратегия должна максимально использовать все данные, особенно при наличии торговых обменов в реальной торговле, а прогноз средней цены должен быть проверен фактической ценой сделки. Я помню, что Стойков, кажется, опубликовал твит, в котором говорилось, что реальная средняя цена должна быть средневзвешенной вероятностью сделки «купи-продай». Этот вопрос как раз изучался в предыдущей статье. Из-за ограниченного объема эти вопросы будут подробно рассмотрены в следующей статье.

Related Recommendations
Comment
All comments (3)

    '高频交易中,引入中间价的目的是为了更好的预测未来价格的变化,也就是和未来的价格差异越小,中间价就定义的越好'。感谢草神的高品质文章
    有一点搞不明白,您光说了预测中间价的重要性,但是没说预测中间价怎么应用?
    我的理解是,用aggtrade冲击价格可能扫到的盘口深度作为开仓价格,而把预测中间价作为开仓后的平仓价格。这个理解对吗?请草神指教指教

    a month ago

    已经卷的看不懂了

    3 years ago

    牛逼!

    3 years ago
  • 1
iPhone Download
Forums
PINE Language
© 2015 - ∞ INVENTOR PTE LTD (SG)