Baru-baru ini, terdapat banyak strategi Martingale yang dibincangkan dalam kumpulan rasmi FMZ, dan tidak banyak strategi Martingale kontrak mata wang kripto di platform. Oleh itu, saya mengambil peluang ini untuk merancang strategi Martingale yang mudah untuk niaga hadapan mata wang kripto. Mengapa ia dipanggil strategi Martingale? Kerana risiko berpotensi strategi Martin memang tidak kecil, ia tidak direka dengan tepat mengikut strategi Martin. Walau bagaimanapun, jenis strategi ini masih mempunyai banyak risiko, dan tetapan parameter strategi jenis Martin sangat berkaitan dengan risiko, dan risiko tidak boleh diabaikan.
Artikel ini terutamanya menerangkan dan belajar dari reka bentuk strategi jenis Martin.
Jumlah ekuiti sering digunakan ketika merancang strategi niaga hadapan mata wang kripto. Ini kerana pulangan harus dikira, terutamanya apabila anda perlu mengira pulangan terapung. Oleh kerana kedudukan didiami dengan margin, pesanan yang menunggu juga diduduki. Pada masa ini, antara muka APIexchange.GetAccount()
Pertukaran niaga hadapan mata wang kripto kebanyakan menyediakan data ekuiti keseluruhan, tetapi atribut ini tidak dikemas secara seragam di FMZ.
Jadi kita merancang fungsi untuk mendapatkan data ini mengikut pertukaran yang berbeza:
// 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
}
PeraturantotalEquity
Kemudian kita menulis fungsi sebagai entri panggilan, dan memanggil fungsi yang sepadan mengikut 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"
}
}
Sebelum merancang fungsi utama dan logik utama, kita perlu melakukan beberapa persiapan dan merancang beberapa fungsi tambahan.
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 biasa bagi mereka yang sering membaca kod contoh strategi pada kotak strategi FMZ, dan banyak strategi telah menggunakan reka bentuk yang sama. Fungsi ini adalah untuk mendapatkan senarai pesanan yang sedang menunggu, dan kemudian membatalkannya satu demi satu.
Operasi penempatan bagi niaga 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 untuk perdagangan niaga hadapan: openLong, openShort, coverLong andcoverShort. Jadi kami merancang empat fungsi pesanan yang sepadan dengan operasi ini. Jika anda hanya mempertimbangkan pesanan, maka terdapat beberapa faktor yang diperlukan: arah, harga pesanan dan jumlah pesanan.
Jadi kami juga merancang fungsi bernama:trade
untuk mengendalikan operasi apabiladistance
, price
, amount
ditentukan.
Panggilan fungsi untuk openLong, openShort, coverLong dan coverShort akhirnya diselesaikan olehtrade
fungsi, iaitu, meletakkan pesanan di bursa niaga hadapan berdasarkan jarak, harga, dan kuantiti yang ditetapkan.
Idea strategi ini sangat mudah, ambil harga semasa sebagai asas, dan tempatkan pesanan jual (pendek) dan beli (panjang) pada jarak tertentu ke atas atau ke bawah.
Kerja awal Kerana pesanan yang menunggu, kita perlukan dua pembolehubah global untuk merakam ID pesanan.
var buyOrderId = null
var sellOrderId = null
Kemudian parameter antara muka strategi direka untuk menggunakan pilihan bot simulasi OKEX_V5, jadi beberapa pemprosesan perlu dilakukan dalam kod:
var exName = exchange.GetName()
// Switch OKEX V5 simulated bot
if (isSimulate && exName == "Futures_OKCoin") {
exchange.IO("simulate", true)
}
Terdapat juga pilihan untuk menetapkan semula semua maklumat dalam parameter antara muka, jadi harus ada pemprosesan yang sepadan dalam kod:
if (isReset) {
_G(null)
LogReset(1)
LogProfitReset()
LogVacuum()
Log("reset all data", "#FF0000")
}
Kami hanya menjalankan kontrak kekal, jadi tulisan ditetapkan di sini dan ditetapkan untuk kekal sahaja.
exchange.SetContractType("swap")
Kemudian kita juga perlu mempertimbangkan ketepatan harga pesanan dan jumlah pesanan. Jika ketepatan tidak ditetapkan dengan betul, ketepatan akan hilang semasa proses pengiraan strategi. Jika data mempunyai sebilangan besar tempat perpuluhan, mudah menyebabkan pesanan ditolak oleh antara muka pertukaran.
exchange.SetPrecision(pricePrecision, amountPrecision)
Log("set precision", pricePrecision, amountPrecision)
Pemulihan data mudah dengan reka bentuk
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 jumlah ekuiti awal akaun apabila strategi berjalan, anda boleh menetapkan parametertotalEq
Jika parameter ini ditetapkan kepada -1, strategi akan membaca data ekuiti total yang disimpan. Jika tidak ada data ekuiti total yang disimpan, ekuiti total yang dibaca semasa digunakan sebagai ekuiti total awal strategi yang sedang berjalan. Selepas itu, peningkatan ekuiti total menunjukkan keuntungan, dan penurunan ekuiti total menunjukkan kerugian. Jika data ekuiti total dibaca, strategi akan terus berjalan dengan data ini.
Logik utama Selepas kerja awal dilakukan, akhirnya kita datang ke bahagian logik utama strategi. untuk kemudahan penjelasan, saya menulis arahan terus pada kod komen.
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 logik dan reka bentuk dijelaskan.
Biarkan strategi melalui pasaran 19 Mei.
Ia boleh dilihat bahawa strategi Martingale masih mempunyai risiko tertentu.
Bot sebenar boleh dijalankan dengan bot simulasi OKEX V5
Alamat strategi:https://www.fmz.com/strategy/294957
Strategi digunakan terutamanya untuk belajar, dan wang sebenar harus digunakan dengan berhati-hati~!