В предыдущей статье мы вместе разработали и разработали простую стратегию сетки с несколькими символами. Далее мы продолжим изучать и двигаться вперед по пути количественной торговли. В этой статье мы обсудим более сложный дизайн стратегии - дизайн стратегии хеджирования. В статье планируется разработать стратегию хеджирования с несколькими символами. Когда дело доходит до стратегии хеджирования с несколькими символами, те, кто знаком с торговлей фьючерсами, должны быть знакомы с ней.
Как правило, хеджирование с пересекающимся периодом имеет контракт длинного и короткого хеджирования и ждет трех ситуаций (длинного и короткого) для закрытия позиций одновременно:
Для других ситуаций, когда есть плавающие потери, вы можете удерживать или продолжать добавлять больше позиций. (поскольку колебания спреда меньше, чем односторонние колебания, риск будет меньше, но обратите внимание, что это только сравнительно!)
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.
Поскольку платформы криптовалют имеют как контракты поставки, так и бессрочные контракты. И цена бессрочных контрактов всегда близка к спотовой цене из-за ставки финансирования. Затем мы выбираем использовать контракты поставки и бессрочные контракты для хеджирования и арбитража. Для контракта поставки мы можем выбрать один с относительно длительным периодом, чтобы контракт хеджирования не нуждался в частом установлении.
После того, как вы ознакомились с основным принципом, вам не нужно торопиться с написанием стратегии. Во-первых, сделайте статистику распространения, графики графиков и наблюдайте за распространениями. Давайте вместе узнаем о стратегии с несколькими символами. Мы разрабатываем его на основеДоговор OKEX. Это очень легко графизировать на FMZ, и вам нужно только использовать инкапсулированную функцию, с библиотекой графиковВысокие диаграммы. Описание функции графики в документации API:https://www.fmz.com/api#chart..- Да, конечно. Поскольку это стратегия с несколькими символами, прежде всего, необходимо определить ценовой спред этих символов перед графикой. В коде сначала запишите два массива, представляющие контракты, которые должны быть выполнены.
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
Согласно контрактному коду, установленному здесь, инициализируйте конфигурацию графика. Конфигурацию графика нельзя написать в бесконечной петле, потому что вы не знаете, какой символ делать, и сколько символов делать (которые определяются в соответствии с значениями arrDeliveryContractType и arrSwapContractType), поэтому конфигурация графика возвращается одной функцией.
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...
}
Мы собираемся подготовить данные; мы используем агрегированный рыночный интерфейс контракта OKEX:
Вечный контракт в USDT:
https://www.okex.com/api/v5/market/tickers?instType=SWAP
Договор поставки в USDT:
https://www.okex.com/api/v5/market/tickers?instType=FUTURES
Здесь мы пишем функцию для обработки вызова двух интерфейсов и обрабатываем данные в одном формате:
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
}
Напишите еще одну функцию для обработки кода контракта.
function formatSymbol(originalSymbol) {
var arr = originalSymbol.split("-")
return [arr[0] + "_" + arr[1], arr[0], arr[1]]
}
Далее нам нужно только повторять и сопоставлять полученные данные, вычислять спреды и графов для экспорта и т.д.
Здесь мы проверили распространение контракта 210924 на следующий квартал и постоянного контракта.
Полный код:
// 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)
}
}
Беги на время.
Сначала посмотрите на расширения!