Ví dụ về thiết kế chiến lược dYdX

Tác giả:Lydia., Tạo: 2022-11-07 10:59:29, Cập nhật: 2023-09-15 21:03:43

img

Để đáp ứng nhu cầu của nhiều người dùng, nền tảng FMZ gần đây đã truy cập dYdX, một sàn giao dịch phi tập trung. Bất cứ ai có chiến lược có thể thưởng thức quá trình mua tiền kỹ thuật số dYdX. Tôi chỉ muốn viết một chiến lược giao dịch chứng khoán từ lâu, không quan trọng nó có kiếm lợi nhuận hay không. Vì vậy, tiếp theo chúng ta cùng nhau thiết kế một chiến lược giao dịch chứng khoán, cho dù chiến lược có hiệu quả tốt hay không, chúng ta chỉ cần học thiết kế chiến lược.

Thiết kế chiến lược giao dịch chứng khoán

Chúng ta hãy suy nghĩ! Nó được lên kế hoạch để thiết kế một chiến lược đặt đơn đặt hàng ngẫu nhiên với các chỉ số ngẫu nhiên và giá cả. Đặt đơn đặt hàng là không gì khác hơn là đi dài hoặc đi ngắn, chỉ đặt cược vào xác suất. Sau đó chúng ta sẽ sử dụng số ngẫu nhiên 1 ~ 100 để xác định xem nên mua dài hay mua ngắn.

Điều kiện để mua dài: số ngẫu nhiên 1 ~ 50. Điều kiện để đi ngắn: số ngẫu nhiên 51 ~ 100.

Do đó, cả đi dài và đi ngắn đều là 50 con số. Tiếp theo, chúng ta hãy suy nghĩ về cách đóng vị trí, vì đó là một cược, sau đó phải có một tiêu chí để thắng hoặc thua. Chúng ta thiết lập một tiêu chí để dừng lợi nhuận và lỗ cố định trong giao dịch. Dừng lợi nhuận cho chiến thắng, dừng lỗ cho thua. Về số lượng dừng lợi nhuận và lỗ, nó thực sự ảnh hưởng đến tỷ lệ lợi nhuận và lỗ, ôi vâng! Nó cũng ảnh hưởng đến tỷ lệ thắng! (Mục đích thiết kế chiến lược này có hiệu quả không? Có thể đảm bảo như một kỳ vọng toán học tích cực không? Làm điều đó trước! (Sau đó, chỉ để học, nghiên cứu!)

Giao dịch không phải là miễn phí, có đủ trượt, phí, vv để kéo tỷ lệ chiến thắng giao dịch ngẫu nhiên của chúng tôi về phía dưới 50%. Vì vậy, làm thế nào để thiết kế nó liên tục? Nếu chúng ta có thể tạo ra một số lượng lớn hơn, thì chúng ta có thể tạo ra một số lượng lớn hơn. Nếu chúng ta có thể tạo ra một số lượng lớn hơn, chúng ta có thể tạo ra một số lượng lớn hơn. Nếu chúng ta có thể tạo ra một số lượng lớn hơn, chúng ta có thể tạo ra một số lượng lớn hơn.

Được rồi, chiến lược được thiết kế đơn giản.

Mã nguồn được thiết kế:

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)
    }
}

Các thông số chiến lược:

img

Ồ vâng! Chiến lược cần một cái tên, hãy gọi nó là đoán kích thước (phiên bản dYdX) .

Kiểm tra hậu quả

Backtesting chỉ để tham khảo, >_

img

img

img

img

Kiểm tra đã hoàn tất, không có lỗi.

Chiến lược này chỉ được sử dụng để học và tham khảo, đừng sử dụng nó trong bot thực sự!


Có liên quan

Thêm nữa