Dalam artikel sebelumnya di FMZ Digest, kami telah merancang beberapa urutan dan kedudukan strategi synchronous.
Reka bentuk ini mengambil akaun rujukan dan akaun sinkron ke dalam strategi yang sama untuk diuruskan untuk merealisasikan penyegerakan pesanan dan kedudukan. hari ini, kita boleh mencuba reka bentuk yang berbeza; berdasarkan antara muka API lanjutan FMZ yang kuat, di sini kita merancang sistem pengurusan sinkron pesanan.
Pertama sekali, kita memerlukan beberapa cadangan dan keperluan yang baik. Dua strategi penyelarasan pesanan dan kedudukan sebelumnya di atas mempunyai beberapa kelemahan yang jelas. Mari kita bincangkannya bersama:
1.Pengguna yang melaksanakan penyegerakan bot strategi mesti mempunyai API KEY platform akaun rujukan dan API KEY akaun penyegerakan. Untuk senario penggunaan, masalahnya adalah: tidak mengapa untuk akaun platform lain anda mengikuti salah satu akaun anda sendiri. Tetapi ia boleh menjadi masalah untuk senario di mana akaun rujukan dan akaun penyegerakan tidak mempunyai pemilik yang sama. Pemilik akaun penyegerakan kadang-kadang tidak mahu memberikan KEY API akaun platformnya kerana pertimbangan keselamatan. Tetapi bagaimana untuk meletakkan pesanan untuk berdagang secara serentak tanpa memberikan KEY API?
Penyelesaian:
Menggunakan FMZ diperluaskan API, pemilik akaun penyelarasan (pemelihara pesanan) hanya perlu mendaftar platform perdagangan FMZ Quant, dan kemudian menjalankan strategi (dalam sistem yang direka dalam artikel ini:Order Synchronous Management System (Synchronous Server)
Kemudian, KEY API diperluaskan FMZ (catat bahawa ia bukan KEY API akaun platform) dan ID bot sistem pengurusan penyegerakan pesanan (Synchronous Server) akan diberikan kepada pemilik akaun rujukan (pemilik pesanan).
Apabila bot pemilik akaun rujukan (pemilik pesanan) (Order Synchronous Management System Library (Single Server)
dalam sistem yang direka dalam artikel) menghantar isyarat, bot pemilik akaun penyegerakan akan menerima isyarat dagangan.
2.Banyak pemaju mempunyai strategi yang lebih baik dan tidak dapat menggunakan dua strategi penyegerakan urutan dan kedudukan sebelumnya yang diterangkan di atas. Kerana itu perlu menggabungkan strategi mereka sendiri dengan strategi penyegerakan ini, dan strategi mereka mungkin perlu diubahsuai, yang memakan masa dan tenaga. Adakah ada cara yang baik untuk meningkatkan beberapa strategi matang anda secara langsung kepada yang mempunyai fungsi penyegerakan pesanan?
Penyelesaian:
Anda boleh merancang perpustakaan templat order synchronous (yangOrder Synchronous Management System Library (Single Server)
strategi dalam sistem yang direka dalam artikel), supaya pemilik akaun rujukan (pemilik pesanan) boleh memasukkan perpustakaan templat ini secara langsung ke dalam strategi sendiri untuk mencapai urutan dan penyegerakan kedudukan.
3.Kurangkan bot tambahan Kelemahan terakhir adalah bahawa jika anda menggunakan dua perintah sebelumnya dan strategi penyegerakan kedudukan yang diterangkan di atas, adalah perlu untuk membuka kedudukan tambahan akaun rujukan ( akaun dengan pesanan) untuk pemantauan bot. Penyelesaian: Gunakan perpustakaan templat untuk menyematkan fungsi ke dalam strategi akaun rujukan.
Oleh itu, sistem ini terdiri daripada dua bahagian: 1.perpustakaan sistem pengurusan sinkron pesanan (Single Server) 2.Sistem pengurusan pesanan serentak (Synchronous Server)
Setelah kita memastikan tuntutan kita, mari kita mula merancang!
Perhatikan bahawa di sini ia bukan strategi, tetapi perpustakaan templat FMZ, yang boleh dicari dalam dokumentasi FMZ API dan kita tidak akan membincangkan di sini.
Kod templat:
// Global variable
var keyName_label = "label"
var keyName_robotId = "robotId"
var keyName_extendAccessKey = "extendAccessKey"
var keyName_extendSecretKey = "extendSecretKey"
var fmzExtendApis = parseConfigs([config1, config2, config3, config4, config5])
var mapInitRefPosAmount = {}
function parseConfigs(configs) {
var arr = []
_.each(configs, function(config) {
if (config == "") {
return
}
var strArr = config.split(",")
if (strArr.length != 4) {
throw "configs error!"
}
var obj = {}
obj[keyName_label] = strArr[0]
obj[keyName_robotId] = strArr[1]
obj[keyName_extendAccessKey] = strArr[2]
obj[keyName_extendSecretKey] = strArr[3]
arr.push(obj)
})
return arr
}
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
}
})
var timestamp = new Date().getTime()
return {ts: timestamp, long: longPosAmount, short: shortPosAmount}
}
function sendCommandRobotMsg (robotId, accessKey, secretKey, msg) {
// https://www.fmz.com/api/v1?access_key=xxx&secret_key=yyyy&method=CommandRobot&args=[186515,"ok12345"]
var url = "https://www.fmz.com/api/v1?access_key=" + accessKey + "&secret_key=" + secretKey + "&method=CommandRobot&args=[" + robotId + ',"' + msg + '"]'
Log(url)
var ret = HttpQuery(url)
return ret
}
function follow(nowPosAmount, symbol, ct, type, delta) {
var msg = ""
var nowAmount = type == PD_LONG ? nowPosAmount.long : nowPosAmount.short
if (delta > 0) {
// Open position
var tradeDirection = type == PD_LONG ? "buy" : "sell"
// Send signal
msg = symbol + "," + ct + "," + tradeDirection + "," + Math.abs(delta)
} else if (delta < 0) {
// Open position
var tradeDirection = type == PD_LONG ? "closebuy" : "closesell"
if (nowAmount <= 0) {
Log("No position detected")
return
}
// Send signal
msg = symbol + "," + ct + "," + tradeDirection + "," + Math.abs(delta)
} else {
throw "error"
}
if (msg) {
_.each(fmzExtendApis, function(extendApiConfig) {
var ret = sendCommandRobotMsg(extendApiConfig[keyName_robotId], extendApiConfig[keyName_extendAccessKey], extendApiConfig[keyName_extendSecretKey], msg)
Log("Call CommandRobot interface,", "label:", extendApiConfig[keyName_label], ", msg:", msg, ", ret:", ret)
Sleep(1000)
})
}
}
$.PosMonitor = function(exIndex, symbol, ct) {
var ts = new Date().getTime()
var ex = exchanges[exIndex]
// Judge the type of ex
var exName = ex.GetName()
var isFutures = exName.includes("Futures_")
var exType = isFutures ? "futures" : "spot"
if (!isFutures) {
throw "Only support futures order supervising"
}
if (exType == "futures") {
// Cache symbol ct
var buffSymbol = ex.GetCurrency()
var buffCt = ex.GetContractType()
// Switch to the corresponding trading pair and contract code
ex.SetCurrency(symbol)
if (!ex.SetContractType(ct)) {
throw "SetContractType failed"
}
// Monitor position
var keyInitRefPosAmount = "refPos-" + exIndex + "-" + symbol + "-" + ct // refPos-exIndex-symbol-contractType
var initRefPosAmount = mapInitRefPosAmount[keyInitRefPosAmount]
if (!initRefPosAmount) {
// The data is not initialized; initialize it
mapInitRefPosAmount[keyInitRefPosAmount] = getPosAmount(_C(ex.GetPosition), ct)
initRefPosAmount = mapInitRefPosAmount[keyInitRefPosAmount]
}
// Monitor
var nowRefPosAmount = getPosAmount(_C(ex.GetPosition), ct)
// Calculate position changes
var longPosDelta = nowRefPosAmount.long - initRefPosAmount.long
var shortPosDelta = nowRefPosAmount.short - initRefPosAmount.short
// Detect changes
if (!(longPosDelta == 0 && shortPosDelta == 0)) {
// Execute long position action
if (longPosDelta != 0) {
Log(ex.GetName(), ex.GetLabel(), symbol, ct, "Execute long position order supervision, change volume:", longPosDelta)
follow(nowRefPosAmount, symbol, ct, PD_LONG, longPosDelta)
}
// Execute short position action
if (shortPosDelta != 0) {
Log(ex.GetName(), ex.GetLabel(), symbol, ct, "Execute short position order supervision, change volume:", shortPosDelta)
follow(nowRefPosAmount, symbol, ct, PD_SHORT, shortPosDelta)
}
// After executing the order supervision operation, update
mapInitRefPosAmount[keyInitRefPosAmount] = nowRefPosAmount
}
// Recover symbol ct
ex.SetCurrency(buffSymbol)
ex.SetContractType(buffCt)
} else if (exType == "spot") {
// Spot
}
}
$.getTbl = function() {
var tbl = {
"type" : "table",
"title" : "Synchrodata",
"cols" : [],
"rows" : []
}
// Construct the table title
tbl.cols.push("Monitoring account:refPos-exIndex-symbol-contractType")
tbl.cols.push(`Mintoring position:{"timestamp":xxx,"long position volume":xxx,"short position volume":xxx}`)
_.each(fmzExtendApis, function(extendApiData, index) {
tbl.cols.push(keyName_robotId + "-" + index)
})
// Write in the data
_.each(mapInitRefPosAmount, function(initRefPosAmount, key) {
var arr = [key, JSON.stringify(initRefPosAmount)]
_.each(fmzExtendApis, function(extendApiData) {
arr.push(extendApiData[keyName_robotId])
})
tbl.rows.push(arr)
})
return tbl
}
// Invocation example of the strategy in the template
function main() {
// Clear all logs
LogReset(1)
//Switch to OKEX simulated bot test
exchanges[0].IO("simulate", true)
// Set contract
exchanges[0].SetCurrency("ETH_USDT")
exchanges[0].SetContractType("swap")
// Timed trading time interval
var tradeInterval = 1000 * 60 * 3 // trade every three minutes, to observe the order supervising signal
var lastTradeTS = new Date().getTime()
while (true) {
// Other logic of the strategy...
// Used to test the simulated trade trigger
var ts = new Date().getTime()
if (ts - lastTradeTS > tradeInterval) {
Log("Simulated strategy with orders has trades, and positions changed", "#FF0000")
exchanges[0].SetDirection("buy")
exchanges[0].Buy(-1, 1)
lastTradeTS = ts
}
// Call the interface function in the template
$.PosMonitor(0, "ETH_USDT", "swap") // You can set multiple monitors, to minitor different exchange objects in the strategy with orders
var tbl = $.getTbl()
// Display the status bar
LogStatus(_D(), "\n" + "`" + JSON.stringify(tbl) + "`")
Sleep(1000)
}
}
Reka bentuknya sangat mudah, perpustakaan mempunyai 2 fungsi.Order Synchronous Management System Library (Single Server)
Perpustakaan kelas templat. Strategi ini kemudian boleh menggunakan fungsi berikut.
Contoh penggunaan adalah dimain
fungsi dalam perpustakaan sistem pengurusan sinkronis pesanan (Single Server):
// Invocation example of the strategy in the template
function main() {
// Clear all logs
LogReset(1)
// Switch to OKEX simulated bot test
exchanges[0].IO("simulate", true)
// Set contract
exchanges[0].SetCurrency("ETH_USDT")
exchanges[0].SetContractType("swap")
// Timed trading time interval
var tradeInterval = 1000 * 60 * 3 // trade every three minutes, to observe the order supervising signal
var lastTradeTS = new Date().getTime()
while (true) {
// Other logic of the strateg...
// Used to test the simulated trade trigger
var ts = new Date().getTime()
var ts = new Date().getTime()
if (ts - lastTradeTS > tradeInterval) {
Log("Simulated strategy with orders has trades, and positions changed", "#FF0000")
exchanges[0].SetDirection("buy")
exchanges[0].Buy(-1, 1)
lastTradeTS = ts
}
// Use the interface function of the template
$.PosMonitor(0, "ETH_USDT", "swap") // You can set multiple monitors to monitor different exchange objects on an strategy with orders
var tbl = $.getTbl()
// Display the status bar
LogStatus(_D(), "\n" + "`" + JSON.stringify(tbl) + "`")
Sleep(1000)
}
}
Perpustakaan templat itu sendiri juga boleh membuat bot strategi, yang biasanya digunakan untuk menguji perpustakaan templat. Sebagai contoh, ujian untuk templat ini.main
Fungsi dalam templat adalahmain
fungsi salah satu strategi anda sendiri.
Kod ujian ditulis untuk menggunakan bot simulasi OKEX untuk menguji, dan API KEY bot simulasi OKEX perlu dikonfigurasi di FMZ sebagai akaun rujukan (dengan pesanan), dan fungsi utama mula beralih ke bot simulasi. Kemudian atur pasangan dagangan ke ETH_USDT, dan atur kontrak untuk menukar. Kemudian masukkan gelung sementara. Dalam gelung, pesanan diletakkan setiap 3 minit untuk mensimulasikan pencetus perdagangan strategi.$.PosMonitor(0, "ETH_USDT", "swap")
dipanggil dalam gelung sementara, dan parameter pertama fungsi dipanggil adalah 0, yang bermaksud untuk memantau pertukaran objek pertukaran[0], pasangan perdagangan ETH_USDT, dan kontrak swap. Kemudian panggil$.getTbl()
untuk mendapatkan maklumat carta, dan menggunakanLogStatus(_D(), "\n" + "`" + JSON.stringify(tbl) + "`")
untuk membuat data carta yang dipaparkan pada bar status.
Jadi anda lihat, selagi$.PosMonitor(0, "ETH_USDT", "swap")
digunakan dalam strategi yang memanggil templat, strategi boleh mempunyai fungsi memantau kedudukan simbol tertentu dan mendorong mesej perubahan kedudukan.
Sebelum ujian, jelaskan reka bentuk parameterOrder Synchronous Management System Library (Single Server)
strategi:
Saya hanya bercakap tentang bagaimana untuk menggunakan fungsi antara muka templat untuk membuat peningkatan strategi dengan fungsi membawa pesanan. jadi siapa isyarat yang dihantar apabila kedudukan berubah?
Persoalan kepada siapa untuk menghantar adalah dikonfigurasikan oleh parameterorder synchronous management system library (Single Server)
.
Anda boleh melihat lima parameter, yang boleh menyokong maksimum lima push (jika anda perlu meningkatkan nombor push, anda boleh memanjangkannya sendiri); lalai parameter adalah rentetan kosong, iaitu tidak diproses.
label Label akaun selaras, digunakan untuk melabelkan akaun; nama label boleh ditetapkan secara rawak.
robotId
ID bot; ID bot daripadaorder synchronous management system (Synchronous Server)
yang dicipta oleh pemilik akaun sinkron.
aksesKey AccessKey FMZ diperluaskan API.
RahsiaKey Kunci rahsia FMZ diperluaskan API.
Kemudian, kita boleh menjalankan ujian yang mudah.
Perintah Perpustakaan Sistem Pengurusan Sinkron (Perkhidmatan Tunggal) operasi bot:
Bot Sistem Pengurusan Sinkron Perintah (Sinkron Pelayan) menerima isyarat: Perintah Sistem Pengurusan Sinkron (Synchronous Server) kini belum sepenuhnya direka oleh kita, dan kita boleh menggunakan kod yang mudah untuk mewujudkannya, tanpa perdagangan, hanya isyarat cetak:
Perintah Sistem Pengurusan Sinkron (Sinkron Pelayan) kod sementara:
function main() {
LogReset(1)
while (true) {
var cmd = GetCommand()
if (cmd) {
// cmd: ETH_USDT,swap,buy,1
Log("cmd: ", cmd)
}
Sleep(1000)
}
}
Seperti yang anda lihat, bot pemilik akaun sinkron menerima mesej:ETH_USDT,swap,buy,1
.
Oleh itu, dalam langkah seterusnya, kita boleh mengawasi pesanan secara automatik, mengikut pasangan dagangan, kod kontrak, arah dagangan dan jumlah.
Pada masa ini,order synchronous management system (Synchronous Server)
adalah hanya kod sementara, dan kita boleh membincangkan lebih lanjut reka bentuknya dalam artikel seterusnya.