Analisis Strategi Pengumpul Keuntungan (2)

Penulis:Ninabadass, Dibuat: 2022-04-26 15:57:02, Diperbarui: 2022-04-26 15:57:53

Analisis Strategi Pengumpul Keuntungan (2)

Mari kita lanjutkanisi dari terakhir kaliuntuk menjelaskan.

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

Ketika konstruktorLeeksReaper()adalah membangun sebuah objek,balanceAccount()fungsi yang ditambahkan ke objek digunakan untuk memperbarui informasi aset akun, yang disimpan diself.account, yaitu untuk membangun Atributaccountdari objek. Menghitung dan mencetak nilai pengembalian secara teratur. Kemudian, sesuai dengan informasi aset akun terbaru, rasio saldo simbol mata uang spot (saldo posisi spot) dihitung, dan ketika ambang offset dipicu, pesanan kecil ditutup untuk membuat simbol (posisi) kembali ke keadaan seimbang. Tunggu untuk periode waktu tertentu untuk mengeksekusi perdagangan, dan kemudian batalkan semua pesanan yang tertunda, dan pelaksanaan fungsi pada putaran berikutnya, saldo akan terdeteksi lagi dan pemrosesan yang sesuai akan dilakukan.

Mari kita lihat kode dari pernyataan fungsi ini dengan pernyataan: Pertama, pernyataan pertamavar account = exchange.GetAccount()menyatakan variabel lokalaccount, memanggilexchange.GetAccount()fungsi di antarmuka FMZ API, mendapatkan data terbaru dari rekening current dan menugaskannya ke variabelaccount. Kemudian, menilai variabelaccount; jika nilai variabel adalahnull(yang akan terjadi ketika gagal untuk mendapatkan variabel, seperti timeout, jaringan, platform interface exception, dll), itu akan kembali langsung (yang sesuai denganif (!account ){...}di sini).

Pernyataanself.account = accountadalah untuk menetapkan variabel lokalaccountuntuk atributaccountdari objek yang dibangun untuk mencatat informasi akun terbaru di objek yang dibangun.

Pernyataanvar now = new Date().getTime()menyatakan variabel lokalnow, dan memanggilgetTime()fungsi objek waktu & tanggal dari bahasa JavaScript untuk mengembalikan timestamp saat ini, dan menetapkan timestamp ke variabelnow.

Kode:if (self.orderBook.Bids.length > 0 && now - self.preCalc > (CalcNetInterval * 1000)) {...}menilai perbedaan antara timestamp saat ini dan timestamp terakhir yang tercatat; jika nilai melebihi parameterCalcNetInterval * 1000, berarti telah melebihiCalcNetInterval * 1000Milisekund (CalcNetIntervaldetik) dari pembaruan terakhir hingga saat ini, yang mewujudkan fungsi mencetak pengembalian secara teratur.self.orderBook.Bids.length > 0(data mendalam, yang harus valid dalam daftar pesanan pembelian sebagai informasi tingkat).

Ketika kondisi pernyataan if diaktifkan, eksekusiself.preCalc = nowuntuk memperbarui variabel timestampself.preCalcdari hasil cetak terakhir pada tanggal dan waktu saat ininowDi sini, statistik laba menggunakan metode perhitungan nilai bersih, kode adalah:var net = _N(account.Balance + account.FrozenBalance + self.orderBook.Bids[0].Price * (account.Stocks + account.FrozenStocks)), yaitu mengubah mata uang menjadi aset (mata uang kutipan) sesuai dengan harga beli 1 saat ini, dan kemudian menambahkannya bersama dengan jumlah aset di rekening dan menugaskannya ke variabel lokal yang dinyatakannetTentukan apakah nilai bersih total saat ini konsisten dengan nilai bersih total terakhir yang tercatat:

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

Jika tidak konsisten, yaitunet != self.preNetadalah benar, update atributself.preNetyang mencatat nilai bersih dengannetKemudian, cetak total data nilai bersihnetke grafik kurva keuntungan dari bot Platform Trading FMZ Quant (Anda dapat menanyakanLogProfitfungsi dalam dokumentasi FMZ API).

Jika pencetakan reguler pengembalian tidak dipicu, maka melanjutkan proses berikut: catatanaccount.Stocks(simbol mata uang yang tersedia saat ini di akun) danaccount.Balance(aktif yang tersedia saat ini di akun) diself.btcdanself.cnyMenghitung rasio offset dan menugaskannya, yang dicatat dalamself.p.

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

Algoritma juga sangat sederhana, yaitu menghitung berapa persen nilai mata uang saat ini dalam total nilai bersih akun.

Jadi bagaimana Anda menilai ketika saldo mata uang (posisi) dipicu? Di sini pengembang menggunakan 50% ke atas dan ke bawah 2 poin persentase sebagai buffer; jika melebihi buffer, mengeksekusi saldo, yaitu ketikaself.p < 0.48Jika Anda berpikir jumlah mata uang kecil, setiap kali harga meningkat sebesar 0,01, menempatkan tiga pesanan kecil.self.p > 0.52, jika Anda berpikir jumlah mata uang yang besar, menunggu pesanan kecil menjual 1 harga di pasar.Sleep(BalanceTimeout), dan membatalkan 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:

Inilah bagian inti dari strategi, yang paling penting.self.poll = function() {...}fungsi adalah logika utama dari seluruh strategi. kita juga berbicara tentang hal itu di artikel sebelumnya. dimain( )fungsi, mulai untuk menjalankan; sebelum memasukiwhileloop tak terbatas, kita menggunakanvar reaper = LeeksReaper()untuk membangun obyek profit harvester, dan kemudianReaper.poll()disebut secara siklis dalammain() function.

Peraturanself.pollfungsi mulai dijalankan, dan melakukan beberapa persiapan sebelum setiap loop;self.numTick++meningkatkan jumlahnya;self.updateTrades()memperbarui catatan perdagangan terbaru di pasar dan menghitung data terkait yang digunakan;self.updateOrderBook()memperbarui data pasar (buku pesanan) dan menghitung data yang relevan;self.balanceAccount()memeriksa saldo mata uang (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

Selanjutnya, kita perlu menilai apakah pasar jangka pendek saat ini adalah banteng 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
        }

Apakah Anda ingatself.updateOrderBook()fungsi dalam artikel sebelumnya, di mana kita menggunakan algoritma rata-rata tertimbang untuk membangun deret waktupricesBagian kode ini menggunakan tiga fungsi baru, yaitu_.min, _.max, slice, yang juga sangat mudah dimengerti.

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

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

  • slice: Fungsi ini adalah fungsi anggota dari objek array JavaScript. Ini adalah untuk mencegat dan mengembalikan bagian dari array sesuai dengan indeks. Misalnya:

    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, kondisi untuk menilai apakah itu adalah pasar bull atau pasar bear adalah:

  • self.numTick > 2harus benar, yaitu, jika ledakan harga terjadi dalam putaran baru deteksi, itu harus dipicu setelah setidaknya tiga putaran deteksi, dan menghindari pemicu di awal.
  • Data terakhir dalam seri hargaself.prices, yaitu perbedaan antara data terbaru dan harga maksimum atau minimum diself.pricesarray di kisaran sebelumnya harus menembusburstPrice .

Jika semua kondisi benar, tandabullataubearsebagaitrue, dan menetapkan nilai untuk variabeltradeAmount, dan rencanakan pertukaran kuda.

Kemudian, untuk parameterBurstThresholdVol, berdasarkanself.voldiperbarui dan dihitung pada tahun sebelumnya.self.updateTrades()fungsi, diputuskan apakah untuk mengurangi intensitas perdagangan (untuk mengurangi volume perdagangan yang direncanakan).

        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
        }

Selanjutnya, menilai apakah sinyal perdagangan dan volume perdagangan memenuhi persyaratan:

        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
        }

Setelah putusan di atas, eksekusivar tradePrice = bull ? self.bidPrice : self.askPriceBerdasarkan apakah itu adalah pasar beruang atau pasar banteng, tetapkan harga perdagangan dan menetapkan nilai dengan harga pesanan pengiriman yang sesuai.

Akhirnya, masukkanwhilelingkaran; satu-satunya kondisi berhenti dan istirahat lingkaran adalahtradeAmount >= MinStock, yaitu volume perdagangan yang direncanakan kurang dari volume perdagangan minimum. Dalam loop, sesuai dengan kondisi pasar bull saat ini atau kondisi pasar bear, mengeksekusi order. dan mencatat ID order dalam variabelorderIdEksekusi.Sleep(200)untuk menunggu selama 200 milidetik setelah menempatkan pesanan di setiap putaran. loop kemudian menilai apakahorderIdadalah benar (jika order gagal, order ID tidak akan dikembalikan, dan kondisi if tidak akan dipicu). Jika kondisi adalah benar, dapatkan order ID dan atributkan keself.tradeOrderId.

Mengisyaratkan variabelorderuntuk menyimpan data pesanan dengan nilai awal darinullKemudian, gunakan loop untuk mendapatkan data pesanan dengan ID, dan menentukan apakah pesanan berada dalam status pesanan yang sedang menunggu; jika berada dalam status pesanan yang sedang menunggu, batalkan pesanan dengan ID; jika tidak berada dalam status pesanan yang sedang menunggu, itu akan keluar dari loop deteksi.

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

Ketika aliran program pecah keluar dariwhile (tradeAmount >= MinStock) {...}loop, itu berarti bahwa pelaksanaan proses perdagangan harga ledakan selesai. Eksekusiself.numTick = 0, yaitu, resetself.numTickke 0.

Eksekusi terakhir konstruktorLeeksReaper()mengembalikanselfobjek, yaitu, ketikavar reaper = LeeksReaper(), objek dikembalikan kereaper.

Sejauh ini, kami telah menganalisis bagaimanaLeeksReaper()setelah membaca artikel ini, saya pikir Anda akan memiliki pemahaman yang lebih jelas tentang proses algoritma strategi frekuensi tinggi.


Lebih banyak