Trong bài viết trước đây, chúng tôi đã nghĩ và thiết kế một chiến lược lưới đa biểu tượng đơn giản cùng nhau. Tiếp theo, chúng tôi sẽ tiếp tục học và tiến lên trên con đường giao dịch định lượng. Trong bài viết này, chúng tôi sẽ thảo luận về một thiết kế chiến lược phức tạp hơn - thiết kế chiến lược phòng hộ. Bài viết dự định thiết kế một chiến lược phòng hộ chéo thời gian đa biểu tượng. Khi nói đến chiến lược phòng hộ chéo thời gian, những người quen thuộc với giao dịch tương lai phải quen thuộc với nó. Đối với người mới bắt đầu, bạn có thể không hiểu những khái niệm này, vì vậy hãy giải thích ngắn gọn các khái niệm về phòng hộ chéo thời gian.
Nói chung, phòng hộ chéo thời gian có một hợp đồng làm dài, và một hợp đồng làm ngắn, và chờ ba tình huống (dài, ngắn) để đóng các vị trí cùng một lúc:
Đối với các tình huống khác khi có tổn thất thay đổi, bạn có thể giữ hoặc tiếp tục thêm nhiều vị trí hơn. (vì biến động chênh lệch nhỏ hơn so với biến động một bên, rủi ro sẽ nhỏ hơn, nhưng lưu ý rằng chỉ so sánh!)
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.
Vì nền tảng tiền điện tử có cả hợp đồng giao hàng và hợp đồng vĩnh cửu. Và giá của hợp đồng vĩnh cửu luôn gần với giá ngay lập tức do tỷ lệ tài trợ. Sau đó chúng tôi chọn sử dụng hợp đồng giao hàng và hợp đồng vĩnh cửu để phòng ngừa và điều chỉnh. Đối với hợp đồng giao hàng, chúng tôi có thể chọn một hợp đồng có thời gian tương đối dài, do đó hợp đồng phòng ngừa không cần phải được đặt thường xuyên.
Sau khi bạn đã quen thuộc với nguyên tắc cơ bản, bạn không cần phải vội vàng viết chiến lược. Đầu tiên, hãy tạo số liệu thống kê, biểu đồ biểu đồ và quan sát sự lây lan. Chúng tôi thiết kế nó dựa trênHợp đồng OKEX. Nó rất dễ dàng để biểu đồ trên FMZ, và bạn chỉ cần sử dụng các hàm đóng gói, với thư viện biểu đồBiểu đồ caoMô tả chức năng vẽ trong tài liệu API:https://www.fmz.com/api#chart... Vì đây là một chiến lược đa biểu tượng, trước hết, cần phải xác định mức chênh lệch giá của các biểu tượng đó trước khi vẽ.
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
Theo mã hợp đồng được đặt ở đây, khởi tạo cấu hình biểu đồ. cấu hình biểu đồ không thể được viết trong một vòng lặp vô hạn, bởi vì bạn không biết biểu tượng nào cần làm và bao nhiêu biểu tượng cần làm (được xác định theo các giá trị của arrDeliveryContractType và arrSwapContractType), vì vậy cấu hình biểu đồ được trả về bởi một hàm.
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...
}
Chúng tôi sẽ chuẩn bị dữ liệu; chúng tôi sử dụng giao diện thị trường tổng hợp của hợp đồng OKEX:
Hợp đồng vĩnh viễn USDT:
https://www.okex.com/api/v5/market/tickers?instType=SWAP
Hợp đồng giao hàng bằng USDT:
https://www.okex.com/api/v5/market/tickers?instType=FUTURES
Ở đây chúng ta viết một hàm để xử lý việc gọi hai giao diện, và xử lý dữ liệu thành một định dạng:
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
}
Viết thêm một hàm để xử lý mã hợp đồng.
function formatSymbol(originalSymbol) {
var arr = originalSymbol.split("-")
return [arr[0] + "_" + arr[1], arr[0], arr[1]]
}
Tiếp theo, chúng ta chỉ cần lặp lại và phù hợp với dữ liệu thu được, tính toán chênh lệch, và biểu đồ phác thảo để xuất, v.v.
Ở đây chúng tôi đã kiểm tra sự phân tán của hợp đồng quý tiếp theo 210924 và hợp đồng vĩnh viễn.
Mã đầy đủ:
// 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)
}
}
Chạy đi một lát.
Hãy quan sát những vết nứt đầu tiên!