Contoh reka bentuk strategi dYdX

Penulis:Lydia, Dicipta: 2022-11-07 10:59:29, Dikemas kini: 2023-09-15 21:03:43

img

Sebagai tindak balas kepada permintaan ramai pengguna, platform FMZ telah mengakses dYdX baru-baru ini, pertukaran terdesentralisasi. Seseorang yang mempunyai strategi boleh menikmati proses memperoleh mata wang digital dYdX. Saya hanya mahu menulis strategi perdagangan stokastik untuk masa yang lama, tidak kira sama ada ia membuat keuntungan. Jadi seterusnya kita datang bersama untuk merancang strategi pertukaran stokastik, tidak kira strategi berfungsi dengan baik atau tidak, kita hanya belajar reka bentuk strategi.

Reka bentuk strategi dagangan stokastik

Mari kita bertukar fikiran! Ia dirancang untuk merancang strategi meletakkan pesanan secara rawak dengan penunjuk rawak dan harga. Menempatkan pesanan tidak lebih daripada pergi panjang atau pergi pendek, hanya bertaruh pada kebarangkalian. Kemudian kita akan menggunakan nombor rawak 1 ~ 100 untuk menentukan sama ada untuk pergi panjang atau pergi pendek.

Syarat untuk pergi panjang: nombor rawak 1 ~ 50. Syarat untuk pergi pendek: nombor rawak 51 ~ 100.

Oleh itu, kedua-dua pergi panjang dan pergi pendek adalah 50 nombor. Seterusnya, mari kita fikirkan bagaimana untuk menutup kedudukan, kerana ia adalah pertaruhan, maka mesti ada kriteria untuk menang atau kalah. Kami menetapkan kriteria untuk keuntungan berhenti tetap dan kerugian dalam urus niaga. Hentikan keuntungan untuk menang, hentikan kerugian untuk kehilangan. Mengenai jumlah keuntungan berhenti dan kerugian, ia sebenarnya kesan nisbah keuntungan dan kerugian, oh ya! Ia juga mempengaruhi kadar kemenangan! (Adakah reka bentuk strategi ini berkesan? Bolehkah ia dijamin sebagai jangkaan matematik positif? Lakukan terlebih dahulu! (Selepas itu, hanya untuk pembelajaran, penyelidikan!)

Perdagangan tidak bebas kos, terdapat cukup slippage, yuran, dan lain-lain untuk menarik kadar kemenangan perdagangan stokastik kami ke arah bahagian kurang daripada 50%. Jadi bagaimana untuk merancangnya secara berterusan? Bagaimana dengan merancang pengganda untuk meningkatkan kedudukan? Oleh kerana ia adalah pertaruhan, maka kebarangkalian kehilangan selama 8 ~ 10 kali dalam satu barisan perdagangan rawak harus rendah. Jadi transaksi pertama direka untuk meletakkan sejumlah kecil pesanan, sekecil mungkin. Kemudian jika saya kalah, saya akan meningkatkan jumlah pesanan dan terus meletakkan pesanan secara rawak.

OK, strategi ini direka dengan mudah.

Kod sumber direka:

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 memerlukan nama, mari kita panggil teka saiz (versi dYdX) .

Ujian belakang

Backtesting adalah untuk rujukan sahaja, >_

img

img

img

img

Ujian belakang telah selesai, tidak ada bug.

Strategi ini digunakan untuk pembelajaran dan rujukan sahaja, jangan menggunakannya dalam bot sebenar!


Berkaitan

Lebih lanjut