Reka bentuk Sistem Pengurusan Pengaturcaraan Pengaturcaraan Berasaskan FMZ Quant (1)

Penulis:Lydia, Dicipta: 2022-11-07 10:20:01, Dikemas kini: 2023-09-15 20:45:23

img

Reka bentuk Sistem Pengurusan Pengaturcaraan Pengaturcaraan Berasaskan FMZ Quant (1)

Dalam artikel sebelumnya di perpustakaan FMZs, kami telah merancang beberapa jenis strategi penyegerakan untuk urutan dan kedudukan.

Ini menguruskan akaun rujukan dan akaun diselaraskan dalam satu strategi untuk mencapai pesanan dan kedudukan penyelarasan. dan hari ini kita akan mencuba reka bentuk yang berbeza, kita akan merancang sistem pengurusan penyelarasan pesanan berdasarkan antara muka API lanjutan yang kuat dari FMZ Quant Trading Platform.

Idea Reka Bentuk

Pertama, kita memerlukan beberapa cadangan dan keperluan yang baik. dua urutan dan kedudukan sebelum ini strategi penyelarasan di atas, yang mempunyai beberapa kelemahan yang jelas, yang kita akan membincangkan bersama-sama.

    1. Pengguna strategi penyegerakan bot sebenar mesti mempunyai pertukaran API KEY akaun rujukan, dan pertukaran API KEY akaun penyegerakan. Isu ini baik untuk situasi penggunaan di mana akaun pertukaran lain mengikuti akaunnya sendiri. Walau bagaimanapun, ia boleh menjadi bermasalah untuk keadaan di mana akaun rujukan dan akaun penyegerakan bukan pemilik yang sama. Kadang-kadang pemilik akaun yang diselaraskan tidak mahu memberikan Kunci API akaun pertukaran sendiri untuk alasan keselamatan, tetapi bagaimana untuk menyelaraskan transaksi pesanan tanpa menyediakan Kunci API?

    Penyelesaian: Menggunakan antara muka API lanjutan FMZ, pemilik akaun yang diselaraskan (pengikut pesanan) hanya perlu mendaftar akaun di Platform Dagangan Kuantum FMZ, kemudian menjalankan strategi (dalam sistem yang direka dalam artikel ini:Order Synchronous ServerStrategi dalam Bot sebenar). Kemudian hanya memberikan FMZ diperluaskan API KEY (perhatikan bahawa ia bukan API KEY akaun pertukaran) dan Order Synchronous Server bot sebenar ID kepada pemilik akaun rujukan (pemimpin pesanan). Apabila pemilik akaun rujukan (pengikut pesanan) bot sebenar (pengikutOrder Synchronization Management System Class Library (Single Server)dalam sistem yang direka dalam artikel ini) menghantar isyarat, pemilik akaun penyegerakan bot sebenar akan menerima isyarat perdagangan dan meletakkan pesanan berikutnya secara automatik.

    1. Banyak pemaju mempunyai strategi yang baik, tetapi mereka tidak boleh menggunakan 2 strategi sinkronisasi urutan dan kedudukan masa lalu yang dijelaskan di atas. Kerana mereka perlu mengintegrasikan strategi mereka sendiri dengan strategi yang diselaraskan ini, dan strategi mungkin perlu diubah secara drastis, yang akan memerlukan banyak kerja dan usaha. Adakah ada cara yang baik untuk menaik taraf beberapa strategi matang anda secara langsung ke fungsi sinkronisasi pesanan? Penyelesaian: Anda boleh merancang perpustakaan kelas templat penyegerakan pesanan (yangOrder Synchronization Management System Class Library (Single Server)strategi dalam sistem yang direka dalam artikel ini), supaya pemilik akaun rujukan (order-leader) boleh menanam perpustakaan kelas templat ini ke dalam strategi sendiri secara langsung untuk mencapai fungsi urutan dan penyegerakan kedudukan.
    1. Kurangkan satu lagi bot sebenar. Kelemahan terakhir adalah bahawa jika anda menggunakan 2 pesanan terdahulu, strategi penyegerakan kedudukan yang diterangkan di atas. Penyelesaian: Gunakan perpustakaan kelas templat untuk menyematkan fungsi dalam strategi akaun rujukan.

Jadi sistem ini terdiri daripada 2 bahagian:

  1. Perpustakaan kelas sistem pengurusan penyegerakan pesanan (Single Server)
  2. Sistem pengurusan penyegerakan pesanan (Synchronous Server)

Setelah kita menentukan keperluan kita, mari kita mula merancang!

Reka bentuk 1: Perpustakaan kelas sistem pengurusan penyegerakan pesanan (Single Server)

Perhatikan bahawa ini bukan strategi. Ini adalah perpustakaan kelas templat FMZ. Konsep perpustakaan kelas templat boleh dicari dalam dokumentasi API FMZ dan kami tidak akan mengulangi lagi.

Kod perpustakaan kelas templat:

// Global variables
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 the position
        var tradeDirection = type == PD_LONG ? "buy" : "sell"
        // send signals
        msg = symbol + "," + ct + "," + tradeDirection + "," + Math.abs(delta)        
    } else if (delta < 0) {
        // close the position
        var tradeDirection = type == PD_LONG ? "closebuy" : "closesell"
        if (nowAmount <= 0) {
            Log("no positions found")
            return 
        }
        // send signals
        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 the 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 future-following is supported"
    }

    if (exType == "futures") {
        // caching symbol ct
        var buffSymbol = ex.GetCurrency()
        var buffCt = ex.GetContractType()

        // switch to the corresponding contract pair, contract code
        ex.SetCurrency(symbol)
        if (!ex.SetContractType(ct)) {
            throw "SetContractType failed"
        }

        // monitor positions
        var keyInitRefPosAmount = "refPos-" + exIndex + "-" + symbol + "-" + ct    // refPos-exIndex-symbol-contractType
        var initRefPosAmount = mapInitRefPosAmount[keyInitRefPosAmount]
        if (!initRefPosAmount) {
            // no initialization data, initialize it
            mapInitRefPosAmount[keyInitRefPosAmount] = getPosAmount(_C(ex.GetPosition), ct)
            initRefPosAmount = mapInitRefPosAmount[keyInitRefPosAmount]
        }

        // monitor
        var nowRefPosAmount = getPosAmount(_C(ex.GetPosition), ct)
        // calculate the position changes
        var longPosDelta = nowRefPosAmount.long - initRefPosAmount.long
        var shortPosDelta = nowRefPosAmount.short - initRefPosAmount.short

        // detect changes
        if (!(longPosDelta == 0 && shortPosDelta == 0)) {
            // Perform long positions
            if (longPosDelta != 0) {
                Log(ex.GetName(), ex.GetLabel(), symbol, ct, "Perform long position-following, changes in volume:", longPosDelta)
                follow(nowRefPosAmount, symbol, ct, PD_LONG, longPosDelta)
            }
            // Perform short positions
            if (shortPosDelta != 0) {
                Log(ex.GetName(), ex.GetLabel(), symbol, ct, "Perform short position-following, changes in volume:", shortPosDelta)
                follow(nowRefPosAmount, symbol, ct, PD_SHORT, shortPosDelta)
            }

            // Update after performing the order-following operation
            mapInitRefPosAmount[keyInitRefPosAmount] = nowRefPosAmount
        }

        // restore symbol ct
        ex.SetCurrency(buffSymbol)
        ex.SetContractType(buffCt)
    } else if (exType == "spot") {
        // Spots
    }
}

$.getTbl = function() {
    var tbl = {
        "type" : "table", 
        "title" : "synchronization of data", 
        "cols" : [], 
        "rows" : []
    }
    // construct the table headers
    tbl.cols.push("monitor the account: refPos-exIndex-symbol-contractType")
    tbl.cols.push(`monitor the position: {"timestamp":xxx,"long positions":xxx,"short positions":xxx}`)
    _.each(fmzExtendApis, function(extendApiData, index) {
        tbl.cols.push(keyName_robotId + "-" + index)
    })
    
    // Write data in
    _.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
}

// Example of the strategy call that references the template class library
function main() {
    // Clear all logs
    LogReset(1)

    // Switch to OKEX demo to test
    exchanges[0].IO("simulate", true)

    // Set the contract
    exchanges[0].SetCurrency("ETH_USDT")
    exchanges[0].SetContractType("swap")

    // Timed trading interval
    var tradeInterval = 1000 * 60 * 3        // Trade for every three minutes to observe the order-following signals
    var lastTradeTS = new Date().getTime()
    
    while (true) {
        // Other logic of the strategy...

        // Simulated trading triggers for testing
        var ts = new Date().getTime()
        if (ts - lastTradeTS > tradeInterval) {
            Log("Trade the simulation order-leading strategies, position changes", "#FF0000")
            exchanges[0].SetDirection("buy")
            exchanges[0].Buy(-1, 1)
            lastTradeTS = ts
        }

        // Interface functions that use templates
        $.PosMonitor(0, "ETH_USDT", "swap")    // Multiple monitors can be set up to monitor different exchange objects on the order-following strategy  
        var tbl = $.getTbl()
        
        // Display status bar
        LogStatus(_D(), "\n" + "`" + JSON.stringify(tbl) + "`")
        Sleep(1000)
    }
}

Reka bentuknya sangat mudah, perpustakaan kelas mempunyai 2 fungsi. Apabila strategi perdagangan berprogram pada platform FMZ merujuk kepada perpustakaan kelas templatOrder Synchronization Management System Class Library (Single Server). Kemudian strategi boleh menggunakan fungsi berikut.

  • $. Monitor Positif. Tujuan fungsi ini adalah untuk memantau perubahan kedudukan objek pertukaran dalam strategi dan kemudian menghantar isyarat dagangan ke pasaran bot sebenar yang ditetapkan dalam parameter templat: Perpustakaan kelas Sistem Pengurusan Pengaturan Simulasi Perintah (Perkhidmatan Tunggal).

  • $.getTbl Kembali ke data penyelarasan yang dipantau.

Contoh penggunaan adalah dalammainfungsi templat Perpustakaan Kelas Sistem Pengurusan Pengatur Simkron (Perkhidmatan Tunggal):

// Example of the strategy call that references the template class library
function main() {
    // Clear all logs
    LogReset(1)

    // Switch to OKEX demo to test
    exchanges[0].IO("simulate", true)

    // Set the contract
    exchanges[0].SetCurrency("ETH_USDT")
    exchanges[0].SetContractType("swap")

    // Timed trading interval
    var tradeInterval = 1000 * 60 * 3        // Trade for every three minutes to observe the order-following signals
    var lastTradeTS = new Date().getTime()
    
    while (true) {
        // Other logic of the strategy...

        // Simulated trading triggers for testing
        var ts = new Date().getTime()
        if (ts - lastTradeTS > tradeInterval) {
            Log("Trade the simulation order-leading strategies, position changes", "#FF0000")
            exchanges[0].SetDirection("buy")
            exchanges[0].Buy(-1, 1)
            lastTradeTS = ts
        }

        // Interface functions by using templates
        $.PosMonitor(0, "ETH_USDT", "swap")    // Multiple monitors can be set up to monitor different exchange objects on the order-following strategy  
        var tbl = $.getTbl()
        
        // Display status bar
        LogStatus(_D(), "\n" + "`" + JSON.stringify(tbl) + "`")
        Sleep(1000)
    }
}

Perpustakaan kelas templat juga boleh membuat bot sebenar strategi sendiri, yang biasanya digunakan untuk menguji perpustakaan kelas templat, seperti ujian templat.mainfungsi dalam templat adalahmainfungsi salah satu strategi anda sendiri.

Kod ujian ditulis dengan menggunakan demo OKEX untuk menguji, anda perlu mengkonfigurasi kunci API demo OKEX di FMZ sebagai akaun rujukan (pemimpin pesanan), dan ia mula beralih ke demo dalam fungsi utama. Kemudian tetapkan pasangan dagangan ke ETH_USDT dan tetapkan kontrak untuk menukar. Kemudian ia memasuki gelung sementara. Dalam gelung, pesanan diletakkan setiap 3 minit untuk mensimulasikan pencetus transaksi strategi.$.PosMonitor(0, "ETH_USDT", "swap")apabila panggilan dalam gelung sementara, parameter pertama fungsi ini dihantar ke 0, yang bermaksud untuk memantau pertukaran objek pertukaran[0], memantau pasangan perdagangan ETH_USDT, kontrak swap. Kemudian ia akan memanggil$.getTbl()untuk mendapatkan maklumat carta, menggunakanLogStatus(_D(), "\n" + "`" + JSON.stringify(tbl) + "`")untuk membuat data carta yang dipaparkan pada bar status.

Jadi kita boleh melihat bahawa kita boleh membuat strategi mempunyai keupayaan untuk memantau kedudukan spesies tertentu, dan perubahan kedudukan untuk menghantar mesej dengan menggunakan$.PosMonitor(0, "ETH_USDT", "swap")Dalam strategi yang merujuk kepada templat.

Sebelum ujian, kita akan menerangkan reka bentuk parameter strategiOrder Synchronization Management System Class Library (Single Server)- Tidak. Kami baru sahaja bercakap tentang bagaimana untuk menggunakan fungsi antara muka templat untuk menaik taraf strategi untuk mempunyai fungsi perintah-pemimpin. bagaimana dengan isyarat yang dihantar apabila kedudukan berubah, kepada siapa ia akan dihantar? Persoalan siapa yang akan dihantar dikonfigurasikan oleh parameterOrder Synchronization Management System Class Library (Single Server).

img

Kita boleh melihat bahawa terdapat 5 parameter, menyokong sehingga 5 dorongan (ia boleh dilanjutkan sendiri jika ia perlu peningkatan), parameter lalai adalah rentetan kosong, iaitu, tidak diproses. format rentetan konfigurasi: label,robotId,accessKey,secretKey

  • label Label untuk akaun penyegerakan, ia digunakan untuk menetapkan label untuk akaun dengan nama yang boleh ditetapkan mengikut kehendak.

  • robotId Robot ID, ID daripadaOrder Synchronous Serverbot sebenar yang dicipta oleh pemilik akaun sinkron.

  • aksesKey Akses API diperluaskanKey FMZ

  • RahsiaKey Rahsia API diperluaskanKey FMZ

Kod sementara Sistem Pengurusan Simkronisasi Perintah (Synchronous Server):

function main() {
    LogReset(1)
    while (true) {
        var cmd = GetCommand()
        if (cmd) {
            // cmd: ETH_USDT,swap,buy,1
            Log("cmd: ", cmd)
        }
        Sleep(1000)
    }
}

img

Kita boleh lihat bahawa bot sebenar pemilik akaun yang diselaraskan menerima mesej:ETH_USDT,swap,buy,1- Tidak. Kemudian ia akan membolehkan kita untuk membuat kami sendiri automatik order-mengikuti dalam langkah seterusnya berdasarkan trading pasangan, kod kontrak, arah perdagangan, dan jumlah dalam maklumat.

Setakat ini,Order Synchronization Management System (Synchronous Server)adalah kod sementara, kita akan terus meneroka reka bentuknya dalam isu seterusnya.


Berkaitan

Lebih lanjut