Réflexion sur les stratégies de trading à haute fréquence (3)

Auteur:Le foin, Créé à partir de: 2023-08-07 18:17:28, Mis à jour à partir de: 2023-09-18 19:50:53

img

Dans l'article précédent, j'ai expliqué comment modéliser le volume cumulé des transactions et comment analyser simplement les chocs de prix. Cet article se concentrera sur les données des ordres de transactions.

Les délais de commande

En général, on suppose que l'heure d'arrivée de l'ordre est conforme au processus de partage.Le processus de BarthèsJe vais vous le prouver ci-dessous.

Le téléchargement de l'aggTrades du 5 août, avec un total de 1931.193 transactions, est très exagéré. Tout d'abord, en regardant la distribution des paiements, on peut voir un pic local peu lisse autour de 100 ms et 500 ms, qui devrait être causé par le calendrier robot mis en place par l'iceberg, ce qui pourrait être l'une des raisons de l'anomalie du jour.

La fonction de masse de probabilité (PMF) de la distribution de Parsons est donnée par la formule suivante:

img

Parmi eux:

  • k est le nombre d'événements qui nous intéressent.
  • λ est la fréquence moyenne d'événements en unité de temps (ou espace unitaire).
  • P ((k; λ) indique la probabilité que k événements se produisent par hasard, sous une condition donnée de l'incidence moyenne λ.

Dans le processus de Parason, l'intervalle de temps entre les événements est soumis à une distribution indicielle. La fonction de densité de probabilité de la distribution indicielle (PDF) est donnée par la formule suivante:

img

En combinant les résultats et la distribution de Parsons, on constate une différence plus grande que ce qui est attendu, le processus de Parsons sous-estime la fréquence des temps d'intervalle longs et surestime la fréquence des temps d'intervalle bas.

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('YGGUSDT-aggTrades-2023-08-05.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']
buy_trades['interval'][buy_trades['interval']<1000].plot.hist(bins=200,figsize=(10, 5));

img

Intervals = np.array(range(0, 1000, 5))
mean_intervals = buy_trades['interval'].mean()
buy_rates = 1000/mean_intervals
probabilities = np.array([np.mean(buy_trades['interval'] > interval)  for interval in Intervals])
probabilities_s = np.array([np.e**(-buy_rates*interval/1000) for interval in Intervals])

plt.figure(figsize=(10, 5))
plt.plot(Intervals, probabilities)
plt.plot(Intervals, probabilities_s)
plt.xlabel('Intervals')
plt.ylabel('Probability')
plt.grid(True)

img

La distribution de la fréquence des commandes dans les 1s est comparée à la distribution de Parsons, où les différences sont également très évidentes. La distribution de Parsons sous-estime de manière significative la fréquence des événements à faible probabilité.

  • Incidence inconstante: le processus de Parsons suppose que l'incidence moyenne des événements sur une période donnée est constante. Si cette hypothèse n'est pas vraie, la distribution des données est déviée par rapport à la distribution de Parsons.
  • Interaction des processus: Une autre hypothèse fondamentale du processus de Parsons est que les événements sont indépendants entre eux. Si les événements dans le monde réel s'interagissent, leur distribution peut être déviée de la distribution de Parsons.

C'est-à-dire que, dans un environnement réel, la fréquence d'ordre n'est pas constante, nécessite des mises à jour en temps réel, et qu'il y a une incitation, c'est-à-dire que plus d'ordres dans un temps fixe stimulent plus d'ordres.

result_df = buy_trades.resample('0.1S').agg({ 
    'price': 'count',
    'quantity': 'sum'
}).rename(columns={'price': 'order_count', 'quantity': 'quantity_sum'})
count_df = result_df['order_count'].value_counts().sort_index()[result_df['order_count'].value_counts()>20]
(count_df/count_df.sum()).plot(figsize=(10,5),grid=True,label='sample pmf');

from scipy.stats import poisson
prob_values = poisson.pmf(count_df.index, 1000/mean_intervals) 

plt.plot(count_df.index, prob_values,label='poisson pmf');
plt.legend() ;

img

Mettre à jour les paramètres en temps réel

L'analyse des intervalles d'ordres précédents permet de conclure que les paramètres fixes ne sont pas adaptés aux marchés réels et que les paramètres clés de la description du marché de la stratégie doivent être mis à jour en temps réel. La solution la plus facile à penser est la moyenne mobile des fenêtres coulissantes. Les deux graphiques suivants sont respectivement la moyenne de la fréquence des paiements en 1s et la moyenne de l'erreur absolue du résidu pour 1000 fenêtres de transactions.

On peut également comprendre sur le graphique pourquoi la fréquence des commandes s'écarte si fortement de la distribution de Parsons, alors que la moyenne de la quantité d'ordres par seconde est de seulement 8,5 fois, mais que la moyenne des commandes par seconde dans les cas extrêmes s'écarte beaucoup.

Il s'avère que l'erreur de décalage est la plus faible et bien meilleure que la simple moyenne des deux premières secondes.

result_df['order_count'][::10].rolling(1000).mean().plot(figsize=(10,5),grid=True);

img

result_df
Compte de commandes quantité_somme
2023-08-05 03:30:06.100 1 76.0
2023-08-05 03:30:06.200 0 0.0
2023-08-05 03:30:06.300 0 0.0
2023-08-05 03:30:06.400 1 416.0
2023-08-05 03:30:06.500 0 0.0
2023-08-05 23:59:59.500 3 9238.0
2023-08-05 23:59:59.600 0 0.0
2023-08-05 23:59:59.700 1 3981.0
2023-08-05 23:59:59.800 0 0.0
2023-08-05 23:59:59.900 2 534.0
result_df['quantity_sum'].rolling(1000).mean().plot(figsize=(10,5),grid=True);

img

(result_df['order_count'] - result_df['mean_count'].mean()).abs().mean()
6.985628185332997
result_df['mean_count'] = result_df['order_count'].ewm(alpha=0.11, adjust=False).mean()
(result_df['order_count'] - result_df['mean_count'].shift()).abs().mean()
0.6727616961866929
result_df['mean_quantity'] = result_df['quantity_sum'].ewm(alpha=0.1, adjust=False).mean()
(result_df['quantity_sum'] - result_df['mean_quantity'].shift()).abs().mean()
4180.171479076811

Résumé

Cet article présente brièvement les raisons pour lesquelles le processus de décalage des intervalles de temps des commandes se produit, principalement parce que les paramètres changent au fil du temps. Pour prédire le marché plus précisément, les stratégies nécessitent des prévisions en temps réel sur les paramètres de base du marché. On peut mesurer le bien et le mal des prévisions avec des résidus.


Plus de