
Dans l’article précédent, nous avons réfléchi et conçu une stratégie de grille multi-variété simple. Ensuite, nous continuerons à apprendre et à avancer sur la voie du trading quantitatif. Dans cet article, nous discuterons d’une conception de stratégie plus complexe : la conception d’une stratégie de couverture. Cet article a pour objectif de concevoir une stratégie de couverture multi-variétés sur plusieurs périodes. En parlant de stratégies de couverture sur plusieurs périodes, ceux qui sont familiers avec le trading à terme doivent les connaître. Les débutants ne comprennent peut-être pas encore ces concepts, alors expliquons d’abord brièvement le concept de couverture inter-périodes.
La couverture inter-périodes consiste simplement à être long sur un contrat, short sur un autre contrat et à attendre les trois situations suivantes pour clôturer les positions simultanément :
Dans d’autres cas, il y a une perte flottante et vous pouvez la conserver ou continuer à augmenter votre position. (Étant donné que la fluctuation de la différence de prix est beaucoup plus faible que la fluctuation unilatérale, le risque relatif est plus faible. Veuillez noter qu’il n’est que relatif !)
设A1为合约A在1时刻的价格,设B1为合约B在1时刻的价格,此时做空A合约,做空价格A1,做多B合约,做多价格B1。
设A2为合约A在2时刻的价格,设B2为合约B在2时刻的价格,此时平仓A合约(平空),平空价格A2,平仓B合约(平多),平多价格B2。
1时刻的差价:A1 - B1 = X
2时刻的差价:A2 - B2 = Y
X - Y = A1 - B1 - (A2 - B2)
X - Y = A1 - B1 - A2 + B2
X - Y = A1 - A2 + B2 - B1
可以看到,A1 - A2 就是A合约平仓的盈利差价。
B2 - B1就是B合约平仓的盈利差价。只要这两个平仓总体是正数,即:A1 - A2 + B2 - B1 > 0 就是盈利的。也就是说只要X - Y > 0。
因为:X - Y = A1 - A2 + B2 - B1
得出结论,只要开仓时的差价X大于平仓时的差价Y就是盈利的(注意是做空A,做多B开仓,搞反了就是相反的了),当然这个是理论上的,实际上还要考虑手续费、滑点等因素。
Parce que les échanges de devises numériques ont à la fois des contrats de livraison et des contrats perpétuels. De plus, en raison du taux de financement, le prix des contrats perpétuels est toujours proche du prix spot. Nous choisissons ensuite d’utiliser des contrats de livraison et des contrats perpétuels à des fins de couverture et d’arbitrage. Choisissez un contrat de livraison à plus long terme afin de ne pas avoir à conclure fréquemment des contrats de couverture.
Une fois que vous êtes familiarisé avec les principes de base, vous n’avez pas besoin de vous précipiter pour rédiger des stratégies. Tout d’abord, faites une statistique sur la différence de prix, dessinez un graphique et observez la différence de prix. Apprenons à dessiner des graphiques de stratégie multivariés.
Nous sommes basés surContrats OKEXPour concevoir, dessiner sur FMZ est très simple, vous pouvez facilement dessiner en utilisant les fonctions packagées, la bibliothèque de graphiques estHighcharts. Description de la fonction de dessin dans la documentation de l’API : https://www.fmz.com/api#chart...
Comme il existe plusieurs variétés, vous devez d’abord déterminer les différences de prix de ces variétés à imprimer avant de dessiner le graphique. Écrivez d’abord deux tableaux dans le code pour représenter les contrats à conclure.
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"] // 交割合约
Initialisez la configuration du graphique en fonction du code de contrat défini ici. Cette configuration de graphique ne doit pas être codée en dur, car vous ne savez pas quel produit fabriquer ni combien de produits fabriquer (ceux-ci sont déterminés par les valeurs de arrDeliveryContractType et arrSwapContractType), donc la configuration du graphique est renvoyée par une fonction .
function createCfg(symbol) {
var cfg = {
extension: {
// 不参于分组,单独显示,默认为分组 'group'
layout: 'single',
// 指定高度,可以设置为字符串,"300px",设置数值300会自动替换为"300px"
height: 300,
// 指定宽度占的单元值,总值为12
col: 6
},
title: {
text: symbol
},
xAxis: {
type: 'datetime'
},
series: [{
name: 'plus',
data: []
}]
}
return cfg
}
function main() {
// 声明arrCfg
var arrCfg = [] // 声明一个数组,用来存放图表配置信息
_.each(arrSwapContractType, function(ct) { // 迭代记录永续合约代码的数组,用合约名称XXX-USDT部分作为参数传给createCfg函数,构造图表配置信息,返回
arrCfg.push(createCfg(formatSymbol(ct)[0])) // createCfg返回的图表配置信息push进arrCfg数组
})
var objCharts = Chart(arrCfg) // 调用FMZ平台的图表函数Chart,创建图表控制对象objCharts
objCharts.reset() // 初始化图表内容
// 以下省略.....
}
Ensuite, préparons les données. Nous utilisons l’interface de marché agrégée des contrats OKEX :
Contrat perpétuel USDT :
https://www.okex.com/api/v5/market/tickers?instType=SWAP
Contrat de livraison USDT :
https://www.okex.com/api/v5/market/tickers?instType=FUTURES
Nous écrivons une fonction pour gérer les appels de ces deux interfaces et mettons les données dans un format :
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
}
Écrivez une autre fonction pour traiter le code du contrat
function formatSymbol(originalSymbol) {
var arr = originalSymbol.split("-")
return [arr[0] + "_" + arr[1], arr[0], arr[1]]
}
Il reste à coupler de manière itérative les données acquises, calculer la différence de prix, générer le graphique, etc. Ce qui est testé ici est la différence de prix entre le prochain contrat trimestriel 210924 et le contrat perpétuel. Code complet:
// 临时参数
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: {
// 不参于分组,单独显示,默认为分组 'group'
layout: 'single',
// 指定高度,可以设置为字符串,"300px",设置数值300会自动替换为"300px"
height: 300,
// 指定宽度占的单元值,总值为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() {
// 声明arrCfg
var arrCfg = []
_.each(arrSwapContractType, function(ct) {
arrCfg.push(createCfg(formatSymbol(ct)[0]))
})
var objCharts = Chart(arrCfg)
objCharts.reset()
while (true) {
// 获取行情数据
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 : "交割-永续差价",
cols : ["交易对", "交割", "永续", "正对冲", "反对冲"],
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)
}
}

Courir un moment~

Observez d’abord la différence de prix ! 