Dans l'article précédent, nous avons implémenté un simple robot de supervision des ordres au comptant, et aujourd'hui nous allons implémenter une version contractuelle d'un simple bot de supervision des ordres.
Il y a une grande différence entre le bot de supervision des ordres de la version du contrat et la version au comptant. Par conséquent, la situation de la version des contrats à terme est plus compliquée, car il existe différents contrats pour les positions longues et courtes des contrats à terme, qui doivent traiter une série de détails. L'idée principale est de surveiller les changements de position et de déclencher l'action de supervision des ordres en fonction des changements de position. Il a été conçu à l'origine pour traiter les positions longues et courtes ensemble, mais nous avons constaté qu'il serait compliqué de traiter cela. Après avoir analysé le problème, il est décidé de traiter les positions longues et courtes séparément.
Paramètre de stratégie:
Il prend en charge le backtest et peut directement utiliser les paramètres par défaut pour le backtest pour l'observation.
Le code source:
/*backtest
start: 2021-03-18 00:00:00
end: 2021-04-07 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD"},{"eid":"Futures_OKCoin","currency":"BTC_USD"},{"eid":"Futures_OKCoin","currency":"BTC_USD"}]
*/
function test() {
// test function
var ts = new Date().getTime()
if (ts % (1000 * 60 * 60 * 6) > 1000 * 60 * 60 * 5.5) {
Sleep(1000 * 60 * 10)
var nowPosAmount = getPosAmount(_C(exchange.GetPosition), refCt)
var longPosAmount = nowPosAmount.long
var shortPosAmount = nowPosAmount.short
var x = Math.random()
if (x > 0.7) {
exchange.SetDirection("buy")
exchange.Buy(-1, _N(Math.max(1, x * 10), 0), "the reference account tests ordering#FF0000")
} else if(x < 0.2) {
exchange.SetDirection("sell")
exchange.Sell(-1, _N(Math.max(1, x * 10), 0), "the reference account tests ordering#FF0000")
} else if(x >= 0.2 && x <= 0.5 && longPosAmount > 4) {
exchange.SetDirection("closebuy")
exchange.Sell(-1, longPosAmount, "the reference account tests closing positions#FF0000")
} else if(shortPosAmount > 4) {
exchange.SetDirection("closesell")
exchange.Buy(-1, _N(shortPosAmount / 2, 0), "he reference account tests closing position#FF0000")
}
}
}
function getPosAmount(pos, ct) {
var longPosAmount = 0
var shortPosAmount = 0
_.each(pos, function(ele) {
if (ele.ContractType == ct && ele.Type == PD_LONG) {
longPosAmount = ele.Amount
} else if (ele.ContractType == ct && ele.Type == PD_SHORT) {
shortPosAmount = ele.Amount
}
})
return {long: longPosAmount, short: shortPosAmount}
}
function trade(e, ct, type, delta) {
var nowPosAmount = getPosAmount(_C(e.GetPosition), ct)
var nowAmount = type == PD_LONG ? nowPosAmount.long : nowPosAmount.short
if (delta > 0) {
// open position
var tradeFunc = type == PD_LONG ? e.Buy : e.Sell
e.SetDirection(type == PD_LONG ? "buy" : "sell")
tradeFunc(-1, delta)
} else if (delta < 0) {
// close position
var tradeFunc = type == PD_LONG ? e.Sell : e.Buy
e.SetDirection(type == PD_LONG ? "closebuy" : "closesell")
if (nowAmount <= 0) {
Log("no position detected")
return
}
tradeFunc(-1, Math.min(nowAmount, Math.abs(delta)))
} else {
throw "error"
}
}
function main() {
LogReset(1)
if (exchanges.length < 2) {
throw "no platform with order supervision"
}
var exName = exchange.GetName()
// detect the platform for reference
if (!exName.includes("Futures_")) {
throw "only support futures order supervising"
}
Log("start monitoring", exName, "platform", "#FF0000")
// detect the order supervising platform
for (var i = 1 ; i < exchanges.length ; i++) {
if (exchanges[i].GetName() != exName) {
throw "The order supervising platform is different from the reference platform!"
}
}
// set trading pair and contract
_.each(exchanges, function(e) {
if (!IsVirtual()) {
e.SetCurrency(refCurrency)
if (isSimulate) {
if (e.GetName() == "Futures_OKCoin") {
e.IO("simulate", true)
}
}
}
e.SetContractType(refCt)
})
var initRefPosAmount = getPosAmount(_C(exchange.GetPosition), refCt)
while(true) {
if (IsVirtual()) { // only simulate during backtest
test() // test function, which simulates a reference account to trade automatically, to trigger the order supervising of the account
}
Sleep(5000)
var nowRefPosAmount = getPosAmount(_C(exchange.GetPosition), refCt)
var tbl = {
type : "table",
title : "position",
cols : ["name", "label", "long", "short", "account asset (Stocks)", "account assest (Balance)"],
rows : []
}
_.each(exchanges, function(e) {
var pos = getPosAmount(_C(e.GetPosition), refCt)
var acc = _C(e.GetAccount)
tbl.rows.push([e.GetName(), e.GetLabel(), pos.long, pos.short, acc.Stocks, acc.Balance])
})
LogStatus(_D(), "\n`" + JSON.stringify(tbl) + "`")
// calculate the position amount of change
var longPosDelta = nowRefPosAmount.long - initRefPosAmount.long
var shortPosDelta = nowRefPosAmount.short - initRefPosAmount.short
// detect the change
if (longPosDelta == 0 && shortPosDelta == 0) {
continue
} else {
// detect the position change
for (var i = 1 ; i < exchanges.length ; i++) {
// execute the action of long
if (longPosDelta != 0) {
Log(exchanges[i].GetName(), exchanges[i].GetLabel(), "Execute long order supervising, amount of change:", longPosDelta)
trade(exchanges[i], refCt, PD_LONG, longPosDelta)
}
// execute the action of short
if (shortPosDelta != 0) {
Log(exchanges[i].GetName(), exchanges[i].GetLabel(), "Execute short order supervising, amount of change:", shortPosDelta)
trade(exchanges[i], refCt, PD_SHORT, shortPosDelta)
}
}
}
// after the operation of order supervising, update
initRefPosAmount = nowRefPosAmount
}
}
Compte tenu du fait qu'après que OKEX ait mis à jour l'interface V5, et que le bot simulé OKEX puisse être utilisé, j'ai utilisé les API KAYs de deux bots simulés OKEX pour tester, très facilement.
Le premier objet d'échange à ajouter est la plateforme de référence, et la plateforme de surveillance des ordres suit le compte de la plateforme de référence pour fonctionner. Sur la page du bot simulé OKEX, le compte de la plateforme de référence place manuellement 3 contrats de crypto-marge trimestriels en ETH.
On peut voir que le bot a détecté les changements de position, et les opérations suivantes.
Les positions après la fermeture des positions sont indiquées sur la figure:
Le robot a suivi et a conclu 2 contrats.
La stratégie est conçue de manière simple et facile à comprendre sans optimisation. La partie améliorée doit également traiter des détails tels que la détection d'actifs lors de la supervision des ordres. Afin de simplifier la conception, les ordres de marché sont utilisés pour les ordres de supervision des ordres. La stratégie ne fournit que des idées d'apprentissage et le bot peut être optimisé en fonction de vos besoins.
Adresse stratégique:https://www.fmz.com/strategy/270012
Bienvenue à laisser vos commentaires.