Sumber daya yang dimuat... Pemuatan...

Desain strategi Martingale untuk berjangka cryptocurrency

Penulis:FMZ~Lydia, Dibuat: 2022-08-04 15:41:45, Diperbarui: 2023-09-21 21:10:49

img

Desain strategi Martingale untuk berjangka cryptocurrency

Baru-baru ini, ada banyak strategi Martingale yang dibahas di grup resmi FMZ, dan tidak banyak strategi Martingale kontrak cryptocurrency di platform. Oleh karena itu, saya mengambil kesempatan ini untuk merancang strategi Martingale sederhana untuk berjangka cryptocurrency. Mengapa disebut strategi Martingale? Karena potensi risiko strategi Martin memang tidak kecil, itu tidak dirancang persis sesuai dengan strategi Martin. Namun, jenis strategi ini masih memiliki banyak risiko, dan pengaturan parameter strategi jenis Martin terkait erat dengan risiko, dan risiko tidak boleh diabaikan.

Artikel ini terutama menjelaskan dan belajar dari desain strategi tipe Martin. Karena ide strategi sangat jelas, sebagai pengguna FMZ, kami lebih mempertimbangkan desain strategi.

Dapatkan total ekuitas

Total equity sering digunakan saat merancang strategi futures cryptocurrency. Ini karena pengembalian harus dihitung, terutama ketika Anda perlu menghitung pengembalian mengambang. Karena posisi ditempati dengan margin, pesanan yang sedang menunggu juga ditempati. Pada saat ini, antarmuka APIexchange.GetAccount()Pada dasarnya, sebagian besar bursa berjangka cryptocurrency menyediakan data ekuitas total, tetapi atribut ini tidak dikemas secara seragam pada FMZ.

Jadi kita merancang fungsi untuk mendapatkan data ini sesuai dengan pertukaran yang berbeda:

// OKEX V5 obtain total equity
function getTotalEquity_OKEX_V5() {
    var totalEquity = null 
    var ret = exchange.IO("api", "GET", "/api/v5/account/balance", "ccy=USDT")
    if (ret) {
        try {
            totalEquity = parseFloat(ret.data[0].details[0].eq)
        } catch(e) {
            Log("failed to obtain the total equity of the account!")
            return null
        }
    }
    return totalEquity
}

// Binance futures
function getTotalEquity_Binance() {
    var totalEquity = null 
    var ret = exchange.GetAccount()
    if (ret) {
        try {
            totalEquity = parseFloat(ret.Info.totalWalletBalance)
        } catch(e) {
            Log("failed to obtain the total equity of the account!")
            return null
        }
    }
    return totalEquity
}

PeraturantotalEquityKemudian kita menulis fungsi sebagai entri panggilan, dan memanggil fungsi yang sesuai sesuai dengan nama bursa.

function getTotalEquity() {
    var exName = exchange.GetName()
    if (exName == "Futures_OKCoin") {
        return getTotalEquity_OKEX_V5()
    } else if (exName == "Futures_Binance") {
        return getTotalEquity_Binance()
    } else {
        throw "This exchange is not supported"
    }
}

Merancang beberapa fungsi bantu

Sebelum merancang fungsi utama dan logika utama, kita perlu melakukan beberapa persiapan dan merancang beberapa fungsi bantu.

  • Batalkan semua pesanan yang sedang menunggu

    function cancelAll() {
        while (1) {
            var orders = _C(exchange.GetOrders)
            if (orders.length == 0) {
                break
            }
            for (var i = 0 ; i < orders.length ; i++) {
                exchange.CancelOrder(orders[i].Id, orders[i])
                Sleep(500)
            }
            Sleep(500)
        }
    }
    

    Fungsi ini akrab bagi mereka yang sering membaca kode contoh strategi pada kotak strategi FMZ, dan banyak strategi telah menggunakan desain yang sama. Fungsi ini adalah untuk mendapatkan daftar pesanan yang sedang menunggu saat ini, dan kemudian membatalkannya satu per satu.

  • Operasi penempatan untuk futures

    function trade(distance, price, amount) {
        var tradeFunc = null 
        if (distance == "buy") {
            tradeFunc = exchange.Buy
        } else if (distance == "sell") {
            tradeFunc = exchange.Sell
        } else if (distance == "closebuy") {
            tradeFunc = exchange.Sell
        } else {
            tradeFunc = exchange.Buy
        }
        exchange.SetDirection(distance)
        return tradeFunc(price, amount)
    }
    
    function openLong(price, amount) {
        return trade("buy", price, amount)
    }
    
    function openShort(price, amount) {
        return trade("sell", price, amount)
    }
    
    function coverLong(price, amount) {
        return trade("closebuy", price, amount)
    }
    
    function coverShort(price, amount) {
        return trade("closesell", price, amount)
    }
    

    Ada empat arah untuk perdagangan berjangka: openLong, openShort, coverLong dan coverShort. Jadi kami merancang empat fungsi order yang sesuai dengan operasi ini. Jika Anda hanya mempertimbangkan order, maka ada beberapa faktor yang diperlukan: arah, harga order dan volume order. Jadi kami juga merancang fungsi bernama:tradeuntuk menangani operasi ketikadistance, price, amountditentukan. Panggilan fungsi untuk openLong, openShort, coverLong dan coverShort akhirnya diselesaikan olehtradefungsi, yaitu, menempatkan pesanan di bursa berjangka berdasarkan jarak, harga, dan kuantitas yang ditetapkan.

Fungsi Utama

Ide strategi sangat sederhana, ambil harga saat ini sebagai dasar, dan tempatkan jual (pendek) dan beli pesanan (panjang) pada jarak tertentu ke atas atau ke bawah. Setelah transaksi selesai, semua pesanan yang tersisa akan dibatalkan, dan kemudian pesanan penutupan baru akan ditempatkan pada jarak tertentu sesuai dengan harga posisi, dan pesanan kenaikan akan ditempatkan pada harga saat ini yang diperbarui, tetapi volume pesanan tidak akan berlipat ganda untuk posisi tambahan.

  • Pekerjaan awal Karena pesanan yang sedang menunggu, kita membutuhkan dua variabel global untuk merekam ID pesanan.

    var buyOrderId = null
    var sellOrderId = null
    

    Kemudian parameter antarmuka strategi dirancang untuk menggunakan opsi bot simulasi OKEX_V5, sehingga beberapa pemrosesan perlu dilakukan dalam kode:

    var exName = exchange.GetName()    
    // Switch OKEX V5 simulated bot
    if (isSimulate && exName == "Futures_OKCoin") {
        exchange.IO("simulate", true)
    }
    

    Ada juga opsi untuk mengatur ulang semua informasi dalam parameter antarmuka, sehingga harus ada pemrosesan yang sesuai dalam kode:

    if (isReset) {
        _G(null)
        LogReset(1)
        LogProfitReset()
        LogVacuum()
        Log("reset all data", "#FF0000")
    }
    

    Kami hanya menjalankan kontrak abadi, jadi tulisan tetap di sini dan diatur untuk abadi saja.

    exchange.SetContractType("swap")
    

    Kemudian kita juga perlu mempertimbangkan keakuratan harga pesanan dan jumlah pesanan. Jika keakuratan tidak ditetapkan dengan benar, keakuratan akan hilang selama proses perhitungan strategi. Jika data memiliki sejumlah besar tempat desimal, mudah menyebabkan pesanan ditolak oleh antarmuka pertukaran.

    exchange.SetPrecision(pricePrecision, amountPrecision)
    Log("set precision", pricePrecision, amountPrecision)
    

    Pemulihan data sederhana dengan desain

    if (totalEq == -1 && !IsVirtual()) {
        var recoverTotalEq = _G("totalEq")
        if (!recoverTotalEq) {
            var currTotalEq = getTotalEquity()
            if (currTotalEq) {
                totalEq = currTotalEq
                _G("totalEq", currTotalEq)
            } else {
                throw "failed to obtain initial equity"
            }
        } else {
            totalEq = recoverTotalEq
        }
    }
    

    Jika Anda ingin menentukan ekuitas total awal akun ketika strategi berjalan, Anda dapat mengatur parametertotalEqJika parameter ini ditetapkan pada -1, strategi akan membaca data ekuitas total yang tersimpan. Jika tidak ada data ekuitas total yang tersimpan, ekuitas total yang dibaca saat ini digunakan sebagai ekuitas total awal strategi yang sedang berlangsung. Setelah itu, peningkatan ekuitas total menunjukkan keuntungan, dan penurunan ekuitas total menunjukkan kerugian. Jika data ekuitas total dibaca, strategi akan terus berjalan dengan data ini.

  • Logika utama Setelah pekerjaan awal selesai, akhirnya kita sampai pada bagian logika utama dari strategi. untuk kemudahan penjelasan, saya menulis instruksi langsung pada komentar kode.

      while (1) {                                  // The main logic of the strategy is designed as an infinite loop
          var ticker = _C(exchange.GetTicker)      // Read the current market information first, mainly using the latest transaction price
          var pos = _C(exchange.GetPosition)       // Read current position data
          if (pos.length > 1) {                    // Judging the position data, because of the logic of this strategy, it is unlikely that long and short positions will appear at the same time, so if there are long and short positions at the same time, an error will be thrown
              Log(pos)
              throw "Simultaneous long and short positions"                  // Throw an error to stop the strategy
          }
          //Depends on status
          if (pos.length == 0) {                    // Make different operations according to the position status, when there is no position, pos.length == 0 
              // If you have not held a position, count the profit once
              if (!IsVirtual()) {
                  var currTotalEq = getTotalEquity()
                  if (currTotalEq) {
                      LogProfit(currTotalEq - totalEq, "current total equity:", currTotalEq)
                  }
              }
    
              buyOrderId = openLong(ticker.Last - targetProfit, amount)       // Open a buy order for a long position
              sellOrderId = openShort(ticker.Last + targetProfit, amount)     // Open a short sell order
          } else if (pos[0].Type == PD_LONG) {   // For long positions, the position and quantity of pending orders are different
              var n = 1
              var price = ticker.Last
              buyOrderId = openLong(price - targetProfit * n, amount)
              sellOrderId = coverLong(pos[0].Price + targetProfit, pos[0].Amount)
          } else if (pos[0].Type == PD_SHORT) {   // For short positions, the position and quantity of pending orders are different
              var n = 1
              var price = ticker.Last
              buyOrderId = coverShort(pos[0].Price - targetProfit, pos[0].Amount)
              sellOrderId = openShort(price + targetProfit * n, amount)
          }
    
          if (!sellOrderId || !buyOrderId) {   // If one side of the pending order fails, cancel all pending orders and start over
              cancelAll()
              buyOrderId = null 
              sellOrderId = null
              continue
          } 
    
          while (1) {  // The pending order is completed, start monitoring the order
              var isFindBuyId = false 
              var isFindSellId = false
              var orders = _C(exchange.GetOrders)
              for (var i = 0 ; i < orders.length ; i++) {
                  if (buyOrderId == orders[i].Id) {
                      isFindBuyId = true 
                  }
                  if (sellOrderId == orders[i].Id) {
                      isFindSellId = true 
                  }               
              }
              if (!isFindSellId && !isFindBuyId) {    // Detected that both buy and sell orders have been filled
                  cancelAll()
                  break
              } else if (!isFindBuyId) {   // Detected buy order closing
                  Log("buy order closing")
                  cancelAll()
                  break
              } else if (!isFindSellId) {  // Detected sell order closing
                  Log("sell order closing")
                  cancelAll()
                  break
              }
              LogStatus(_D())
              Sleep(3000)
          }
          Sleep(500)
      }
    

Seluruh logika dan desain dijelaskan.

Pengujian balik

Biarkan strategi melalui pasar 19 Mei.

img

img

Hal ini dapat dilihat bahwa strategi Martingale masih memiliki risiko tertentu.

Bot nyata dapat dijalankan dengan OKEX V5 simulasi bot

Alamat strategi:https://www.fmz.com/strategy/294957

Strategi terutama digunakan untuk belajar, dan uang sungguhan harus digunakan dengan hati-hati~!


Berkaitan

Lebih banyak