
In den letzten Artikeln haben wir den Zugriff auf gängige DEXs besprochen. In diesem Artikel liegt der Schwerpunkt auf der tatsächlichen Nutzung und der Durchführung tatsächlicher Strategiebereitstellungstests. Die FMZ-Plattform hat vor Kurzem Unterstützung für die dezentralen Börsen WOOFi und EdgeX hinzugefügt. In diesem Artikel üben wir die Umsetzung einiger einfacher Lehrstrategien an diesen beiden Börsen.
Verbinden Sie Ihr Wallet mit WOOFi und sehen Sie sich dann auf der API-KEY-Seite die API-Schlüsselinformationen an, kopieren Sie sie, fügen Sie sie ein und konfigurieren Sie sie auf FMZ.
Verwenden Sie nach dem Herunterladen und Bereitstellen den neuesten Host von FMZ, der WOOFi DEX und EdgeX DEX bereits unterstützt. Konfigurieren Sie das Austauschobjekt auf der Seite: https://www.fmz.com/m/platforms/add und konfigurieren Sie WOOFis AccountId, AccessKey und SecretKey.
In diesem Test verwendeten wir einePrototyp einer grundlegenden Market-Making-StrategieIn Kombination mit dem Marktvolatilitätsindikator (ATR) wird das Intervall zwischen ausstehenden Aufträgen dynamisch berechnet und die intelligente Identifizierung von Positionen sowie die Auftragserteilungslogik mit Priorität auf das Schließen von Positionen realisiert. Die Strategie aktualisiert das Auftragsbuch in jeder Runde, ruft die Tiefen- und Positionsinformationen erneut ab und platziert Aufträge entsprechend dem festgelegten Preisintervall und der Auftragsmenge. Der gesamte Prozess umfasst:
Durch diese Strategie können wir die tatsächliche Transaktionseffizienz, Auftragsverzögerung und Matching-Erfahrung auf WOOFi beobachten und so den Grundstein für die spätere Entwicklung komplexerer Strategien legen.
Wir verwenden die Testumgebung und das Testnetzwerk von WOOFi: Arbitrum Sepolia.
exchange.SetBase(”https://testnet-api.orderly.org”)
Im WOOFi-Testnetzwerk gibt es einen Faucet, mit dem Sie problemlos USDC zum Testen erhalten können.
Strategiecode:
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)
}
}
Strategiepraxis auf WOOFi



Die API-Informationen zum Konfigurieren von EdgeX auf FMZ sind grundsätzlich dieselben wie für WOOFi, aber verschiedene Börsen erfordern unterschiedliche API-Informationen. Auf EdgeX müssen Sie nur AccountId und SecretKey konfigurieren. Diese können auch auf der API-Verwaltungsseite des Kontos angezeigt werden, nachdem Sie über die Wallet eine Verbindung zum EdgeX-Frontend hergestellt haben.
Die Strategie, die wir auf EdgeX implementieren werden, basiert aufMehrschichtige Bollinger-BänderDie quantitative Handelslogik aus umgekehrter Eröffnung und Mid-Track-Schließung kann kurzfristige Volatilitätsarbitrage realisieren.
Die Strategie ist sehr einfach, die Kernidee ist:
Sie werden es vielleicht nicht glauben, aber das Schreiben einer vollständigen Strategie auf FMZ erfordert nur 50 Zeilen Code. Die aktuelle Entwicklung großer KI-Modelle hat die Schwelle für die Strategieentwicklung erheblich gesenkt. Die von uns getesteten Strategieideen können problemlos durch KI erstellt werden und die Schreibqualität ist ausreichend. Das Einzige, was erforderlich ist, ist, dass manuelle Korrekturen vorgenommen werden müssen. Allerdings ist dadurch die Hemmschwelle für den Normalbürger, quantitative Handelstechnologien zu nutzen, erheblich gesunken.
Strategiecode:
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)
}
}
Lassen Sie uns zunächst einen langfristigen Backtest durchführen:


EdgeX-Test bereitstellen

Die oben genannten Strategien dienen ausschließlich Lehr- und Forschungszwecken. Bitte seien Sie bei der Anwendung vorsichtig. Vielen Dank fürs Lesen.