No artigo anterior, introduzimos a arbitragem de mudança de tijolo cruzada. Neste artigo, vamos dar uma olhada profunda em como aplicar o efeito Lead-Lag à negociação de alta frequência, que requer capturar pequenas diferenças de preço em um tempo muito curto e obter lucros rapidamente. O efeito Lead-Lag fornece aos comerciantes informações preditivas para ajudá-los a julgar a tendência de curto prazo dos preços e alcançar arbitragem entre diferentes trocas.
A seguir:uma simplificação do código públicoO princípio de código desta estratégia original é muito simples e já foi muito rentável.
O chamado
A estratégia obtém dados do livro de pedidos de diferentes bolsas quase sincronicamente, como o preço de lançamento, o preço de compra, o volume de pedidos pendentes, etc. Em seguida, o preço médio (ou seja, a média do preço de compra e venda) de diferentes bolsas é comparado para inferir a dinâmica do mercado.
A estratégia centra-se principalmente nas alterações de preços de três bolsas externas (okex, binance, huobipro):
Aqui, cada tendência X é determinada pela diferença entre o
A estratégia só compra ou vende depois que a tendência é confirmada, e cancela a ordem anterior antes de colocar cada ordem (ou seja, evitando ordens pendentes acidentais que levam ao acúmulo de risco). Ao mesmo tempo, o script também define módulos como alavancagem, operação de lote e monitoramento de controle de risco, o que significa que várias contas e vários pares de moedas são usados simultaneamente na negociação ao vivo, expandindo assim a frequência de negociação da estratégia e a eficiência de utilização do capital.
Além disso, esta estratégia é uma estratégia de alta frequência. Você não precisa prestar atenção ao lucro ou perda de cada ordem, nem precisa parar de perder. Você pode continuar enquanto houver probabilidade de obter lucros.
// 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;
// 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
}
// 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}`);
}
}
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}`);
}
}
}
Os mercados tornam-se eficientes
Quando mais e mais estratégias quantitativas ou de alta frequência estão envolvidas e encontram a mesma relação Lead-Lag, uma grande quantidade de fundos eliminará a diferença de preço rapidamente.
Restrições cambiais ou alterações de taxas
À medida que a estrutura de taxas de diferentes exchanges muda, uma vez que os custos de taxas excedem os lucros de arbitragem, a lucratividade das estratégias de negociação de alta frequência será muito reduzida. Ou se a exchange acelerar a velocidade de correspondência, limitar a frequência e a quantidade e reduzir o atraso, também invalidará a estratégia que originalmente dependia de atrasos inconsistentes.
Desagregação e deslizamento da liquidez
Quando o volume de mercado é insuficiente, as estratégias de alta frequência geralmente encontram deslizamentos mais graves; ou grandes ordens elevarão os preços rapidamente, fazendo com que o inicialmente esperado
Mudanças na volatilidade do mercado
Algumas estratégias funcionam muito bem em condições de "alta volatilidade" ou "período específico".
O ponto-chave da estratégia de negociação de alta frequência está na captura de preços de várias bolsas e no julgamento da síntese de tendências. Uma vez que realizou um método de negociação de entrada e saída de alta frequência e rápida baseado no princípio do Lead-Lag: observar quais bolsas o preço se move primeiro e, em seguida, direcionar os preços de outras bolsas para segui-lo, capturando assim diferenças de preço instantâneas ou tendências de curto prazo. No entanto, como disse o autor, as mudanças no ambiente de mercado, a homogeneidade da estratégia, as taxas de manipulação e os limites de frequência tornaram esta estratégia que depende do primeiro movimento e, em seguida, move a diferença de preço cada vez menos útil e até mesmo perde lucratividade. Para aqueles que querem explorar esse tipo de estratégia de Lead-Lag novamente, é necessário otimizar o módulo de negociação em combinação com as últimas regras de estrutura de mercado (liquidez, algoritmo de manipulação de correspondência, controle de risco), prestando atenção ao controle de velocidade, a fim de manter a competitividade