Stratégie de haute fréquence de la monnaie numérique Introduction détaillée

Auteur:Je ne sais pas., Créé à: 2023-03-27 16:46:14, Mis à jour à: 2023-09-18 20:12:59

img

Stratégie de haute fréquence de la monnaie numérique Introduction détaillée

J'ai écrit un article en 2020 présentant des stratégies à haute fréquence,https://www.fmz.com/bbs-topic/9750. Bien qu'il ait reçu un peu d'attention, il n'a pas été très en profondeur. Plus de deux ans se sont écoulés depuis lors, et le marché a changé. Après la publication de cet article, ma stratégie à haute fréquence a pu générer des profits stables pendant longtemps, mais progressivement, les profits ont diminué et ont même cessé à un moment donné. Au cours des derniers mois, j'ai déployé quelques efforts pour la rénover, et maintenant elle peut encore générer des profits. Dans cet article, je vais fournir une introduction plus détaillée de mes idées de stratégie à haute fréquence et un code simplifié comme point de départ pour les communications; et les commentaires sont les bienvenus.

Conditions de négociation à haute fréquence

  • Bien sûr, les frais des preneurs sont toujours basés sur des taux VIP, donc si la stratégie ne nécessite pas de preneurs, le niveau VIP a peu d'impact sur les stratégies à haute fréquence. Différents niveaux d'échanges ont généralement des taux de rabais différents et nécessitent de maintenir un montant de transaction élevé. Au début, lorsque certains marchés de devises fluctuaient considérablement, il y avait des profits même sans rabais.

  • La vitesse. La raison pour laquelle les stratégies à haute fréquence sont appelées à haute fréquence est parce qu'elles sont très rapides. Joindre le serveur de colo de l'échange, obtenir la plus faible latence et la connexion la plus stable est également devenue l'une des conditions de la concurrence interne. Le temps de consommation interne de la stratégie devrait être le moins possible, et cet article présentera le framework websocket que j'utilise, qui adopte l'exécution simultanée.

  • Marché approprié. Le trading à haute fréquence est connu comme la perle du trading quantitatif, et de nombreux traders programmatiques l'ont essayé, mais la plupart des gens ont arrêté parce qu'ils ne peuvent pas faire de profit et ne peuvent pas trouver une direction pour l'amélioration. La raison principale devrait être qu'ils ont choisi le mauvais marché de trading. Au stade initial du développement de la stratégie, des marchés relativement faciles devraient être choisis pour réaliser des profits dans le trading afin qu'il y ait des profits et des commentaires pour l'amélioration, ce qui est propice à la progression de la stratégie. Si vous commencez à rivaliser sur le marché le plus compétitif avec de nombreux adversaires potentiels, peu importe à quel point vous essayez, vous perdrez de l'argent et abandonnez bientôt. Je recommande les paires de trading de contrats perpétuels nouvellement cotés quand il n'y a pas autant de concurrents, en particulier ceux avec un montant de transaction relativement important; c'est à ce moment-là que les profits sont les plus faciles.

  • Face à la concurrence. Le marché pour toute transaction est en constante évolution, et aucune stratégie de trading ne peut durer éternellement, en particulier dans le trading à haute fréquence. Entrer sur ce marché signifie concurrencer directement les traders les plus intelligents et les plus diligents. Dans un marché de jeu à somme nulle, plus vous gagnez, moins les autres gagneront. Plus vous entrez tard, plus la difficulté est élevée; ceux qui sont déjà sur le marché doivent également s'améliorer continuellement. Il y a 3-4 ans, c'était probablement la meilleure opportunité; récemment, l'activité globale sur les marchés de la monnaie numérique a diminué, ce qui rend très difficile pour les nouveaux arrivants de commencer le trading à haute fréquence maintenant.

Principe de haute fréquence

Il existe différentes stratégies de haute fréquence:

  • La couverture à haute fréquence, c'est-à-dire la recherche d'opportunités de couverture par l'intermédiaire de cette bourse ou d'autres bourses, en s'appuyant sur l'avantage de la vitesse pour saisir des ordres et réaliser des bénéfices;
  • tendance à haute fréquence, réalisant des bénéfices en évaluant les tendances à court terme;
  • Créateur de marché, plaçant des ordres sur les deux côtés de l'achat et de la vente, contrôlant bien les positions et réalisant des bénéfices grâce aux remises;
  • Il y en a beaucoup d'autres que je ne vais pas énumérer une par une. Ma stratégie est une combinaison de tendance et de market maker. D'abord, nous jugons la tendance, puis nous passons une commande. Après la transaction est terminée, passer un ordre immédiatement à vendre sans détenir des positions d'inventaire. Ensuite, je vais l'introduire en conjonction avec le code de stratégie.

Cadre stratégique

Le code suivant est basé sur le cadre de base des contrats perpétuels de Binance, souscrivant principalement à la profondeur du websocket, aux données de marché des transactions de flux d'ordres de profondeur et aux informations de position. Puisque les données de marché et les informations de compte sont souscrites séparément, il est nécessaire d'utiliser read ((-1) en continu pour déterminer si les dernières informations ont été obtenues. Ici, EventLoop ((1000) est utilisé pour éviter les boucles sans fin directes et réduire la charge du système. EventLoop ((1000) bloquera jusqu'à ce qu'il y ait des retours de tâches wss ou simultanés avec un temps d'arrêt de 1000 ms.

var datastream = null
var tickerstream = null
var update_listenKey_time = 0

function ConncetWss(){
    if (Date.now() - update_listenKey_time < 50*60*1000) {
        return
    }
    if(datastream || tickerstream){
        datastream.close()
        tickerstream.close()
    }
    //Need APIKEY
    let req = HttpQuery(Base+'/fapi/v1/listenKey', {method: 'POST',data: ''}, null, 'X-MBX-APIKEY:' + APIKEY) 
    let listenKey = JSON.parse(req).listenKey
    datastream = Dial("wss://fstream.binance.com/ws/" + listenKey + '|reconnect=true', 60)
    //Symbols are the set trading pairs
    let trade_symbols_string = Symbols.toLowerCase().split(',')
    let wss_url = "wss://fstream.binance.com/stream?streams="+trade_symbols_string.join(Quote.toLowerCase()+"@aggTrade/")+Quote.toLowerCase()+"@aggTrade/"+trade_symbols_string.join(Quote.toLowerCase()+"@depth20@100ms/")+Quote.toLowerCase()+"@depth20@100ms"
    tickerstream = Dial(wss_url+"|reconnect=true", 60)
    update_listenKey_time = Date.now()
}

function ReadWss(){
    let data = datastream.read(-1)
    let ticker = tickerstream.read(-1)
    while(data){
        data = JSON.parse(data)
        if (data.e == 'ACCOUNT_UPDATE') {
            updateWsPosition(data)
        }
        if (data.e == 'ORDER_TRADE_UPDATE'){
            updateWsOrder(data)
        }        
        data = datastream.read(-1)
    }
    while(ticker){
        ticker = JSON.parse(ticker).data
        if(ticker.e == 'aggTrade'){
            updateWsTrades(ticker)
        }
        if(ticker.e == 'depthUpdate'){
            updateWsDepth(ticker)
        }
        ticker = tickerstream.read(-1)
    }
    makerOrder()
}

function main() {
    while(true){
        ConncetWss()
        ReadWss()
        worker()
        updateStatus()
        EventLoop(1000)
    }
}

Indicateurs stratégiques

Comme mentionné précédemment, ma stratégie à haute fréquence nécessite de déterminer la tendance avant d'exécuter l'achat et la vente. La tendance à court terme est principalement jugée sur la base des données de transaction tick-by-tick, c'est-à-dire de l'aggTrade dans l'abonnement, qui comprend la direction de la transaction, le prix, la quantité, le temps de transaction, etc. L'achat et la vente se réfèrent principalement à la profondeur et au montant des transactions. Voici des introductions détaillées des indicateurs à prendre en compte; la plupart d'entre eux sont divisés en groupes d'achat et de vente et sont comptés dynamiquement dans une certaine fenêtre de temps.

  • Le montant moyen de la transaction par transaction, par transaction commerciale est la collection d'ordres différents avec la même direction et le même prix dans un délai de 100 ms, reflétant la taille des ordres d'achat et de vente.
  • La fréquence de commande ou l'intervalle de commande, elle est également basée sur les données transaction par transaction, le montant moyen de transaction mentionné précédemment ne prend pas en compte le concept de temps et n'est pas tout à fait précis. Si un ordre dans une direction a un petit montant moyen de transaction mais une fréquence élevée, il contribue toujours à la force de ce sens. Le montant moyen de transaction * la fréquence de commande représente le montant total de transaction à intervalles fixes et peut être utilisé pour la comparaison directe.
  • L'écart moyen, c'est relativement facile à comprendre, c'est-à-dire vendre un moins acheter un. Le marché actuel a généralement un écart de 1 tick. Si l'écart devient plus grand, cela signifie souvent qu'il y a une tendance du marché.
  • Le prix moyen d'achat et de vente, calculer le prix moyen de chaque transaction séparément, et le comparer avec le dernier prix.

La logique de la stratégie

Déterminer l'évolution à court terme

//bull represents short-term bullish, bear represents short-term bearish
let bull =  last_sell_price > avg_sell_price && last_buy_price > avg_buy_price &&
            avg_buy_amount / avg_buy_time > avg_sell_amount / avg_sell_time;
let bear =  last_sell_price < avg_sell_price && last_buy_price < avg_buy_price && 
            avg_buy_amount / avg_buy_time < avg_sell_amount / avg_sell_time;

Si le prix de vente le plus récent est supérieur au prix de vente moyen, le prix d'achat le plus récent est supérieur au prix d'achat moyen et la valeur de l'ordre d'achat à intervalles fixes est supérieure à la valeur de l'ordre de vente, alors il est jugé haussier à court terme.

Prix des commandes

function updatePrice(depth, bid_amount, ask_amount) {

    let buy_price = 0
    let sell_price = 0
    let acc_bid_amount = 0
    let acc_ask_amount = 0

    for (let i = 0; i < Math.min(depth.asks.length, depth.bids.length); i++) {
        acc_bid_amount += parseFloat(depth.bids[i][1])
        acc_ask_amount += parseFloat(depth.asks[i][1])
        if (acc_bid_amount > bid_amount  && buy_price == 0) {
            buy_price = parseFloat(depth.bids[i][0]) + tick_size
        }
        if (acc_ask_amount > ask_amount  && sell_price == 0) {
            sell_price = parseFloat(depth.asks[i][0]) - tick_size
        }
        if (buy_price > 0 && sell_price > 0) {
            break
        }
    }
    return [buy_price, sell_price]
}

Ici, nous adoptons toujours l'ancienne approche, en itérant à la profondeur requise. En supposant que 10 pièces peuvent être échangées en 1 seconde, sans tenir compte de nouveaux ordres en attente, le prix de vente est fixé à la position où 10 pièces sont achetées. La taille spécifique de la fenêtre de temps doit être définie par vous-même.

Montant de la commande

let buy_amount = Ratio * avg_sell_amount / avg_sell_time
let sell_amount = Ratio * avg_buy_amount / avg_buy_time

Le ratio représente une proportion fixe, ce qui signifie que la quantité d'ordre d'achat est une proportion fixe de la quantité récente d'ordre de vente.

Conditions relatives à l'ordre de placement

if(bull && (sell_price-buy_price) > N * avg_diff) {
    trade('buy', buy_price, buy_amount)
}else if(position.amount < 0){
    trade('buy', buy_price, -position.amount)
}
if(bear && (sell_price-buy_price) >  N * avg_diff) {
    trade('sell', sell_price, sell_amount)
}else if(position.amount > 0){
    trade('sell', sell_price, position.amount)
}

où avg_diff est la différence moyenne de prix du marché, et un ordre d'achat ne sera placé que lorsque l'écart offre-demande est supérieur à un certain multiple de cette valeur et qu'il est haussier. Si vous maintenez une position courte, il fermera également la position pour éviter de la maintenir pendant une période prolongée. Les ordres peuvent être placés en tant qu'ordres de fabricant unique pour s'assurer qu'ils sont exécutés. En outre, l'ID d'ordre personnalisé de Binance peut être utilisé afin qu'il n'y ait pas besoin d'attendre la réponse de l'ordre.

Structure concomitante

var tasks = []
var jobs = []

function worker(){
    let new_jobs = []
    for(let i=0; i<tasks.length; i++){
        let task = tasks[i]
        jobs.push(exchange.Go.apply(this, task.param))
    }
    _.each(jobs, function(t){
        let ret = t.wait(-1)
        if(ret === undefined){
            new_jobs.push(t)//Unreturned tasks will continue to wait next time
        }
    })
    jobs = new_jobs
    tasks = []
}

/*
Write the required task parameters in param
tasks.push({'type':'order','param': ["IO", "api", "POST","/fapi/v1/order",
        "symbol="+symbol+Quote+"&side="+side+"&type=LIMIT&timeInForce=GTX&quantity="+
        amount+"&price="+price+"&newClientOrderId=" + UUID() +"&timestamp="+Date.now()]})
*/

Données surveillées

  • Le délai, l'importance de la vitesse de la stratégie à haute fréquence a été soulignée. Dans la stratégie, divers retards doivent être surveillés et enregistrés, tels que la passation d'ordres, l'annulation d'ordres, les rendements de position, la profondeur, le flux d'ordres, les positions, les boucles globales, etc. Tous les retards anormaux doivent être étudiés à temps et essayer de raccourcir le délai global de stratégie.
  • Ratio de montant de la transaction, calculer le montant de la transaction en pourcentage du montant total de la transaction. Si le ratio est faible, il y a encore de la place pour la croissance.
  • Taux de profit des positions de clôture, le calcul du taux de profit moyen de la position de clôture est la référence la plus importante pour juger si une stratégie est efficace.
  • Le ratio de remise, la proportion de remises dans le chiffre d'affaires total, reflète le degré de dépendance à l'égard des remises par la stratégie.
  • Le taux d'échec de la commande, les ordres ne sont négociés qu'en plaçant un ordre. En raison du retard dans la mise en place d'un ordre, il peut ne pas être placé. Si ce ratio est élevé, cela signifie que la vitesse de la stratégie n'est pas avantageuse.
  • La proportion d'ordres exécutés, les plateformes ont souvent des exigences pour le taux de transaction.
  • La distance moyenne entre les ordres d'achat et de vente, qui reflète la stratégie de placement des ordres et l'écart entre le marché, nous pouvons voir que la plupart d'entre eux occupent encore la position d'acheter un et de vendre un.

Autres suggestions

  • La stratégie de haute fréquence dans cet article ne fait référence qu'à un seul échange, une seule monnaie et un seul marché. Elle a de grandes limitations et la plupart des situations et des devises ne peuvent pas générer de bénéfices. Cependant, il est impossible de prédire quelle devise sera rentable à l'avenir, vous pouvez donc échanger plusieurs ou même toutes les devises sans manquer d'opportunités. Même sous la limite de fréquence des échanges, un robot peut échanger plusieurs paires de trading. Bien sûr, pour une vitesse optimale, un sous-compte peut échanger une paire de trading avec un serveur correspondant à un robot; cependant, cela entraînerait des coûts beaucoup plus élevés.
  • Déterminez la quantité de commande et les conditions de commande en fonction du rendement. Le trading avec plusieurs devises entraînera un coût élevé des tentatives, si la surveillance n'est pas rentable, utilisez le montant minimum de la transaction et réduisez la fréquence de négociation jusqu'à ce que la stratégie surveille dynamiquement un taux de rendement positif, puis augmentez le montant de la transaction pour améliorer les rendements progressivement.
  • Obtenez plus d'informations, une autre caractéristique du trading à haute fréquence est qu'il traite une plus grande quantité de données et utilise plus d'informations. Toutes les informations de marché pour une seule paire de négociation au sein d'un seul échange doivent être référencées, et les contrats perpétuels peuvent également se référer aux données du marché au comptant, ainsi qu'aux données d'autres échanges pour la même paire de négociation, ou même des données d'autres devises. Plus il y a de données, plus l'avantage correspondant est grand. Par exemple, Binance peut souscrire aux meilleures informations d'ordre en attente par Symbol, car le temps de poussée le plus court pour la profondeur et le flux d'ordres est de 100 ms; seulement cela est en temps réel et très précieux pour les stratégies à haute fréquence.
  • Le serveur de Binance est situé à Tokyo, les serveurs des autres bourses varient, vous pouvez consulter le personnel technique de l'échange pour plus de détails.
  • Le code de stratégie dans cet article n'est qu'un exemple de code simplifié, avec de nombreux détails encombrants mais nécessaires supprimés. Les indicateurs utilisés sont uniquement à titre de référence et ne doivent pas être utilisés directement.

Relationnée

Plus de