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年以上が経過し、市場は変化しました。その記事が公開された後、私の高頻度取引戦略は長い間安定して利益を上げることができましたが、徐々に利益が減少し、一時は止まってしまうこともありました。ここ数か月、私は改装に多大な労力を費やし、現在はいくらかの収入を得ることができています。この記事では、高頻度戦略といくつかの簡略化されたコードに関する私のアイデアを詳しく紹介します。これらは議論の出発点として役立ちます。どなたでもコミュニケーションを取り、フィードバックをいただければ幸いです。

高頻度取引の条件

  • リベートを受け取るアカウントの場合、Binance を例にとると、現在のメーカーリベートは 100,000 の 0.5% です。1 日の取引量が 1 億 U の場合、リベートは 5,000 U になります。もちろん、テイカー手数料は依然として VIP レートに基づいているため、注文を取る必要がない戦略の場合、VIP レベルは高頻度戦略にほとんど影響を与えません。一般的に、取引所のレベルによってリベート率が異なり、より高い取引量を維持する必要があります。昔、一部の通貨の市場が大きく変動していたときは、リベートがなくても利益がありました。内部循環の激化に伴い、リベートが利益の大きな割合を占め、完全にリベートに依存するようになりました。高頻度取引業者は、最高料金。

  • スピード。高頻度戦略が高頻度と呼ばれる理由は、非常に高速だからです。最も低いレイテンシと最も安定した接続を得るために取引所のコロケーションサーバーに参加することも、内部循環の条件の 1 つになっています。戦略の内部時間消費も可能な限り低くする必要があります。この記事では、並行実行を使用する私が使用している Websocket フレームワークを紹介します。

  • 適切な市場。高頻度取引は定量取引の宝石として知られています。多くのプログラマティックトレーダーが試したことがあると思いますが、ほとんどの人はお金を稼げず、改善する方法が見つからないため、おそらくやめてしまいます。主な理由はおそらく彼らは間違った方向を探している。取引市場。戦略の初期段階では、比較的簡単に取引して利益をあげられる市場を探す必要があります。そうすることで、利益と改善に関するフィードバックが得られ、戦略の前進につながります。最も競争の激しい市場でスタートし、多くの潜在的なライバルと競争すると、どれだけ努力してもお金を失い、長く持ちこたえることはできなくなります。新しく上場された無期限契約の取引ペアをお勧めします。現時点では、特に取引量が比較的多いため、競争相手はそれほど多くありません。これは、お金を稼ぐのが最も簡単な時期です。 BTC と ETH は取引量が最も多く、最も活発なトランザクションを誇りますが、生き残るのが最も難しい通貨でもあります。

  • 競争に正面から立ち向かってください。あらゆる取引市場は動的に変化しています。一度で永遠に機能する取引戦略は存在しません。これは高頻度取引ではさらに顕著です。この市場に参入するということは、最も賢く勤勉なトレーダーのグループと直接競争することを意味します。ゼロサム市場では、あなたが稼ぐ金額が増えるほど、他の人の稼ぐ金額は少なくなります。参入が遅れれば遅れるほど、困難になります。すでに市場に参入している人も、いつ淘汰されるかわからないので、改善を続けなければなりません。 3、4年前が最高のチャンスだったはずです。最近、デジタル通貨市場全体の活動は低下しており、初心者が高頻度取引を行うことは非常に困難になっています。

高周波原理

高頻度戦略には多くの種類がある

  • 高頻度ヘッジ:この取引所や他の取引所を通じてヘッジの機会を見つけ、スピードを利用して最初に注文を獲得し、利益を得る
  • 高頻度トレンド、短期トレンドから利益を得る
  • マーケットメーカーは買い側と売り側の両方に注文を出し、ポジションを管理し、手数料を得て利益を上げます。
  • 他にもたくさんありますが、一つ一つ説明することはできません。

私の戦略はトレンドとマーケットメーカーの組み合わせです。まずトレンドを判断して注文を出し、取引が完了したらすぐに売り注文を出します。在庫ポジションは保持しません。戦略コードは下記に紹介します。

戦略フレームワーク

以下のコードは、Binance 永久契約の基本アーキテクチャに基づいており、主に Websocket の深度注文フロー取引市場情報とポジション情報をサブスクライブします。マーケット情報とアカウント情報は別々に購読されるため、最新の情報を取得しているかどうかを判断するためにread(-1)を継続的に使用する必要があります。ここでEventLoop(1000)を使用するのは、直接の無限ループを回避し、システム負荷を軽減するためです。 EventLoop(1000) は、wss または同時タスクが返されるまでブロックされ、タイムアウトは 1000 ミリ秒です。

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の取引方向、価格、数量、取引時間などを含む取引データに基づいて判断されます。売買の主な基準は、深さと取引量です。以下は、注意が必要なインジケーターの詳細な紹介です。ほとんどのインジケーターは、買いと売りの 2 つのグループに分かれており、特定の時間枠で動的にカウントされます。私の戦略の時間枠は 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は平均市場価格の差です。買い注文は、ビッド・アスク・スプレッドがこの値の特定の倍数よりも大きく、トレンドが強気の場合にのみ発注されます。ショート注文を保有している場合、ポジションは注文の長期保留を避けるため、この時点では閉鎖されます。保留中の注文が確実に実行されるように、メーカーのみの注文を出すことができます。また、Binance のカスタム注文 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つのサブアカウントで1つの取引ペアを取引し、1つのサーバーが1つのロボットに対応しますが、コストははるかに高くなります。 。
  • 利益率に基づいて注文数量と注文条件を決定します。複数の通貨を取引すると、実験コストが高くなります。監視が利益を生まない場合は、最小取引量を使用し、戦略がプラスの収益率を動的に監視するまで取引頻度を減らし、その後、徐々に取引量を増やして利益を増やします。
  • より多くの情報を取得します。高頻度取引のもう 1 つの特徴は、大量のデータを処理し、より多くの情報を使用することです。単一の取引所における単一の取引ペアのすべての市場情報を参照する必要があります。また、永久スワップはスポットデータだけでなく、他の取引所における取引ペアのデータ、さらには他の通貨のデータも参照できます。データが多いほど、より良いです。それに応じた利点も大きくなります。たとえば、Binance は Symbol による最良の保留注文情報を購読できます。深さと注文フローの最短プッシュは 100 ミリ秒であるため、これだけがリアルタイムであり、高頻度戦略にとって非常に価値があります。
  • BinanceのサーバーはAWS東京にあり、他の取引所のサーバーは異なります。詳細については取引所の技術スタッフにお問い合わせください。
  • この記事の戦略コードは、多くの面倒ではあるが必要な詳細を削除した、簡略化されたサンプル コードです。使用されているインジケーターは参照用であり、直接使用しないでください。実際に高頻度戦略を実行する際には注意すべき細かい点が多く、修正や改善には忍耐が必要です。