Dalam artikel yang lalu, kami telah memikirkan dan merancang strategi grid multi-simbol yang mudah bersama-sama. Seterusnya, kami akan terus belajar dan bergerak ke hadapan di jalan perdagangan kuantitatif. Dalam artikel ini, kami akan membincangkan reka bentuk strategi yang lebih rumit - reka bentuk strategi lindung nilai. Artikel ini merancang untuk merancang strategi lindung nilai lintas-periode multi-simbol. Ketika datang ke strategi lindung nilai lintas-periode, mereka yang biasa dengan perdagangan niaga hadapan mestilah biasa dengannya. Bagi pemula, anda mungkin tidak memahami konsep ini, jadi mari kita jelaskan secara ringkas konsep mengenai lindung nilai lintas-periode.
Secara amnya, lindung nilai merentasi tempoh mempunyai kontrak membuat panjang, dan kontrak membuat pendek, dan menunggu tiga situasi (panjang, pendek) untuk menutup kedudukan pada masa yang sama: masa
Untuk situasi lain apabila terdapat kerugian terapung, anda boleh memegang atau terus menambah lebih banyak kedudukan. (kerana turun naik penyebaran lebih kecil daripada turun naik satu sisi, risiko akan lebih kecil, tetapi perhatikan bahawa hanya perbandingan!)
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.
Kerana platform cryptocurrency mempunyai kedua-dua kontrak penghantaran dan kontrak kekal. Dan harga kontrak kekal sentiasa dekat dengan harga spot kerana kadar pembiayaan. Kemudian kita memilih untuk menggunakan kontrak penghantaran dan kontrak kekal untuk melakukan lindung nilai dan arbitrage. Untuk kontrak penghantaran, kita boleh memilih satu dengan tempoh yang agak lama, sehingga kontrak lindung nilai tidak perlu ditetapkan dengan kerap.
Setelah anda mengetahui prinsip asasnya, anda tidak perlu tergesa-gesa menulis strategi. Pertama, buat statistik spread, grafik plot, dan perhatikan spread. Mari belajar tentang strategi plot multi-simbol bersama-sama. Kami merancangnya berdasarkanKontrak OKEX. Ia adalah sangat mudah untuk merangka pada FMZ, dan anda hanya perlu menggunakan fungsi yang terkapas, dengan perpustakaan cartaCarta tinggi. Penerangan fungsi plot dalam dokumentasi API:https://www.fmz.com/api#chart..- Tidak. Oleh kerana ia adalah strategi multi-simbol, pertama sekali, adalah perlu untuk menentukan penyebaran harga simbol-simbol itu sebelum plot. dalam kod, menulis dua array pertama, mewakili kontrak yang akan dilakukan.
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
Menurut kod kontrak yang ditetapkan di sini, mulakan konfigurasi carta. Konfigurasi carta tidak boleh ditulis dalam gelung tanpa akhir, kerana anda tidak tahu simbol apa yang perlu dilakukan, dan berapa banyak simbol yang perlu dilakukan (yang ditentukan mengikut nilai arrDeliveryContractType dan arrSwapContractType), jadi konfigurasi carta dikembalikan oleh satu fungsi.
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...
}
Kami akan menyediakan data; kami menggunakan antara muka pasaran gabungan kontrak OKEX:
Kontrak kekal USDT:
https://www.okex.com/api/v5/market/tickers?instType=SWAP
Kontrak penghantaran USDT:
https://www.okex.com/api/v5/market/tickers?instType=FUTURES
Di sini kita menulis fungsi untuk menangani panggilan dua antara muka, dan memproses data ke dalam satu format:
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
}
Tulis satu lagi fungsi untuk memproses kod kontrak.
function formatSymbol(originalSymbol) {
var arr = originalSymbol.split("-")
return [arr[0] + "_" + arr[1], arr[0], arr[1]]
}
Seterusnya, kita hanya perlu mengulangi dan memadankan data yang diperoleh, mengira penyebaran, dan grafik grafik untuk mengeksport, dan sebagainya.
Di sini kami menguji penyebaran kontrak suku berikutnya 210924 dan kontrak kekal.
Kod lengkap:
// 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)
}
}
Berlari untuk seketika.
Perhatikan penyebaran pertama!