Desain Sistem Manajemen Sinkron Berbasis FMZ (1)

Penulis:Ninabadass, Dibuat: 2022-04-06 15:08:26, Diperbarui: 2022-04-24 18:00:51

Desain Sistem Manajemen Sinkron Berbasis FMZ (1)

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.

Pemikiran Desain

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 bot akan menerima sinyal perdagangan.

  • 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!

Desain 1: Perintahkan Perpustakaan Sistem Manajemen Sinkron (Single Server)

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.

  • $. PosMonitor Efek dari fungsi ini adalah untuk memantau perubahan posisi objek pertukaran dalam strategi, dan kemudian mengirim sinyal perdagangan ke bot yang ditetapkan dalam parameter template: order synchronous management system library (Single Server).
  • $.getTbl Fungsi ini mengembalikan data sinkron yang dipantau.

Contoh penggunaan adalah padamainfungsi 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.mainFungsi dalam template adalahmainfungsi 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).

img

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:

img

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)
    }
}

img

Seperti yang Anda lihat, bot pemilik akun sinkron menerima pesan:ETH_USDT,swap,buy,1Aku 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.


Lebih banyak