avatar of 发明者量化-小小梦 发明者量化-小小梦
关注 私信
4
关注
1128
关注者

DEX交易所量化实践(4)-- WOOFi / EdgeX 策略接入测试

创建于: 2025-04-10 15:36:06, 更新于: 2025-04-11 13:35:33
comments   0
hits   159

DEX交易所量化实践(4)–  WOOFi / EdgeX 策略接入测试

在过去的几篇文章中,我们围绕主流 DEX 的接入做了探讨,而本篇将聚焦于实际使用方面,进行实际策略部署测试。FMZ平台近期又新增支持了WOOFi和EdgeX去中心化交易所,本篇我们就一起在这两个交易所上实践运行一些简单的教学策略。

WOOFi

在WOOFi上连接钱包,然后在API KEY页面,可以查看到API秘钥信息,复制粘贴出来配置到FMZ上即可。

使用FMZ最新的托管者,已经支持WOOFi DEX和EdgeX DEX,下载、部署完成后。在页面: https://www.fmz.com/m/platforms/add 配置交易所对象,配置WOOFi的AccountId、AccessKey、SecretKey。

在本次测试中,我们使用了一个基础做市策略原型,结合市场波动率指标(ATR)动态计算挂单间距,并实现了对持仓的智能识别和平仓优先的下单逻辑。策略每轮刷新订单簿,重新获取深度与持仓信息,并按设定的价格间隔和下单数量进行挂单。整个流程涵盖了:

  • 市场行情的实时拉取与指标分析;
  • 多空方向的挂单逻辑控制;
  • 平仓与开仓的判断与分流;
  • 仓位与账户状态的可视化输出。

通过该策略,我们可以观察在 WOOFi 的实际成交效率、订单延迟、撮合体验,为后续设计更复杂的策略打下了基础。

我们使用WOOFi的测试环境、测试网:Arbitrum Sepolia。

exchange.SetBase(”https://testnet-api.orderly.org”)

在WOOFi测试网上有水龙头,可以很方便的获取测试用USDC。

策略代码:

function createOrders(e, symbol, side, ordersNum, beginPrice, firstAmount, spacing, pos) {
    if (side == "buy" || side == "closesell") {
        if (spacing > 0) {
            throw "spacing error"
        }
    } else if (side == "sell" || side == "closebuy") {
        if (spacing < 0) {
            throw "spacing error"
        }
    } else {
        throw "side error"
    }
    
    var holdAmount = 0
    if (pos) {
        holdAmount = pos.Amount
    }

    var amount = firstAmount
    for (var i = 0 ; i < ordersNum ; i++) {
        var id = null 
        amount = amount * 2
        var price = beginPrice + i * spacing

        if (price <= 0 || amount <= 0) {
            Log("continue loop:", price, amount, "#FF0000")
            continue 
        }

        if (holdAmount - amount >= 0) {
            id = e.CreateOrder(symbol, side == "buy" ? "closesell" : "closebuy", price, holdAmount)
            holdAmount = 0
        } else {
            id = e.CreateOrder(symbol, side, price, amount)
        }

        Sleep(100)
    }
}

function cancelAll(e, symbol) {
    while (true) {
        var orders = _C(e.GetOrders, symbol)
        var sideOrders = []
        for (var o of orders) {
            sideOrders.push(o)
        }
        if (sideOrders.length == 0) {
            break
        }

        for (var o of sideOrders) {
            e.CancelOrder(o.Id, o)
        }

        Sleep(500)
    }
}

function main() {
    LogReset(1)
    LogProfitReset()
    exchange.SetBase("https://testnet-api.orderly.org")

    // 参数
    var symbol = "ETH_USDC.swap"
    var ordersNum = 5
    var orderAmount = 0.01
    var priceSpace = 0

    // 初始化
    exchange.SetPrecision(2, 3)    
    var msg = []
    var buyOrdersNum = ordersNum
    var sellOrdersNum = ordersNum

    while (true) {
        cancelAll(exchange, symbol)

        var r = _C(exchange.GetRecords, symbol, 60 * 5)
        var art = TA.ATR(r, 20)
        priceSpace = art[art.length - 1]
        var pos = _C(exchange.GetPositions, symbol)        

        // depth
        var depth = _C(exchange.GetDepth, symbol)
        if (depth.Bids.length == 0 || depth.Asks.length == 0) {
            msg.push("invalid depth")
        } else {
            var bid1Price = depth.Bids[0].Price
            var ask1Price = depth.Asks[0].Price

            var longPos = null
            var shortPos = null
            for (var p of pos) {
                if (p.Type == PD_LONG) {
                    longPos = p
                } else if (p.Type == PD_SHORT) {
                    shortPos = p
                }
            }

            // long
            createOrders(exchange, symbol, "buy", buyOrdersNum, bid1Price, orderAmount, -priceSpace, shortPos)
            // short
            createOrders(exchange, symbol, "sell", sellOrdersNum, ask1Price, orderAmount, priceSpace, longPos)
        }
        
        var acc = _C(exchange.GetAccount)
        var orders = _C(exchange.GetOrders, symbol)
        LogProfit(acc.Equity, "&")

        var posTbl = {"type": "table", "title": "pos", "cols": ["Symbol", "Type", "Price", "Amount"], "rows": []}
        for (var p of pos) {
            posTbl["rows"].push([p.Symbol, p.Type == PD_LONG ? "多" : "空", p.Price, p.Amount])
        }

        var ordersTbl = {"type": "table", "title": "orders", "cols": ["Symbol", "Type", "Price", "Amount"], "rows": []}
        for (var o of orders) {
            ordersTbl["rows"].push([o.Symbol, o.Type == ORDER_TYPE_BUY ? "买" : "卖", o.Price, o.Amount])
        }

        LogStatus(_D(), "priceSpace:", priceSpace, "\n`" + JSON.stringify([posTbl, ordersTbl]) + "`")
        Sleep(1000 * 60)
        LogReset(1000)
    }
}

WOOFi上的策略实践

DEX交易所量化实践(4)–  WOOFi / EdgeX 策略接入测试

DEX交易所量化实践(4)–  WOOFi / EdgeX 策略接入测试

DEX交易所量化实践(4)–  WOOFi / EdgeX 策略接入测试

EdgeX

在FMZ上配置EdgeX的API信息与WOOFi基本一致,不过不同的交易所对于需要的API信息并不同,在EdgeX上只需要配置AccountId和SecretKey。这些同样在使用钱包连接EdgeX的前端后,在账户API管理页面查看。

对于在EdgeX上我们要实践的策略是一个基于多层布林带的反向开仓+中轨平仓的量化交易逻辑,实现短线波动套利。

策略十分简单,核心思路为:

  • 利用了多重布林标准差,能量化出市场波动强度。
  • 有开仓加仓逻辑,突破越强,仓位越大。
  • 有明确的平仓逻辑,回到中轨即撤离。
  • 成交量与标准差倍数成正比:更强的突破下更大仓位。

可能您都不会相信,在FMZ上编写一个完整的策略竟然只有50行代码。目前AI大模型的发展给策略设计大大降低了门槛,我们测试的策略思路可以很轻松的让AI产出,编写质量也足够用,唯一的是需要人工修正,但是已经大大降低了普通人使用量化交易技术的门槛。

策略代码:

function main() {
    var symbol = "ETH_USDT.swap"
    var arrUp = []
    var arrDown = []
    let c = KLineChart({
        overlay: true
    }) 
    while (true) {
        var bolls = []
        var r = _C(exchange.GetRecords, symbol)
        for (var i = 0; i < 3; i++) {
            var boll = TA.BOLL(r, 20, i + 1)
            bolls.push(boll)
            var up = boll[0][boll[0].length - 1]
            var mid = boll[1][boll[1].length - 1]
            var down = boll[2][boll[2].length - 1]
            var close = r[r.length - 1].Close
            if (close > up && i >= arrUp.length) {
                exchange.CreateOrder(symbol, "sell", -1, 0.01 * (i + 1))
                arrUp.push({"symbol": symbol, "amount": 0.01 * (i + 1)})
            } else if (close < down && i >= arrDown.length) {
                exchange.CreateOrder(symbol, "buy", -1, 0.01 * (i + 1))
                arrDown.push({"symbol": symbol, "amount": 0.01 * (i + 1)})
            } else if ((arrUp.length > 0 && close < mid) || (arrDown.length > 0 && close > mid)) {
                var pos = exchange.GetPositions(symbol)
                for (var p of pos) {
                    if (p.Type == PD_LONG) {
                        exchange.CreateOrder(symbol, "closebuy", -1, p.Amount)
                    } else if (p.Type == PD_SHORT) {
                        exchange.CreateOrder(symbol, "closesell", -1, p.Amount)
                    }
                }
                arrUp = []
                arrDown = []
            }
        }
        r.forEach(function(bar, index) {
            c.begin(bar)
            for (var i in bolls) {
                var b = bolls[i]
                c.plot(b[0][index], 'up_' + (i + 1))
                c.plot(b[1][index], 'mid_' + (i + 1))
                c.plot(b[2][index], 'down_' + (i + 1))
            }
            c.close()
        })
        LogStatus(_D(), "\n", arrUp, "\n", arrDown)
        Sleep(500)
    }
}

我们先长期回测一下看看:

DEX交易所量化实践(4)–  WOOFi / EdgeX 策略接入测试

DEX交易所量化实践(4)–  WOOFi / EdgeX 策略接入测试

部署上EdgeX测试

DEX交易所量化实践(4)–  WOOFi / EdgeX 策略接入测试

END

以上策略仅教学研究为主,请谨慎实盘。感谢您的阅读。

相关推荐