이전 기사에서, 우리는 교류
다음은공공법규의 단순화그리고 FMZ API로 변환되었습니다. 이 원래 전략의 코드 원칙은 매우 간단하고 한때 매우 수익성이있었습니다. 현재는 사용할 수 없으며 참조용입니다.
이른바
이 전략은 시상대 가격, 수요 가격, 미뤄진 수요량 등과 같은 다른 거래소에서 거의 동기적으로 주문서 데이터를 얻습니다. 그 다음 시장 역학을 추론하기 위해 다른 거래소의 중간 가격 (즉, 수요 가격과 수요 가격의 평균) 을 비교합니다.
이 전략은 주로 세 개의 외부 거래소 (okex, binance, huobipro) 의 가격 변화에 초점을 맞추고 있습니다.
여기서, 각 트렌드X는 특정 임계값 (수준 * 가격_증가) 을 초과한
이 전략은 트렌드가 확인된 후에만 구매 또는 판매하고, 각 주문을 하기 전에 이전 오더를 취소합니다. 동시에, 스크립트는 레버리지, 래치 운영, 리스크 제어 모니터링과 같은 모듈을 설정합니다. 이는 여러 계정과 여러 통화 쌍이 라이브 거래에서 동시에 사용된다는 것을 의미합니다. 이를 통해 전략의 거래 빈도와 자본 활용 효율성을 확장합니다.
또한 이 전략은 고주파 전략입니다. 각 주문의 이익이나 손실에 주의를 기울일 필요가 없으며 손실을 중단 할 필요가 없습니다. 이익을 얻을 확률이있는 한 계속 할 수 있습니다.
// 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}`);
}
}
}
시장의 효율성
점점 더 많은 양적 또는 고주파 전략이 참여하고 동일한 리드-래그 관계를 발견하면 많은 자금이 가격 차이를 빠르게 제거 할 것입니다. 시장은 점점 더 "동시화"되고 있으며 전략이 작은 가격 차이에서 "위험 없는" 중재 또는 단기 중재를 만드는 것이 어렵습니다.
환율 제한 또는 수수료 변경
다른 거래소의 수수료 구조가 변화함에 따라 수수료 비용이 중재 수익을 초과하면 고주파 거래 전략의 수익성이 크게 감소 할 것입니다. 또는 거래소가 일치 속도를 가속화하고 주파수와 양을 제한하고 지연을 줄이면 원래 불일치한 지연에 의존했던 전략을 무효화 할 것입니다.
유동성 감소 및 미끄러짐
시장 규모가 충분하지 않을 때, 고주파 전략은 종종 더 심각한 미끄러짐을 겪습니다. 또는 큰 주문은 가격을 빠르게 끌어 올릴 것이며, 원래 예상 된 '저기 구매하고 높은 판매'가 자신의 주문에 영향을 받아 수익률이 감소합니다.
시장 변동성 변화
일부 전략은 "고위 변동성" 또는 "특정 기간"에서 매우 잘 작동합니다. 시장이 평평하거나 변동성이 감소하고 지렛대가 감소하면 전략은 적합한 환경을 잃고 종종 손실을 입을 수 있습니다.
높은 주파수 거래 전략의 핵심은 여러 거래소에서 가격을 캡처하고 "트렌드 합성"의 판단에 있다. 리드-래그 원칙에 기반한 초고 주파수 및 빠른 입출시 거래 방법을 실현했다: 어느 거래소 가격이 먼저 움직이고 다른 거래소 가격을 따라가도록 유도하여 즉각적인 가격 차이 또는 단기 트렌드를 캡처한다. 그러나 저자가 말한 바와 같이 시장 환경의 변화, 전략의 균일성, 처리 수수료 및 주파수 제한은 "첫 번째 이동"에 의존하고 그 다음 "가격 차이"를 이동하는 이 전략을 점차 유용하지 않게 만들고 수익성을 잃게 만들었다. 이러한 유형의 리드-래그 전략을 다시 탐구하려는 사람들에게는 최신 시장 구조 (액성, 대응 알고리즘, 속도 관리) 와 결합하여 거래 모듈을 최적화 할 필요가 있으며, 시장 환경의 지속적인 변화에 따라 경쟁력을 유지하기 위해 위험 관리에주의를 기울여야 한다.