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

Auteur:Le foin, Créé à partir de: 2023-08-03 16:14:16, mis à jour à partir de: 2023-12-08 16:37:21

img

L'article explore les stratégies de négociation à haute fréquence de la crypto-monnaie, y compris les sources de profit (principalement les fortes fluctuations du marché et les frais de transaction des bourses), les problèmes de contrôle des positions et des positions, ainsi que les méthodes de modélisation de la transaction avec la distribution Pareto. En outre, il cite les données de transaction individuelles et les meilleures commandes à haute fréquence fournies par Binance pour le retouche, et il est prévu de discuter en profondeur d'autres questions de stratégie de négociation à haute fréquence dans les articles suivants.

J'ai écrit deux articles précédents sur les transactions à haute fréquence en crypto-monnaie.Introduction détaillée à la stratégie de haute fréquence des crypto-monnaies, 5 antennes 80 fois plus puissantes que les stratégies de haute fréquenceCette fois-ci, j'ai l'intention d'écrire une série d'articles qui présentent l'idée du trading haute fréquence dès le début, en espérant être aussi concise que possible, mais en raison de mon niveau personnel limité, la compréhension du trading haute fréquence n'est pas très profonde.

Les sources de profits à haute fréquence

Dans les articles précédents, nous avons mentionné que les stratégies à haute fréquence sont particulièrement adaptées aux marchés où les fluctuations sont très fortes. Examinons les variétés de transactions qui changent de prix dans un court laps de temps, composées de tendances globales et de bouleversements. Bien sûr, nous pouvons gagner de l'argent si nous pouvons prédire avec précision les changements de tendance, mais c'est aussi le plus difficile.

Les problèmes à résoudre

1.策略同时挂买单和卖单,第一个问题就是在哪里挂单。挂的离盘口越近,成交的概率越高,但在剧烈波动的行情中,瞬间成交的价格可能离盘口较远,挂的那太近没有能吃到足够的利润。挂的太远的单子成交概率又低。这是一个需要优化的问题。

2.控制仓位。为了控制风险,策略就不能长时间累计过多的仓位。可以通过控制挂单距离、挂单量、总仓位限制等办法解决。

Pour atteindre les objectifs ci-dessus, il est nécessaire de modéliser les estimations sur de nombreux aspects tels que la probabilité de transaction, les bénéfices des transactions, les estimations de marché. De nombreux articles et articles sur ce sujet peuvent être trouvés dans des mots-clés tels que High-Frequency Trading, Orderbook. Il y a beaucoup de recommandations en ligne, mais pas ici. Il est également préférable d'établir un système de rétroévaluation rapide et fiable.

Les données requises

Binance fournit des données sur les transactions individuelles et les meilleures commandes en attente.TéléchargerLes données de profondeur doivent être téléchargées à l'API de la liste blanche et peuvent également être collectées par vous-même. Les données de transaction peuvent être utilisées pour l'attribution de données de transaction.

from datetime import date,datetime
import time
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

Les transactions individuelles sont les suivantes:

  1. agg_trade_id: l'identifiant de la transaction qui est intégrée,
  2. prix: le prix de l'opération
  3. quantité: le nombre de transactions effectuées
  4. first_trade_id: l'ensemble des transactions peut avoir plusieurs transactions simultanées, et ne comporte qu'une seule statistique, qui est l'id de la première transaction
  5. Last_trade_id: l'id de la dernière opération effectuée
  6. transact_time: heure de fin de transaction
  7. is_buyer_maker: Direction de transaction, True représente le acheteur-acheteur, le vendeur est le preneur

Vous pouvez voir qu'il y a eu 660 000 transactions ce jour-là et que les transactions sont très actives.

trades = pd.read_csv('COMPUSDT-aggTrades-2023-07-02.csv')
trades

664475 lignes × 7 colonnes

Nom de l'entreprise prix quantité première_échange_id dernière_échange_id Temps de transaction est_acheteur_fabricant
120719552 52.42 22.087 207862988 207862990 1688256004603 Faux
120719553 52.41 29.314 207862991 207863002 1688256004623 C' est vrai.
120719554 52.42 0.945 207863003 207863003 1688256004678 Faux
120719555 52.41 13.534 207863004 207863006 1688256004680 C' est vrai.
121384024 68.29 10.065 210364899 210364905 1688342399863 Faux
121384025 68.30 7.078 210364906 210364908 1688342399948 Faux
121384026 68.29 7.622 210364909 210364911 1688342399979 C' est vrai.

Modélisation des transactions effectuées en une seule transaction

Les données sont d'abord traitées, en divisant les trades initiaux en groupes de transaction active pour les paiements et en groupes de transaction active pour les ordres de vente. Les données d'agrégation primaire des transactions sont des données à la fois au même prix et dans la même direction, il peut arriver qu'un volume de transaction active soit de 100, si elles sont divisées en plusieurs transactions et à des prix différents, par exemple pour 60 et 40 pièces, deux données sont produites, ce qui affecte l'estimation du volume de transaction.

trades['date'] = pd.to_datetime(trades['transact_time'], unit='ms')
trades.index = trades['date']
buy_trades = trades[trades['is_buyer_maker']==False].copy()
sell_trades = trades[trades['is_buyer_maker']==True].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'
})
sell_trades = sell_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()
sell_trades['interval']=sell_trades['transact_time'] - sell_trades['transact_time'].shift()
print(trades.shape[0] - (buy_trades.shape[0]+sell_trades.shape[0]))
146181

Pour l'exemple des paiements, en traçant une ligne droite, vous pouvez voir l'effet de la queue longue très évident, la plupart des données étant concentrées un peu à gauche, mais aussi une petite quantité de transactions importantes réparties sur la queue.

buy_trades['quantity'].plot.hist(bins=200,figsize=(10, 5));

png

为了观察方便,截掉尾部观察.可以看到成交量越大,出现频率越低,且减少的趋势更快。

buy_trades['quantity'][buy_trades['quantity']<200].plot.hist(bins=200,figsize=(10, 5));

png

La distribution satisfaite par la loi de la puissance, également appelée distribution de Pareto, est une distribution de probabilité courante en physique statistique et en sciences sociales. Dans la distribution de la puissance, la probabilité d'un événement est proportionnelle à un indice négatif de la taille de l'événement. La principale caractéristique de cette distribution est que les événements importants ont une fréquence plus élevée que celle attendue dans de nombreuses autres distributions.

Le graphique ci-dessous indique la probabilité d'une transaction supérieure à une certaine valeur, la ligne bleue est la probabilité réelle, la ligne de curve est la probabilité simulée.

png

où N est un paramètre standardisé. Ici, on choisit la moyenne de transactions M, l'alpha choisit 2.06. L'estimation de l'alpha spécifique peut être calculée en inversant la valeur P lorsque D = N. Plus précisément: alpha = log ((P ((d>M)) /log ((2)).

depths = range(0, 250, 2)
probabilities = np.array([np.mean(buy_trades['quantity'] > depth) for depth in depths])
alpha = np.log(np.mean(buy_trades['quantity'] > mean_quantity))/np.log(2)
mean_quantity = buy_trades['quantity'].mean()
probabilities_s = np.array([(1+depth/mean_quantity)**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)

img

plt.figure(figsize=(10, 5))
plt.grid(True)
plt.title('Diff')
plt.plot(depths, probabilities_s-probabilities);

png

Mais cette estimation ne ressemble qu'à ce que nous avons dessiné ci-dessus, la différence entre la valeur simulée et la valeur réelle. Lorsque les échanges sont plus petits, l'écart est grand, voire proche de 10%. On peut choisir différents points pour rendre la probabilité de ce point plus précise lors de l'estimation des paramètres, mais cela ne résout pas non plus le problème de la déviation.

png

Pour simplifier, le volume de transaction standardisé est représenté par r = q/M. Les paramètres peuvent être estimés de la même manière que ci-dessus. Le graphique ci-dessous montre que l'écart maximal après la correction ne dépasse pas 2%.

depths = range(0, 250, 2)
probabilities = np.array([np.mean(buy_trades['quantity'] > depth) for depth in depths])
mean = buy_trades['quantity'].mean()
alpha = np.log(np.mean(buy_trades['quantity'] > mean))/np.log(2.05)
probabilities_s = np.array([(((1+20**(-depth/mean))*depth+mean)/mean)**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)
plt.figure(figsize=(10, 5))
plt.grid(True)
plt.title('Diff')
plt.plot(depths, probabilities_s-probabilities);

png

Avec les équations d'estimation de la distribution des transactions, l'attention est portée sur la probabilité de l'équation, non pas une probabilité réelle, mais une probabilité conditionnelle. On peut alors répondre à la question: quelle est la probabilité que cette commande soit supérieure à une certaine valeur si le prochain ordre se produit?

J'ai presque fini d'écrire ce billet, mais il y a encore beaucoup de questions à répondre, et la série d'articles qui suit tentera de les répondre.


Plus de

Quantitatif de l'oc 🐂🍺

Je suis zéro.Il est trop fort!

Le foinLe csv est trop grand pour le télécharger.