Strategi Hedge Spot Cryptocurrency (2)

Penulis:Ninabadass, Dicipta: 2022-04-14 16:17:46, Dikemas kini: 2022-04-15 14:16:23

Strategi Hedge Spot Cryptocurrency (2)

Dalam artikel sebelumnya, kita melaksanakan strategi lindung nilai mudah bersama-sama, dan kemudian kita akan belajar bagaimana untuk menaik taraf strategi. Tidak banyak perubahan dalam strategi, tetapi butiran perubahan perlu diperhatikan.

Keperluan untuk Meningkatkan Strategi

  • Tukar mod margin objek pertukaran spot Pengubahsuaian ini hanya berkaitan dengan bot. Sesetengah platform spot mempunyai antara muka margin spot, yang juga dikapsul pada FMZ. Untuk objek pertukaran yang langsung dikapsul pada FMZ dan menyokong margin spot, anda boleh terus menukar mod.
  • Tambah lebih banyak paparan carta spread Untuk menambah paparan carta spread lebih, dan kita hanya merangka lengkung spreadA->BdanB->A, serta garis pencetus penyebaran mendatar, kita boleh terus menggunakanchart plot libraryDari sini, kita juga belajar bagaimana untuk menggunakan fungsi FMZtemplate library together.
  • Fungsi lindung nilai satu sisi Perubahan ini agak besar, kerana sukar untuk membalikkan sepenuhnya spread harga antara kedua-dua platform semasa perdagangan lindung nilai tertentu. Kebanyakan masa, harga pada satu platform secara konsisten lebih tinggi daripada harga pada platform lain. Pada masa ini, jika aset kita telah dilindung nilai sepenuhnya (iaitu, semua simbol mata wang berada di platform dengan harga yang lebih rendah, dan aset berada di platform dengan harga yang lebih tinggi). lindung nilai terhenti, dan tidak lagi mungkin bergantung pada turun naik penyebaran untuk membuat keuntungan. Pada masa ini, anda perlu membuat strategi untuk lindung nilai dan mengembalikan simbol mata wang kembali dengan hanya kehilangan sedikit aset (biarkan simbol mata wang kembali ke platform dengan harga yang lebih tinggi lagi).
  • Secara interaktif mengubah suai parameter seperti baris penyebaran lindung nilai
    Tambah fungsi interaktif kepada strategi, supaya mengubah suai garis pencetus penyebaran dalam masa nyata.
  • Mengurus maklumat bar status dan memaparkannya dalam format jadual Menyusun dan menguruskan data yang perlu dipaparkan, untuk pemerhatian yang mudah.

Seterusnya, mari kita merealisasikan idea reka bentuk satu demi satu.

Tukar mod margin objek pertukaran spot

Ambil Binance bot spot sebagai contoh. Untuk beralih ke mod margin spot, gunakan kodexchanges[i].IO, import parametertrade_normaluntuk beralih kepada margin yang terpencil, dan importtrade_super_marginuntuk beralih ke margin silang, yang tidak disokong dalam backtest. yang hanya boleh digunakan dalam bot.

Dalam persediaan pada awalmainfungsi, tambah:

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

Strategi di sini hanya menambah kod untuk menukar mod margin spot Binance Spot, jadi tetapan suis dalam parameter strategi hanya berfungsi untuk Binance Spot.

Tambah lebih banyak paparan carta spread

Menggunakan templat plot yang dikapsulkan adalah sangat mudah. Nama templat yang kita gunakan di sini adalahchart plot LibraryAnda boleh cari secara langsung di platform Lapangan FMZ.

img

Atau anda boleh terus klik pautan:https://www.fmz.com/strategy/27293untuk melompat ke halaman salinan templat.

img

Klik butang dan anda boleh dengan mudah menyalin templat ke perpustakaan strategi anda sendiri.

img

Kemudian, pada halaman penyuntingan strategi, anda boleh menyemak perpustakaan templat yang akan digunakan dalam lajur templat. Simpan strategi selepas menyemaknya, dan strategi akan menggunakan templat ini. Ini hanya penerangan ringkas penggunaan perpustakaan templat. Oleh kerana strategi telah merujuk kepada templat ini, tidak perlu mengulangi operasi. Apabila anda menyalin kod strategi di Square, anda dapat melihat bahawachart plot Librarytelah dirujuk dalam bar templat halaman penyuntingan strategi.

Di sini kita terutamanya belajar bagaimana untuk menggunakan fungsichart plot libraryuntuk merangka.

img

Kami merancang untuk merangka penyebaranA->BdanB->A, dan garis pencetus penyebaran. kita perlu merangka dua lengkung (kini, penyebaran dari A ke B dan B ke A), dan dua garis mendatar (garis pencetus penyebaran), seperti yang ditunjukkan dalam gambar di atas.

Kerana kita mahu untuk mereka bentuk pagar satu sisi, garis pencetusA->BdanB->Aakan berbeza, dan kita tidak boleh menggunakan reka bentuk dalam artikel sebelumnya. Dalam artikel sebelumnya:

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

Hanya ada satu penyebaran yang dicetuskantargetDiffPrice. Oleh itu, di sini kita perlu mengubah suai kod, dan kita perlu mengubah suai parameter terlebih dahulu.

img

Kemudian, ubah kod:

        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
        }

Oleh itu, garis pencetus penyebaran telah berubah dari yang sebelumnyatargetDiffPricekepada dua, iaitutargetDiffPriceA2BdantargetDiffPriceB2A. Seterusnya, anda boleh menggunakan fungsi grafik plot perpustakaan grafik plot untuk menarik data pada carta.

        // 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")

Apabila strategi dijalankan, carta akan dipaparkan seperti ini.

img

Seterusnya, lukis lengkung spread masa nyata; untuk mengelakkan overdrawing, letakkan kod yang merangka lengkung spread masa nyata dalam pengesanan baki. 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
        }

Kod plot hanya memerlukan 4 baris untuk membolehkan strategi dengan paparan carta semasa berjalan.

Fungsi Hedge Satu Sisi

Seperti yang dinyatakan di atas, nombor garis pencetus spread telah diubah menjadi dua, yang masing-masing mengawal pencetus lindung nilaiA->BdanB->ADengan cara ini, algoritma harga pesanan sebelumnya tidak boleh digunakan, dan kaedah menambah harga slaid kepada harga pasaran digunakan sebagai gantinya.

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

Oleh kerana harga beli dan jual dibahagikan kepada dua data,hedgefungsi juga perlu diubah.

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

Terdapat juga beberapa penyesuaian kecil berdasarkan pengubahsuaian ini, yang tidak akan diterangkan di sini.

Secara interaktif mengubah suai parameter seperti baris penyebaran lindung nilai

Tambah interaksi kepada strategi, supaya strategi boleh mengubah suai garis pencetus penyebaran dalam masa nyata. Reka bentuk interaksi strategi juga sangat mudah. Pertama, tambah kawalan interaktif kepada strategi di halaman penyuntingan strategi.

img

Terdapat dua kawalan ditambah, satu dipanggil A2B dan yang lain dipanggil B2A. Selepas memasukkan nilai dalam kotak input kawalan, klik butang di sebelah kanan kotak input. Perintah akan dihantar ke strategi dengan segera, contohnya: masukkan nilai123dalam kotak input, klikA2Bbutang, dan arahan akan dihantar ke strategi dengan segera.

A2B:123

Reka bentuk kod pengesanan dan pemprosesan interaktif dalam kod strategi.

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

Mengurus maklumat bar status dan memaparkannya dalam format jadual

Buat paparan data bar status lebih terkawal dan mudah diperhatikan.

        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

Ujian belakang

Ujian belakang hanya ujian strategi, sebagai fungsi pengesanan awal. Banyak bug sebenarnya boleh diuji dalam peringkat ujian belakang. Tidak perlu terlalu peduli tentang hasil ujian belakang. Akhirnya, strategi masih perlu diuji dalam persekitaran sebenar dengan bot sebenar.

img

img

Kod sumber strategi:https://www.fmz.com/strategy/302834


Lebih lanjut