Les ressources ont été chargées... Je charge...

Stratégie d'acquisition et de suivi du taux de financement de la FMZ

Auteur:FMZ~Lydia, Créé: 2024-11-04 14:54:42, mis à jour:

Stratégie d'acquisition et de suivi des taux de financement à terme multiplateforme

Définition:

Cette stratégie est utilisée pour obtenir et surveiller les taux de financement de multiples plateformes de contrats à terme telles que OKCoin, Binance, Bitget, etc. Elle étudie les marchés de contrats perpétuels de divers échanges à travers des fils parallèles et obtient des données sur les taux de financement, tout en utilisant un mécanisme de retard pour optimiser la fréquence des demandes.

Cet article apporte quelques modifications à la stratégie pour prendre en charge les fonctions d'affichage et de poussée d'alarme de taux de financement.

Adresse de source ouverte:https://www.fmz.com/strategy/470345

Fonction:

  • Prise en charge multiplateforme: synchroniser les taux de financement sur plusieurs plateformes de négociation et définir des délais de demande différents pour chaque plateforme.
  • Acquisition de symboles spécifiques: permet d'obtenir le taux de financement de paires de négociation spécifiques (telles que BTC/USDT, ETH/USDT).
  • Optimiser pour différentes plateformes: Distinguer entre les plateformes qui n'ont pas besoin de consulter chaque marché une par une (comme Binance) et les plateformes qui doivent traverser tous les marchés (comme OKCoin).
  • Affichage du taux: Affiche les taux de financement de plusieurs plateformes de négociation.
  • Poussée d'avertissement de débit: un certain seuil peut être fixé, et lorsque le taux équivalent de 24h dépasse la personnalisation, il sera poussé vers l'APP mobile FMZ.

Dans quelle direction?

Vous pouvez ajuster la liste des plateformes, la liste des symboles et l'intervalle de polling selon vos besoins spécifiques.

Code de stratégie

Le scénario est divisé en plusieurs parties principales:

  1. débutFundingWorker: démarre un fil séparé pour chaque échange afin de surveiller le taux de financement afin d'éviter les restrictions causées par un seul fil demandant trop de données.
  2. obtenirFonds: lit les données sur le taux de financement pour un échange spécifié à partir du stockage.
  3. Mise à jourStatus: Traite et met à jour le tableau des taux de financement pour toutes les bourses, affiche les données agrégées sous forme de tableau et enregistre les symboles avec des frais élevés.
  4. le principal: lance le programme principal, lance le fil de suivi et met régulièrement à jour le statut du taux de financement global.
// 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()
    }
}

Plus de