avatar of 发明者量化-小小梦 发明者量化-小小梦
fokus pada mesej peribadi
4
fokus pada
1271
Pengikut

Reka bentuk sistem pengurusan penyegerakan pesanan berdasarkan kuantifikasi FMZ (1)

Dicipta dalam: 2022-02-14 19:46:30, dikemas kini pada: 2025-05-16 16:36:53
comments   11
hits   1939

Reka bentuk sistem pengurusan penyegerakan pesanan berdasarkan kuantifikasi FMZ (1)

Reka bentuk sistem pengurusan penyegerakan pesanan berdasarkan kuantifikasi FMZ (1)

Dalam artikel Perpustakaan FMZ sebelum ini, kami telah mereka beberapa strategi penyegerakan susunan dan kedudukan.

Ini adalah untuk meletakkan akaun rujukan dan akaun penyegerakan ke dalam satu strategi untuk mengurus dan menyegerakkan pesanan dan kedudukan. Hari ini kami akan mencuba reka bentuk yang berbeza Berdasarkan antara muka API lanjutan yang berkuasa bagi platform dagangan kuantitatif FMZ, kami akan mereka bentuk sistem pengurusan penyegerakan pesanan.

Idea reka bentuk

Pertama sekali kita memerlukan beberapa cadangan dan keperluan yang baik. Dua strategi penyegerakan susunan dan kedudukan sebelumnya di atas mempunyai beberapa titik kesakitan yang jelas Mari kita bincangkannya bersama-sama:

  • 1. Pelaksana strategi penyegerakan mesti mempunyai KEY API pertukaran akaun rujukan dan KEY API pertukaran akaun penyegerakan. Senario penggunaan untuk isu ini ialah: tidak mengapa untuk akaun pertukaran anda yang lain mengikuti salah satu akaun anda sendiri. Tetapi ia akan menyusahkan jika akaun rujukan dan akaun penyegerakan tidak mempunyai pemilik yang sama. Kadangkala, disebabkan kebimbangan keselamatan, pemilik akaun yang disegerakkan tidak bersedia untuk memberikan KUNCI API akaun pertukarannya. Tetapi bagaimana saya boleh membuat pesanan secara serentak tanpa menyediakan API KEY?

Penyelesaian: Menggunakan antara muka API lanjutan FMZ, pemilik akaun penyegerakan (pengikut) hanya perlu mendaftarkan platform dagangan kuantitatif FMZ dan kemudian menjalankan strategi (dalam sistem yang direka dalam artikel ini:订单同步管理系统(Synchronous Server)Strategi pasaran sebenar). Kemudian berikan KUNCI API lanjutan FMZ (nota, bukan KUNCI API akaun pertukaran) dan ID masa nyata sistem pengurusan penyegerakan pesanan (Pelayan Segerak) kepada pemilik akaun rujukan (orang yang membawa pesanan) . Apabila merujuk kepada susunan sebenar pemilik akaun (yang mempunyai pesanan) (dalam sistem yang direka dalam artikel ini)订单同步管理系统类库(Single Server)) menghantar isyarat, akaun sebenar pemilik akaun yang disegerakkan akan menerima isyarat dagangan dan membuat pesanan secara automatik selepas itu.

    1. Ramai pembangun mempunyai strategi yang lebih baik, tetapi tidak boleh menggunakan dua strategi penyegerakan susunan dan kedudukan lalu yang diterangkan di atas. Kerana itu memerlukan penyepaduan strategi sendiri dengan strategi penyegerakan ini, dan strategi itu mungkin perlu dirombak, yang akan memakan masa dan susah payah. Adakah terdapat cara yang baik untuk meningkatkan beberapa strategi matang saya terus kepada fungsi penyegerakan pesanan? Penyelesaian: Anda boleh mereka bentuk perpustakaan templat penyegerakan pesanan (sistem yang direka dalam artikel ini订单同步管理系统类库(Single Server)Strategi), membenarkan pemilik akaun rujukan (orang yang mengambil pesanan) untuk membenamkan perpustakaan templat ini secara langsung ke dalam strateginya sendiri untuk mencapai fungsi penyegerakan pesanan dan kedudukan.
    1. Kurangkan satu pesanan sebenar tambahan. Titik kesakitan terakhir ialah jika anda menggunakan dua strategi penyegerakan susunan dan kedudukan yang lalu yang diterangkan di atas. Ia adalah perlu untuk membuka akaun sebenar tambahan untuk memantau kedudukan akaun rujukan (dengan satu akaun). Penyelesaian: Gunakan perpustakaan templat untuk membenamkan fungsi ke dalam strategi akaun rujukan.

Jadi sistem ini terdiri daripada 2 bahagian: 1. Pustaka kelas sistem pengurusan penyegerakan pesanan (Pelayan Tunggal) 2. Pesanan Sistem Pengurusan Segerak (Pelayan Segerak)

Setelah keperluannya jelas, mari mula mereka bentuk!

Reka Bentuk 1: Perpustakaan Kelas Sistem Pengurusan Penyegerakan Pesanan (Pelayan Tunggal)

Ambil perhatian bahawa ini bukan strategi. Ia adalah perpustakaan kelas templat FMZ Konsep perpustakaan kelas templat boleh dicari dalam dokumentasi API FMZ, jadi saya tidak akan membincangkan butiran di sini.

Kod perpustakaan templat:

// 全局变量
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) {
        // 开仓
        var tradeDirection = type == PD_LONG ? "buy" : "sell"
        // 发送信号
        msg = symbol + "," + ct + "," + tradeDirection + "," + Math.abs(delta)        
    } else if (delta < 0) {
        // 平仓
        var tradeDirection = type == PD_LONG ? "closebuy" : "closesell"
        if (nowAmount <= 0) {
            Log("未检测到持仓")
            return 
        }
        // 发送信号
        msg = symbol + "," + ct + "," + tradeDirection + "," + Math.abs(delta)
    } else {
        throw "错误"
    }
    if (msg) {
        _.each(fmzExtendApis, function(extendApiConfig) {
            var ret = sendCommandRobotMsg(extendApiConfig[keyName_robotId], extendApiConfig[keyName_extendAccessKey], extendApiConfig[keyName_extendSecretKey], msg)
            Log("调用CommandRobot接口,", "label:", extendApiConfig[keyName_label], ", msg:", msg, ", ret:", ret)
            Sleep(1000)
        })
    }
}

$.PosMonitor = function(exIndex, symbol, ct) {    
    var ts = new Date().getTime()
    var ex = exchanges[exIndex]
    // 判断ex类型
    var exName = ex.GetName()
    var isFutures = exName.includes("Futures_")
    var exType = isFutures ? "futures" : "spot"
    if (!isFutures) {
        throw "仅支持期货跟单"
    }

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

        // 切换到对应的交易对、合约代码
        ex.SetCurrency(symbol)
        if (!ex.SetContractType(ct)) {
            throw "SetContractType failed"
        }

        // 监控持仓
        var keyInitRefPosAmount = "refPos-" + exIndex + "-" + symbol + "-" + ct    // refPos-exIndex-symbol-contractType
        var initRefPosAmount = mapInitRefPosAmount[keyInitRefPosAmount]
        if (!initRefPosAmount) {
            // 没有初始化数据,初始化          
            mapInitRefPosAmount[keyInitRefPosAmount] = getPosAmount(_C(ex.GetPosition), ct)
            initRefPosAmount = mapInitRefPosAmount[keyInitRefPosAmount]
        }

        // 监控
        var nowRefPosAmount = getPosAmount(_C(ex.GetPosition), ct)
        // 计算仓位变动
        var longPosDelta = nowRefPosAmount.long - initRefPosAmount.long
        var shortPosDelta = nowRefPosAmount.short - initRefPosAmount.short

        // 检测变动
        if (!(longPosDelta == 0 && shortPosDelta == 0)) {
            // 执行多头动作
            if (longPosDelta != 0) {
                Log(ex.GetName(), ex.GetLabel(), symbol, ct, "执行多头跟单,变动量:", longPosDelta)
                follow(nowRefPosAmount, symbol, ct, PD_LONG, longPosDelta)
            }
            // 执行空头动作
            if (shortPosDelta != 0) {
                Log(ex.GetName(), ex.GetLabel(), symbol, ct, "执行空头跟单,变动量:", shortPosDelta)
                follow(nowRefPosAmount, symbol, ct, PD_SHORT, shortPosDelta)
            }

            // 执行跟单操作后,更新
            mapInitRefPosAmount[keyInitRefPosAmount] = nowRefPosAmount
        }

        // 恢复 symbol ct
        ex.SetCurrency(buffSymbol)
        ex.SetContractType(buffCt)
    } else if (exType == "spot") {
        // 现货
    }
}

$.getTbl = function() {
    var tbl = {
        "type" : "table", 
        "title" : "同步数据", 
        "cols" : [], 
        "rows" : []
    }
    // 构造表头
    tbl.cols.push("监控账户:refPos-exIndex-symbol-contractType")
    tbl.cols.push(`监控持仓:{"时间戳":xxx,"多头持仓量":xxx,"空头持仓量":xxx}`)
    _.each(fmzExtendApis, function(extendApiData, index) {
        tbl.cols.push(keyName_robotId + "-" + index)
    })
    
    // 写入数据
    _.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
}

// 引用该模板类库的策略调用范例
function main() {
    // 清除所有日志
    LogReset(1)

    // 切换到OKEX 模拟盘测试
    exchanges[0].IO("simulate", true)

    // 设置合约
    exchanges[0].SetCurrency("ETH_USDT")
    exchanges[0].SetContractType("swap")

    // 定时交易时间间隔
    var tradeInterval = 1000 * 60 * 3        // 三分钟交易一次,用于观察跟单信号
    var lastTradeTS = new Date().getTime()
    
    while (true) {
        // 策略其它逻辑...

        // 用于测试的模拟交易触发
        var ts = new Date().getTime()
        if (ts - lastTradeTS > tradeInterval) {
            Log("模拟带单策略发生交易,持仓变化", "#FF0000")
            exchanges[0].SetDirection("buy")
            exchanges[0].Buy(-1, 1)
            lastTradeTS = ts
        }

        // 使用模板的接口函数
        $.PosMonitor(0, "ETH_USDT", "swap")    // 可以设置多个监控,监控带单策略上的不同的exchange对象  
        var tbl = $.getTbl()
        
        // 显示状态栏
        LogStatus(_D(), "\n" + "`" + JSON.stringify(tbl) + "`")
        Sleep(1000)
    }
}

Reka bentuknya sangat mudah, perpustakaan kelas ini mempunyai 2 fungsi berfungsi. Apabila strategi dagangan terprogram pada platform FMZ merujuk订单同步管理系统类库(Single Server)Selepas perpustakaan templat. Strategi ini boleh dilaksanakan menggunakan fungsi berikut.

  • $.PosMonitor Fungsinya adalah untuk memantau perubahan kedudukan objek pertukaran dalam strategi, dan kemudian menghantar isyarat dagangan ke pasaran sebenar yang ditetapkan dalam parameter templat: Perpustakaan Kelas Sistem Pengurusan Penyegerakan Pesanan (Pelayan Tunggal).

  • $.getTbl Mengembalikan data penyegerakan yang dipantau.

Contoh penggunaan adalah dalam: Templat Perpustakaan Kelas Sistem Pengurusan Penyegerakan (Pelayan Tunggal).mainDalam fungsi:

// 引用该模板类库的策略调用范例
function main() {
    // 清除所有日志
    LogReset(1)

    // 切换到OKEX 模拟盘测试
    exchanges[0].IO("simulate", true)

    // 设置合约
    exchanges[0].SetCurrency("ETH_USDT")
    exchanges[0].SetContractType("swap")

    // 定时交易时间间隔
    var tradeInterval = 1000 * 60 * 3        // 三分钟交易一次,用于观察跟单信号
    var lastTradeTS = new Date().getTime()
    
    while (true) {
        // 策略其它逻辑...

        // 用于测试的模拟交易触发
        var ts = new Date().getTime()
        if (ts - lastTradeTS > tradeInterval) {
            Log("模拟带单策略发生交易,持仓变化", "#FF0000")
            exchanges[0].SetDirection("buy")
            exchanges[0].Buy(-1, 1)
            lastTradeTS = ts
        }

        // 使用模板的接口函数
        $.PosMonitor(0, "ETH_USDT", "swap")    // 可以设置多个监控,监控带单策略上的不同的exchange对象  
        var tbl = $.getTbl()
        
        // 显示状态栏
        LogStatus(_D(), "\n" + "`" + JSON.stringify(tbl) + "`")
        Sleep(1000)
    }
}

Pustaka templat itu sendiri juga boleh mencipta strategi sebenar, yang biasanya digunakan untuk menguji perpustakaan templat. Sebagai contoh, ujian templat ini. Anda boleh memahami templatmainFungsi ialah strategi anda sendiri.mainfungsi.

Kod ujian ditulis untuk menggunakan ujian cakera simulasi OKEX Ia adalah perlu untuk mengkonfigurasi cakera simulasi OKEX KEY API pada FMZ sebagai akaun rujukan (dengan pesanan), dan mula bertukar kepada cakera simulasi dalam fungsi utama. Kemudian tetapkan pasangan dagangan kepada ETH_USDT dan kontrak kepada kekal (swap). Kemudian masukkan gelung sementara. Pesanan dibuat setiap 3 minit dalam kitaran untuk mensimulasikan pencetus perdagangan strategi. Gelung sementara memanggil$.PosMonitor(0, "ETH_USDT", "swap")Parameter pertama fungsi ini dihantar sebagai 0, menunjukkan pertukaran pemantauan[0] Objek pertukaran ini memantau pasangan dagangan ETH_USDT dan kontrak swap. Kemudian telefon$.getTbl()Untuk mendapatkan maklumat carta, gunakanLogStatus(_D(), "\n" + "” + JSON.stringify(tbl) + “")Membolehkan data carta dipaparkan pada bar status.

Jadi anda lihat, selagi anda menggunakannya dalam dasar yang merujuk templat ini$.PosMonitor(0, "ETH_USDT", "swap"), strategi boleh dilengkapi dengan fungsi memantau kedudukan produk tertentu dan menghantar mesej berdasarkan perubahan kedudukan.

Sebelum ujian, sila jelaskan订单同步管理系统类库(Single Server)Reka bentuk parameter strategi: Saya baru sahaja bercakap tentang cara menggunakan fungsi antara muka templat untuk membolehkan peningkatan strategi mempunyai satu fungsi. Jadi kepada siapa isyarat dihantar apabila kedudukan berubah? Kepada siapa soalan ini dihantar ditentukan oleh订单同步管理系统类库(Single Server)Parameter untuk dikonfigurasikan.

Reka bentuk sistem pengurusan penyegerakan pesanan berdasarkan kuantifikasi FMZ (1)

Anda boleh melihat bahawa terdapat 5 parameter, menyokong sehingga 5 tolakan (anda boleh mengembangkannya jika anda perlu meningkatkannya), dan parameter lalai kepada rentetan kosong, yang bermaksud ia tidak diproses. Format rentetan konfigurasi: label, robotId, accessKey, secretKey

  • label Label akaun yang disegerakkan digunakan untuk menandakan akaun tertentu, dan nama boleh ditetapkan sesuka hati.

  • robotId ID sebenar, dibuat oleh pemilik akaun penyegerakan订单同步管理系统(Synchronous Server)ID transaksi sebenar.

  • accessKey Kekunci akses API lanjutan FMZ

  • secretKey Kekunci rahsia API lanjutan FMZ

Seterusnya kita boleh melakukan ujian mudah.

Perpustakaan kelas sistem pengurusan penyegerakan pesanan (Pelayan Tunggal) operasi cakera sebenar:

Reka bentuk sistem pengurusan penyegerakan pesanan berdasarkan kuantifikasi FMZ (1)

Sistem pengurusan penyegerakan pesanan (Synchronous Server) menerima isyarat: Kami belum menyelesaikan reka bentuk sistem pengurusan penyegerakan pesanan (Pelayan Segerak Mari kita laksanakan dahulu dengan kod mudah yang tidak membuat transaksi tetapi hanya mencetak isyarat:

Kod sementara sistem pengurusan penyegerakan pesanan (Pelayan Segerak):

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

Reka bentuk sistem pengurusan penyegerakan pesanan berdasarkan kuantifikasi FMZ (1)

Anda boleh melihat bahawa akaun sebenar pemilik akaun penyegerakan telah menerima maklumat:ETH_USDT,swap,buy,1。 Dengan cara ini, langkah seterusnya ialah mengikut transaksi secara automatik mengikut pasangan transaksi, kod kontrak, arah transaksi dan kuantiti dalam maklumat.

pada masa ini订单同步管理系统(Synchronous Server)Ini hanyalah kod sementara Kami akan terus meneroka reka bentuknya dalam keluaran seterusnya.