
En los últimos artículos, hemos analizado el acceso a los DEX principales y este artículo se centrará en el uso real y en la realización de pruebas reales de implementación de estrategias. La plataforma FMZ ha agregado recientemente soporte para los intercambios descentralizados WOOFi y EdgeX. En este artículo, practicaremos la ejecución de algunas estrategias de enseñanza simples en estos dos intercambios.
Conecte su billetera en WOOFi, y luego en la página API KEY, podrá ver la información de la clave API, copiarla y pegarla y configurarla en FMZ.
Utilice el último host de FMZ, que ya admite WOOFi DEX y EdgeX DEX, después de descargarlo e implementarlo. Configure el objeto de intercambio en la página: https://www.fmz.com/m/platforms/add, y configure AccountId, AccessKey y SecretKey de WOOFi.
En esta prueba, utilizamos unPrototipo de estrategia básica de creación de mercado, combinado con el indicador de volatilidad del mercado (ATR), se calcula dinámicamente el intervalo entre órdenes pendientes y se realiza la identificación inteligente de posiciones y la lógica de colocación de órdenes con prioridad en el cierre de posiciones. La estrategia actualiza el libro de órdenes en cada ronda, recupera la información de profundidad y posición y coloca órdenes de acuerdo con el intervalo de precio y la cantidad de órdenes establecidos. Todo el proceso cubre:
A través de esta estrategia, podemos observar la eficiencia real de las transacciones, el retraso de las órdenes y la experiencia de coincidencia en WOOFi, sentando las bases para el diseño posterior de estrategias más complejas.
Utilizamos el entorno de pruebas y la red de pruebas de WOOFi: Arbitrum Sepolia.
exchange.SetBase(”https://testnet-api.orderly.org”)
Hay un faucet en la red de prueba WOOFi que le permite obtener USDC fácilmente para probar.
Código de estrategia:
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)
}
}
Práctica de estrategia en WOOFi



La información de API para configurar EdgeX en FMZ es básicamente la misma que la de WOOFi, pero los diferentes intercambios requieren información de API diferente. En EdgeX, solo necesita configurar AccountId y SecretKey. Estos también se pueden ver en la página de administración de API de la cuenta después de usar la billetera para conectarse al front-end de EdgeX.
La estrategia que vamos a implementar en EdgeX se basa enBandas de Bollinger multicapaLa lógica comercial cuantitativa de apertura inversa + cierre a mitad de pista puede lograr arbitraje de volatilidad a corto plazo.
La estrategia es muy sencilla, la idea central es:
Puede que no lo creas, pero escribir una estrategia completa en FMZ solo requiere 50 líneas de código. El desarrollo actual de grandes modelos de IA ha reducido enormemente el umbral para el diseño de estrategias. Las ideas de estrategia que probamos pueden ser producidas fácilmente por IA y la calidad de redacción es suficiente. Lo único es que se requiere una corrección manual, pero ha reducido enormemente el umbral para que la gente común utilice la tecnología de comercio cuantitativo.
Código de estrategia:
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)
}
}
Primero, hagamos una prueba retrospectiva a largo plazo:


Implementar la prueba EdgeX

Las estrategias anteriores son sólo para fines de enseñanza e investigación. Tenga cuidado al aplicarlos. Gracias por leer.