Les ressources ont été chargées... Je charge...

Introduction à l'arbitrage au retard de plomb dans les crypto-monnaies (3)

Auteur:FMZ~Lydia, Créé: 2024-12-25 16:04:11, mis à jour:

Dans l'article précédent, nous avons introduit l'arbitrage croisé. Dans cet article, nous allons examiner en profondeur comment appliquer l'effet Lead-Lag au trading à haute fréquence, ce qui nécessite de capturer de petites différences de prix en très peu de temps et de réaliser des bénéfices rapidement.

Ce qui suit:une simplification du code publicLe principe de code de cette stratégie originale est très simple et était autrefois très rentable.

Principe de stratégie de haute fréquence de retard de plomb

Le soi-disant Lead-Lag peut être compris comme les prix (ou certains indicateurs) de certains échanges seront plus leading dans les changements globaux du marché, tandis que d'autres échanges ou autres indicateurs seront relativement lagging. Dans cette stratégie, Price_1, Price_2, Price_3 représentent les conditions de marché de différents échanges respectivement. Ce sont des échanges traditionnels. Parce qu'ils sont plus sensibles aux nouvelles du marché, ou que leur profondeur de négociation et les types de participants sont différents, une fois qu'il y a de gros ordres d'achat ou de vente, les prix de ces échanges fluctueront en premier. Les échanges commerciaux réels seront légèrement en retard dans les fluctuations de prix en raison de facteurs tels que les mécanismes de correspondance et les groupes de négociation.

Navigation dans le carnet de commandes multi-échanges

La stratégie obtient des données de carnet de commandes de différentes bourses presque en même temps, telles que le prix d'offre, le prix de vente, le volume d'ordres en attente, etc. Ensuite, le prix moyen (c'est-à-dire la moyenne du prix d'offre et du prix de vente) de différentes bourses est comparé pour en déduire la dynamique du marché.

Jugement du signal de tendance

La stratégie est principalement axée sur les variations de prix de trois bourses externes (okex, binance, huobipro):

Ici, chaque tendance X est déterminée par la différence entre le prix actuel et le prix passé qui dépasse un certain seuil (niveau * augmentation de prix). Après addition des signaux de hausse/baisse des trois bourses, si la tendance globale est supérieure à 0, cela signifie que le marché est généralement en hausse et que la stratégie est d'acheter; si la tendance est inférieure à 0, cela signifie que le marché est généralement en baisse et que la stratégie est de vendre.

Ordonnance et contrôle des risques unidirectionnels

La stratégie n'achète ou vend qu'après la confirmation de la tendance et annule l'ordre précédent avant de placer chaque ordre (c'est-à-dire en évitant les ordres en attente accidentels qui entraînent une accumulation de risques).

En outre, cette stratégie est une stratégie à haute fréquence. Vous n'avez pas besoin de prêter attention au profit ou à la perte de chaque ordre, et vous n'avez pas besoin d'arrêter la perte. Vous pouvez continuer tant qu'il y a une probabilité de réaliser des profits.

Mise en œuvre de la stratégie FMZ

Réglage des paramètres

// Hyperparameter settings
const SYMBOL = "BTC_USDT"; // Trading pair
const PRICE_INCREMENT = 0.1; // Price increment
const LEVEL = 10; // Sensitivity of trend judgment
const RATIO = 10; // Order price adjustment ratio
const INTERVAL = 200; // Time interval (milliseconds)
const S_AMOUNT = 0.02; // Default transaction volume
const MIN_AMOUNT = 0.005; // Minimum transaction volume

// Initial state
let buyOrders = [];
let sellOrders = [];
let previousPrices = [0, 0, 0]; // Store the previous price
let loop = 0;

Logique de base: collecte de données et évaluation des tendances

// Get order book data
function fetchOrderBooks() {
    let orderBooks = [];
    let tasks = [];

    // Start asynchronous order book acquisition tasks for all exchanges
    for (let i = 0; i < exchanges.length; i++) {
        // Assume that each exchange object can call the Go method
        let task = exchanges[i].Go("GetDepth");
        tasks.push({ index: i, task: task });
    }

    // Wait for all tasks to complete and collect results
    for (let i = 0; i < tasks.length; i++) {
        let { index, task } = tasks[i];
        try {
            // Waiting for an asynchronous task to return a result
            let depth = task.wait(1000);

            // Check if the returned data is valid
            if (!depth || !depth.Bids || !depth.Asks) {
                throw new Error("The returned order book data is invalid");
            }

            // Add valid order book data to the result array
            orderBooks[index] = depth;
        } catch (error) {
            // Recording error logs
            Log(`Failed to obtain the order book of exchange ${index}: ${error.message}`);

            // Added default order book data to avoid crashes
            orderBooks[index] = {
                Bids: [[0, 0]],
                Asks: [[0, 0]]
            };
        }
    }

    return orderBooks;
}


// Judge the trends
function calculateTrend(orderBooks) {
    let trends = [];
    for (let i = 0; i < orderBooks.length; i++) {
        const midPrice = (orderBooks[i].Bids[0][0] + orderBooks[i].Asks[0][0]) / 2;
        if (midPrice > previousPrices[i] + LEVEL * PRICE_INCREMENT) {
            trends.push(1); // Upward trend
        } else if (midPrice < previousPrices[i] - LEVEL * PRICE_INCREMENT) {
            trends.push(-1); // Downward trend
        } else {
            trends.push(0); // No significant trend
        }
        previousPrices[i] = midPrice; // Update price record
    }
    return trends.reduce((a, b) => a + b, 0); // Return to overall trend
}

Placement et annulation des ordres

// Cancel all pending orders
function cancelOrders(orders) {
    for (let orderId of orders) {
        try {
            exchanges[0].CancelOrder(orderId); // Use the main exchange by default
            Log(`Cancel order: ${orderId}`);
        } catch (error) {
            Log(`Failed to cancel order: ${error.message}`);
        }
    }
}

// Create a buy order
function createBuyOrder(price, amount) {
    try {
        const orderId = exchanges[0].Buy(price, amount);
        buyOrders.push(orderId);
        Log(`Create a buy order: price ${price}, quantity ${amount}`);
    } catch (error) {
        Log(`Failed to create buy order: ${error.message}`);
    }
}

// Create a sell order
function createSellOrder(price, amount) {
    try {
        const orderId = exchanges[0].Sell(price, amount);
        sellOrders.push(orderId);
        Log(`Create a sell order: price ${price}, quantity ${amount}`);
    } catch (error) {
        Log(`Failed to create sell order: ${error.message}`);
    }
}

Logique de la stratégie principale

function main() {
    while (true) {
        try {
            // Get order book data
            const orderBooks = fetchOrderBooks();

            // Calculate trends
            const trend = calculateTrend(orderBooks);
            Log(`Current trend: ${trend}`);

            // Cancel pending order
            cancelOrders(buyOrders);
            cancelOrders(sellOrders);
            buyOrders = [];
            sellOrders = [];

            // Order based on trends
            if (trend > 0 && loop > 0) {
                const price = _N(orderBooks[0].Bids[0][0] + RATIO * PRICE_INCREMENT, 2);
                const amount = _N(Math.max(S_AMOUNT, MIN_AMOUNT), 4);
                createBuyOrder(price, amount);
            } else if (trend < 0 && loop > 0) {
                const price = _N(orderBooks[0].Asks[0][0] - RATIO * PRICE_INCREMENT, 2);
                const amount = _N(Math.max(S_AMOUNT, MIN_AMOUNT), 4);
                createSellOrder(price, amount);
            }

            // Loop count and interval
            loop++;
            Sleep(INTERVAL);

        } catch (error) {
            Log(`Main logic error: ${error.message}`);
        }
    }
}

Analyse des raisons de l'échec de la stratégie

Les marchés deviennent plus efficaces

Lorsque de plus en plus de stratégies quantitatives ou à haute fréquence sont impliquées et trouvent la même relation Lead-Lag, une grande quantité de fonds éliminera rapidement la différence de prix.

Restrictions de change ou changements de frais

À mesure que la structure des frais des différents échanges change, une fois que les coûts des frais dépassent les bénéfices de l'arbitrage, la rentabilité des stratégies de négociation à haute fréquence sera considérablement réduite.

Dégradation et dérapage de la liquidité

Lorsque le volume du marché est insuffisant, les stratégies à haute fréquence rencontrent souvent un glissement plus grave; ou de gros ordres poussent rapidement les prix à la hausse, ce qui entraîne l'effet de leurs propres ordres sur le "acheter bas et vendre haut" initialement attendu, ce qui entraîne une baisse des rendements.

Variations de la volatilité du marché

Certaines stratégies fonctionnent très bien dans des conditions de "haute volatilité" ou de "période spécifique".

Résumé

Le point clé de la stratégie de négociation à haute fréquence réside dans la capture des prix de plusieurs bourses et le jugement de la synthèse de tendance. Il a réalisé une fois une méthode de négociation d'entrée et de sortie à très haute fréquence et rapide basée sur le principe de Lead-Lag: observer les prix des bourses qui se déplacent en premier, puis pousser les prix des autres bourses à suivre, capturant ainsi les différences de prix instantanées ou les tendances à court terme. Cependant, comme l'a dit l'auteur, les changements dans l'environnement du marché, l'homogénéité de la stratégie, les frais de manutention et les limites de fréquence ont rendu cette stratégie qui repose sur le premier mouvement puis le déplacement de la différence de prix progressivement moins utile, et même perdre de la rentabilité. Pour ceux qui veulent explorer à nouveau ce type de stratégie de Lead-Lag, il est nécessaire d'optimiser le module de négociation en combinaison avec les dernières règles de gestion des frais du marché (liquidité, algorithme de gestion, correspond


Plus de