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

Commerce quantitatif de crypto-monnaie pour les débutants - vous rapprocher de la crypto-monnaie quantitative (7)

Auteur:FMZ~Lydia, Créé: 2022-08-09 11:15:23, Mis à jour: 2023-09-21 21:00:10

img

Dans l'article précédent, nous avons pensé et conçu ensemble une stratégie de grille simple multi-espèces. Ensuite, nous continuerons à apprendre et à avancer sur la voie du trading quantitatif. Dans cet article, nous explorerons une conception de stratégie plus complexe - la conception de stratégies de couverture. Cet article prévoit de concevoir une stratégie de couverture intertemporelle multi-espèces. En ce qui concerne les stratégies de couverture intertemporelle, ceux qui connaissent le trading à terme doivent être familiers avec elle. Pour les débutants, ils peuvent ne pas comprendre ces concepts, alors commençons par une brève explication du concept de couverture intertemporelle.

La couverture intertemporelle

En termes simples, la couverture intertemporelle consiste à conclure un contrat long, à conclure un contrat court et à attendre trois situations (longue et courte) pour fermer la position en même temps:

  • Si vous gagnez de l'argent en allant long et en perdant de l'argent en allant court, et fermez votre position lorsque le profit (comme on dit) est plus que la perte (comme on dit), vous ferez un profit après le solde profit/perte.
  • Les positions longues perdent de l'argent, les positions courtes gagnent de l'argent, et fermez la position lorsque celle qui est plus rentable que celle qui perd,... (même que ci-dessus).
  • Faites de l'argent si vous allez long, et faites de l'argent si vous allez court, alors pourquoi hésiter?

Dans d'autres cas, il s'agit de pertes flottantes, portant ou continuant à évoluer dans la position (parce que la fluctuation du spread est plus modérée que la fluctuation unilatérale, le risque relatif est plus faible, notez que seulement relative!)

Let A1 be the price of contract A at moment 1, and set B1 to be the price of contract B at moment 1. At this time, short contract A, short price A1, long contract B, and long price B1.
Let A2 be the price of contract A at moment 2, and set B2 to be the price of contract B at moment 2. At this time, close the position contract A (short), close short A2, close the position B contract (long), and close long price B2.

Moment 1 difference:A1 - B1 = X 
Moment 2 difference:A2 - B2 = Y 
X - Y = A1 - B1 - (A2 - B2)
X - Y = A1 - B1 - A2 + B2
X - Y = A1 - A2 + B2 - B1

It can be seen that A1 - A2 is the profit difference in closing the position of contract A.
B2 - B1 is the profit spread of closing the position of contract B. As long as the two closed positions are overall positive, ie: A1 - A2 + B2 - B1 > 0 is profitable. That is, as long as X - Y > 0.
Because of: X - Y = A1 - A2 + B2 - B1

It is concluded that as long as the difference X of opening a position is greater than the difference Y of closing a position, it is profitable (note that it is short A, long B to open a position, the reverse will be the opposite), of course, this is theoretical, practical factors such as commission and slippage should also be considered.

Parce que les échanges de crypto-monnaie ont à la fois des contrats de livraison et des contrats perpétuels. Et le prix des contrats perpétuels est toujours proche du prix au comptant en raison du taux de financement. Ensuite, nous choisissons d'utiliser des contrats de livraison et des contrats perpétuels pour l'arbitrage de couverture. Le contrat de livraison choisit un contrat à plus long terme, de sorte que le contrat de couverture n'a pas besoin d'être fixé fréquemment.

On se réchauffe d'abord avec une statistique de propagation multi-espèces.

Une fois que vous connaissez les principes de base, vous n'avez pas à vous précipiter pour écrire des stratégies. Tout d'abord, vous pouvez obtenir une statistique de propagation, dessiner un graphique et observer les propagations.

Nous concevons sur la base deContrat OKEX. Il est très simple de dessiner sur FMZ. Il est très facile d'utiliser les fonctions emballées pour dessiner.Tableaux de bordLa description de la fonction de dessin dans la documentation de l'API:https://www.fmz.com/api#chart...

Puisqu'il s'agit d'un multi-espèces, tout d'abord, il est nécessaire de déterminer la différence de prix de ces espèces avant de dessiner.

var arrSwapContractType = ["BTC-USDT-SWAP", "LTC-USDT-SWAP", "ETH-USDT-SWAP", "ETC-USDT-SWAP"]   // Perpetual contracts
var arrDeliveryContractType = ["BTC-USDT-210924", "LTC-USDT-210924", "ETH-USDT-210924", "ETC-USDT-210924"]  // Delivery contracts

Cette configuration de graphique ne peut certainement pas être codée en dur, car vous ne savez pas quelles espèces et combien d'espèces faire (ceux-ci sont déterminés par les valeurs de arrDeliveryContractType et arrSwapContractType), de sorte que la configuration de graphique est renvoyée par une fonction.

function createCfg(symbol) {
    var cfg = {
        extension: {
            // No grouping, displayed separately, default is 'group'
            layout: 'single', 
            // Specify the height, which can be set as a string, "300px", and the value 300 will be replaced with "300px" automatically
            height: 300,      
            // The unit value of the specified width, the total value is 12
            col: 6
        },
        title: {
            text: symbol
        },
        xAxis: {
            type: 'datetime'
        },
        series: [{
            name: 'plus',
            data: []
        }]
    }

    return cfg
}

function main() {
    // Declare arrCfg
    var arrCfg = []                                    // Declare an array to store chart configuration information
    _.each(arrSwapContractType, function(ct) {         // Record the array of perpetual contract codes iteratively, pass the XXX-USDT part of the contract name as a parameter to the createCfg function, construct the chart configuration information, and return
        arrCfg.push(createCfg(formatSymbol(ct)[0]))    // The chart configuration information returned by createCfg is pushed into the arrCfg array
    })
    var objCharts = Chart(arrCfg)                      // Call the chart function Chart of the FMZ platform to create the chart control object objCharts
    objCharts.reset()                                  // Initialize chart content
    
    // Hereafter omitted ...
}

Ensuite, préparons les données à l'aide de l'interface de marché agrégée du contrat OKEX:

Contrats perpétuels en USDT:

https://www.okex.com/api/v5/market/tickers?instType=SWAP

Contrats de livraison en USDT:

https://www.okex.com/api/v5/market/tickers?instType=FUTURES

Nous écrivons une fonction pour gérer les appels de ces deux interfaces et mettre les données dans un format:

function getTickers(url) {
    var ret = []
    try {
        var arr = JSON.parse(HttpQuery(url)).data
        _.each(arr, function(ele) {
            ret.push({
                bid1: parseFloat(ele.bidPx),             // Price of stock buy order
                bid1Vol: parseFloat(ele.bidSz),          // Amount for the price of stock buy order
                ask1: parseFloat(ele.askPx),             // Price of stock sell order
                ask1Vol: parseFloat(ele.askSz),          // Amount for the price of stock sell order
                symbol: formatSymbol(ele.instId)[0],     // Formats into trading pairs
                type: "Futures",                         // Type
                originalSymbol: ele.instId               // Original contract code
            })
        })
    } catch (e) {
        return null 
    }
    return ret 
}

Écrire une autre fonction pour traiter le code du contrat

function formatSymbol(originalSymbol) {
    var arr = originalSymbol.split("-")
    return [arr[0] + "_" + arr[1], arr[0], arr[1]]
}

Il ne reste plus qu'à apparier les données acquises de manière itérative, à calculer les spreads, à tracer la sortie, etc. Le test ici est l'écart entre le contrat du deuxième trimestre 210924 et le contrat perpétuel. Le code complet:

// Temporary parameters
var arrSwapContractType = ["BTC-USDT-SWAP", "LTC-USDT-SWAP", "ETH-USDT-SWAP", "ETC-USDT-SWAP"]
var arrDeliveryContractType = ["BTC-USDT-210924", "LTC-USDT-210924", "ETH-USDT-210924", "ETC-USDT-210924"]
var interval = 2000

function createCfg(symbol) {
    var cfg = {
        extension: {
            // No grouping, displayed separately, default is 'group'
            layout: 'single', 
            // Specify the height, which can be set as a string, "300px", and the value 300 will be replaced with "300px" automatically
            height: 300,      
            // The unit value of the specified width, the total value is 12
            col: 6
        },
        title: {
            text: symbol
        },
        xAxis: {
            type: 'datetime'
        },
        series: [{
            name: 'plus',
            data: []
        }]
    }

    return cfg
}

function formatSymbol(originalSymbol) {
    var arr = originalSymbol.split("-")
    return [arr[0] + "_" + arr[1], arr[0], arr[1]]
}

function getTickers(url) {
    var ret = []
    try {
        var arr = JSON.parse(HttpQuery(url)).data
        _.each(arr, function(ele) {
            ret.push({
                bid1: parseFloat(ele.bidPx), 
                bid1Vol: parseFloat(ele.bidSz), 
                ask1: parseFloat(ele.askPx), 
                ask1Vol: parseFloat(ele.askSz), 
                symbol: formatSymbol(ele.instId)[0], 
                type: "Futures", 
                originalSymbol: ele.instId
            })
        })
    } catch (e) {
        return null 
    }
    return ret 
}

function main() {
    // Declare arrCfg
    var arrCfg = []
    _.each(arrSwapContractType, function(ct) {
        arrCfg.push(createCfg(formatSymbol(ct)[0]))
    })
    var objCharts = Chart(arrCfg)
    objCharts.reset()
    
    while (true) {
        // Obtain market data        
        var deliveryTickers = getTickers("https://www.okex.com/api/v5/market/tickers?instType=FUTURES")
        var swapTickers = getTickers("https://www.okex.com/api/v5/market/tickers?instType=SWAP")
        if (!deliveryTickers || !swapTickers) {
            Sleep(2000)
            continue
        }

        var tbl = {
            type : "table",
            title : "delivery - perpetual spread",
            cols : ["trading pairs", "delivery", "perpetual", "positive hedging", "negative hedging"],
            rows : []
        }
        
        var subscribeDeliveryTickers = []
        var subscribeSwapTickers = []
        _.each(deliveryTickers, function(deliveryTicker) {
            _.each(arrDeliveryContractType, function(symbol) {
                if (deliveryTicker.originalSymbol == symbol) {
                    subscribeDeliveryTickers.push(deliveryTicker)
                }
            })
        })
        _.each(swapTickers, function(swapTicker) {
            _.each(arrSwapContractType, function(symbol) {
                if (swapTicker.originalSymbol == symbol) {
                    subscribeSwapTickers.push(swapTicker)
                }
            })
        })
        
        var pairs = []
        var ts = new Date().getTime()
        _.each(subscribeDeliveryTickers, function(deliveryTicker) {
            _.each(subscribeSwapTickers, function(swapTicker) {
                if (deliveryTicker.symbol == swapTicker.symbol) {
                    var pair = {symbol: swapTicker.symbol, swapTicker: swapTicker, deliveryTicker: deliveryTicker, plusDiff: deliveryTicker.bid1 - swapTicker.ask1, minusDiff: deliveryTicker.ask1 - swapTicker.bid1}
                    pairs.push(pair)
                    tbl.rows.push([pair.symbol, deliveryTicker.originalSymbol, swapTicker.originalSymbol, pair.plusDiff, pair.minusDiff])
                    for (var i = 0 ; i < arrCfg.length ; i++) {
                        if (arrCfg[i].title.text == pair.symbol) {
                            objCharts.add([i, [ts, pair.plusDiff]])
                        }                        
                    }                    
                }
            })
        })

        LogStatus(_D(), "\n`" + JSON.stringify(tbl) + "`")        
        Sleep(interval)
    }
}

Un vrai robot en marche.

img

On s'enfuit un peu.

img

Observez la propagation et parlez-en!img


Relationnée

Plus de