Пример разработки стратегии dYdX

Автор:Лидия., Создано: 2022-11-07 10:59:29, Обновлено: 2023-09-15 21:03:43

img

В ответ на спрос многих пользователей, платформа FMZ недавно получила доступ к dYdX, децентрализованной бирже. Кто-то, у кого есть стратегии, может насладиться процессом приобретения цифровой валюты dYdX. Я просто хотел написать стохастическую торговую стратегию давно, неважно, приносит ли она прибыль.

Проектирование стохастической стратегии торговли

Давайте проведем мозговой штурм! Планируется разработать стратегию размещения заказов случайным образом с случайными показателями и ценами. Размещение заказов - это не что иное, как длинный или короткий ход, просто ставки на вероятность. Затем мы будем использовать случайное число 1 ~ 100 для определения длинного или короткого.

Условие для покупки: случайное число от 1 до 50. Условие для короткого расписания: случайный номер 51~100.

Таким образом, и длинный, и короткий ход - это 50 цифр. Далее, давайте подумаем о том, как закрыть позицию, поскольку это ставка, то должны быть критерии для выигрыша или проигрыша. Мы устанавливаем критерии для фиксированной остановки прибыли и убытка в сделке. Остановить прибыль для выигрыша, остановить убыток для проигрыша. Что касается суммы остановки прибыли и убытка, на самом деле это влияние соотношения прибыли и убытка, о да! Это также влияет на коэффициент выигрыша! (Это дизайн стратегии эффективен? Можно ли гарантировать как положительные математические ожидания? Сделайте это сначала! (После, это просто для обучения, исследования!)

Торговля не является бесплатной, есть достаточно скольжения, сборов и т.д., чтобы вытащить наш стохастический процент выигрыша торговли к стороне менее 50%. Как насчет разработки мультипликатора для увеличения позиции? Поскольку это ставка, то вероятность проигрыша в течение 8 ~ 10 раз в ряд случайных сделок должна быть низкой. Так что первая транзакция была разработана для размещения небольшого количества заказов, как можно меньше.

Хорошо, стратегия спроектирована просто.

Исходный код разработан:

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

Параметры стратегии:

img

О да! Стратегия нуждается в названии, давайте назовем его "Угадай размер (версия dYdX) ".

Обратный тест

Обратное тестирование только для справки, >_

img

img

img

img

Бактэст завершен, нет ошибок.

Эта стратегия используется только для обучения и справки, не используйте ее в реальном боте!


Связанные

Больше