지난 기사에서 우리는 간단한 멀티 심볼 그리드 전략을 함께 생각하고 설계했습니다. 다음으로 우리는 양적 거래의 길을 계속 배우고 앞으로 나아갈 것입니다. 이 기사에서는 더 복잡한 전략 디자인 - 헤지 전략의 설계에 대해 논의 할 것입니다. 이 기사는 멀티 심볼 크로스 페리오드 헤지 전략을 설계 할 계획입니다. 크로스 페리오드 헤지 전략에 관해서는 미래에셋 거래에 익숙한 사람들은 익숙해야합니다. 초보자에게는이 개념을 이해하지 못할 수 있으므로 크로스 페리오드 헤지에 대한 개념을 간략하게 설명해 보겠습니다.
일반적으로, 크로스 페리오드 헤지는 긴 계약과 짧은 계약이 있고, 세 가지 상황 (장, 짧은) 을 동시에 닫을 때까지 기다립니다.
변동 손실이 있는 다른 상황에서는 더 많은 포지션을 유지하거나 추가할 수 있습니다. (스프레드 변동이 일방 변동보다 적기 때문에 위험은 더 작지만 비교적일 뿐입니다!)
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)
}
}
잠시 도망가자
먼저 스프레드를 보세요!