Analisis Strategi Pengumpul Keuntungan (2)

Penulis:Ninabadass, Dicipta: 2022-04-26 15:57:02, Dikemas kini: 2022-04-26 15:57:53

Analisis Strategi Pengumpul Keuntungan (2)

Mari kita teruskankandungan kali terakhiruntuk menerangkan.

Fungsi Tambahan Ketiga:

    self.balanceAccount = function() {
        var account = exchange.GetAccount()
        if (!account) {
            return
        }
        self.account = account
        var now = new Date().getTime()
        if (self.orderBook.Bids.length > 0 && now - self.preCalc > (CalcNetInterval * 1000)) {
            self.preCalc = now
            var net = _N(account.Balance + account.FrozenBalance + self.orderBook.Bids[0].Price * (account.Stocks + account.FrozenStocks))
            if (net != self.preNet) {
                self.preNet = net
                LogProfit(net)
            }
        }
        self.btc = account.Stocks
        self.cny = account.Balance
        self.p = self.btc * self.prices[self.prices.length-1] / (self.btc * self.prices[self.prices.length-1] + self.cny)
        var balanced = false
        
        if (self.p < 0.48) {
            Log("start to balance", self.p)
            self.cny -= 300
            if (self.orderBook.Bids.length >0) {
                exchange.Buy(self.orderBook.Bids[0].Price + 0.00, 0.01)
                exchange.Buy(self.orderBook.Bids[0].Price + 0.01, 0.01)
                exchange.Buy(self.orderBook.Bids[0].Price + 0.02, 0.01)
            }
        } else if (self.p > 0.52) {
            Log("start to balance", self.p)
            self.btc -= 0.03
            if (self.orderBook.Asks.length >0) {
                exchange.Sell(self.orderBook.Asks[0].Price - 0.00, 0.01)
                exchange.Sell(self.orderBook.Asks[0].Price - 0.01, 0.01)
                exchange.Sell(self.orderBook.Asks[0].Price - 0.02, 0.01)
            }
        }
        Sleep(BalanceTimeout)
        var orders = exchange.GetOrders()
        if (orders) {
            for (var i = 0; i < orders.length; i++) {
                if (orders[i].Id != self.tradeOrderId) {
                    exchange.CancelOrder(orders[i].Id)
                }
            }
        }
    }

Apabila pembinaLeeksReaper()adalah membina objek,balanceAccount()fungsi yang ditambahkan kepada objek digunakan untuk mengemas kini maklumat aset akaun yang disimpan dalamself.account, iaitu untuk membina sifataccountPerkiraan dan cetak nilai pulangan secara berkala. Kemudian, mengikut maklumat aset akaun terkini, nisbah baki simbol mata wang spot (saldo kedudukan spot) dikira, dan apabila ambang offset dicetuskan, pesanan kecil ditutup untuk membuat simbol (posisi) kembali ke keadaan seimbang. Tunggu untuk tempoh masa tertentu untuk melaksanakan perdagangan, dan kemudian batalkan semua pesanan yang belum selesai, dan pelaksanaan fungsi dalam pusingan seterusnya, baki akan dikesan lagi dan pemprosesan yang sesuai akan dilakukan.

Mari kita lihat kod pernyataan fungsi ini dengan pernyataan: Pertama sekali, pernyataan pertamavar account = exchange.GetAccount()menyatakan pembolehubah tempatanaccount, memanggilexchange.GetAccount()fungsi dalam antara muka FMZ API, mendapatkan data terkini akaun semasa dan menetapkannya kepada pembolehubahaccount. Kemudian, menilai pembolehubahaccount; jika nilai pembolehubah adalahnull(yang akan berlaku apabila ia gagal untuk mendapatkan pembolehubah, seperti masa lapang, rangkaian, platform antara muka pengecualian, dan lain-lain), ia akan kembali secara langsung (mengikutif (!account ){...}di sini).

Kenyataanself.account = accountadalah untuk menetapkan pembolehubah tempatanaccountkepada atributaccountobjek yang dibina untuk merakam maklumat akaun terkini dalam objek yang dibina.

Kenyataanvar now = new Date().getTime()menyatakan pembolehubah tempatannow, dan memanggilgetTime()fungsi objek masa & tarikh bahasa JavaScript untuk mengembalikan cap masa semasa, dan menetapkan cap masa kepada pembolehubahnow.

Kodnya:if (self.orderBook.Bids.length > 0 && now - self.preCalc > (CalcNetInterval * 1000)) {...}menilai perbezaan antara stempel masa semasa dan stempel masa terakhir yang direkodkan; jika nilai melebihi parameterCalcNetInterval * 1000, ia bermakna ia telah melebihiCalcNetInterval * 1000Milisaat (CalcNetIntervaldetik) dari kemas kini terakhir kepada sekarang, yang merealisasikan fungsi mencetak pulangan secara berkala.self.orderBook.Bids.length > 0(data mendalam, yang mesti sah dalam senarai pesanan beli sebagai maklumat tahap).

Apabila syarat pernyataan if dicetuskan, pelaksanaanself.preCalc = nowuntuk mengemas kini pembolehubah stempel masaself.preCalcdari keuntungan terakhir yang dicetak pada cap masa semasanowDi sini, statistik keuntungan menggunakan kaedah pengiraan nilai bersih, kod adalah:var net = _N(account.Balance + account.FrozenBalance + self.orderBook.Bids[0].Price * (account.Stocks + account.FrozenStocks)), iaitu menukar mata wang kepada aset (mata wang kutipan) mengikut harga beli 1 semasa, dan kemudian menambahkannya bersama-sama dengan jumlah aset dalam akaun dan menetapkannya kepada pembolehubah tempatan yang dinyatakannetTentukan sama ada nilai bersih keseluruhan semasa adalah konsisten dengan nilai bersih keseluruhan terakhir yang direkodkan:

            if (net != self.preNet) {
                self.preNet = net
                LogProfit(net)
            }

Jika tidak konsisten, iaitunet != self.preNetadalah benar, mengemas kini atributself.preNetyang mencatat nilai bersih dengannetKemudian, cetak jumlah data nilai bersihnetkepada carta lengkung keuntungan bot Platform Dagangan Kuantum FMZ (anda boleh menyoalLogProfitfungsi dalam dokumentasi FMZ API).

Jika pencetakan biasa pulangan tidak dicetuskan, kemudian meneruskan proses berikut: rekodaccount.Stocks(simbol mata wang yang sedia ada pada masa ini dalam akaun) danaccount.Balance(aset sedia ada semasa dalam akaun) dalamself.btcdanself.cny. Mengira nisbah offset dan menetapkan ia, yang direkodkan dalamself.p.

self.p = self.btc * self.prices[self.prices.length-1] / (self.btc * self.prices[self.prices.length-1] + self.cny)

Algoritma ini juga sangat mudah, iaitu untuk mengira berapa peratusan nilai mata wang semasa dalam jumlah nilai bersih akaun.

Jadi bagaimana anda menilai apabila baki mata wang (posisi) dicetuskan? Di sini pemaju menggunakan 50% ke atas dan ke bawah 2 mata peratusan sebagai penyangga; jika ia melebihi penyangga, melaksanakan baki, iaitu apabilaself.p < 0.48Jika anda fikir jumlah mata wang adalah kecil, setiap kali harga meningkat sebanyak 0.01, meletakkan tiga pesanan kecil.self.p > 0.52, jika anda fikir jumlah mata wang adalah besar, menunggu pesanan kecil menjual 1 harga di pasaran. Akhirnya, menunggu untuk tempoh masa tertentu, mengikut tetapan parameterSleep(BalanceTimeout), dan batalkan semua pesanan.

        var orders = exchange.GetOrders()                  # obtain all the current pending orders, and save them in the variable orders"
        if (orders) {                                      # if the variable "orders", which obtains all the current pending orders, is not null
            for (var i = 0; i < orders.length; i++) {      # use the loop to traverse "orders", and cancel the orders one by one 
                if (orders[i].Id != self.tradeOrderId) {
                    exchange.CancelOrder(orders[i].Id)     # call "exchange.CancelOrder", and cancel orders by "orders[i].Id"
                }
            }
        }

Fungsi yang ditambahkan keempat:

Ini adalah bahagian utama strategi, yang paling penting.self.poll = function() {...}fungsi adalah logik utama keseluruhan strategi. kita juga bercakap tentang ia dalam artikel sebelumnya.main( )fungsi, mula untuk melaksanakan; sebelum memasukiwhilegelung tak terhingga, kita gunakanvar reaper = LeeksReaper()untuk membina objek pemanen keuntungan, dan kemudianReaper.poll()dipanggil secara kitaran dalammain() function.

Peraturanself.pollfungsi mula untuk melaksanakan, dan melakukan beberapa persediaan sebelum setiap gelung;self.numTick++meningkatkan jumlah;self.updateTrades()mengemas kini rekod perdagangan terkini di pasaran dan mengira data yang berkaitan yang digunakan;self.updateOrderBook()mengemas kini data pasaran (buku pesanan) dan mengira data yang relevan;self.balanceAccount()memeriksa baki mata wang (posisi).

        var burstPrice = self.prices[self.prices.length-1] * BurstThresholdPct   # calculate the burst price 
        var bull = false             # declare the variable marked by the bull market; the initial value is false
        var bear = false             # declare the variable marked by the bear market; the initial value is false
        var tradeAmount = 0          # declare the variable of trading amount; the initial value is 0

Seterusnya, kita perlu menilai sama ada pasaran jangka pendek semasa adalah lembu atau beruang.

        if (self.numTick > 2 && (
            self.prices[self.prices.length-1] - _.max(self.prices.slice(-6, -1)) > burstPrice ||
            self.prices[self.prices.length-1] - _.max(self.prices.slice(-6, -2)) > burstPrice && self.prices[self.prices.length-1] > self.prices[self.prices.length-2]
            )) {
            bull = true
            tradeAmount = self.cny / self.bidPrice * 0.99
        } else if (self.numTick > 2 && (
            self.prices[self.prices.length-1] - _.min(self.prices.slice(-6, -1)) < -burstPrice ||
            self.prices[self.prices.length-1] - _.min(self.prices.slice(-6, -2)) < -burstPrice && self.prices[self.prices.length-1] < self.prices[self.prices.length-2]
            )) {
            bear = true
            tradeAmount = self.btc
        }

Adakah anda ingatself.updateOrderBook()fungsi dalam artikel sebelumnya, di mana kita menggunakan algoritma purata tertimbang untuk membina siri masapricesSepotong kod ini menggunakan tiga fungsi baru, iaitu_.min, _.max, slice, yang juga sangat mudah difahami.

  • _.min: Fungsi adalah untuk mencari minimum dalam array parameter.

  • _.max: Fungsi adalah untuk mencari maksimum dalam array parameter.

  • slice: Fungsi ini adalah fungsi ahli objek array JavaScript. Ia adalah untuk memintas dan mengembalikan sebahagian daripada array mengikut indeks. Sebagai contoh:

    function main() {
        // index     .. -8 -7 -6 -5 -4 -3 -2 -1
        var arr = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
        Log(arr.slice(-5, -1))    // it will intercept several elements from 4 to 1, and return a new array: [4,3,2,1]
    }
    

Di sini, syarat untuk menilai sama ada ia adalah pasaran lembu atau pasaran beruang adalah:

  • self.numTick > 2mesti benar, iaitu, jika ledakan harga berlaku dalam pusingan pengesanan baru, ia mesti dicetuskan selepas sekurang-kurangnya tiga pusingan pengesanan, dan mengelakkan pemicu pada mulanya.
  • Data terakhir dalam siri hargaself.prices, iaitu perbezaan antara data terkini dan harga maksimum atau minimum dalamself.pricesarray dalam julat sebelumnya harus memecahkan melaluiburstPrice .

Jika semua syarat adalah benar, tandabullataubearsebagaitrue, dan menetapkan nilai kepada pembolehubahtradeAmount, dan merancang pertukaran kuda.

Kemudian, untuk parameterBurstThresholdVol, berdasarkanself.voldiperbaharui dan dikira pada tahun sebelumnya.self.updateTrades()fungsi, ia diputuskan sama ada untuk mengurangkan intensiti dagangan (untuk mengurangkan jumlah dagangan yang dirancang).

        if (self.vol < BurstThresholdVol) {
            tradeAmount *= self.vol / BurstThresholdVol   // reduce the planned trading volume, and reduce it to the previous volume multiplied by "self.vol / BurstThresholdVol" 
        }
        
        if (self.numTick < 5) {
            tradeAmount *= 0.8      // reduced to 80% of the plan 
        }
        
        if (self.numTick < 10) {    // reduced to 80% of the plan
            tradeAmount *= 0.8
        }

Seterusnya, menilai sama ada isyarat dagangan dan jumlah dagangan memenuhi keperluan:

        if ((!bull && !bear) || tradeAmount < MinStock) {   # if it is not a bull market nor a bear market, or the planned trading volume "tradeAmount" is less than the minimum trading volume "MinStock" set by the parameter, the "poll" function returns directly without any trading operation
            return
        }

Selepas keputusan di atas, melaksanakanvar tradePrice = bull ? self.bidPrice : self.askPriceMengikut sama ada ia adalah pasaran beruang atau pasaran lembu, tetapkan harga dagangan dan menetapkan nilai dengan harga pesanan penghantaran yang sepadan.

Akhirnya, masukkanwhilegelung; satu-satunya keadaan berhenti dan pecah gelung adalahtradeAmount >= MinStock, iaitu jumlah dagangan yang dirancang adalah kurang daripada jumlah dagangan minimum. Dalam gelung, mengikut keadaan pasaran lembu semasa atau keadaan pasaran beruang, melaksanakan pesanan. dan mencatat ID pesanan dalam pembolehubahorderIdBunuh dia.Sleep(200)untuk menunggu selama 200 milidetik selepas meletakkan pesanan dalam setiap pusingan. gelung kemudian menilai sama adaorderIdadalah benar (jika pesanan gagal, ID pesanan tidak akan dikembalikan, dan keadaan if tidak akan dicetuskan). Jika keadaan adalah benar, mendapatkan ID pesanan dan menetapkannya kepadaself.tradeOrderId.

Mengisytiharkan pembolehubahorderuntuk menyimpan data pesanan dengan nilai awalnull. Kemudian, gunakan gelung untuk mendapatkan data pesanan dengan ID, dan menentukan sama ada pesanan berada dalam status pesanan menunggu; jika ia berada dalam status pesanan menunggu, membatalkan pesanan dengan ID; jika ia tidak berada dalam status pesanan menunggu, ia akan keluar dari gelung pengesanan.

                var order = null           // declare a variable to save the order data 
                while (true) {             // a while loop 
                    order = exchange.GetOrder(orderId)    // call "GetOrder" to query the order data with the ID of  orderId
                    if (order) {                          // if the order data is queried,and the query fails, the order is null, and "if" will not be triggered  
                        if (order.Status == ORDER_STATE_PENDING) {   // judge whether the current order status is pending order
                            exchange.CancelOrder(orderId)            // if the current order status is pending order, cancel the order 
                            Sleep(200)
                        } else {                                     // if not, execute "break" to break out of the while loop 
                            break
                        }
                    }
                }

Kemudian, lakukan proses berikut:

                self.tradeOrderId = 0              // reset "self.tradeOrderId"
                tradeAmount -= order.DealAmount    // update "tradeAmount", and subtract the executed amount of the orders in the delivery order 
                tradeAmount *= 0.9                 // reduce the intensity of ordering  
                if (order.Status == ORDER_STATE_CANCELED) {     // if the order is canceled 
                    self.updateOrderBook()                      // update the data, including the order book data
                    while (bull && self.bidPrice - tradePrice > 0.1) {   // in a bull market, if the updated bid price exceeds the current trading price by 0.1, reduce the trading intensity, and slightly adjust the trading price 
                        tradeAmount *= 0.99
                        tradePrice += 0.1
                    }
                    while (bear && self.askPrice - tradePrice < -0.1) {  // in a bear market, if the updated ask price exceeds the current trading price by 0.1, reduce the trading intensity, and slightly adjust the trading price 
                        tradePrice -= 0.1
                    }
                }

Apabila aliran program pecah keluar dariwhile (tradeAmount >= MinStock) {...}gelung, ia bermaksud bahawa pelaksanaan proses perdagangan harga pecah telah selesai. Melakukanself.numTick = 0, iaitu, set semulaself.numTickkepada 0.

Pelaksanaan terakhir pembinaLeeksReaper()mengembalikanselfobjek, iaitu, apabilavar reaper = LeeksReaper(), objek dikembalikan kereaper.

Setakat ini, kami telah menganalisis bagaimanaLeeksReaper()constructor membina objek ini keuntungan harvester, pelbagai kaedah objek, dan proses pelaksanaan fungsi logik utama. selepas membaca artikel, saya fikir anda akan mempunyai pemahaman yang lebih jelas tentang proses algoritma strategi frekuensi tinggi.


Lebih lanjut