Dalam artikel sebelumnya di FMZ Digest, kami telah merancang beberapa urutan dan posisi strategi sinkron.
Desain ini mengambil akun referensi dan akun sinkron ke dalam strategi yang sama untuk dikelola untuk mewujudkan sinkronisasi pesanan dan posisi. hari ini, kita dapat mencoba desain yang berbeda; berdasarkan antarmuka API diperpanjang FMZ yang kuat, di sini kita merancang sistem manajemen sinkron pesanan.
Pertama-tama, kita perlu beberapa saran dan persyaratan yang baik. dua urutan di atas sebelumnya dan posisi strategi sinkronisasi memiliki beberapa kelemahan yang jelas. mari kita bahas mereka bersama-sama:
1.Pengguna yang menerapkan strategi sinkronisasi bot harus memiliki KEY API platform akun referensi dan KEY API akun sinkronisasi. Untuk skenario penggunaan, masalahnya adalah: tidak apa-apa jika akun platform Anda yang lain mengikuti salah satu akun Anda sendiri. Tetapi bisa menjadi merepotkan untuk skenario di mana akun referensi dan akun sinkronisasi tidak memiliki pemilik yang sama. Pemilik akun sinkronisasi kadang-kadang tidak mau memberikan KEY API akun platformnya karena pertimbangan keamanan. Tapi bagaimana cara menempatkan pesanan untuk perdagangan secara sinkronis tanpa memberikan KEY API?
Solusi:
Menggunakan FMZ diperluas API, pemilik akun sinkronisasi (pemelihara pesanan) hanya perlu mendaftarkan platform perdagangan FMZ Quant, dan kemudian menjalankan strategi (dalam sistem yang dirancang dalam artikel ini:Order Synchronous Management System (Synchronous Server)
Kemudian, KEY API diperpanjang FMZ (perhatikan bahwa itu bukan KEY API akun platform) dan ID bot dari sistem manajemen sinkronisasi pesanan (Synchronous Server) akan diberikan kepada pemilik akun referensi (pemilik pesanan).
Ketika bot dari pemilik akun referensi (pemilik order) (Order Synchronous Management System Library (Single Server)
dalam sistem yang dirancang dalam artikel) mengirim sinyal, pemilik akun sinkronisasi
2.Banyak pengembang memiliki strategi yang lebih baik dan tidak dapat menggunakan dua strategi sinkronisasi urutan dan posisi sebelumnya yang dijelaskan di atas. Karena itu perlu menggabungkan strategi mereka sendiri dengan strategi sinkronisasi ini, dan strategi mereka mungkin perlu dimodifikasi secara besar-besaran, yang memakan waktu dan tenaga. Apakah ada cara yang baik untuk secara langsung meningkatkan beberapa strategi matang Anda ke mereka dengan fungsi sinkronisasi urutan?
Solusi:
Anda dapat merancang perpustakaan template sinkron order (theOrder Synchronous Management System Library (Single Server)
strategi dalam sistem yang dirancang dalam artikel), sehingga pemilik akun referensi (pemilik pesanan) dapat langsung memasukkan perpustakaan template ini ke dalam strategi sendiri untuk mencapai sinkronisasi urutan dan posisi.
3. Mengurangi bot tambahan Kelemahan terakhir adalah bahwa jika Anda menggunakan dua perintah sebelumnya dan strategi sinkronisasi posisi yang dijelaskan di atas, perlu untuk membuka posisi tambahan dari akun referensi (akun dengan pesanan) untuk pemantauan bot. Solusi: Gunakan perpustakaan template untuk menyematkan fungsi ke dalam strategi akun referensi.
Oleh karena itu, sistem ini terdiri dari dua bagian: Perpustakaan sistem manajemen sinkron order (Single Server) 2.Sistem manajemen sinkron pesanan (Synchronous Server)
Setelah kita memastikan tuntutan kita, mari kita mulai merancang!
Perhatikan bahwa di sini bukan strategi, tetapi perpustakaan template FMZ, yang dapat dicari dalam dokumentasi FMZ API dan kita tidak akan membahas di sini.
Kode template:
// 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)
}
}
Desainnya sangat sederhana, perpustakaan memiliki 2 fungsi.Order Synchronous Management System Library (Single Server)
template class library. Strategi ini kemudian dapat menggunakan fungsi berikut.
Contoh penggunaan adalah padamain
fungsi dalam perpustakaan sistem manajemen sinkron 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)
}
}
Sebuah perpustakaan template sendiri juga dapat membuat bot strategi, yang biasanya digunakan untuk menguji perpustakaan template.main
Fungsi dalam template adalahmain
fungsi dari salah satu strategi Anda sendiri.
Kode uji ditulis untuk menggunakan OKEX simulated bot untuk menguji, dan API KEY dari OKEX simulated bot perlu dikonfigurasi di FMZ sebagai akun referensi (dengan pesanan), dan fungsi utama mulai beralih ke bot yang disimulasikan. Kemudian atur pasangan perdagangan ke ETH_USDT, dan atur kontrak untuk swap. Kemudian masukkan loop sementara. Dalam loop, sebuah order ditempatkan setiap 3 menit untuk mensimulasikan pemicu perdagangan strategi.$.PosMonitor(0, "ETH_USDT", "swap")
disebut dalam loop sementara, dan parameter pertama dari fungsi yang dipanggil adalah 0, yang berarti untuk memantau pertukaran objek pertukaran[0], pasangan perdagangan ETH_USDT, dan kontrak swap.$.getTbl()
untuk mendapatkan informasi grafik, dan menggunakanLogStatus(_D(), "\n" + "`" + JSON.stringify(tbl) + "`")
untuk membuat data grafik ditampilkan pada bilah status.
Jadi Anda lihat, selama$.PosMonitor(0, "ETH_USDT", "swap")
digunakan dalam strategi yang memanggil template, strategi dapat memiliki fungsi untuk memantau posisi simbol tertentu dan mendorong pesan perubahan posisi.
Sebelum pengujian, jelaskan desain parameter dariOrder Synchronous Management System Library (Single Server)
strategi:
Saya baru saja berbicara tentang bagaimana menggunakan fungsi antarmuka templat untuk membuat upgrade strategi dengan fungsi membawa pesanan. jadi siapa sinyal yang dikirim ketika posisi berubah?
Pertanyaan siapa yang akan dikirim dikonfigurasi oleh parameter dariorder synchronous management system library (Single Server)
.
Anda dapat melihat lima parameter, yang dapat mendukung maksimum lima push (jika Anda perlu meningkatkan nomor push, Anda dapat memperpanjangnya sendiri); standar parameter adalah string kosong, yaitu tidak diproses.
label Label akun sinkron, digunakan untuk memberi label akun; nama label dapat ditetapkan secara acak.
robotId
ID bot; ID bot dariorder synchronous management system (Synchronous Server)
dibuat oleh pemilik akun sinkron.
aksesKey AccessKey dari FMZ diperluas API.
RahasiaKey Kunci rahasia dari FMZ diperpanjang API.
Kemudian, kita bisa melakukan tes sederhana.
Perintah Perpustakaan Sistem Manajemen Sinkron (Single Server) operasi bot:
Order Synchronous Management System (Synchronous Server) bot menerima sinyal: Order Synchronous Management System (Synchronous Server) sekarang belum sepenuhnya dirancang oleh kita, dan kita dapat menggunakan kode sederhana untuk merealisasikannya, tanpa perdagangan, hanya mencetak sinyal:
Order Synchronous Management System (Synchronous Server) kode 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 akun sinkron menerima pesan:ETH_USDT,swap,buy,1
Aku tidak tahu.
Dengan demikian, pada langkah berikutnya, kita dapat mengawasi pesanan secara otomatis, sesuai dengan pasangan perdagangan, kode kontrak, arah perdagangan dan volume.
Saat ini,order synchronous management system (Synchronous Server)
hanya kode sementara, dan kita bisa membahas lebih lanjut desainnya di artikel berikutnya.