Sebagai tindak balas kepada keperluan ramai pengguna, platform FMZ baru-baru ini telah menyokong platform terdesentralisasi dYdX. Rakan-rakan dengan strategi boleh menambang di dYdX dengan gembira. Hanya lama yang lalu, saya ingin menulis strategi perdagangan rawak. Tidak kira sama ada saya mendapat keuntungan atau tidak. Tujuannya adalah untuk mengamalkan teknik saya dan mengajar reka bentuk strategi dengan cara. Jadi seterusnya, mari kita merancang strategi platform rawak bersama-sama. Jangan risau tentang prestasi strategi, dan hanya belajar reka bentuk strategi.
Tangkapan skrin strategi perlombongan dalam artikel.
Selamat datang rakan-rakan yang mempunyai idea strategi perlombongan yang baik untuk dikongsi!
Mari kita bertukar fikiran! Kami merancang untuk merancang strategi untuk meletakkan pesanan secara rawak tanpa melihat petunjuk atau harga. Memesan tidak lebih daripada melakukan panjang dan pendek, yang bertaruh pada kebarangkalian. Kemudian kami menggunakan nombor rawak dari 1 hingga 100 untuk menentukan sama ada melakukan panjang atau melakukan pendek.
Keadaan melakukan panjang: nombor rawak dari 1 hingga 50. Syarat untuk melakukan pendek: nombor rawak dari 51 hingga 100.
Untuk melakukan long dan short, kedua-duanya memerlukan 50 nombor. Seterusnya, mari kita fikirkan bagaimana untuk menutup kedudukan. Oleh kerana ia adalah pertaruhan, mesti ada standard menang atau kalah. Kemudian, mari kita tetapkan stopProfit dan stopLoss tetap sebagai standard menang atau kalah. Ambil stopProfit sebagai menang, dan stopLoss sebagai kehilangan. Mengenai kesesuaian stopProfit dan stopLoss, ia sebenarnya mempengaruhi nisbah keuntungan dan kerugian, dan kadar kemenangan juga! (Adakah berkesan untuk merancang strategi dengan cara ini? Bolehkah ia dijamin menjadi jangkaan matematik yang positif? Bagaimanapun, mari kita lakukan terlebih dahulu! Kerana ia adalah untuk pembelajaran dan penyelidikan!)
Perdagangan tidak bebas kos, dan terdapat faktor-faktor seperti slippoint dan yuran yang cukup untuk menarik kadar kemenangan perdagangan rawak kami ke sisi kurang daripada 50%. Berfikir tentang itu, bagaimana untuk meneruskan reka bentuk dari sini? Ia lebih baik untuk merancang skala dalam dengan berganda untuk meningkatkan kedudukan. Kerana ia adalah pertaruhan, kebarangkalian kehilangan berturut-turut 10 atau 8 kali tidak boleh sangat besar. jadi saya mahu untuk merancang meletakkan jumlah pesanan yang kecil dalam perdagangan pertama, kecil seperti yang boleh. kemudian jika saya kehilangan taruhan, meningkatkan jumlah pesanan dan terus meletakkan pesanan rawak.
Baiklah, strategi ini cukup mudah.
Kod sumber reka bentuk:
var openPrice = 0
var ratio = 1
var totalEq = null
var nowEq = null
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)
}
}
function main() {
if (isReset) {
_G(null)
LogReset(1)
LogProfitReset()
LogVacuum()
Log("reset all data", "#FF0000")
}
exchange.SetContractType(ct)
var initPos = _C(exchange.GetPosition)
if (initPos.length != 0) {
throw "Position detected when starting the strategy!"
}
exchange.SetPrecision(pricePrecision, amountPrecision)
Log("setPrecision", pricePrecision, amountPrecision)
if (!IsVirtual()) {
var recoverTotalEq = _G("totalEq")
if (!recoverTotalEq) {
var currTotalEq = _C(exchange.GetAccount).Balance // equity
if (currTotalEq) {
totalEq = currTotalEq
_G("totalEq", currTotalEq)
} else {
throw "fail to obtain the initial equity"
}
} else {
totalEq = recoverTotalEq
}
} else {
totalEq = _C(exchange.GetAccount).Balance
}
while (1) {
if (openPrice == 0) {
// update account information, and calculate the profit
var nowAcc = _C(exchange.GetAccount)
nowEq = IsVirtual() ? nowAcc.Balance : nowAcc.Balance // equity
LogProfit(nowEq - totalEq, nowAcc)
var direction = Math.floor((Math.random()*100)+1) // 1~50 , 51~100
var depth = _C(exchange.GetDepth)
if (depth.Asks.length <= 2 || depth.Bids.length <= 2) {
Sleep(1000)
continue
}
if (direction > 50) {
// long
openPrice = depth.Bids[1].Price
exchange.SetDirection("buy")
exchange.Buy(Math.abs(openPrice) + slidePrice, amount * ratio)
} else {
// short
openPrice = -depth.Asks[1].Price
exchange.SetDirection("sell")
exchange.Sell(Math.abs(openPrice) - slidePrice, amount * ratio)
}
Log("place", direction > 50 ? "buy order" : "sell order", ",price:", Math.abs(openPrice))
continue
}
var orders = _C(exchange.GetOrders)
if (orders.length == 0) {
var pos = _C(exchange.GetPosition)
if (pos.length == 0) {
openPrice = 0
continue
}
// detect close positions
while (1) {
var depth = _C(exchange.GetDepth)
if (depth.Asks.length <= 2 || depth.Bids.length <= 2) {
Sleep(1000)
continue
}
var stopLossPrice = openPrice > 0 ? Math.abs(openPrice) - stopLoss : Math.abs(openPrice) + stopLoss
var stopProfitPrice = openPrice > 0 ? Math.abs(openPrice) + stopProfit : Math.abs(openPrice) - stopProfit
var winOrLoss = 0 // 1 win , -1 loss
// plot
$.PlotLine("bid", depth.Bids[0].Price)
$.PlotLine("ask", depth.Asks[0].Price)
// stop loss
if (openPrice > 0 && depth.Bids[0].Price < stopLossPrice) {
exchange.SetDirection("closebuy")
exchange.Sell(depth.Bids[0].Price - slidePrice, pos[0].Amount)
winOrLoss = -1
} else if (openPrice < 0 && depth.Asks[0].Price > stopLossPrice) {
exchange.SetDirection("closesell")
exchange.Buy(depth.Asks[0].Price + slidePrice, pos[0].Amount)
winOrLoss = -1
}
// stop profit
if (openPrice > 0 && depth.Bids[0].Price > stopProfitPrice) {
exchange.SetDirection("closebuy")
exchange.Sell(depth.Bids[0].Price - slidePrice, pos[0].Amount)
winOrLoss = 1
} else if (openPrice < 0 && depth.Asks[0].Price < stopProfitPrice) {
exchange.SetDirection("closesell")
exchange.Buy(depth.Asks[0].Price + slidePrice, pos[0].Amount)
winOrLoss = 1
}
// detect pending orders
Sleep(2000)
var orders = _C(exchange.GetOrders)
if (orders.length == 0) {
pos = _C(exchange.GetPosition)
if (pos.length == 0) {
if (winOrLoss == -1) {
ratio++
} else if (winOrLoss == 1) {
ratio = 1
}
break
}
} else {
// cancel pending orders
cancelAll()
Sleep(2000)
pos = _C(exchange.GetPosition)
// after canceling, update positions, which needs to be detected again
if (pos.length == 0) {
if (winOrLoss == -1) {
ratio++
} else if (winOrLoss == 1) {
ratio = 1
}
break
}
}
var tbl = {
"type" : "table",
"title" : "info",
"cols" : ["totalEq", "nowEq", "openPrice", "bid1Price", "ask1Price", "ratio", "pos.length"],
"rows" : [],
}
tbl.rows.push([totalEq, nowEq, Math.abs(openPrice), depth.Bids[0].Price, depth.Asks[0].Price, ratio, pos.length])
tbl.rows.push(["pos", "type", "amount", "price", "--", "--", "--"])
for (var j = 0 ; j < pos.length ; j++) {
tbl.rows.push([j, pos[j].Type, pos[j].Amount, pos[j].Price, "--", "--", "--"])
}
LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
}
} else {
// cancel pending orders
// reset openPrice
cancelAll()
openPrice = 0
}
Sleep(1000)
}
}
Parameter strategi:
Baiklah! Strategi ini memerlukan nama, dan mari kita memanggilnya "Tebak mana yang lebih besar (versi dYdX).
Ujian belakang hanya untuk rujukan! Ia terutamanya untuk memeriksa sama ada terdapat sebarang bug dalam strategi; backtest dengan Binance Futures.
Ujian balik telah selesai, tiada bug, tapi saya rasa sistem uji balik telah sepadan... mari kita jalankan dalam bot sebenar untuk pemerhatian.
Strategi ini hanya untuk pembelajaran dan rujukan.Jangan!! Jangangunakan dalam bot sebenar!