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

Pemula dalam Dagangan Kuantitatif dalam Bulatan Mata Wang Kripto, sila lihat ini - Membawa Anda Lebih Dekat dengan Dagangan Kuantitatif dalam Bulatan Mata Wang Kripto (VI)

Dicipta dalam: 2021-06-04 10:08:48, dikemas kini pada: 2024-12-04 21:14:15
comments   6
hits   2596

Pemula dalam Dagangan Kuantitatif dalam Bulatan Mata Wang Kripto, sila lihat ini - Membawa Anda Lebih Dekat dengan Dagangan Kuantitatif dalam Bulatan Mata Wang Kripto (VI)

Pemula dalam Dagangan Kuantitatif dalam Bulatan Mata Wang Kripto, sila lihat ini - Membawa Anda Lebih Dekat dengan Dagangan Kuantitatif dalam Bulatan Mata Wang Kripto (VI)

Dalam artikel sebelumnya, kami bekerjasama untuk mencipta strategi grid mudah Dalam artikel ini, kami akan meningkatkan dan mengembangkan strategi ini kepada strategi grid spot berbilang pelbagai dan menguji strategi ini dalam pertempuran sebenar. Tujuannya bukan untuk mencari “holy grail”, tetapi untuk meneroka pelbagai masalah dan penyelesaian apabila mereka strategi. Artikel ini akan menerangkan beberapa pengalaman saya dalam mereka bentuk strategi ini. Kandungan artikel ini sedikit rumit dan memerlukan asas tertentu dalam pengaturcaraan.

Reka bentuk pemikiran berdasarkan keperluan strategik

Artikel ini, seperti yang sebelumnya, masih membincangkan reka bentuk berdasarkan Kuantiti Pencipta (FMZ.COM).

  • Pelbagai jenis Secara terang-terangan, saya fikir strategi grid ini bukan sahajaBTC_USDT, boleh juga buatLTC_USDT/EOS_USDT/DOGE_USDT/ETC_USDT/ETH_USDT. Bagaimanapun, untuk pasangan dagangan spot, semua produk yang anda ingin berdagang boleh didagangkan secara grid pada masa yang sama.

Um~~Rasanya bagus untuk menguasai pasaran yang tidak menentu pelbagai jenis. Keperluan itu kelihatan mudah, tetapi masalah timbul semasa reka bentuk.

    1. Pertama, dapatkan maklumat pasaran pelbagai jenis. Ini adalah masalah pertama yang perlu diselesaikan. Selepas menyemak dokumentasi API pertukaran, saya mendapati bahawa kebanyakan bursa menyediakan antara muka maklumat pasaran terkumpul. OK, gunakan antara muka data pasaran agregat untuk mendapatkan data.
    1. Masalah kedua yang dihadapi ialah aset akaun. Oleh kerana kami ingin melaksanakan strategi pelbagai kepelbagaian, kami perlu mempertimbangkan pengurusan aset yang berasingan untuk setiap transaksi. Dan untuk mendapatkan data dan rekod semua aset sekaligus. Mengapakah kita perlu mendapatkan data aset akaun? Adakah kita perlu menyimpan rekod berasingan untuk setiap pasangan transaksi? Kerana anda perlu menilai aset yang ada semasa membuat pesanan, adakah anda perlu mendapatkannya sebelum membuat penghakiman? Dan anda perlu mengira pendapatan Adakah anda juga perlu merekodkan data aset akaun awal dahulu, dan kemudian mendapatkan data aset akaun semasa dan membandingkannya dengan yang awal untuk mengira untung dan rugi? Nasib baik, antara muka akaun aset bursa biasanya mengembalikan data aset semua mata wang Kami hanya perlu mendapatkannya sekali dan kemudian memproses data.
    1. Reka bentuk parameter strategi. Reka bentuk parameter pelbagai jenis agak berbeza daripada jenis tunggal, kerana walaupun logik dagangan setiap varieti adalah sama, parameter semasa perdagangan mungkin berbeza. Sebagai contoh, dalam strategi grid, anda mungkin ingin berdagang 0.01 BTC setiap kali semasa melakukan pasangan dagangan BTC_USDT Walau bagaimanapun, jika anda masih menggunakan parameter ini (berdagang 0.01 syiling) apabila melakukan DOGE_USDT, sudah tentu, anda boleh juga mengendalikannya mengikut jumlah USDT. Tetapi masih akan ada masalah. Bagaimana jika anda hanya mahu berdagang 1000U dengan BTC_USDT dan 10U dengan DOGE_USDT Permintaan tidak boleh dipenuhi? Sesetengah pelajar mungkin berfikir tentang soalan ini dan kemudian berkata: “Saya boleh menetapkan beberapa kumpulan parameter untuk mengawal parameter pasangan dagangan yang berbeza secara berasingan.” Ini masih tidak dapat memenuhi keperluan secara fleksibel Berapa banyak kumpulan parameter yang perlu ditetapkan? Tiga set parameter ditetapkan Bagaimana jika saya ingin berdagang 4 jenis? Adakah mungkin untuk mengubah suai strategi dan menambah parameter? Oleh itu, apabila mereka bentuk parameter strategi pelbagai variasi, kita mesti mempertimbangkan sepenuhnya permintaan untuk parameter yang dibezakan Satu penyelesaian adalah untuk mereka bentuk parameter sebagai rentetan biasa atau rentetan JSON. Contohnya:
    ETHUSDT:100:0.002|LTCUSDT:20:0.1
    

    “|” memisahkan data setiap varieti, yang bermaksudETHUSDT:100:0.002Ia mengawal pasangan dagangan ETH_USDT.LTCUSDT:20:0.1Ia mengawal pasangan dagangan LTC_USDT. “|” di tengah berfungsi sebagai pemisah. ETHUSDT:100:0.002, di mana ETHUSDT menunjukkan pasangan dagangan yang anda ingin berdagang, 100 ialah jarak grid, 0.002 ialah bilangan syiling ETH yang didagangkan dalam setiap grid, dan tanda “:” digunakan untuk memisahkan data ini (sudah tentu, peraturan parameter ini adalah ditetapkan oleh pereka strategi). Anda boleh mereka bentuk mengikut keperluan anda). Rentetan ini mengandungi maklumat parameter bagi setiap produk yang ingin anda niagakan. Parsing rentetan ini dalam strategi dan tetapkan nilai khusus kepada pembolehubah strategi untuk mengawal logik dagangan setiap produk. Jadi bagaimana untuk menghuraikannya? Mari kita gunakan contoh di atas sekali lagi.

    function main() {
        var net = []  // 记录的网格参数,具体运行到网格交易逻辑时,使用这里面的数据
        var params = "ETHUSDT:100:0.002|LTCUSDT:20:0.1"
        var arrPair = params.split("|")
        _.each(arrPair, function(pair) {
            var arr = pair.split(":")
            var symbol = arr[0]              // 交易对名称
            var diff = parseFloat(arr[1])    // 网格间距
            var amount = parseFloat(arr[2])  // 网格下单量
            net.push({symbol : symbol, diff : diff, amount : amount})
        })
        Log("网格参数数据:", net)
    }
    

    Pemula dalam Dagangan Kuantitatif dalam Bulatan Mata Wang Kripto, sila lihat ini - Membawa Anda Lebih Dekat dengan Dagangan Kuantitatif dalam Bulatan Mata Wang Kripto (VI)

    Anda boleh melihat bahawa parameter dihuraikan dengan cara ini Sudah tentu, anda juga boleh menggunakan rentetan JSON secara langsung, yang lebih mudah.

    function main() {        
        var params = '[{"symbol":"ETHUSDT","diff":100,"amount":0.002},{"symbol":"LTCUSDT","diff":20,"amount":0.1}]'
        var net = JSON.parse(params)  // 记录的网格参数,具体运行到网格交易逻辑时,使用这里面的数据        
        _.each(net, function(pair) {
            Log("交易对:", pair.symbol, pair)
        })
    }
    

    Pemula dalam Dagangan Kuantitatif dalam Bulatan Mata Wang Kripto, sila lihat ini - Membawa Anda Lebih Dekat dengan Dagangan Kuantitatif dalam Bulatan Mata Wang Kripto (VI)

    1. Kegigihan data Terdapat juga perbezaan besar antara strategi yang boleh digunakan secara praktikal dan strategi pengajaran Strategi pengajaran dalam artikel sebelum ini hanyalah ujian awal bagi logik dan reka bentuk strategi. Semasa dagangan sebenar, anda boleh memulakan dan menghentikan dagangan sebenar. Pada masa ini, semua data semasa operasi masa nyata akan hilang. Jadi bagaimana kita boleh membuat cakera sebenar berhenti dan kemudian mulakan semula untuk terus berjalan dalam keadaan sebelumnya? Di sini, adalah perlu untuk mengekalkan data utama semasa operasi masa nyata supaya data boleh dibaca dan diteruskan apabila sistem dimulakan semula. Ia boleh digunakan pada Platform Dagangan Kuantitatif Pencipta_G()Fungsi, atau gunakan fungsi operasi pangkalan dataDBExec()Untuk butiran, sila rujuk dokumentasi API FMZ.

    Sebagai contoh, kami mereka bentuk fungsi sapuan, menggunakan_G()Berfungsi, simpan data grid.

    var net = null 
    function main() {  // 策略主函数
        // 首先读取储存的net
        net = _G("net")
    
    
        // ...
    }
    
    
    function onExit() {
        _G("net", net)
        Log("执行扫尾处理,保存数据", "#FF0000")
    }
    
    
    function onexit() {    // 平台系统定义的退出扫尾函数,在点击实盘停止时触发执行
        onExit()
    }
    
    
    function onerror() {   // 平台系统定义的异常退出函数,在程序发生异常时触发执行
        onExit()
    }
    
    1. Sekatan ke atas ketepatan kuantiti pesanan, ketepatan harga pesanan, kuantiti pesanan minimum, jumlah pesanan minimum, dsb.

    Sistem backtest tidak mengenakan sekatan ketat terhadap kuantiti pesanan dan ketepatan pesanan, tetapi dalam perdagangan sebenar, setiap pertukaran mungkin mempunyai piawaian yang ketat untuk harga pesanan dan kuantiti pesanan, dan piawaian ini untuk setiap pasangan dagangan juga sangat ketat yang sama. Oleh itu, pemula sering menguji sistem ujian belakang dan melihat semua jenis masalah apabila mencetuskan urus niaga di pasaran sebenar Mereka kemudiannya tidak membaca mesej ralat dan mengalami semua jenis masalah gila [kepala anjing].

    Untuk pelbagai jenis, keperluan ini lebih rumit. Untuk strategi produk tunggal, anda boleh mereka bentuk parameter untuk menentukan maklumat seperti ketepatan Walau bagaimanapun, apabila mereka bentuk strategi berbilang produk, adalah jelas bahawa menulis maklumat ini ke dalam parameter akan menjadikan parameter kelihatan sangat kembung.

    Pada masa ini, anda perlu menyemak dokumentasi API pertukaran untuk melihat sama ada terdapat antara muka dengan maklumat berkaitan pasangan dagangan dalam dokumentasi pertukaran. Jika antara muka ini tersedia, anda boleh mereka bentuk antara muka akses automatik dalam strategi untuk mendapatkan maklumat seperti ketepatan, dan mengkonfigurasinya kepada maklumat pasangan dagangan yang terlibat dalam urus niaga (dalam istilah mudah, ketepatan diminta secara automatik daripada bursa, dan kemudian disesuaikan dengan parameter strategi).

    1. Penyesuaian kepada pertukaran yang berbeza Mengapa meletakkan soalan ini di penghujung? Kerana penyelesaian kepada masalah yang kami bincangkan di atas akan membawa masalah terakhir ini, kerana strategi kami merancang untuk menggunakan antara muka pasaran agregat, mengakses ketepatan pasangan dagangan pertukaran dan penyesuaian data lain, mengakses maklumat akaun dan memproses setiap pasangan dagangan secara berasingan, dsb. Penyelesaian ini akan Terdapat perbezaan besar antara pertukaran. Terdapat perbezaan dalam panggilan antara muka dan perbezaan dalam mekanisme. Untuk pertukaran spot, perbezaannya lebih kecil jika strategi grid ini dikembangkan kepada versi niaga hadapan. Perbezaan dalam mekanisme pelbagai pertukaran adalah lebih besar. Satu penyelesaian adalah untuk mereka bentuk perpustakaan templat FMZ. Tulis dan reka bentuk pelaksanaan yang berbeza ini dalam perpustakaan kelas. Kurangkan gandingan antara strategi itu sendiri dan pertukaran. Kelemahan melakukan ini ialah anda perlu menulis perpustakaan templat dan melaksanakannya secara khusus untuk setiap pertukaran dalam templat ini.

Reka bentuk perpustakaan templat

Berdasarkan analisis di atas, perpustakaan templat direka untuk mengurangkan gandingan antara strategi dan mekanisme pertukaran dan antara muka.

Kita boleh mereka bentuk perpustakaan kelas templat ini seperti ini (beberapa kod ditinggalkan):

function createBaseEx(e, funcConfigure) {
    var self = {}
    self.e = e 
    
    self.funcConfigure = funcConfigure
    self.name = e.GetName()
    self.type = self.name.includes("Futures_") ? "Futures" : "Spot"
    self.label = e.GetLabel()
    
    // 需要实现的接口
    self.interfaceGetTickers = null   // 创建异步获取聚合行情数据线程的函数
    self.interfaceGetAcc = null       // 创建异步获取账户数据线程的函数
    self.interfaceGetPos = null       // 获取持仓
    self.interfaceTrade = null        // 创建并发下单
    self.waitTickers = null           // 等待并发行情数据 
    self.waitAcc = null               // 等待账户并发数据
    self.waitTrade = null             // 等待下单并发数据
    self.calcAmount = null            // 根据交易对精度等数据计算下单量
    self.init = null                  // 初始化工作,获取精度等数据
    
    // 执行配置函数,给对象配置
    funcConfigure(self)

    // 检测configList约定的接口是否都实现
    _.each(configList, function(funcName) {
        if (!self[funcName]) {
            throw "接口" + funcName + "未实现"
        }
    })
    
    return self
}

$.createBaseEx = createBaseEx
$.getConfigureFunc = function(exName) {
    dicRegister = {
        "Futures_OKCoin" : funcConfigure_Futures_OKCoin,    // OK期货的实现
        "Huobi" : funcConfigure_Huobi,
        "Futures_Binance" : funcConfigure_Futures_Binance,
        "Binance" : funcConfigure_Binance,
        "WexApp" : funcConfigure_WexApp,                    // wexApp的实现
    }
    return dicRegister
}

Dalam templat, tuliskannya untuk pelaksanaan pertukaran khusus, sebagai contoh, ambil cakera simulasi FMZ WexApp sebagai contoh:

function funcConfigure_WexApp(self) {
    var formatSymbol = function(originalSymbol) {
        // BTC_USDT
        var arr = originalSymbol.split("_")
        var baseCurrency = arr[0]
        var quoteCurrency = arr[1]
        return [originalSymbol, baseCurrency, quoteCurrency]
    }

    self.interfaceGetTickers = function interfaceGetTickers() {
        self.routineGetTicker = HttpQuery_Go("https://api.wex.app/api/v1/public/tickers")
    }

    self.waitTickers = function waitTickers() {
        var ret = []
        var arr = JSON.parse(self.routineGetTicker.wait()).data
        _.each(arr, function(ele) {
            ret.push({
                bid1: parseFloat(ele.buy), 
                bid1Vol: parseFloat(-1),
                ask1: parseFloat(ele.sell), 
                ask1Vol: parseFloat(-1),
                symbol: formatSymbol(ele.market)[0],
                type: "Spot", 
                originalSymbol: ele.market
            })
        })
        return ret 
    }

    self.interfaceGetAcc = function interfaceGetAcc(symbol, updateTS) {
        if (self.updateAccsTS != updateTS) {
            self.routineGetAcc = self.e.Go("GetAccount")
        }
    }

    self.waitAcc = function waitAcc(symbol, updateTS) {
        var arr = formatSymbol(symbol)
        var ret = null 
        if (self.updateAccsTS != updateTS) {
            ret = self.routineGetAcc.wait().Info
            self.bufferGetAccRet = ret 
        } else {
            ret = self.bufferGetAccRet
        }
        if (!ret) {
            return null 
        }        
        var acc = {symbol: symbol, Stocks: 0, FrozenStocks: 0, Balance: 0, FrozenBalance: 0, originalInfo: ret}
        _.each(ret.exchange, function(ele) {
            if (ele.currency == arr[1]) {
                // baseCurrency
                acc.Stocks = parseFloat(ele.free)
                acc.FrozenStocks = parseFloat(ele.frozen)
            } else if (ele.currency == arr[2]) {
                // quoteCurrency
                acc.Balance = parseFloat(ele.free)
                acc.FrozenBalance = parseFloat(ele.frozen)
            }
        })
        return acc
    }

    self.interfaceGetPos = function interfaceGetPos(symbol, price, initSpAcc, nowSpAcc) {
        var symbolInfo = self.getSymbolInfo(symbol)
        var sumInitStocks = initSpAcc.Stocks + initSpAcc.FrozenStocks
        var sumNowStocks = nowSpAcc.Stocks + nowSpAcc.FrozenStocks
        var diffStocks = _N(sumNowStocks - sumInitStocks, symbolInfo.amountPrecision)
        if (Math.abs(diffStocks) < symbolInfo.min / price) {
            return []
        }
        return [{symbol: symbol, amount: diffStocks, price: null, originalInfo: {}}]
    }

    self.interfaceTrade = function interfaceTrade(symbol, type, price, amount) {
        var tradeType = ""
        if (type == self.OPEN_LONG || type == self.COVER_SHORT) {
            tradeType = "bid"
        } else {
            tradeType = "ask"
        }
        var params = {
            "market": symbol,
            "side": tradeType,
            "amount": String(amount),
            "price" : String(-1),
            "type" : "market"
        }
        self.routineTrade = self.e.Go("IO", "api", "POST", "/api/v1/private/order", self.encodeParams(params))
    }

    self.waitTrade = function waitTrade() {
        return self.routineTrade.wait()
    }

    self.calcAmount = function calcAmount(symbol, type, price, amount) {
        // 获取交易对信息
        var symbolInfo = self.getSymbolInfo(symbol)
        if (!symbol) {
            throw symbol + ",交易对信息查询不到"
        }
        var tradeAmount = null 
        var equalAmount = null  // 记录币数
        if (type == self.OPEN_LONG || type == self.COVER_SHORT) {
            tradeAmount = _N(amount * price, parseFloat(symbolInfo.pricePrecision))
            // 检查最小交易量
            if (tradeAmount < symbolInfo.min) {
                Log(self.name, " tradeAmount:", tradeAmount, "小于", symbolInfo.min)
                return false 
            }
            equalAmount = tradeAmount / price
        } else {
            tradeAmount = _N(amount, parseFloat(symbolInfo.amountPrecision))
            // 检查最小交易量
            if (tradeAmount < symbolInfo.min / price) {
                Log(self.name, " tradeAmount:", tradeAmount, "小于", symbolInfo.min / price)
                return false 
            }
            equalAmount = tradeAmount
        }
        return [tradeAmount, equalAmount]
    }

    self.init = function init() {   // 自动处理精度等条件的函数
        var ret = JSON.parse(HttpQuery("https://api.wex.app/api/v1/public/markets"))
        _.each(ret.data, function(symbolInfo) {
            self.symbolsInfo.push({
                symbol: symbolInfo.pair,
                amountPrecision: parseFloat(symbolInfo.basePrecision),
                pricePrecision: parseFloat(symbolInfo.quotePrecision),
                multiplier: 1,
                min: parseFloat(symbolInfo.minQty),
                originalInfo: symbolInfo
            })
        })        
    }
}

Kemudian menggunakan templat ini dalam strategi adalah mudah:

function main() {
    var fuExName = exchange.GetName()
    var fuConfigureFunc = $.getConfigureFunc()[fuExName]
    var ex = $.createBaseEx(exchange, fuConfigureFunc)

    var arrTestSymbol = ["LTC_USDT", "ETH_USDT", "EOS_USDT"]
    var ts = new Date().getTime()
    
    // 测试获取行情
    ex.goGetTickers()
    var tickers = ex.getTickers()
    Log("tickers:", tickers)
    
    // 测试获取账户信息
    ex.goGetAcc(symbol, ts)
    
    _.each(arrTestSymbol, function(symbol) {        
        _.each(tickers, function(ticker) {
            if (symbol == ticker.originalSymbol) {
                // 打印行情数据
                Log(symbol, ticker)
            }
        })

        // 打印资产数据
        var acc = ex.getAcc(symbol, ts)
        Log("acc:", acc.symbol, acc)
    })
}

Strategi pasaran sebenar

Ia adalah sangat mudah untuk mereka bentuk dan menulis strategi berdasarkan templat di atas Keseluruhan strategi adalah kira-kira 300+ baris, yang melaksanakan strategi grid berbilang pelbagai tempat mata wang digital.

Pemula dalam Dagangan Kuantitatif dalam Bulatan Mata Wang Kripto, sila lihat ini - Membawa Anda Lebih Dekat dengan Dagangan Kuantitatif dalam Bulatan Mata Wang Kripto (VI)

Pemula dalam Dagangan Kuantitatif dalam Bulatan Mata Wang Kripto, sila lihat ini - Membawa Anda Lebih Dekat dengan Dagangan Kuantitatif dalam Bulatan Mata Wang Kripto (VI)

Pada masa ini kehilangan wangT_T, kod sumber tidak akan dikeluarkan buat masa ini.

Berikut ialah beberapa kod pendaftaran Jika anda berminat, anda boleh mencubanya di wexApp:

购买地址: https://www.fmz.com/m/s/284507
注册码: 
adc7a2e0a2cfde542e3ace405d216731
f5db29d05f57266165ce92dc18fd0a30
1735dca92794943ddaf277828ee04c27
0281ea107935015491cda2b372a0997d
1d0d8ef1ea0ea1415eeee40404ed09cc

Terdapat hanya lebih 200 Us, dan apabila ia mula berjalan, ia menemui pasaran berat sebelah yang besar dan perlahan-lahan pulih. Kelebihan terbesar grid spot ialah: “Anda boleh tidur lena!” Kestabilan tidak mengapa saya tidak menyentuhnya sejak 27 Mei Saya tidak berani mencuba grid niaga hadapan buat masa ini.