Contoh desain strategi dYdX

Penulis:Lydia, Dibuat: 2022-11-07 10:59:29, Diperbarui: 2023-09-15 21:03:43

img

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.

Desain strategi perdagangan stokastik

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:

img

Oh ya! Strategi ini membutuhkan nama, mari kita sebut teka ukuran (versi dYdX) .

Backtest

Backtesting hanya untuk referensi, >_

img

img

img

img

Backtest selesai, tidak ada bug.

Strategi ini digunakan untuk belajar dan referensi saja, jangan gunakan di bot nyata!


Berkaitan

Lebih banyak