Tài nguyên đang được tải lên... tải...

Phân tích chiến lược thu hoạch lợi nhuận (2)

Tác giả:Ninabadass, Tạo: 2022-04-26 15:57:02, Cập nhật: 2022-04-26 15:57:53

Phân tích chiến lược thu hoạch lợi nhuận (2)

Hãy tiếp tụcnội dung của lần cuối cùngđể giải thích.

Chức năng bổ sung thứ ba:

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

Khi người xây dựngLeeksReaper()là xây dựng một đối tượng,balanceAccount()chức năng được thêm vào đối tượng được sử dụng để cập nhật thông tin tài sản tài khoản, được lưu trữ trongself.account, đó là để xây dựng thuộc tínhaccountcủa đối tượng. Tính toán và in giá trị lợi nhuận thường xuyên. Sau đó, theo thông tin tài sản tài khoản mới nhất, tỷ lệ số dư của các biểu tượng tiền mặt tại chỗ (tỷ lệ số dư vị trí tại chỗ) được tính toán, và khi ngưỡng offset được kích hoạt, các lệnh nhỏ được đóng để làm cho các biểu tượng (vị trí) trở lại trạng thái cân bằng. Chờ một khoảng thời gian nhất định để thực hiện giao dịch, và sau đó hủy tất cả các lệnh đang chờ, và thực hiện chức năng trong vòng tiếp theo, số dư sẽ được phát hiện lại và xử lý tương ứng sẽ được thực hiện.

Hãy xem mã của câu lệnh hàm này theo câu lệnh: Trước hết, câu đầu tiênvar account = exchange.GetAccount()tuyên bố một biến địa phươngaccount, gọi làexchange.GetAccount()chức năng trong giao diện FMZ API, nhận dữ liệu mới nhất của tài khoản hiện tại và gán nó cho biếnaccount. Sau đó, đánh giá các biếnaccount; nếu giá trị biến lànull(điều sẽ xảy ra khi nó không có được biến, chẳng hạn như thời gian hết, mạng, nền tảng giao diện ngoại lệ, vv), nó sẽ trở lại trực tiếp (tương ứng vớiif (!account ){...}ở đây).

Tuyên bốself.account = accountlà để chỉ định các biến địa phươngaccountđến thuộc tínhaccountcủa đối tượng được xây dựng để ghi lại thông tin tài khoản mới nhất trong đối tượng được xây dựng.

Tuyên bốvar now = new Date().getTime()tuyên bố một biến địa phươngnow, và gọi chogetTime()chức năng của đối tượng thời gian & ngày của ngôn ngữ JavaScript để trả lại dấu thời gian hiện tại, và gán dấu thời gian cho biếnnow.

Mã:if (self.orderBook.Bids.length > 0 && now - self.preCalc > (CalcNetInterval * 1000)) {...}đánh giá sự khác biệt giữa dấu giờ hiện tại và dấu giờ được ghi lại cuối cùng; nếu giá trị vượt quá tham sốCalcNetInterval * 1000, nghĩa là nó đã vượt quáCalcNetInterval * 1000milliseconds (CalcNetIntervalVì giá mua 1 trên thị trường cần phải được sử dụng khi tính toán lợi nhuận, điều kiện này cũng được giới hạn trong điều kiệnself.orderBook.Bids.length > 0(dữ liệu sâu, phải có giá trị trong danh sách lệnh mua như thông tin cấp).

Khi điều kiện của câu lệnh if được kích hoạt, thực hiệnself.preCalc = nowđể cập nhật biến timestampself.preCalccủa lợi nhuận được in cuối cùng đến thời điểm hiện tạinowỞ đây, thống kê lợi nhuận sử dụng phương pháp tính toán giá trị ròng, mã là:var net = _N(account.Balance + account.FrozenBalance + self.orderBook.Bids[0].Price * (account.Stocks + account.FrozenStocks)), tức là chuyển đổi tiền tệ thành tài sản (tiền tệ báo giá) theo giá mua hiện tại, sau đó cộng với số tiền tài sản trong tài khoản và gán nó cho biến địa phương được khai báonetXác định xem tổng giá trị ròng hiện tại có phù hợp với tổng giá trị ròng được ghi nhận cuối cùng không:

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

Nếu không phù hợp, tức lànet != self.preNetlà true, cập nhật thuộc tínhself.preNetghi lại giá trị ròng vớinetSau đó, in tổng số dữ liệu giá trị ròngnetđến biểu đồ đường cong lợi nhuận của bot FMZ Quant Trading Platform (bạn có thể truy vấnLogProfitchức năng trong tài liệu API FMZ).

Nếu việc in thường xuyên của trở lại không được kích hoạt, sau đó tiếp tục quá trình sau: ghiaccount.Stocks(tiếng biểu tượng tiền tệ hiện có trong tài khoản) vàaccount.Balance(các tài sản hiện có trong tài khoản) trongself.btcself.cny. Tính toán tỷ lệ offset và gán nó, được ghi trongself.p.

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

Các thuật toán cũng rất đơn giản, đó là để tính toán bao nhiêu phần trăm của giá trị tiền tệ hiện tại trong tổng giá trị ròng của tài khoản.

Vì vậy, làm thế nào bạn đánh giá khi đồng tiền (vị trí) cân bằng được kích hoạt? Ở đây, các nhà phát triển sử dụng 50% lên và xuống 2 điểm phần trăm như một đệm; nếu nó vượt quá đệm, thực hiện số dư, đó là khiself.p < 0.48Nếu bạn nghĩ rằng số tiền tiền tệ là nhỏ, mỗi khi giá tăng 0.01, đặt ba lệnh nhỏ.self.p > 0.52Cuối cùng, chờ một khoảng thời gian nhất định, theo các thiết lập tham sốSleep(BalanceTimeout), và hủy tất cả các đơn đặt hàng.

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

Chức năng bổ sung thứ tư:

Đây là phần cốt lõi của chiến lược, điểm nổi bật.self.poll = function() {...}Chúng tôi cũng đã nói về nó trong bài viết trước.main( )chức năng, bắt đầu thực hiện; trước khi nhậpwhilevòng lặp vô hạn, chúng tôi sử dụngvar reaper = LeeksReaper()để xây dựng đối tượng thu hoạch lợi nhuận, và sau đóReaper.poll()được gọi là chu kỳ trongmain() function.

Cácself.pollchức năng bắt đầu thực hiện, và thực hiện một số chuẩn bị trước mỗi vòng lặp;self.numTick++tăng số lượng;self.updateTrades()cập nhật hồ sơ giao dịch gần đây trên thị trường và tính toán các dữ liệu liên quan được sử dụng;self.updateOrderBook()cập nhật dữ liệu thị trường (tổ phiếu lệnh) và tính toán các dữ liệu có liên quan;self.balanceAccount()kiểm tra số dư tiền tệ (cơ sở).

        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

Tiếp theo, chúng ta cần đánh giá liệu thị trường ngắn hạn hiện tại có tăng hay giảm.

        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
        }

Anh có nhớself.updateOrderBook()chức năng trong bài viết trước, trong đó chúng tôi đã sử dụng thuật toán trung bình cân nhắc để xây dựng một chuỗi thời gianpricesBộ mã này sử dụng ba chức năng mới, cụ thể là_.min, _.max, slice, cũng rất dễ hiểu.

  • _.min: Chức năng là tìm mức tối thiểu trong mảng tham số.

  • _.max: Chức năng là tìm tối đa trong mảng tham số.

  • slice: Chức năng này là một hàm thành viên của đối tượng mảng JavaScript. Nó là để chặn và trả lại một phần của mảng theo chỉ mục. Ví dụ:

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

Ở đây, các điều kiện để đánh giá liệu đó là thị trường tăng hay thị trường giảm là:

  • self.numTick > 2phải là đúng, tức là, nếu sự bùng nổ giá xảy ra trong một vòng phát hiện mới, nó phải được kích hoạt sau ít nhất ba vòng phát hiện, và tránh kích hoạt ngay từ đầu.
  • Dữ liệu cuối cùng trong chuỗi giáself.prices, tức là sự khác biệt giữa dữ liệu mới nhất và giá tối đa hoặc tối thiểu trongself.pricesmảng trong phạm vi trước đây nên phá vỡburstPrice .

Nếu tất cả các điều kiện là đúng, đánh dấubullhoặcbearnhưtrue, và gán một giá trị cho biếntradeAmount, và lên kế hoạch giao dịch ngựa.

Sau đó, cho các tham sốBurstThresholdVol, dựa trênself.volđược cập nhật và tính toán trong năm trướcself.updateTrades()Các hoạt động giao dịch sẽ được thực hiện theo các quy định của các cơ quan quản lý.

        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
        }

Tiếp theo, đánh giá liệu tín hiệu giao dịch và khối lượng giao dịch có đáp ứng các yêu cầu không:

        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
        }

Sau phán quyết trên, thực thivar tradePrice = bull ? self.bidPrice : self.askPriceTùy thuộc vào việc đó là thị trường gấu hay thị trường tăng, đặt giá giao dịch và gán giá trị với giá lệnh giao hàng tương ứng.

Cuối cùng, nhập mộtwhilevòng lặp; điều kiện dừng và phá vỡ duy nhất của vòng lặp làtradeAmount >= MinStock, nghĩa là khối lượng giao dịch dự kiến thấp hơn khối lượng giao dịch tối thiểu. Trong vòng lặp, theo trạng thái thị trường tăng hiện tại hoặc trạng thái thị trường gấu, thực hiện lệnh.orderId- Chết đi.Sleep(200)để chờ 200 mili giây sau khi đặt một lệnh trong mỗi vòng. vòng lặp sau đó đánh giá liệuorderIdlà true (nếu lệnh thất bại, ID lệnh sẽ không được trả về, và điều kiện if sẽ không được kích hoạt). Nếu điều kiện là true, lấy ID lệnh và gán nó choself.tradeOrderId.

Xác định một biếnorderđể lưu trữ dữ liệu đơn đặt hàng với giá trị ban đầu củanull. Sau đó, sử dụng một vòng lặp để có được dữ liệu đơn đặt hàng với ID, và xác định xem đơn đặt hàng có trong trạng thái đơn đặt hàng đang chờ không; nếu nó ở trạng thái đơn đặt hàng đang chờ, hủy đơn đặt hàng với ID; nếu nó không ở trạng thái đơn đặt hàng đang chờ, nó sẽ thoát khỏi vòng lặp phát hiện.

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

Sau đó, thực hiện quy trình sau:

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

Khi dòng chảy chương trình phá vỡ ra khỏiwhile (tradeAmount >= MinStock) {...}vòng lặp, nó có nghĩa là việc thực hiện quá trình giao dịch giá bùng nổ đã hoàn thành. Thực hiệnself.numTick = 0, nghĩa là, thiết lập lạiself.numTickđến 0.

Việc thực hiện cuối cùng của người xây dựngLeeksReaper()trả vềselfđối tượng, đó là, khivar reaper = LeeksReaper(), đối tượng được trả vềreaper.

Cho đến nay, chúng tôi đã phân tích cáchLeeksReaper()constructor xây dựng đối tượng thu hoạch lợi nhuận này, các phương pháp khác nhau của đối tượng, và quá trình thực hiện các chức năng logic chính. sau khi đọc bài viết, tôi nghĩ bạn sẽ có một sự hiểu biết rõ ràng hơn về quá trình thuật toán chiến lược tần số cao.


Thêm nữa