資源の読み込みに... 荷物...

FMZ 資金調達の利子獲得と監視戦略

作者: リン・ハーンFMZ~リディア作成日:2024年11月04日 14:54:42 更新日:

複数のプラットフォームの先物投資金利の取得と監視戦略

記述:

この戦略は,OKCoin,Binance,Bitgetなどの複数の先物プラットフォームから資金調達率を取得し,監視するために使用されます. 要求頻度を最適化するために遅延メカニズムを使用して,並行スレッドを通じてさまざまな取引所の永続契約市場を調査し,資金調達率データを取得します.

この記事では,表示および資金提供率アラームプッシュ機能をサポートするための戦略にいくつかの変更を行います.

オープンソースアドレス:https://www.fmz.com/strategy/470345

機能:

  • 複数のプラットフォームのサポート複数の取引プラットフォームで資金提供率を同期し,各プラットフォームで異なるリクエスト遅延を設定します.
  • 特定のシンボルの取得: 特定の取引対 (BTC/USDT,ETH/USDTなど) の資金率を取得するサポート.
  • 異なるプラットフォームに最適化: 各市場を"つずつクエリする必要のないプラットフォーム (Binanceなど) とすべての市場をクエリする必要のあるプラットフォーム (OKCoinなど) を区別する.
  • 速度の表示:複数の取引プラットフォームの資金提供率を表示します.収集間隔が異なるため,直接比較のために24hレートに均等に調整されています.
  • 速度の警告プッシュ: 特定の値が設定され,24時間相当のレートはカスタマイズを超えると,FMZモバイルAPPに押し出されます.

指示:

プラットフォームリスト,シンボルのリスト,投票間隔を 必要なように調整して 特定の取引ニーズに対応できます

戦略コード

脚本はいくつかの主要部分に分かれています.

  1. start 資金提供 労働者: 資金提供率を監視するために各取引所に別々のスレッドを起動し,単一のスレッドで大量のデータを要求することで発生する絞め込みを回避します.
  2. get 資金提供: 貯蔵から指定された交換のための資金提供率データを読み取ります.
  3. アップデートステータス: すべての取引所の資金提供率表を処理し,更新し,総データを表として表示し,高い手数料のシンボルをログします.
  4. 主要: 主要プログラムを開始し,モニタリングスレッドを開始し,総資金調達の水準を定期的に更新します.
// Start the funding rate monitoring thread and create a separate thread for each exchange's funding rate data
function startFundingWorker() {
    exchanges.forEach((_, pos) => {
        __Thread(function (pos) {
            let e = exchanges[pos]
            let eName = e.GetName()
            // Set request delays for different exchanges to prevent frequent requests from causing throttling
            let delaySettings = {
                'Futures_OKCoin': 20,
                'Futures_Binance': 500,
                'Futures_MEXC': 100,
            }
            // Need to traverse the list of exchange names for all markets, these exchanges do not support getting all trading pairs at once
            let needInterate = ['Futures_OKCoin', 'Futures_Bitget','Futures_OKX', 'Futures_KuCoin', 'Futures_MEXC'] 
            // Set delay based on exchange name
            let delay = function () {
                let n = delaySettings[eName]
                if (n) {
                    Sleep(n)
                }
            }
            // Set the update interval to update every two minutes
            let epoch = 60000 * 2;
            let ts = 0;
            let fundings = {}
            // Infinite loop, get funding rate at fixed intervals
            while (true) {
                let now = new Date().getTime()
                if (now - ts < epoch) {
                    // If the update cycle is not reached, pause for 1 second and then continue checking
                    Sleep(1000)
                    continue
                }
                let markets = e.GetMarkets()
                if (!markets) {
                    // If market information cannot be obtained, try again after a delay
                    Sleep(1000)
                    continue
                }
                // If the exchange is in the list that needs to be traversed, request the funding rate for each market
                if (needInterate.includes(eName)) {
                    for (let symbol in markets) {
                        if (symbol.includes('.swap') && symbol.includes('_USDT')) {
                            let ret = e.GetFundings(symbol)
                            if (ret) {
                                for (let r of ret) {
                                    fundings[r.Symbol] = r
                                }
                            }
                            delay();
                        }
                    }
                } else {
                    // For exchanges not in the traversal list, only request the funding rate of USDT.swap
                    let ret = e.GetFundings('USDT.swap')
                    if (ret) {
                        for (let r of ret) {
                            fundings[r.Symbol] = r
                        }
                    }
                }
                // Update data timestamp
                ts = now
                // Stores the exchange's funding rate data
                __threadSetData(0, eName+"_funding", fundings)
            }
        }, pos)
    })
}

// Get the funding rate data of the specified exchange
function getFundings(eName) {
    let efundings = __threadGetData(0, eName+"_funding")
    if (!efundings) {
        return null
    }
    return efundings
}

// Update the funding rate table and display it in the log
function UpdateStatus(){
    let table = { 
        type: 'table', 
        title: 'Funding Rate%', 
        cols: ['index', 'symbol'], // Initialization column, containing symbol
        rows: [] 
    };
    let fundingRates = {};
    exchanges.forEach((e) => {
        let eName = e.GetName();
        if (fundings[eName]) {
            for (let symbol in fundings[eName]) {
                // Parse short symbol names and remove unnecessary prefixes
                let short_symbol = symbol.split('_')[0].replace(/^(100|1000|10000|100000|1000000|10000000)|^(100|1000|10000|100000|1000000|10000000)$/g, '');
                let rate = fundings[eName][symbol].Rate;
                let day = 24 / (fundings[eName][symbol].Interval / 3600000)
                // Initialize symbol data structure
                if (!fundingRates[short_symbol]) {
                    fundingRates[short_symbol] = { total: 0, count: 0,  day_rate: {},  next_time: {}, last_time:0};
                }
                // Record and push rates that exceed the threshold
                if (Math.abs(rate) > 0.01 && Date.now() - fundingRates[short_symbol].last_time > 30*60*1000) {
                    Log(e.GetName(), symbol, rate, '@')
                    fundingRates[short_symbol].last_time = Date.now()
                }
                fundingRates[short_symbol].total += rate;
                fundingRates[short_symbol].count++;
                fundingRates[short_symbol].day_rate[eName] = _N(rate * day , 6); // Record rates
                fundingRates[short_symbol].next_time[eName] = _N((fundings[eName][symbol].Time - Date.now()) / 3600000 , 1) + 'h'
            }
        }
    });
    // Added rate columns and next update time columns for each exchange
    for (let e of exchanges) {
        table.cols.push(e.GetName()+' Rate');
        table.cols.push('Next Time');
    }
   
    table.cols.push('Average Rate'); // Add an average rate column
    let i = 0;
    // Iterate over each symbol and fill in the data
    for (let symbol in fundingRates) {
        let data = fundingRates[symbol];
        if (data.count == 1) {
            continue // Symbols containing only a single data point are ignored
        }
        let averageRate = data.total / data.count; // Calculate average rate
        let row = [i++, symbol];
        for (let e of exchanges) {
            row.push(data.day_rate[e.GetName()] || null); // Filling the fees of various exchanges
            row.push(data.next_time[e.GetName()] || null);
        }
        row.push(_N(averageRate, 6)); // Filling average rate
        table.rows.push(row);
    }
    LogStatus('`' + JSON.stringify(table) + '`');
}

// Main function, start funding rate monitoring and status update
var fundings = {}
function main() {
    startFundingWorker() // Start monitoring threads for each exchange
    while (true) {
        exchanges.forEach((e) => {
            let eName = e.GetName()
            let eFundings = getFundings(eName)
            fundings[eName] = eFundings
        })
        Sleep(15000) // Update every 15 seconds
        UpdateStatus()
    }
}

もっと