O recurso está a ser carregado... Carregamento...

Novato, confira Leva-o ao Comércio Quantitativo de Criptomoedas (7)

Autora:Ninabadass, Criado: 2022-04-22 11:59:32, Atualizado: 2022-04-22 12:01:11

Novato, confira Leva-o ao Comércio Quantitativo de Criptomoedas (7)

No último artigo, pensamos e projetamos uma estratégia simples de grade de múltiplos símbolos juntos. Em seguida, continuaremos a aprender e avançar no caminho da negociação quantitativa. Neste artigo, discutiremos um projeto de estratégia mais complicado - o projeto da estratégia de hedge. O artigo planeja projetar uma estratégia de hedge de período cruzado de múltiplos símbolos. Quando se trata de estratégia de hedge de período cruzado, aqueles que estão familiarizados com a negociação de futuros devem estar familiarizados com ela. Para iniciantes, você pode não entender esses conceitos, então vamos explicar brevemente os conceitos sobre hedge de período cruzado.

Segurança de períodos cruzados

De um modo geral, a cobertura de período cruzado tem um contrato de fazer longo e um contrato de fazer curto e espera três situações (longo, curto) para fechar posições ao mesmo tempo:

  • Quando fazer longo é lucrativo, fazer curto tem uma perda, e o lucro é maior do que a perda, fechar posições; haverá um retorno depois que o lucro cobre a perda.
  • Quando fazer curto é lucrativo, fazer longo tem uma perda, e o lucro é maior do que a perda, posições fechadas; haverá um retorno depois que o lucro cobre a perda. (semelhante)
  • Quando fazer longo é lucrativo e fazer curto também é lucrativo, não hesite em fechar posições!

Para outras situações em que existem perdas flutuantes, pode manter ou continuar a adicionar mais posições. (porque a flutuação do spread é menor do que a flutuação unilateral, o risco será menor, mas note que é apenas comparativo!)

Set A1 as the price of contract A at the time 1, and set B1 as the price of contract B at the time 1. At the time, do short in contract A, at A1; do long in contract B, at B1. 
Set A2 as the price of contract A at the time 2, and set B2 as the price of contract B at the time 2. At the time, close positions (close short) of contract A, at A2; close positions (close long) of contract B, at B2. 

Spread at time 1: A1 - B1 = X 
Spread at time 2: A2 - B2 = Y 
X - Y = A1 - B1 - (A2 - B2)
X - Y = A1 - B1 - A2 + B2
X - Y = A1 - A2 + B2 - B1

As you can see, "A1 - A2 " is the profit spread of closing position in contract A. 
"B2 - B1" is the profit spread of closing position in contract B. It is profitable, as long as the closing postion spread of the two contracts is a positive number, namely A1 - A2 + B2 - B1 > 0. That is to say as long as X - Y > 0,
for: X - Y = A1 - A2 + B2 - B1

It is concluded that as long as the spread X when opening a position is greater than the spread Y when closing a position, it is profitable (note that it is making short in contract A and making long in contract B to open a position; if the situation is reversed, the result will be opposite). Of course, this is just theoretical, and factors such as the handling fee and slippoint should also be considered in practice. 

Porque as plataformas de criptomoeda têm contratos de entrega e contratos perpétuos. E o preço dos contratos perpétuos é sempre próximo do preço ao instante devido à taxa de financiamento. Então escolhemos usar contratos de entrega e contratos perpétuos para fazer hedge e arbitragem. Para o contrato de entrega, podemos escolher um com um período comparativamente longo, para que o contrato de hedge não precise ser definido com frequência.

Aqueça-se com algumas estatísticas de multiplicação de símbolos

Depois de familiarizar-se com o princípio básico, você não precisa se apressar em escrever a estratégia. Primeiro, faça estatísticas de spread, gráficos de gráficos e observe os spreads. Nós projetamos com base emContrato OKEXÉ muito fácil de traçar em FMZ, e você só precisa usar a função encapsulada, com a biblioteca de gráficosHighcharts (Highcharts). A descrição da função de gráfico na documentação da API:https://www.fmz.com/api#chart..- Não. Uma vez que é uma estratégia multi-símbolo, em primeiro lugar, é necessário determinar o spread de preço desses símbolos antes de traçar.

var arrSwapContractType = ["BTC-USDT-SWAP", "LTC-USDT-SWAP", "ETH-USDT-SWAP", "ETC-USDT-SWAP"]   // perpetual contract 
var arrDeliveryContractType = ["BTC-USDT-210924", "LTC-USDT-210924", "ETH-USDT-210924", "ETC-USDT-210924"]  // delivery contract 

De acordo com o código de contrato definido aqui, inicialize a configuração do gráfico. A configuração do gráfico não pode ser escrita em um loop infinito, porque você não sabe qual símbolo fazer e quantos símbolos fazer (que são determinados de acordo com os valores de arrDeliveryContractType e arrSwapContractType), então a configuração do gráfico é devolvida por uma função.

function createCfg(symbol) {
    var cfg = {
        extension: {
            // it is not part of the group, and is individually displayed; the default is 'group'
            layout: 'single', 
            // the specified height, which can be set as string; "300px", which means it will be replaced by "300px" automatically through setting a value of 300
            height: 300,      
            // the occupied unit value of the specified width, with a total value of 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 the chart configuration information
    _.each(arrSwapContractType, function(ct) {         // iteratively record the array of perpetual contract codes, 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 "push" returned by "createCfg" is in the "arrCfg" array 
    })
    var objCharts = Chart(arrCfg)                      // call the function Chart on FMZ platform, and create a chart controlled object called objCharts
    objCharts.reset()                                  // initialize the chart content  
    
    // the rest is omitted...
}

Vamos preparar os dados; usamos a interface de mercado agregada do contrato OKEX:

Contrato perpétuo USDT:

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

Contrato de entrega em USDT:

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

Aqui escrevemos uma função para lidar com a invocação das duas interfaces, e processar os dados em um formato:

function getTickers(url) {
    var ret = []
    try {
        var arr = JSON.parse(HttpQuery(url)).data
        _.each(arr, function(ele) {
            ret.push({
                bid1: parseFloat(ele.bidPx),             // buy one price
                bid1Vol: parseFloat(ele.bidSz),          // volume of buy one price 
                ask1: parseFloat(ele.askPx),             // ell one price 
                ask1Vol: parseFloat(ele.askSz),          // volume of sell one price 
                symbol: formatSymbol(ele.instId)[0],     // in the format of trading pair  
                type: "Futures",                         // type
                originalSymbol: ele.instId               // original contract code 
            })
        })
    } catch (e) {
        return null 
    }
    return ret 
}

Escreva mais uma função para processar o código do contrato.

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

Em seguida, só precisamos iterar e combinar os dados obtidos, calcular os spreads e traçar gráficos para exportar, etc. Aqui testamos o spread do contrato do próximo trimestre 210924 e do contrato perpétuo.
Código completo:

// 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: {
            // it is not part of the group, and is individually displayed; the default is 'group'
            layout: 'single', 
            // the specified height, which can be set as string; "300px", which means it will be replaced by "300px" automatically through setting a value of 300
            height: 300,      
            // the occupied unit value of the specified width, with a total value of 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 the market quote 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 pair", "delivery", "perpetual", "positive hedge", "negative hedge"],
            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)
    }
}

Operação do bot

img

Foge por uns tempos.

img

Observe primeiro os espalhamentos!


Mais.