3
집중하다
1444
수행원

고주파 디지털 통화 전략에 대한 자세한 소개

만든 날짜: 2023-03-10 10:09:13, 업데이트 날짜: 2024-11-11 22:39:27
comments   13
hits   11533

고주파 디지털 통화 전략에 대한 자세한 소개

[TOC] 저는 2020년에 고빈도 전략을 소개하는 기사를 썼습니다. https://www.fmz.com/digest-topic/6228. 많은 주목을 받았지만 깊이 있게 쓰여지지는 않았습니다. 2년이 넘도록 시장은 변화해 왔습니다. 그 기사가 나온 후로, 저의 고빈도 전략은 오랫동안 꾸준히 수익을 낼 수 있었지만, 수익은 점점 줄어들었고 어느 ​​순간 중단되기도 했습니다. 최근 몇 달 동안, 저는 리노베이션에 많은 노력을 기울였고, 지금은 약간의 돈을 벌 수 있게 되었습니다. 이 글에서는 고빈도 전략에 대한 제 아이디어와 몇 가지 단순화된 코드를 더 자세히 소개할 것입니다. 이는 토론의 시작점이 될 수 있습니다. 누구나 소통하고 피드백을 제공할 수 있습니다.

고빈도 거래의 조건

  • 리베이트를 받는 계정의 경우, 바이낸스를 예로 들면, 현재 메이커 리베이트는 100,000의 0.5%입니다. 일일 거래량이 1억 U인 경우, 리베이트는 5,000 U가 됩니다. 물론, 테이커 수수료는 여전히 VIP 요금에 따라 결정되므로, 해당 전략에 주문 접수가 필요하지 않다면 VIP 레벨은 고빈도 전략에 거의 영향을 미치지 않습니다. 일반적으로 거래소의 레벨에 따라 할인율이 다르며, 더 높은 거래량을 유지해야 합니다. 오래전 일부 통화의 시장이 크게 변동했을 때, 리베이트가 없어도 여전히 이익이 있었습니다. 내부 유통이 강화되면서 리베이트가 이익의 상당 부분을 차지했고, 심지어 전적으로 리베이트에 의존하기도 했습니다. 고빈도 트레이더는 다음을 추구합니다. 최상의 가격.

  • 속도. 고빈도 전략이 고빈도라고 불리는 이유는 그것이 매우 빠르기 때문입니다. 가장 낮은 지연 시간과 가장 안정적인 연결을 얻기 위해 거래소의 콜로 서버에 가입하는 것도 내부 순환을 위한 조건 중 하나가 되었습니다. 전략의 내부 시간 소모도 가능한 한 낮아야 합니다. 이 글에서는 동시 실행을 사용하는 제가 사용하는 웹소켓 프레임워크를 소개합니다.

  • 적절한 시장. 고빈도 트레이딩은 양적 트레이딩의 보석으로 알려져 있습니다. 저는 많은 프로그래매틱 트레이더가 시도해 봤다고 믿지만, 대부분의 사람들은 돈을 벌지 못하고 개선할 방법을 찾을 수 없어서 중단할 것입니다. 가장 큰 이유는 아마도 그들이 잘못된 길을 찾고 있다는 것입니다. 거래 시장. 전략의 초기 단계에서는 돈을 벌기 쉬운 시장을 찾아 거래해야 합니다. 그렇게 하면 수익을 낼 수 있고 개선에 대한 피드백도 얻을 수 있는데, 이는 전략의 진전에 도움이 됩니다. 가장 경쟁이 심한 시장에서 사업을 시작하여 많은 잠재적 경쟁자들과 경쟁하게 되면 아무리 노력해도 돈을 잃게 되고 더 이상 버틸 수 없게 됩니다. 새로 상장된 영구 계약 거래 쌍을 추천합니다. 지금은 경쟁자가 그렇게 많지 않습니다. 특히 거래량이 비교적 많을 때는 더욱 그렇습니다. 돈을 벌기 가장 쉬운 시기입니다. BTC와 ETH는 거래량이 가장 많고 거래 활동도 가장 활발하지만, 생존하기가 가장 어렵기도 합니다.

  • 경쟁에 정면으로 맞서세요. 모든 거래 시장은 역동적으로 변화합니다. 어떤 거래 전략도 단번에 효과가 있을 수는 없습니다. 이는 고빈도 거래에서 더욱 분명합니다. 이 시장에 진입한다는 것은 가장 똑똑하고 가장 근면한 거래자 그룹과 직접 경쟁한다는 것을 의미합니다. 제로섬 시장에서는 당신이 많이 벌수록 다른 사람들의 수입은 줄어듭니다. 늦게 진입할수록 더 어려워질 것입니다. 이미 시장에 있는 사람들도 언제든지 제거될 수 있으므로 계속 개선해야 합니다. 3~4년 전이 가장 좋은 기회였어야 합니다. 최근 디지털 통화 시장의 전반적인 활동이 감소했고, 이제 초보자가 고빈도 거래에 참여하기가 매우 어렵습니다.

고주파 원리

고빈도 전략에는 여러 유형이 있습니다

  • 고빈도 헤지: 본 거래소 또는 타 거래소를 통해 헤지 기회를 찾고, 속도를 활용해 주문을 먼저 확보하고 수익을 얻는 방식
  • 고주파 트렌드, 단기 트렌드에서 이익을 얻으세요
  • 시장 조성자는 매수와 매도 양쪽에서 주문을 내고, 포지션을 통제하며 수수료를 벌어 수익을 냅니다.
  • 다른 많은 것들, 하나하나씩 설명되지 않음

제 전략은 트렌드와 마켓 메이커의 조합입니다. 저는 먼저 트렌드를 파악한 다음 주문을 하고, 거래가 완료된 후 즉시 매도 주문을 합니다. 저는 재고 포지션을 보유하지 않습니다. 전략 코드는 아래에 소개되어 있습니다.

전략 프레임워크

다음 코드는 바이낸스 선물 계약의 기본 아키텍처를 기반으로 하며, 주로 웹소켓 심도 주문 흐름 거래, 시장 정보 및 포지션 정보를 구독합니다. 시장 정보와 계좌 정보가 별도로 구독되므로 최신 정보를 얻었는지 여부를 확인하기 위해 read(-1)을 지속적으로 사용해야 합니다. 여기서는 EventLoop(1000)을 사용하여 직접 무한 루프를 피하고 시스템 부담을 줄입니다. EventLoop(1000)은 wss 또는 동시 작업이 반환될 때까지 차단되며, 시간 제한은 1000ms입니다.

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()
    }
    //需要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是设定的交易对
    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)
    }
}

전략 지표

앞서 언급했듯이, 저의 고빈도 전략은 매수 및 매도를 실행하기 전에 추세를 파악하는 것을 요구합니다. 단기 추세는 주로 각 거래의 거래 데이터, 즉 구독의 aggTrade를 기준으로 판단되며, 여기에는 거래 방향, 가격, 수량, 거래 시간 등이 포함됩니다. 매수 및 매도의 주요 기준은 거래량과 깊이입니다. 다음은 주의가 필요한 지표에 대한 자세한 소개입니다. 대부분의 지표는 매수와 매도의 두 그룹으로 나뉘며 특정 시간 창에서 동적으로 계산됩니다. 내 전략의 시간 창은 10초 이내입니다.

  • 각 거래의 평균 거래량입니다. 거래량은 100ms 이내에 같은 방향과 가격의 다른 주문의 집합이며, 이는 매수 및 매도 주문의 크기를 반영합니다. 이 데이터는 더 높은 가중치를 갖습니다. 다음과 같은 경우를 가정할 수 있습니다. 매수 주문의 거래량이 매도 주문보다 큰 경우, 매수자 주도 시장입니다.
  • 주문 빈도 또는 주문 간격도 거래 데이터를 기반으로 합니다. 이전 평균 거래량은 시간 개념을 고려하지 않으며 완전히 정확하지 않습니다. 한 방향의 주문량이 평균적으로 적지만 빈도가 높은 경우에도 기여합니다. 이 방향의 강점. 평균 볼륨*주문 빈도는 고정된 간격의 총 거래량을 나타내며 직접적인 비교에 사용할 수 있습니다. 주문 도착 이벤트는 포아송 분포를 따르며, 이는 특정 시간 간격 동안 도착하는 총 주문 수를 간단히 추정하고 보류 중인 주문의 위치에 대한 참조를 제공하는 데 사용할 수 있습니다.
  • 평균 시장 스프레드는 매도 가격에서 매수 가격을 뺀 값으로 이해하기 비교적 쉽습니다. 현재 시장 가격의 대부분은 1틱의 가격 차이를 가지고 있습니다. 가격 차이가 커지면 종종 시장 추세가 나타났다는 것을 의미합니다.
  • 평균 매수 및 매도 가격은 각 거래 가격의 평균을 구하고 최신 가격과 비교하여 계산됩니다. 가장 최근의 매수 주문 가격이 평균 매수 주문 가격보다 높으면 돌파구가 발생한 것으로 예비 판단할 수 있습니다.

전략 논리

단기 추세를 파악하세요

//bull代表短期看涨,bear短期看跌
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;

최신 매도가격이 평균 매도가격보다 크고, 최신 매수가격이 평균 매수가격보다 크고, 고정간격 매수주문가가 매도주문가보다 큰 경우 단기 강세로 판단한다. . 오히려 반대로 하락세입니다.

주문 가격

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]
}

여기서 우리는 여전히 오래된 아이디어를 채택하고 필요한 양만큼 깊이를 반복합니다. 여기서 우리는 10코인의 매수 주문이 1초 이내에 실행될 수 있다고 가정합니다. 새로운 보류 주문을 고려하지 않고 매도 주문 가격은 다음 위치로 설정됩니다. 10개의 코인을 매수 주문하면 성사됩니다. 구체적인 시간 창 크기를 직접 설정해야 합니다.

주문 수량

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

비율은 고정 비율을 의미하며, 이는 매수 주문 수량이 가장 최근의 매도 주문 수량에 대한 고정 비율임을 의미합니다. 이 전략을 사용하면 현재의 매수 및 매도 활동에 따라 주문 크기를 적응적으로 조정할 수 있습니다.

주문 조건

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)
}

그 중 avg_diff는 평균 시장 가격의 차이입니다. 매수 주문은 매수-매도 차이가 이 값의 특정 배수보다 크고 추세가 강세일 때만 이루어집니다. 숏 주문을 보유하면 포지션 또한, 장기간 주문을 보류하는 것을 피하기 위해 이 시점에는 주문이 닫힙니다. 보류 주문이 실행되도록 하려면 유일 메이커 주문을 할 수 있습니다. 또한 바이낸스의 사용자 지정 주문 ID를 사용하면 주문이 반환될 때까지 기다릴 필요가 없습니다.

동시 아키텍처

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)//未返回的任务下次继续等待
        }
    })
    jobs = new_jobs
    tasks = []
}

/*
需要的任务参数写在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()]})
*/

모니터링 데이터

  • 지연. 고빈도 전략의 속도의 중요성이 강조되었습니다. 주문, 주문 취소, 포지션 반환, 깊이, 주문 흐름, 포지션, 전체 사이클 등과 같은 다양한 지연을 전략에서 모니터링하고 기록해야 합니다. 비정상적인 지연은 즉시 확인해야 하며, 전반적인 전략 지연을 단축할 방법을 찾아야 합니다.
  • 거래량 비중, 통계는 전체 거래량에서 거래량이 차지하는 비중을 보여줍니다. 비중이 낮다면 개선의 여지가 여전히 있습니다. 최대 거래 시간에는 특정 전략이 전체 거래량의 10% 이상을 차지할 수도 있습니다.
  • 마감수익률, 즉 통계적 평균 마감수익률은 해당 전략이 효과적인지 판단하는 데 가장 중요한 기준입니다.
  • 수수료 비율이란 총 수익에 대한 수수료의 비율로, 전략이 수수료에 얼마나 의존하는지를 반영합니다. 거래소에는 다양한 할인 레벨이 있으며, 할인 레벨이 한 단계 높아지면 수익성이 없는 전략도 수익성이 생길 수 있습니다.
  • 실패한 주문의 비율. 주문은 배치되고 실행될 뿐입니다. 주문 배치가 지연되어 배치되지 않을 수 있습니다. 이 비율이 높으면 전략 속도가 유리하지 않다는 것을 의미합니다.
  • 실행되는 주문의 비율. 플랫폼은 종종 실행 비율에 대한 요구 사항을 가지고 있습니다. 너무 낮으면 전략이 주문을 너무 자주 취소하고 해결해야 함을 의미합니다.
  • 매수와 매도 주문 사이의 평균 거리. 이 데이터는 전략 주문과 시장 가격 사이의 거리를 반영합니다. 대부분이 여전히 매수 1과 매도 1 포지션을 차지하고 있는 것을 볼 수 있습니다.

기타 제안

  • 여러 통화를 거래하는 이 기사의 고빈도 전략은 단일 거래소, 단일 통화, 단일 시장의 시장만을 말합니다. 이는 큰 한계가 있으며 대부분의 경우 대부분의 통화에 대해 수익성이 없습니다. 그러나 미래에 어떤 통화가 수익성이 있을지 예측하는 것은 불가능합니다. 따라서 여러 통화 또는 모든 통화를 거래해도 기회를 놓치지 않을 수 있습니다. 거래소의 주파수 한계 하에서도 로봇은 여러 거래 쌍을 거래할 수 있습니다. 물론 최상의 속도를 위해 하나의 하위 계정은 하나의 거래 쌍을 거래할 수 있고, 하나의 서버는 하나의 로봇에 해당하지만 비용은 훨씬 더 높을 것입니다. .
  • 반품율에 따라 주문수량과 주문조건을 결정합니다. 여러 통화를 거래하면 실험 비용이 많이 듭니다. 모니터링이 수익성이 없다면 최소 거래량을 사용하고 전략이 긍정적인 수익률을 동적으로 모니터링할 때까지 거래 빈도를 줄인 다음 점차적으로 거래량을 늘려 수익을 늘리세요.
  • 더 많은 정보를 얻으세요. 고빈도 거래의 또 다른 특징은 더 많은 양의 데이터를 처리하고 더 많은 정보를 사용한다는 것입니다. 단일 거래소의 단일 거래 쌍에 대한 모든 시장 정보를 참조해야 하며, 영구 스왑은 현물 데이터뿐만 아니라 다른 거래소의 거래 쌍 데이터 또는 다른 통화의 데이터도 참조할 수 있습니다. 데이터가 많을수록 더 좋다. 그에 상응하는 이점도 더 크다. 예를 들어, 바이낸스는 심볼별로 최상의 보류 주문 정보를 구독할 수 있습니다. 깊이와 주문 흐름의 가장 짧은 푸시는 100ms이므로 이것만이 실시간이며, 이는 고빈도 전략에 매우 귀중합니다.
  • 바이낸스의 서버는 AWS 도쿄에 있으며, 다른 거래소의 서버는 다릅니다. 자세한 내용은 거래소의 기술 담당자에게 문의하세요.
  • 이 기사의 전략 코드는 단순화된 샘플 코드일 뿐이며, 지루하지만 필요한 세부 사항을 많이 삭제했습니다. 사용된 지표는 참조용일 뿐이며 직접 사용해서는 안 됩니다. 실제로 고빈도 전략을 실행할 때 주의해야 할 세부 사항이 많으며, 전략을 수정하고 개선하려면 인내심이 필요합니다.