Chiến lược phòng hộ giao ngay tiền điện tử (2)

Tác giả:Ninabadass, Tạo: 2022-04-14 16:17:46, Cập nhật: 2022-04-15 14:16:23

Chiến lược phòng hộ 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. Không có nhiều thay đổi trong chiến lược, nhưng chi tiết của các thay đổi cần phải được chú ý.

Yêu cầu nâng cấp chiến lược

  • Chuyển đổi chế độ biên đối tượng trao đổi tại chỗ Sự thay đổi chỉ liên quan đến bot. Một số nền tảng spot có giao diện margin spot, cũng được đóng gói trên FMZ. Đối với các đối tượng trao đổi được đóng gói trực tiếp trên FMZ và hỗ trợ margin spot, bạn có thể chuyển đổi chế độ trực tiếp.
  • Thêm thêm biểu đồ hiển thị chênh lệch Để thêm nhiều biểu đồ hiển thị chênh lệch, và chúng tôi chỉ vẽ đường cong chênh lệch củaA->BB->A, cũng như các đường kích hoạt phân tán ngang, chúng ta có thể trực tiếp sử dụng cácchart plot library; lợi thế là sự đơn giản và dễ sử dụng.template library together.
  • Chức năng của hàng rào một mặt Sự thay đổi này tương đối lớn, bởi vì rất khó để hoàn toàn đảo ngược chênh lệch giá giữa hai nền tảng trong quá trình giao dịch phòng ngừa rủi ro cụ thể. Hầu hết thời gian, giá trên một nền tảng đều cao hơn giá trên nền tảng khác. Tại thời điểm này, nếu tài sản của chúng tôi đã được bảo hiểm đầy đủ (tức là tất cả các biểu tượng tiền tệ đều có trong nền tảng với giá thấp hơn, và các tài sản đều có trong nền tảng với giá cao hơn). Bảo hiểm đều đứng yên, và không còn có thể phụ thuộc vào biến động chênh lệch để kiếm lợi nhuận. Tại thời điểm này, bạn cần thực hiện chiến lược bảo hiểm và trả lại các biểu tượng tiền tệ bằng cách chỉ mất một lượng tài sản nhỏ (để các biểu tượng tiền tệ trở lại nền tảng với giá cao hơn một lần nữa). Khi giá trở nên lớn hơn, bạn có thể tiếp tục bảo hiểm và kiếm lợi nhuận.
  • Tương tác sửa đổi các thông số như đường phân phối phòng hộ
    Thêm chức năng tương tác vào chiến lược, để sửa đổi đường kích hoạt chênh lệch trong thời gian thực.
  • Quản lý thông tin thanh trạng thái và hiển thị nó theo định dạng bảng Đặt và quản lý dữ liệu cần được hiển thị, để quan sát thuận tiện.

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

Chuyển đổi chế độ biên đối tượng trao đổi tại chỗ

Để chuyển sang chế độ ký quỹ tại chỗ, sử dụng mãexchanges[i].IO, nhập tham sốtrade_normalđể chuyển sang biên độ cô lập, và nhập khẩutrade_super_marginđể chuyển sang biên ngang, mà không được hỗ trợ trong backtest.

Trong quá trình chuẩn bị vào đầumainchức năng, thêm:

    // switch the margin mode 
    for (var i = 0 ; i < exchanges.length ; i++) {   // traverse and detect all exchange objects added
        if (exchanges[i].GetName() == "Binance" && marginType != 0) {   // if the exchange object represented by the current index i is Binance Spot, and the parameter marginType on the strategy interface is not selected as the "common spot" option, execute the switch
            if (marginType == 1) {
                Log(exchanges[i].GetName(), "set to isolated margin")
                exchanges[i].IO("trade_normal")
            } else if (marginType == 2) {
                Log(exchanges[i].GetName(), "set to cross margin")
                exchanges[i].IO("trade_super_margin")
            }
        }
    }

Chiến lược ở đây chỉ thêm mã để chuyển đổi chế độ ký quỹ giao ngay của Binance Spot, vì vậy cài đặt chuyển đổi trong các thông số chiến lược chỉ hoạt động cho Binance Spot.

Thêm thêm biểu đồ hiển thị chênh lệch

Sử dụng các mẫu phác thảo được đóng gói rất đơn giản. Tên mẫu chúng tôi sử dụng ở đây làchart plot LibraryBạn có thể trực tiếp tìm kiếm nó trên quảng trường FMZ.

img

Hoặc bạn có thể nhấp trực tiếp vào liên kết:https://www.fmz.com/strategy/27293để chuyển sang trang sao chép của mẫu.

img

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

img

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

Ở đây chúng ta chủ yếu học cách sử dụng các chức năng củachart plot libraryđể âm mưu.

img

Chúng tôi có kế hoạch để vẽ ra sự lan rộng củaA->BB->AChúng ta cần vẽ hai đường cong (hiện tại, các đường chênh lệch từ A đến B và B đến A), và 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ế một hàng rào một bên, các đường kích hoạt củaA->BB->Asẽ khác nhau, và chú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 sự gia tăng được kích hoạttargetDiffPrice. Do đó, ở đây chúng ta cần sửa đổi mã, và chúng ta cần sửa đổi các tham số đầu tiên.

img

sau đó, sửa đổ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
        }

Do đó, đường kích hoạt lây lan đã thay đổi từ trước đó mộttargetDiffPriceđến hai, cụ thể làtargetDiffPriceA2BtargetDiffPriceB2A. Tiếp theo, bạn có thể sử dụng chức năng vẽ biểu đồ của thư viện biểu đồ để vẽ dữ liệu trên biểu đồ.

        // plot
        $.PlotHLine(targetDiffPriceA2B, "A->B")  // the first parameter of the 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 được chạy, biểu đồ sẽ được hiển thị như thế này.

img

Tiếp theo, vẽ đường cong chênh lệch thời gian thực; để tránh vẽ quá mức, đặt mã vẽ các đường cong chênh lệch thời gian thực trong phát hiện số dư. s

        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)  // plot real-time spread curves
            $.PlotLine("B2A", depthB.Bids[0].Price - depthA.Asks[0].Price)  // the first parameter is the curve name, and the second parameter is the curve value at the current moment, that is, the value in the Y-axis direction at the current moment
        }

Mã vẽ chỉ cần 4 dòng để cho phép chiến lược với một biểu đồ hiển thị trong khi chạy.

Chức năng của hàng rào một mặt

Như đã đề cập ở trên, số dòng kích hoạt chênh lệch đã được thay đổi thành hai, tương ứng kiểm soát kích hoạt phòng hộ củaA->BB->ABằng 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á trượt 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 condition satisfied             
            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("triggerA->B:", depthA.Bids[0].Price - depthB.Asks[0].Price, priceBuy, priceSell, amount, nowAccs[1].Balance * 0.8 / priceSell, nowAccs[0].Stocks)  // prompt message
                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 condition satisfied 
            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("triggerB->A:", depthB.Bids[0].Price - depthA.Asks[0].Price, priceBuy, priceSell, amount, nowAccs[0].Balance * 0.8 / priceBuy, nowAccs[1].Stocks)  // prompt message
                hedge(exA, exB, priceBuy, priceSell, amount)
                cancelAll()
                lastKeepBalanceTS = 0
                isTrade = true 
            }            
        }

Vì giá mua và giá bán được chia thành hai dữ liệu,hedgechức năng cũ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 các sửa đổi này, mà sẽ không được mô tả ở đây.

Tương tác sửa đổi các thông số như đường phân phối phòng hộ

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

Có hai điều khiển được thêm vào, một tên là A2B và một tên 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 lệnh 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.

        // interaction 
        var cmd = GetCommand()   // every time when the loop is operated here, it will detect whether an interactive command is sent; if no, return null string 
        if (cmd) {               // interactive command detected, such as A2B:123
            Log("received command:", cmd)
            var arr = cmd.split(":")   // split out the interactive control name and the value in the input box; arr[0] means A2B, and arr[1] means 123
            if (arr[0] == "A2B") {     // judge whether the triggered interactive control is A2B
                Log("modify parameterA2B,", diffAsPercentage ? "parameter of spread ratio:" : "parameter of spread:", arr[1])
                if (diffAsPercentage) {
                    hedgeDiffPercentageB2A = parseFloat(arr[1])     // modify the spread trigger line 
                } else {
                    hedgeDiffPriceA2B = parseFloat(arr[1])          // modify the spread trigger line 
                }
            } else if (arr[0] == "B2A") {           // detected the triggered control is B2A 
                Log("modify parameterB2A,", diffAsPercentage ? "parameter of spread ratio:" : "parameter of spread:", arr[1])
                if (diffAsPercentage) {
                    hedgeDiffPercentageA2B = parseFloat(arr[1])
                } else {
                    hedgeDiffPriceB2A = parseFloat(arr[1])
                }
            }
        }

Quản lý thông tin thanh trạng thái và hiển thị nó theo định dạng bảng

Làm cho hiển thị dữ liệu thanh trạng thái được điều chỉnh và dễ quan sát hơn.

        var tbl = {
            "type" : "table", 
            "title" : "data", 
            "cols" : ["platform", "Currency", "frozenCurrrency", "quoteCurrency", "frozenQuoteCurrency", "triggerSpread", "currentSpread"], 
            "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 hậu quả

Backtest chỉ là một thử nghiệm của chiến lược, như một chức năng phát hiện sơ bộ. Nhiều lỗi thực sự có thể được thử nghiệm trong giai đoạn backtest. Không cần phải quan tâm quá nhiều đến kết quả backtest. Cuối cùng, chiến lược vẫn cần được thử nghiệm trong môi trường thực tế với các bot thực sự.

img

img

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


Thêm nữa