3
フォロー
1444
フォロワー

FMZ資金調達率獲得および監視戦略

作成日:: 2024-10-31 16:41:13, 更新日:: 2024-11-11 08:47:40
comments   2
hits   1513

FMZ資金調達率獲得および監視戦略

マルチプラットフォーム先物資金調達率の取得と監視戦略

説明する:

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

この記事では、表示および資金調達率アラーム プッシュ機能をサポートするために戦略にいくつかの変更を加えます。

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

関数:

  • マルチプラットフォームサポート: 複数の取引所間で資金調達率を同期し、それぞれに異なるリクエスト遅延を設定します。
  • 特定のシンボルの取得: 特定の取引ペア(BTC/USDT、ETH/USDT など)の資金調達率の取得をサポートします。
  • さまざまなプラットフォームに最適化各市場を 1 つずつ照会する必要がないプラットフォーム (Binance など) と、すべての市場を横断する必要があるプラットフォーム (OKCoin など) を区別します。
  • レート表示: 複数の取引プラットフォームの資金調達率を表示します。課金間隔が異なるため、直接比較できるように 24 時間レートに統一されています。
  • レート警告プッシュ: 一定のしきい値を設定できます。24 時間相当のレートが設定値を超えると、FMZ モバイル アプリにプッシュされます。

方向:

特定の取引ニーズに合わせて、プラットフォーム リスト、シンボル リスト、ポーリング間隔を必要に応じて調整できます。

戦略コード

スクリプトはいくつかの主要な部分に分かれています。

  1. startFundingWorker:単一のスレッドが大量のデータを要求することによって引き起こされる現在の制限問題を回避できるように、資金調達率を監視するために各取引所ごとに独立したスレッドを開始します。
  2. getFundings: 指定された取引所の資金調達率データをストレージから読み取ります。
  3. UpdateStatus: すべての取引所の資金調達率テーブルを処理および更新し、集計データをテーブルとして表示し、手数料の高いシンボルをログに記録します。
  4. main:メインプログラムを起動し、監視スレッドを開始し、要約された資金調達率のステータスを定期的に更新します。
// 启动资金费率监控线程,为每个交易所的资金费率数据创建一个单独的线程
function startFundingWorker() {
    exchanges.forEach((_, pos) => {
        __Thread(function (pos) {
            let e = exchanges[pos]
            let eName = e.GetName()
            // 设置不同交易所的请求延迟,以防止频繁请求导致被限流
            let delaySettings = {
                'Futures_OKCoin': 20,
                'Futures_Binance': 500,
                'Futures_MEXC': 100,
            }
            // 需要遍历所有市场的交易所名称列表,这些交易所不支持一次获取所有交易对
            let needInterate = ['Futures_OKCoin', 'Futures_Bitget','Futures_OKX', 'Futures_KuCoin', 'Futures_MEXC'] 
            // 根据交易所名称设定延迟
            let delay = function () {
                let n = delaySettings[eName]
                if (n) {
                    Sleep(n)
                }
            }
            // 设定更新间隔,每两分钟更新一次
            let epoch = 60000 * 2;
            let ts = 0;
            let fundings = {}
            // 无限循环,以固定间隔获取资金费率
            while (true) {
                let now = new Date().getTime()
                if (now - ts < epoch) {
                    // 未达到更新周期则暂停1秒后继续检查
                    Sleep(1000)
                    continue
                }
                let markets = e.GetMarkets()
                if (!markets) {
                    // 如果未能获取到市场信息,则延迟后重试
                    Sleep(1000)
                    continue
                }
                // 如果交易所在需要遍历的列表中,逐个市场请求资金费率
                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 {
                    // 不在遍历列表中的交易所,仅请求 USDT.swap 的资金费率
                    let ret = e.GetFundings('USDT.swap')
                    if (ret) {
                        for (let r of ret) {
                            fundings[r.Symbol] = r
                        }
                    }
                }
                // 更新数据时间戳
                ts = now
                // 存储该交易所的资金费率数据
                __threadSetData(0, eName+"_funding", fundings)
            }
        }, pos)
    })
}

// 获取指定交易所的资金费率数据
function getFundings(eName) {
    let efundings = __threadGetData(0, eName+"_funding")
    if (!efundings) {
        return null
    }
    return efundings
}

// 更新资金费率表并在日志中显示
function UpdateStatus(){
    let table = { 
        type: 'table', 
        title: 'Funding Rate%', 
        cols: ['index', 'symbol'], // 初始化列,包含 symbol 
        rows: [] 
    };
    let fundingRates = {};
    exchanges.forEach((e) => {
        let eName = e.GetName();
        if (fundings[eName]) {
            for (let symbol in fundings[eName]) {
                // 解析简短的 symbol 名称,去除多余前缀
                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)
                // 初始化符号的数据结构
                if (!fundingRates[short_symbol]) {
                    fundingRates[short_symbol] = { total: 0, count: 0,  day_rate: {},  next_time: {}, last_time:0};
                }
                // 对超过阈值的费率进行记录并推送
                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); // 记录费率
                fundingRates[short_symbol].next_time[eName] = _N((fundings[eName][symbol].Time - Date.now()) / 3600000 , 1) + 'h'
            }
        }
    });
    // 为每个交易所添加费率列和下次更新的时间列
    for (let e of exchanges) {
        table.cols.push(e.GetName()+' Rate');
        table.cols.push('Next Time');
    }
   
    table.cols.push('Average Rate'); // 添加平均费率列
    let i = 0;
    // 遍历每个符号并填充数据
    for (let symbol in fundingRates) {
        let data = fundingRates[symbol];
        if (data.count == 1) {
            continue // 只包含单个数据点的符号忽略
        }
        let averageRate = data.total / data.count; // 计算平均费率
        let row = [i++, symbol];
        for (let e of exchanges) {
            row.push(data.day_rate[e.GetName()] || null); // 填充各个交易所的费率
            row.push(data.next_time[e.GetName()] || null);
        }
        row.push(_N(averageRate, 6)); // 填充平均费率
        table.rows.push(row);
    }
    LogStatus('`' + JSON.stringify(table) + '`');
}

// 主函数,启动资金费率监控和状态更新
var fundings = {}
function main() {
    startFundingWorker() // 启动每个交易所的监控线程
    while (true) {
        exchanges.forEach((e) => {
            let eName = e.GetName()
            let eFundings = getFundings(eName)
            fundings[eName] = eFundings
        })
        Sleep(15000) // 每15秒更新一次
        UpdateStatus()
    }
}