Reka bentuk strategi lindung nilai spot cryptocurrency(2)

Penulis:Lydia, Dicipta: 2022-07-19 15:19:52, Dikemas kini: 2023-09-24 19:34:38

img

Reka bentuk strategi lindung nilai spot cryptocurrency (2)

Dalam artikel sebelumnya, kita melaksanakan strategi lindung nilai mudah bersama-sama, dan kemudian kita akan belajar bagaimana untuk menaik taraf strategi ini. Perubahan strategi tidak besar, tetapi butiran perubahan memerlukan perhatian. definisi beberapa tempat dalam kod telah berubah dari yang sebelumnya, yang perlu difahami.

Keperluan untuk meningkatkan strategi ini

  • Memindahkan mod leverage objek pertukaran spot Perubahan ini hanya berkaitan dengan bot sebenar. Sesetengah bursa spot mempunyai antara muka leverage spot, yang juga dikemas dalam FMZ. Untuk objek pertukaran yang telah dikemas secara langsung di FMZ dan menyokong leverage spot, mod boleh ditukar secara langsung.
  • Tambah paparan carta spread Tambah paparan carta spread, kerana ia hanya menggambar garis spreadA exchange -> B exchange, B exchange -> A exchange, dan melukis garis mendatar yang mencetuskan penyebaran.line drawing class libraryuntuk menangani secara langsung, kelebihan adalah bahawa ia mudah digunakan, di sini kita juga belajar bagaimana untuk menggunakantemplate class libraryfungsi FMZ.
  • Fungsi lindung nilai satu sisi Perubahan ini boleh menjadi sangat penting, kerana sukar untuk membalikkan sepenuhnya perbezaan harga antara kedua-dua bursa semasa transaksi lindung nilai tertentu. Kebanyakan masa harga di satu bursa secara konsisten lebih tinggi daripada harga di bursa lain. Pada masa ini, jika aset kita telah dilindung nilai sepenuhnya (iaitu, duit syiling semuanya berada di bursa dengan harga rendah, dan wang berada di bursa dengan harga tinggi). lindung nilai terhenti, dan tidak lagi mungkin bergantung pada turun naik penyebaran untuk memperoleh keuntungan. Pada masa ini, kita perlu membuat strategi supaya anda boleh kehilangan sedikit wang untuk lindung nilai kembali (biarkan duit syiling wujud di bursa dengan harga tinggi lagi), dan apabila perbezaan harga menjadi lebih besar lagi, kita boleh terus lindung nilai dan memperoleh keuntungan.
  • Mengubahsuai parameter secara interaktif seperti garis penyebaran lindung nilai Tambah fungsi interaktif kepada strategi untuk mengubah garis pencetus penyebaran dalam masa nyata.
  • Menyusun maklumat bar status dan memaparkannya dalam format jadual Susun data yang perlu dipaparkan untuk dilihat dengan mudah.

Seterusnya, mari kita melaksanakan reka bentuk ini satu demi satu.

Tukar mod leverage objek pertukaran spot

Ambil Binance bot sebenar spot sebagai contoh, beralih ke mod leveraged spot, gunakan kodexchanges[i].IO, masukkan parametertrade_normaluntuk beralih ke kedudukan leverage mengikut kedudukan, dan inputtrade_super_marginuntuk beralih ke kedudukan sepenuhnya, backtesting tidak disokong. ini hanya digunakan dalam bot sebenar.

Tambah kepada fasa persediaan pada awalmainfungsi:

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

Strategi di sini hanya menambah kod untuk menukar mod leverage koin ke koin Binance spot, jadi tetapan suis pada parameter strategi hanya sah untuk Binance spot.

Tambahan paparan carta spread

Ia adalah sangat mudah untuk menggunakan templat lukisan yang sudah dibungkus. nama templat yang kita gunakan adalahLine Drawing Library. Ia boleh diperolehi dengan mencari terus di platform FMZ strategi persegi.

img

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

img

Klik butang untuk menyalin perpustakaan kelas templat ini ke perpustakaan strategi anda sendiri.

img

Kemudian anda boleh menyemak perpustakaan kelas templat yang akan digunakan dalam lajur templat di halaman penyuntingan strategi. Simpan strategi selepas menyemaknya, dan strategi akan merujuk kepada templat ini. Ini hanya penerangan ringkas penggunaan perpustakaan kelas templat. Strategi ini telah merujuk kepada templat ini, jadi tidak perlu mengulangi operasi. Apabila anda menyalin strategi ini di kotak strategi, anda dapat melihat bahawaLine Drawing Librarytelah dirujuk dalam bar templat pada halaman penyuntingan strategi.

Kami akan belajar bagaimana untuk menggunakan fungsiLine Drawing Libraryuntuk membuat carta.

img

Kami merancang untuk menarik penyebaranA->B, penyebaranB->A, dan garis pemicu penyebaran. kita perlu melukis dua lengkung (menyebar semasa A ke B, B ke A), dua garis mendatar (garis penyebaran pemicu), seperti yang ditunjukkan dalam gambar di atas.

Kerana kita mahu untuk mereka bentuk lindung nilai satu sisi, garis pencetusA->BdanB->AKita 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
      }

Terdapat hanya satu penyebaran pencetustargetDiffPrice. Jadi di sini kita perlu mengubah kod, mengubah 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
        }

Dengan cara ini, garis pemicu perbezaan telah berubah dari yang sebelumnyatargetDiffPriceUntuk duatargetDiffPriceA2B, targetDiffPriceB2A. Langkah seterusnya adalah untuk melukis data ini pada carta dengan menggunakan fungsi garis gambar perpustakaan lukisan garis.

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

Apabila strategi berjalan, terdapat carta seperti ini.

img

Seterusnya lukis kurva spread masa nyata, untuk mengelakkan menggambar garis.

        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
        }

Dengan cara ini, kod lukisan hanya 4 baris, yang membolehkan strategi untuk mempunyai grafik yang dipaparkan pada masa berjalan.

Fungsi lindung nilai satu sisi

Seperti yang dinyatakan di atas, garis pencetus spread telah diubah menjadi dua, mengawal pencetus lindung nilaiA->BdanB->ADengan cara ini, algoritma harga pesanan sebelumnya tidak boleh digunakan, dan kaedah penambahan harga slip 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 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 
            }            
        }

Oleh kerana harga beli dan jualan dipisahkan kepada dua data, fungsi lindung nilaihedgejuga 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 perubahan ini, yang tidak akan diulangi di sini.

Mengubahsuai parameter secara interaktif seperti garis penyebaran lindung nilai

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

img

Tambah dua kawalan, satu dipanggil A2B dan satu dipanggil B2A. Selepas memasukkan nilai dalam kotak input kawalan, klik butang di sebelah kanan kotak input. Arahan akan dihantar ke strategi dengan serta-merta, contohnya: masukkan nilai123dalam kotak input, klikA2Bbutang, dan arahan akan dihantar kepada strategi segera.

A2B:123

Reka bentuk kod pengesanan dan pemprosesan interaktif dalam kod strategi.

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

Menyusun maklumat bar status dan memaparkannya dalam format jadual

Buat paparan bar status data lebih teratur dan mudah untuk memerhatikan.

        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

Ujian semula

Backtesting hanyalah strategi ujian, fungsi pengesanan awal, dan banyak bug boleh diuji pada peringkat backtesting sebenarnya.

img

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


Berkaitan

Lebih lanjut