avatar of 发明者量化-小小梦 发明者量化-小小梦
fokus pada mesej peribadi
4
fokus pada
1271
Pengikut

Reka Bentuk Strategi Martingale untuk Niaga Hadapan Mata Wang Kripto

Dicipta dalam: 2021-07-02 14:35:34, dikemas kini pada: 2023-09-21 21:09:56
comments   22
hits   6170

Reka Bentuk Strategi Martingale untuk Niaga Hadapan Mata Wang Kripto

Reka Bentuk Strategi Martingale untuk Niaga Hadapan Mata Wang Kripto

Baru-baru ini, terdapat banyak perbincangan mengenai strategi Martingale dalam kumpulan rasmi FMZ, tetapi tidak banyak strategi Martingale untuk kontrak mata wang digital pada platform. Oleh itu, saya mengambil peluang ini untuk mereka bentuk strategi Martingale mudah untuk niaga hadapan mata wang kripto. Mengapa ia dipanggil strategi seperti Martin kerana potensi risiko strategi Martin memang tidak kecil, jadi ia tidak direka sepenuhnya mengikut strategi Martin. Walau bagaimanapun, jenis strategi ini masih mempunyai risiko yang besar, dan tetapan parameter strategi Martingale berkait rapat dengan risiko, dan risiko tidak boleh diabaikan.

Artikel ini menerangkan dan mempelajari daripada reka bentuk strategi jenis Martin. Idea strategi itu sendiri adalah sangat jelas. Sebagai pengguna FMZ, kami mempertimbangkan reka bentuk strategi.

Dapatkan jumlah ekuiti

Apabila mereka bentuk strategi niaga hadapan mata wang digital, jumlah data ekuiti sering digunakan. Kerana ia adalah perlu untuk mengira pulangan, terutamanya apabila pulangan terapung perlu dikira. Memandangkan kedudukan terbuka menduduki margin, pesanan belum selesai juga menduduki margin. Pada masa ini, hubungi antara muka API platform FMZexchange.GetAccount()Apa yang diperolehi adalah aset yang ada dan aset yang dibekukan oleh pesanan yang belum selesai. Malah, kebanyakan pertukaran niaga hadapan mata wang digital menyediakan data tentang jumlah ekuiti, tetapi FMZ tidak merangkum atribut ini secara seragam.

Oleh itu, kami mereka bentuk fungsi untuk mendapatkan data ini mengikut pertukaran yang berbeza:

// OKEX V5 获取总权益
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("获取账户总权益失败!")
            return null
        }
    }
    return totalEquity
}

// 币安期货
function getTotalEquity_Binance() {
    var totalEquity = null 
    var ret = exchange.GetAccount()
    if (ret) {
        try {
            totalEquity = parseFloat(ret.Info.totalWalletBalance)
        } catch(e) {
            Log("获取账户总权益失败!")
            return null
        }
    }
    return totalEquity
}

Dalam kodtotalEquityIni adalah jumlah ekuiti yang kami perlukan. Kemudian kami menulis fungsi sebagai entri panggilan dan memanggil fungsi yang sepadan mengikut nama pertukaran.

function getTotalEquity() {
    var exName = exchange.GetName()
    if (exName == "Futures_OKCoin") {
        return getTotalEquity_OKEX_V5()
    } else if (exName == "Futures_Binance") {
        return getTotalEquity_Binance()
    } else {
        throw "不支持该交易所"
    }
}

Reka beberapa fungsi pembantu

Sebelum mereka bentuk fungsi utama dan logik utama. Kita masih perlu melakukan beberapa penyediaan dan mereka bentuk beberapa fungsi tambahan.

  • Batalkan semua pesanan belum selesai semasa
  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)
      }
  }

Saya percaya bahawa mereka yang sering melihat kod contoh strategi di Dataran Strategi FMZ sangat mengenali fungsi ini. Banyak strategi telah menggunakan reka bentuk yang serupa. Fungsinya adalah untuk mendapatkan senarai pesanan yang belum selesai semasa dan kemudian membatalkannya satu persatu.

  • Operasi pesanan hadapan
  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)
  }

Terdapat empat arah dalam perdagangan niaga hadapan: buka posisi beli (openLong), buka posisi jual (openShort), tutup posisi beli (coverLong), dan tutup posisi jual (coverShort). Oleh itu, kami mereka bentuk empat fungsi pesanan untuk sepadan dengan operasi ini. Jika anda hanya mempertimbangkan untuk membuat pesanan, terdapat beberapa faktor yang perlu: arah, harga pesanan dan kuantiti pesanan. Oleh itu, kami juga merancang program yang dipanggil:tradeFungsi untuk mengendalikan方向(distance)下单价格(price)下单量(amount)Semua operasi adalah jelas. Panggilan fungsi membuka kedudukan panjang (openLong), membuka kedudukan pendek (openShort), menutup kedudukan panjang (coverLong), dan menutup kedudukan pendek (coverShort) akhirnya dilaksanakan olehtradeFungsi melaksanakan fungsi sebenar, iaitu membuat pesanan di bursa niaga hadapan mengikut arah, harga dan kuantiti yang ditetapkan.

Fungsi utama

Strateginya sangat mudah. ​​Gunakan harga semasa sebagai garis dasar dan buat pesanan jual (pendek) dan pesanan beli (panjang) pada jarak tertentu di atas dan di bawah harga semasa. Sebaik sahaja satu pihak dilaksanakan, semua pesanan yang tinggal akan dibatalkan, dan kemudian pesanan penutup baharu akan diletakkan pada jarak tertentu berdasarkan harga kedudukan, dan pesanan kenaikan akan diletakkan pada harga semasa yang dikemas kini, tetapi pesanan kenaikan akan tidak menggandakan kuantiti pesanan.

  • Kerja awal Kerana kita perlu membuat pesanan, kita memerlukan dua pembolehubah global untuk merekodkan ID pesanan.
  var buyOrderId = null
  var sellOrderId = null

Kemudian pilihan untuk menggunakan cakera simulasi OKEX_V5 direka dalam parameter antara muka strategi, jadi beberapa pemprosesan perlu dilakukan dalam kod:

  var exName = exchange.GetName()    
  // 切换OKEX V5模拟盘
  if (isSimulate && exName == "Futures_OKCoin") {
      exchange.IO("simulate", true)
  }

Parameter antara muka juga termasuk pilihan untuk menetapkan semula semua maklumat, jadi kod itu juga harus mempunyai pemprosesan yang sepadan:

  if (isReset) {
      _G(null)
      LogReset(1)
      LogProfitReset()
      LogVacuum()
      Log("重置所有数据", "#FF0000")
  }

Kami hanya menjalankan kontrak kekal, jadi ia dikodkan keras di sini dan hanya ditetapkan kepada kontrak kekal.

  exchange.SetContractType("swap")

Kemudian kita juga perlu mempertimbangkan ketepatan harga pesanan dan kuantiti pesanan Jika ketepatan tidak ditetapkan dengan betul, ketepatan akan hilang semasa proses pengiraan strategi Jika data mempunyai banyak tempat perpuluhan, ia akan menyebabkan pesanan menjadi ditolak oleh antara muka pertukaran.

  exchange.SetPrecision(pricePrecision, amountPrecision)
  Log("设置精度", pricePrecision, amountPrecision)

Fungsi pemulihan data mudah

  if (totalEq == -1 && !IsVirtual()) {
      var recoverTotalEq = _G("totalEq")
      if (!recoverTotalEq) {
          var currTotalEq = getTotalEquity()
          if (currTotalEq) {
              totalEq = currTotalEq
              _G("totalEq", currTotalEq)
          } else {
              throw "获取初始权益失败"
          }
      } else {
          totalEq = recoverTotalEq
      }
  }

Jika anda ingin menentukan jumlah ekuiti akaun awal apabila strategi dijalankan, anda boleh menetapkan parametertotalEqJika parameter ini ditetapkan kepada -1, strategi akan membaca jumlah data ekuiti yang disimpan Jika tiada jumlah data ekuiti yang disimpan, jumlah ekuiti bacaan semasa akan digunakan sebagai jumlah ekuiti awal strategi yang menjalankan kemajuan ekuiti meningkat, bermakna Jika anda membuat wang, tetapi jumlah ekuiti anda kurang, bermakna anda telah kehilangan wang. Jika jumlah data ekuiti dibaca, teruskan berjalan menggunakan data ini.

  • Logik utama Selepas kerja awal selesai, kami akhirnya sampai ke logik utama strategi Untuk kemudahan penjelasan, saya menulis penjelasan secara langsung dalam komen kod.
    while (1) {                                  // 策略主要逻辑设计为一个死循环
        var ticker = _C(exchange.GetTicker)      // 首先读取当前行情信息,主要用到最新成交价
        var pos = _C(exchange.GetPosition)       // 读取当前持仓数据
        if (pos.length > 1) {                    // 判断持仓数据,由于这个策略的逻辑,是不太可能同时出现多空持仓的,所以发现同时出现多空持仓就抛出错误
            Log(pos)
            throw "同时有多空持仓"                  // 抛出错误,让策略停止
        }
        // 根据状态而定
        if (pos.length == 0) {                    // 根据持仓状态做出不同操作,pos.length == 0是当没有持仓时
            // 未持仓了,统计一次收益
            if (!IsVirtual()) {
                var currTotalEq = getTotalEquity()
                if (currTotalEq) {
                    LogProfit(currTotalEq - totalEq, "当前总权益:", currTotalEq)
                }
            }

            buyOrderId = openLong(ticker.Last - targetProfit, amount)       // 挂开多仓的买单
            sellOrderId = openShort(ticker.Last + targetProfit, amount)     // 挂开空仓的卖单
        } else if (pos[0].Type == PD_LONG) {   // 有多头持仓,挂单位置、数量有所不同
            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) {   // 有空头持仓,挂单位置、数量有所不同
            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) {   // 如果有一边挂单失败就取消所有挂单,重来
            cancelAll()
            buyOrderId = null 
            sellOrderId = null
            continue
        } 

        while (1) {  // 挂单完成,开始监控订单
            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) {    // 检测到买卖单都成交了
                cancelAll()
                break
            } else if (!isFindBuyId) {   // 检测到买单成交
                Log("买单成交")
                cancelAll()
                break
            } else if (!isFindSellId) {  // 检测到卖单成交
                Log("卖单成交")
                cancelAll()
                break
            }
            LogStatus(_D())
            Sleep(3000)
        }
        Sleep(500)
    }

Keseluruhan logik dan reka bentuk telah dijelaskan.

Ujian belakang

Biarkan strategi mengalami situasi pasaran pada 19 Mei.

Reka Bentuk Strategi Martingale untuk Niaga Hadapan Mata Wang Kripto

Reka Bentuk Strategi Martingale untuk Niaga Hadapan Mata Wang Kripto

Dapat dilihat bahawa strategi Martingale masih mempunyai risiko tertentu.

Anda boleh mencuba demo OKEX V5 untuk dagangan sebenar.

Reka Bentuk Strategi Martingale untuk Niaga Hadapan Mata Wang Kripto

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

Strategi digunakan terutamanya untuk pembelajaran, jadi gunakan wang sebenar dengan berhati-hati ~!