Thiết kế chiến lược phòng ngừa rủi ro giao ngay tiền điện tử ((2)

Tác giả:Lydia., Tạo: 2022-07-19 15:19:52, Cập nhật: 2023-09-24 19:34:38

img

Thiết kế chiến lược phòng ngừa rủi ro giao ngay tiền điện tử (2)

Trong bài viết trước, chúng tôi đã thực hiện một chiến lược phòng hộ đơn giản cùng nhau, và sau đó chúng tôi sẽ học cách nâng cấp chiến lược này. Các thay đổi chiến lược không lớn, nhưng các chi tiết của những thay đổi cần chú ý.

Nhu cầu nâng cấp chiến lược này

  • Chuyển đổi chế độ đòn bẩy đối tượng giao dịch tại chỗ Thay đổi này chỉ liên quan đến bot thực tế. Một số sàn giao dịch giao ngay có giao diện đòn bẩy giao ngay, cũng được đóng gói trên FMZ. Đối với các đối tượng giao dịch đã được đóng gói trực tiếp trên FMZ và hỗ trợ đòn bẩy giao ngay, chế độ có thể được chuyển trực tiếp.
  • Thêm hiển thị biểu đồ phân phối Thêm hiển thị biểu đồ chênh lệch, bởi vì nó chỉ là vẽ đường chênh lệch củaA exchange -> B exchange, B exchange -> A exchange, và vẽ đường ngang kích hoạt sự lây lan.line drawing class libraryđể đối phó trực tiếp, lợi thế là nó dễ sử dụng, ở đây chúng ta cũng học cách sử dụngtemplate class librarychức năng của FMZ.
  • Chức năng phòng ngừa rủi ro một bên Sự thay đổi này có thể khá đáng kể, bởi vì rất khó để hoàn toàn đảo ngược sự khác biệt giá giữa hai sàn giao dịch trong các giao dịch phòng ngừa rủi ro cụ thể. Hầu hết thời gian giá trên một sàn giao dịch đều cao hơn giá trên sàn giao dịch khác. Vào thời điểm này, nếu tài sản của chúng ta đã được bảo hiểm đầy đủ (tức là, tất cả các đồng xu đều được bảo hiểm trên sàn giao dịch với giá thấp, và tiền đang được bảo hiểm trên sàn giao dịch với giá cao).
  • Thay đổi các tham số tương tác như các đường phòng ngừa chênh lệch Thêm chức năng tương tác vào chiến lược để sửa đổi đường kích hoạt lây lan trong thời gian thực.
  • Tổ chức thông tin thanh trạng thái và hiển thị nó theo định dạng bảng Đặt dữ liệu cần hiển thị để dễ dàng xem.

Tiếp theo, chúng ta hãy thực hiện các thiết kế này từng cái một.

Chuyển đổi chế độ đòn bẩy đối tượng giao dịch tại chỗ

Hãy lấy Binance điểm thực bot như một ví dụ, chuyển sang chế độ đòn bẩy điểm, sử dụng mãexchanges[i].IO, nhập tham sốtrade_normalđể chuyển sang vị trí đòn bẩy theo vị trí và đầu vàotrade_super_marginđể chuyển sang vị trí đầy đủ đòn bẩy, backtesting không được hỗ trợ.

Thêm vào giai đoạn chuẩn bị ở đầumainchức năng:

    // Switch leverage mode
    for (var i = 0 ; i < exchanges.length ; i++) {   // Traverse and detect all added exchange objects
        if (exchanges[i].GetName() == "Binance" && marginType != 0) {   //If the exchange object represented by the current i-index is Binance spot, and the parameter marginType of the strategy interface is not the option of "common currency", execute the switch operation
            if (marginType == 1) {
                Log(exchanges[i].GetName(), "Set to leveraged position-by-position")
                exchanges[i].IO("trade_normal")
            } else if (marginType == 2) {
                Log(exchanges[i].GetName(), "Set to leveraged full position")
                exchanges[i].IO("trade_super_margin")
            }
        }
    }

Chiến lược ở đây chỉ thêm mã để chuyển đổi chế độ đòn bẩy coin-to-coin của Binance spot, vì vậy cài đặt chuyển đổi trên các thông số chiến lược chỉ có giá trị cho Binance spot.

Thêm hiển thị biểu đồ phân phối

Nó rất dễ dàng để sử dụng mẫu vẽ đã được bọc.Line Drawing LibraryNó có thể được tìm kiếm trực tiếp trên quảng trường chiến lược nền tảng FMZ.

img

Hoặc nhấp vào liên kết trực tiếp:https://www.fmz.com/strategy/27293để nhảy đến trang sao chép cho mẫu này.

img

Nhấp vào nút để sao chép thư viện lớp mẫu này vào thư viện chiến lược của riêng bạn.

img

Sau đó, bạn có thể kiểm tra thư viện lớp mẫu để sử dụng trong cột mẫu trên trang chỉnh sửa chiến lược. Lưu chiến lược sau khi kiểm tra nó, và chiến lược sẽ tham chiếu đến mẫu này. Đây chỉ là một mô tả ngắn gọn về việc sử dụng thư viện lớp mẫu. Chiến lược này đã tham chiếu đến mẫu này, vì vậy không cần phải lặp lại hoạt động. Khi bạn sao chép chiến lược này vào ô chiến lược, bạn có thể thấy rằngLine Drawing Libraryđã được tham chiếu trong thanh mẫu trên trang chỉnh sửa chiến lược.

Chúng ta sẽ chủ yếu học cách sử dụng các chức năng củaLine Drawing Libraryđể vẽ một biểu đồ.

img

Chúng tôi có kế hoạch để rút ra sự lan rộng củaA->B, sự lây lan củaB->AChúng ta cần vẽ hai đường cong (tiền A đến B, B đến A), hai đường ngang (đường chênh lệch chênh lệch), như được hiển thị trong hình trên.

Bởi vì chúng tôi muốn thiết kế phòng hộ đơn phương, các đường kích hoạt củaA->BB->AChúng ta không thể sử dụng thiết kế trong bài trước. Trong bài trước:

      var targetDiffPrice = hedgeDiffPrice
      if (diffAsPercentage) {
          targetDiffPrice = (depthA.Bids[0].Price + depthB.Asks[0].Price + depthB.Bids[0].Price + depthA.Asks[0].Price) / 4 * hedgeDiffPercentage
      }

Chỉ có một cách kích hoạt.targetDiffPrice. Vì vậy, ở đây chúng ta phải biến đổi mã, biến đổi các tham số đầu tiên.

img

Sau đó thay đổi mã:

        var targetDiffPriceA2B = hedgeDiffPriceA2B
        var targetDiffPriceB2A = hedgeDiffPriceB2A
        if (diffAsPercentage) {
            targetDiffPriceA2B = (depthA.Bids[0].Price + depthB.Asks[0].Price + depthB.Bids[0].Price + depthA.Asks[0].Price) / 4 * hedgeDiffPercentageA2B
            targetDiffPriceB2A = (depthA.Bids[0].Price + depthB.Asks[0].Price + depthB.Bids[0].Price + depthA.Asks[0].Price) / 4 * hedgeDiffPercentageB2A
        }

Bằng cách này, sự khác biệt kích hoạt đường đã thay đổi từ trước đótargetDiffPriceđến haitargetDiffPriceA2B, targetDiffPriceB2A. Bước tiếp theo là vẽ các dữ liệu này trên biểu đồ bằng cách sử dụng chức năng đường vẽ của thư viện vẽ đường.

        // drawing
        $.PlotHLine(targetDiffPriceA2B, "A->B")  // The first parameter of this function is the value of the horizontal line in the Y-axis direction, and the second parameter is the display text
        $.PlotHLine(targetDiffPriceB2A, "B->A")

Khi chiến lược đang chạy, có một biểu đồ như thế này.

img

Tiếp theo vẽ đường cong phân bố thời gian thực, để tránh quá vẽ đường.

        if (ts - lastKeepBalanceTS > keepBalanceCyc * 1000) {
            nowAccs = _C(updateAccs, exchanges)
            var isBalance = keepBalance(initAccs, nowAccs, [depthA, depthB])
            cancelAll()
            if (isBalance) {
                lastKeepBalanceTS = ts
                if (isTrade) {
                    var nowBalance = _.reduce(nowAccs, function(sumBalance, acc) {return sumBalance + acc.Balance}, 0)
                    var initBalance = _.reduce(initAccs, function(sumBalance, acc) {return sumBalance + acc.Balance}, 0)
                    LogProfit(nowBalance - initBalance, nowBalance, initBalance, nowAccs)
                    isTrade = false 
                }                
            }

            $.PlotLine("A2B", depthA.Bids[0].Price - depthB.Asks[0].Price)  // Draw real-time spread curves
            $.PlotLine("B2A", depthB.Bids[0].Price - depthA.Asks[0].Price)  // The first parameter is the name of the curve, and the second parameter is the value of the curve at the current moment, that is, the value in the Y-axis direction at the current moment
        }

Bằng cách này, mã vẽ chỉ có 4 dòng, cho phép chiến lược có biểu đồ hiển thị tại thời điểm chạy.

Chức năng phòng ngừa rủi ro một bên

Như đã đề cập ở trên, đường kích hoạt chênh lệch đã được sửa đổi thành hai, điều khiển kích hoạt phòng ngừa rủi ro củaA->BB->ATheo cách này, thuật toán giá đặt hàng trước đó không thể được sử dụng, và thay vào đó, phương pháp thêm giá vé vào giá thị trường được sử dụng.

        if (depthA.Bids[0].Price - depthB.Asks[0].Price > targetDiffPriceA2B && Math.min(depthA.Bids[0].Amount, depthB.Asks[0].Amount) >= minHedgeAmount) {          // A -> B market conditions are met            
            var priceSell = depthA.Bids[0].Price - slidePrice
            var priceBuy = depthB.Asks[0].Price + slidePrice
            var amount = Math.min(depthA.Bids[0].Amount, depthB.Asks[0].Amount)
            if (nowAccs[0].Stocks > minHedgeAmount && nowAccs[1].Balance * 0.8 / priceSell > minHedgeAmount) {
                amount = Math.min(amount, nowAccs[0].Stocks, nowAccs[1].Balance * 0.8 / priceSell, maxHedgeAmount)
                Log("trigger A->B:", depthA.Bids[0].Price - depthB.Asks[0].Price, priceBuy, priceSell, amount, nowAccs[1].Balance * 0.8 / priceSell, nowAccs[0].Stocks)  // Tips
                hedge(exB, exA, priceBuy, priceSell, amount)
                cancelAll()
                lastKeepBalanceTS = 0
                isTrade = true 
            }            
        } else if (depthB.Bids[0].Price - depthA.Asks[0].Price > targetDiffPriceB2A && Math.min(depthB.Bids[0].Amount, depthA.Asks[0].Amount) >= minHedgeAmount) {   // B -> A market conditions are met
            var priceBuy = depthA.Asks[0].Price + slidePrice
            var priceSell = depthB.Bids[0].Price - slidePrice
            var amount = Math.min(depthB.Bids[0].Amount, depthA.Asks[0].Amount)
            if (nowAccs[1].Stocks > minHedgeAmount && nowAccs[0].Balance * 0.8 / priceBuy > minHedgeAmount) {
                amount = Math.min(amount, nowAccs[1].Stocks, nowAccs[0].Balance * 0.8 / priceBuy, maxHedgeAmount)
                Log("trigger B->A:", depthB.Bids[0].Price - depthA.Asks[0].Price, priceBuy, priceSell, amount, nowAccs[0].Balance * 0.8 / priceBuy, nowAccs[1].Stocks)  //Tips
                hedge(exA, exB, priceBuy, priceSell, amount)
                cancelAll()
                lastKeepBalanceTS = 0
                isTrade = true 
            }            
        }

Vì giá mua và giá bán được tách thành hai dữ liệu, chức năng phòng ngừa rủi rohedgecũng cần phải được sửa đổi.

function hedge(buyEx, sellEx, priceBuy, priceSell, amount) {
    var buyRoutine = buyEx.Go("Buy", priceBuy, amount)
    var sellRoutine = sellEx.Go("Sell", priceSell, amount)
    Sleep(500)
    buyRoutine.wait()
    sellRoutine.wait()
}

Ngoài ra còn có một số điều chỉnh nhỏ dựa trên những thay đổi này, mà sẽ không được lặp lại ở đây.

Thay đổi các tham số tương tác như các đường phòng ngừa chênh lệch

Thêm tương tác vào chiến lược, để chiến lược có thể sửa đổi đường kích hoạt lây lan trong thời gian thực. Thiết kế tương tác chiến lược cũng rất đơn giản. Đầu tiên, thêm điều khiển tương tác vào chiến lược trên trang chỉnh sửa chiến lược.

img

Thêm hai điều khiển, một được gọi là A2B và một được gọi là B2A. Sau khi nhập một giá trị trong hộp đầu vào điều khiển, nhấp vào nút ở bên phải của hộp đầu vào. Một lệnh sẽ được gửi đến chiến lược ngay lập tức, ví dụ: nhập giá trị123trong hộp đầu vào, bấm vàoA2Bnút, và một hướng dẫn sẽ được gửi đến chiến lược ngay lập tức.

A2B:123

Thiết kế mã phát hiện và xử lý tương tác trong mã chiến lược.

        // interact
        var cmd = GetCommand()   // Every time the loop is executed here, it checks whether there is an interactive command, and returns to an empty string if not.
        if (cmd) {               // An interactive command was detected, such as A2B:123
            Log("command received:", cmd)
            var arr = cmd.split(":")   // Split out the interactive control name and the value in the input box, arr[0] is A2B, arr[1] is 123
            if (arr[0] == "A2B") {     // Determine whether the triggered interactive control is A2B
                Log("Modify the parameters of A2B, ", diffAsPercentage ? "The parameter is the difference percentage" : "The parameter is the difference:", arr[1])
                if (diffAsPercentage) {
                    hedgeDiffPercentageB2A = parseFloat(arr[1])     // Modify the trigger spread line
                } else {
                    hedgeDiffPriceA2B = parseFloat(arr[1])          // Modify the trigger spread line
                }
            } else if (arr[0] == "B2A") {           // Triggered control detected is B2A     
                Log("Modify the parameters of B2A, ", diffAsPercentage ? "The parameter is the difference percentage" : "The parameter is the difference:", arr[1])
                if (diffAsPercentage) {
                    hedgeDiffPercentageA2B = parseFloat(arr[1])
                } else {
                    hedgeDiffPriceB2A = parseFloat(arr[1])
                }
            }
        }

Tổ chức thông tin thanh trạng thái và hiển thị nó theo định dạng bảng

Làm cho dữ liệu thanh trạng thái hiển thị có tổ chức và dễ quan sát hơn.

        var tbl = {
            "type" : "table", 
            "title" : "data", 
            "cols" : ["exchange", "coin", "freeze coin", "denominated currency", "freeze denominated currency", "trigger spread", "current spread"], 
            "rows" : [], 
        }
        tbl.rows.push(["A:" + exA.GetName(), nowAccs[0].Stocks, nowAccs[0].FrozenStocks, nowAccs[0].Balance, nowAccs[0].FrozenBalance, "A->B:" + targetDiffPriceA2B, "A->B:" + (depthA.Bids[0].Price - depthB.Asks[0].Price)])
        tbl.rows.push(["B:" + exB.GetName(), nowAccs[1].Stocks, nowAccs[1].FrozenStocks, nowAccs[1].Balance, nowAccs[1].FrozenBalance, "B->A:" + targetDiffPriceB2A, "B->A:" + (depthB.Bids[0].Price - depthA.Asks[0].Price)])

        LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")

img

Kiểm tra ngược

Backtesting chỉ là một chiến lược thử nghiệm, một chức năng phát hiện sơ bộ, và nhiều lỗi có thể được thử nghiệm trong giai đoạn backtesting thực sự.

img

Mã nguồn chiến lược:https://www.fmz.com/strategy/302834


Có liên quan

Thêm nữa