El artículo anterior demostró la necesidad de ajustar dinámicamente los parámetros y cómo evaluar la calidad de las estimaciones mediante el estudio de los intervalos de llegada de pedidos.
Binance proporciona descargas de datos históricos para best_bid_price (el precio de compra más alto), best_bid_quantity (la cantidad al mejor precio de oferta), best_ask_price (el precio de venta más bajo), best_ask_quantity (la cantidad al mejor precio de venta) y transaction_time. Estos datos no incluyen los niveles de libro de pedidos segundos o más profundos. El análisis en este artículo se basa en el mercado YGG el 7 de agosto, que experimentó una volatilidad significativa con más de 9 millones de puntos de datos.
Primero, echemos un vistazo a las condiciones del mercado ese día. Hubo grandes fluctuaciones, y el volumen de la cartera de pedidos cambió significativamente junto con la volatilidad del mercado. El spread, en particular, indicó el alcance de las fluctuaciones del mercado, que es la diferencia entre los mejores precios de compra y venta. En las estadísticas del mercado YGG ese día, el spread fue mayor que un tick por el 20% del tiempo. En esta era de varios bots comerciales que compiten en la cartera de pedidos, tales situaciones se están volviendo cada vez más raras.
En [1]:
from datetime import date,datetime
import time
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
En [2]:
books = pd.read_csv('YGGUSDT-bookTicker-2023-08-07.csv')
En [3]:
tick_size = 0.0001
En [4]:
books['date'] = pd.to_datetime(books['transaction_time'], unit='ms')
books.index = books['date']
En [5]:
books['spread'] = round(books['best_ask_price'] - books['best_bid_price'],4)
En [6]:
books['best_bid_price'][::10].plot(figsize=(10,5),grid=True);
Fuera de juego[6]:
En [7]:
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);
Fuera[7]:
En [8]:
(books['spread'][::10]/tick_size).rolling(10000).mean().plot(figsize=(10,5),grid=True);
Fuera[8]:
En [9]:
books['spread'].value_counts()[books['spread'].value_counts()>500]/books['spread'].value_counts().sum()
Fuera[9]:
Las cotizaciones desequilibradas se observan a partir de la diferencia significativa en el volumen del libro de pedidos entre las órdenes de compra y venta la mayor parte del tiempo. Esta diferencia tiene un fuerte efecto predictivo en las tendencias del mercado a corto plazo, similar a la razón mencionada anteriormente de que una disminución en el volumen de pedidos de compra a menudo conduce a una disminución. Si un lado del libro de pedidos es significativamente más pequeño que el otro, asumiendo que las órdenes de compra y venta activas son similares en volumen, existe una mayor probabilidad de que el lado más pequeño se consuma, lo que impulsa los cambios de precios.
Donde Q_b representa el importe de las órdenes de compra pendientes (best_bid_qty) y Q_a representa el importe de las órdenes de venta pendientes (best_ask_qty).
Define el precio medio:
El siguiente gráfico muestra la relación entre la tasa de cambio del precio medio durante el siguiente intervalo de 1 y el desequilibrio I. Como se espera, cuanto más probable es que el precio aumente a medida que I aumenta y cuanto más se acerca a 1, más se acelera el cambio de precio. En el comercio de alta frecuencia, la introducción del precio intermedio es para predecir mejor los cambios futuros de precios, es decir, y la diferencia de precio futura es menor, cuanto mejor se define el precio intermedio. Obviamente, el desequilibrio de las órdenes pendientes proporciona información adicional para la predicción de la estrategia, teniendo esto en cuenta, definiendo el precio medio ponderado:
En el [10]:
books['I'] = books['best_bid_qty'] / (books['best_bid_qty'] + books['best_ask_qty'])
En [11]:
books['mid_price'] = (books['best_ask_price'] + books['best_bid_price'])/2
En [12]:
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)
Fuera [12]:
En [13]:
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)
Fuera[13]:
Desde el gráfico, se puede observar que el precio medio ponderado muestra variaciones más pequeñas en comparación con diferentes valores de I, lo que indica que es un mejor ajuste. Sin embargo, todavía hay algunas desviaciones, particularmente alrededor de 0.2 y 0.8. Esto sugiere que todavía brindo información adicional. La suposición de una relación completamente lineal entre el término de corrección de precios e I, como lo implica el precio medio ponderado, no se alinea con la realidad. Se puede ver desde el gráfico que la velocidad de desviación aumenta cuando me acerco a 0 y 1, lo que indica una relación no lineal.
Para proporcionar una representación más intuitiva, aquí hay una redefinición de I:
Definición revisada de I:
En este punto:
Al observar, se puede notar que el precio medio ponderado es una corrección al precio medio medio, donde el término de corrección se multiplica por el spread. El término de corrección es una función de I, y el precio medio ponderado asume una relación simple de I/2. En este caso, la ventaja de la distribución I ajustada (-1, 1) se hace evidente, ya que I es simétrica alrededor del origen, lo que hace que sea conveniente encontrar una relación adecuada para la función. Al examinar la gráfica, parece que esta función debe satisfacer potencias de I, ya que se alinea con el rápido crecimiento en ambos lados impares y la simetría del origen. Además, se puede observar que los valores cercanos al origen son cercanos a la lineal. Además, cuando I es 0, el resultado de la función es 0, y cuando I es 1, el resultado es 0.5.
Aquí N es un número par positivo, después de las pruebas reales, es mejor cuando N es 8.
En este punto, la predicción de los cambios de precio medio ya no está significativamente relacionada con I. Aunque este resultado es ligeramente mejor que el precio medio ponderado simple, todavía no es aplicable en escenarios comerciales reales. Este es solo un enfoque propuesto.Micro-precioEl método de la cadena de Markov se presenta con el código relacionado, y los investigadores pueden explorar más este método.
En [14]:
books['I'] = (books['best_bid_qty'] - books['best_ask_qty']) / (books['best_bid_qty'] + books['best_ask_qty'])
En [15]:
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)
Fuera [1]:
En [16]:
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'].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)
Fuera [1]:
El precio medio es crucial para las estrategias de alta frecuencia, ya que sirve como una predicción de los precios futuros a corto plazo. Por lo tanto, es importante que el precio medio sea lo más preciso posible. Los enfoques de precio medio discutidos anteriormente se basan en los datos del libro de pedidos, ya que solo se utiliza el nivel superior del libro de pedidos en el análisis. En el comercio en vivo, las estrategias deben tener como objetivo utilizar todos los datos disponibles, incluidos los datos comerciales, para validar las predicciones de precio medio contra los precios reales de las transacciones.