
В последних нескольких статьях мы обсуждали доступ к основным DEX, а в этой статье основное внимание будет уделено реальному использованию и проведению реальных тестов развертывания стратегии. Платформа FMZ недавно добавила поддержку децентрализованных бирж WOOFi и EdgeX. В этой статье мы попрактикуемся в применении некоторых простых стратегий обучения на этих двух биржах.
Подключите свой кошелек к WOOFi, а затем на странице API KEY вы можете просмотреть информацию об API-ключе, скопировать и вставить ее, а также настроить на FMZ.
Используйте новейший хост FMZ, который уже поддерживает WOOFi DEX и EdgeX DEX, после загрузки и развертывания. Настройте объект обмена на странице: https://www.fmz.com/m/platforms/add, а также настройте AccountId, AccessKey и SecretKey WOOFi.
В этом тесте мы использовалиБазовый прототип стратегии создания рынкав сочетании с индикатором волатильности рынка (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



Информация API для настройки EdgeX на FMZ в основном такая же, как и для WOOFi, но для разных бирж требуется разная информация API. В EdgeX вам нужно настроить только AccountId и SecretKey. Их также можно просмотреть на странице управления API учетной записи после использования кошелька для подключения к интерфейсу EdgeX.
Стратегия, которую мы собираемся реализовать на EdgeX, основана наМногослойные полосы БоллинджераКоличественная торговая логика обратного открытия + закрытия на промежуточном этапе может реализовать краткосрочный арбитраж волатильности.
Стратегия очень проста, основная идея такова:
Вы можете не поверить, но написание полноценной стратегии на FMZ занимает всего 50 строк кода. Текущее развитие крупных моделей ИИ значительно снизило порог разработки стратегии. Протестированные нами стратегические идеи могут быть легко созданы с помощью искусственного интеллекта, и качество текста является удовлетворительным. Единственное, что требуется, так это ручная коррекция, но это значительно снизило порог использования обычными людьми технологий количественной торговли.
Код стратегии:
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)
}
}
Давайте сначала проведем долгосрочное тестирование:


Развернуть тест EdgeX

Вышеуказанные стратегии предназначены только для учебных и исследовательских целей. Пожалуйста, будьте осторожны при их применении. Спасибо за прочтение.