Im vorherigen Artikel haben wir einen einfachen Spot-Order-Supervising-Bot implementiert, und heute werden wir eine Vertragsversion eines einfachen Order-Supervising-Bots implementieren.
Es gibt einen großen Unterschied zwischen dem Auftragsüberwachungsbot der Kontraktversion und der Spotversion. Daher ist die Situation der Futures-Version komplizierter, da es verschiedene Verträge für lange und kurze Positionen von Futures gibt, die sich mit einer Reihe von Details befassen müssen. Die Kernidee besteht darin, die Positionsänderungen zu überwachen und die Auftragsüberwachungsmaßnahmen basierend auf den Positionsänderungen auszulösen. Ursprünglich wurde es entwickelt, um mit langen und kurzen Positionen zusammen umzugehen, aber wir fanden heraus, dass es kompliziert wäre, damit umzugehen. Nachdem das Problem analysiert wurde, wurde beschlossen, die langen und kurzen Positionen separat zu behandeln.
Strategieparameter:
Es unterstützt Backtest und kann direkt die Standard-Einstellungen zum Backtest für die Beobachtung verwenden.
Quelle:
/*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
}
}
In Anbetracht der Tatsache, dass OKEX die V5-Schnittstelle aktualisiert hat und der OKEX simulierte Bot verwendet werden kann, habe ich API-KAYs von zwei OKEX simulierten Bots verwendet, um sie sehr bequem zu testen.
Das erste zu ergänzende Austauschobjekt ist die Referenzplattform, und die Auftragsüberwachungsplattform folgt dem Konto der Referenzplattform, um zu funktionieren. Auf der Seite des simulierten OKEX-Bots platziert das Referenzplattformkonto manuell 3 vierteljährliche Krypto-Margin-Kontrakte in ETH.
Man sieht, dass der Bot die Positionsänderungen und die folgenden Operationen erkannt hat.
Lassen Sie uns versuchen, die 2 Vertragspositionen zu schließen, die wir gerade eröffnet haben.
Der Bot folgte und schloss 2 Verträge.
Die Strategie ist auf einfache und leicht verständliche Weise ohne Optimierung konzipiert. Der verbesserte Teil muss sich auch mit Details wie Asset Detection beim Überwachen von Aufträgen befassen. Um das Design zu vereinfachen, werden Marktordern für Auftragsüberwachung verwendet. Die Strategie bietet nur Lernideen und der Bot kann entsprechend Ihren Bedürfnissen optimiert werden.
Strategieadresse:https://www.fmz.com/strategy/270012
Bitte hinterlassen Sie Ihre Kommentare.