Sebagai tanggapan atas permintaan banyak pengguna, platform FMZ telah mengakses dYdX baru-baru ini, pertukaran terdesentralisasi. Seseorang yang memiliki strategi dapat menikmati proses memperoleh mata uang digital dYdX. Saya hanya ingin menulis strategi perdagangan stokastik untuk waktu yang lama, tidak masalah apakah itu menghasilkan keuntungan. Jadi selanjutnya kita datang bersama untuk merancang strategi pertukaran stokastik, tidak peduli apakah strategi berkinerja baik atau tidak, kita hanya belajar desain strategi.
Mari kita melakukan brainstorming! direncanakan untuk merancang strategi penempatan pesanan secara acak dengan indikator dan harga acak. penempatan pesanan tidak lebih dari pergi panjang atau pergi pendek, hanya bertaruh pada probabilitas. kemudian kita akan menggunakan angka acak 1 ~ 100 untuk menentukan apakah untuk pergi panjang atau pergi pendek.
Kondisi untuk pergi panjang: nomor acak 1 ~ 50. Kondisi untuk pergi pendek: nomor acak 51 ~ 100.
Jadi baik long dan short adalah 50 angka. Selanjutnya, mari kita pikirkan bagaimana menutup posisi, karena ini adalah taruhan, maka harus ada kriteria untuk menang atau kalah. Kami menetapkan kriteria untuk stop profit dan loss tetap dalam transaksi. Stop profit untuk menang, stop loss untuk kalah. Sedangkan jumlah stop profit dan loss, sebenarnya dampak rasio profit dan loss, oh ya! Ini juga mempengaruhi tingkat kemenangan! (Apakah desain strategi ini efektif? Dapatkah dijamin sebagai harapan matematika positif? Lakukan dulu! (Setelah itu, itu hanya untuk belajar, penelitian!)
Trading tidak bebas biaya, ada cukup slippage, biaya, dll untuk menarik stochastic trading win rate kita ke sisi kurang dari 50%. Jadi bagaimana untuk mendesainnya terus menerus? Bagaimana dengan mendesain pengganda untuk meningkatkan posisi? Karena ini adalah taruhan, maka probabilitas kehilangan selama 8 ~ 10 kali berturut-turut dalam perdagangan acak harus rendah. Jadi transaksi pertama dirancang untuk menempatkan sejumlah kecil pesanan, sesedikit mungkin. Kemudian jika saya kalah, saya akan meningkatkan jumlah pesanan dan terus menempatkan pesanan secara acak.
Oke, strategi ini dirancang sederhana.
Kode sumber dirancang:
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 "Strategy starts with a position!"
}
exchange.SetPrecision(pricePrecision, amountPrecision)
Log("set the pricePrecision", 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 "failed to obtain initial interest"
}
} else {
totalEq = recoverTotalEq
}
} else {
totalEq = _C(exchange.GetAccount).Balance
}
while (1) {
if (openPrice == 0) {
// Update account information and calculate profits
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 ? "buying order" : "selling 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
}
// Test for closing the position
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
// drawing the line
$.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
}
// Test the 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)
// update the position after cancellation, and check it 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 the pending orders
// reset openPrice
cancelAll()
openPrice = 0
}
Sleep(1000)
}
}
Parameter strategi:
Oh ya! Strategi ini membutuhkan nama, mari kita sebut
Backtesting hanya untuk referensi, >_
Backtest selesai, tidak ada bug.
Strategi ini digunakan untuk belajar dan referensi saja, jangan gunakan di bot nyata!