[TOC]

Mit der rasanten Entwicklung der Technologie der künstlichen Intelligenz (KI) hat sich in vielen Bereichen eine extrem hohe Effizienz und Kreativität gezeigt. Als hochtechnisches Feld erforscht der quantitative Handel natürlich auch aktiv die Anwendung von KI. In der Praxis werden wir jedoch feststellen, dass es immer noch große Herausforderungen mit sich bringt, sich ausschließlich auf KI zu verlassen, um direkt vollständige, stabile und nachhaltig profitable Handelsstrategien zu entwickeln.
Insbesondere für neue Benutzer auf der Plattform ist es aufgrund ihrer schwachen Programmierkenntnisse schwierig, ihre Handelsideen in Strategiecodes umzusetzen. Obwohl wir der KI derzeit unsere Ideen mitteilen und sie Strategien ausgeben lassen können. Allerdings blieb der Umsetzungseffekt hinter den Erwartungen zurück. Ich treffe häufig auf Benutzer, die Fragen mit KI-generierten Codes stellen, und manchmal kann ich die KI-generierten Strategien auf einen Blick erkennen. Da es in dieser Phase noch viele Probleme mit den von der KI generierten Strategiecodes gibt, löst die Verwendung der KI auf diese Weise nicht nur keine Probleme, sondern bringt für Anfänger auch mehr Verwirrung und Probleme mit sich. Je mehr ich lernte, desto verwirrter wurde ich und schließlich gab ich es auf, überhaupt anzufangen.
Ich persönlich denke, dass es zwei Hauptgründe für die aktuellen Probleme mit KI-Direktausgabestrategien gibt:
Gibt es also andere, effizientere Anwendungsmethoden? Mit diesem Artikel möchten wir eine neue Denkweise vermitteln: Lassen Sie uns mithilfe von KI bestehende Strategien erlernen, das Strategiedesign verstehen, wichtige Details und Techniken extrahieren und deren Wirksamkeit und Verbesserungspotenzial weiter analysieren. Diese Methode kann uns nicht nur helfen, das Wesentliche der Strategiegestaltung schneller zu erfassen, sondern auch unser quantitatives Handelsniveau systematisch zu verbessern.
Durch die Nutzung künstlicher Intelligenz kann KI ein relativ genaues Verständnis der spezifischen Codeanalyse erlangen, da für KI die Codedaten „1 ist 1, 2 ist 2“ sind und es keine logischen Verwirrungen, Mehrdeutigkeiten oder andere Probleme gibt, die durch die Anforderungen an die Beschreibung in natürlicher Sprache verursacht werden. Warum also nicht die Vorteile der KI nutzen, um den manuellen Arbeitsaufwand zu reduzieren und die Vorteile manueller Arbeit voll auszuschöpfen?
Es lässt sich in folgende Schritte unterteilen:
Wählen Sie eine vorhandene Strategie aus Es kann selbst geschrieben sein, Open Source oder ein hervorragendes Strategiebeispiel auf der quantitativen Plattform des Erfinders.
Lassen Sie sich von KI bei der Erklärung der Strategie unterstützen
Verstehen Sie die Gesamtidee
Sortieren Sie die Funktionsmodule jedes Teils
Klären Sie die verwendeten Indikatoren, Parameter und Handelslogik
Unter welchen Marktbedingungen ist die Strategie leistungsfähiger?
Was sind mögliche Risikopunkte?
Welche Bereiche können optimiert und verbessert werden?
Backtesting für verschiedene Produkte und Zeiträume
Fügen Sie zusätzliche Filter oder Maßnahmen zur Risikokontrolle hinzu
Beobachten Sie Leistungsänderungen und bilden Sie sich Ihre eigenen Erkenntnisse
Lassen wir die KI eine Strategie erlernen und sie uns erklären, um zu sehen, ob sie unseren Erwartungen entspricht. Es kann uns helfen, Quantifizierung zu lernen.
Entwurf und Implementierung einer schrittweisen Handelsstrategie zur Positionserhöhung basierend auf der EMA-Trendfilterung Strategieadresse: https://www.fmz.com/strategy/492116
/*backtest
start: 2024-10-01 00:00:00
end: 2025-04-23 00:00:00
period: 1h
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT"}]
args: [["targetProfit",20],["amount",20],["amountPrecision",3],["isAmountForUSDT",true]]
*/
function getTotalEquity_OKEX_V5() {
var totalEquity = null
var ret = exchange.IO("api", "GET", "/api/v5/account/balance", "ccy=USDT")
if (ret) {
try {
totalEquity = parseFloat(ret.data[0].details[0].eq)
} catch(e) {
Log("获取账户总权益失败!")
return null
}
}
return totalEquity
}
function getTotalEquity_Binance() {
var totalEquity = null
var ret = exchange.GetAccount()
if (ret) {
try {
totalEquity = parseFloat(ret.Info.totalWalletBalance)
} catch(e) {
Log("获取账户总权益失败!")
return null
}
}
return totalEquity
}
function getTotalEquity() {
var exName = exchange.GetName()
if (exName == "Futures_OKCoin") {
return getTotalEquity_OKEX_V5()
} else if (exName == "Futures_Binance") {
return getTotalEquity_Binance()
} else {
throw "不支持该交易所"
}
}
function ceilToDecimals(value, decimals) {
const factor = Math.pow(10, decimals);
return Math.ceil(value * factor) / factor;
}
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(interval)
}
Sleep(interval)
}
}
function trade(distance, price, amount) {
var tradeFunc = null
if (distance == "buy") {
tradeFunc = exchange.Buy
} else if (distance == "sell") {
tradeFunc = exchange.Sell
} else if (distance == "closebuy") {
tradeFunc = exchange.Sell
} else {
tradeFunc = exchange.Buy
}
exchange.SetDirection(distance)
return tradeFunc(price, amount)
}
function openLong(price, amount) {
return trade("buy", price, amount)
}
function openShort(price, amount) {
return trade("sell", price, amount)
}
function coverLong(price, amount) {
return trade("closebuy", price, amount)
}
function coverShort(price, amount) {
return trade("closesell", price, amount)
}
function plotRecords(c, buyOrder, sellOrder, pos) {
var bars = _C(exchange.GetRecords)
if (bars.length == 0) {
return
}
bars.forEach(function(bar, index) {
c.begin(bar)
if (index == bars.length - 1) {
if (buyOrder) {
c.hline(buyOrder.Price, "buy", "rgba(255, 0, 0, 0.2)", "dotted")
}
if (sellOrder) {
c.hline(sellOrder.Price, "sell", "rgba(0, 255, 0, 0.2)", "dotted")
}
if (pos && pos.length == 1) {
c.hline(pos[0].Price, "pos", "rgba(0, 0, 255, 0.2)", "dashed")
}
}
c.close()
})
}
var buyOrderId = null
var sellOrderId = null
var logStatusMsgBuff = ""
function main() {
var exName = exchange.GetName()
if (isSimulate && exName == "Futures_OKCoin") {
exchange.IO("simulate", true)
}
if (isReset) {
_G(null)
LogReset(1)
LogProfitReset()
LogVacuum()
Log("重置所有数据", "#FF0000")
}
exchange.SetContractType(contractType)
exchange.SetPrecision(pricePrecision, amountPrecision)
Log("设置精度", pricePrecision, amountPrecision)
exchange.SetMarginLevel(marginLevel)
if (totalEq == -1 && !IsVirtual()) {
var recoverTotalEq = _G("totalEq")
if (!recoverTotalEq) {
var currTotalEq = getTotalEquity()
if (currTotalEq) {
totalEq = currTotalEq
_G("totalEq", currTotalEq)
} else {
throw "获取初始权益失败"
}
} else {
totalEq = recoverTotalEq
}
}
var addCounter = _G("addCounter")
if (!addCounter) {
addCounter = 1
if (setAddCounter != -1) {
addCounter = setAddCounter
}
_G("addCounter", addCounter)
} else {
addCounter -= 1
}
let c = KLineChart({
overlay: true
})
var isLock = false
while (true) {
var ticker = _C(exchange.GetTicker)
var pos = _C(exchange.GetPosition)
if (pos.length > 1) {
Log(pos)
throw "同时有多空持仓"
}
var r = _C(exchange.GetRecords, 60 * 60)
var ema = TA.EMA(r, 60)
if (Math.abs(ticker.Last - ema[ema.length - 2]) / ema[ema.length - 2] > 0.03) {
cancelAll()
isLock = true
}
if (Math.abs(ticker.Last - ema[ema.length - 2]) / ema[ema.length - 2] < 0.02) {
isLock = false
}
if (isLock) {
LogStatus(_D(), "暂停, 检测阈值:", _N(Math.abs(ticker.Last - ema[ema.length - 2]) / ema[ema.length - 2], 3), logStatusMsgBuff)
plotRecords(c, null, null, pos)
Sleep(interval)
continue
}
var currentAcc = _C(exchange.GetAccount)
if (currentAcc.Balance < totalEq * reserve) {
throw "no money, stop"
}
if (addCounter > maxAddCounter) {
LogStatus(_D(), "加仓已达到上限", logStatusMsgBuff)
if (isMaxAddCounterClear && pos.length >= 1) {
Log("加仓已达到上限,撤单,清仓")
cancelAll()
if (pos[0].Type == PD_LONG) {
var coverId = coverLong(-1, pos[0].Amount)
} else if (pos[0].Type == PD_SHORT) {
var coverId = coverShort(-1, pos[0].Amount)
}
addCounter = 1
}
continue
}
if (pos.length == 0) {
if (!IsVirtual()) {
var currTotalEq = getTotalEquity()
if (currTotalEq) {
LogProfit(currTotalEq - totalEq, "当前总权益:", currTotalEq)
}
}
var tradeAmountLong = amount
var tradeAmountShort = amount
if (isAmountForUSDT) {
tradeAmountLong = ceilToDecimals(tradeAmountLong * 1.01 / (ticker.Last - targetProfit / 5) / oneCtValue, amountPrecision)
tradeAmountShort = ceilToDecimals(tradeAmountShort * 1.01 / (ticker.Last + targetProfit / 5) / oneCtValue, amountPrecision)
}
buyOrderId = openLong(ticker.Last - targetProfit / 5, tradeAmountLong)
sellOrderId = openShort(ticker.Last + targetProfit / 5, tradeAmountShort)
addCounter = 1
_G("addCounter", addCounter)
} else if (pos[0].Type == PD_LONG) {
var n = ratio
var price = ticker.Last
var addAmount = isDoubling ? pos[0].Amount : (isAmountForUSDT ? (ceilToDecimals(amount * 1.01 / (price - targetProfit * n) / oneCtValue, amountPrecision)) : amount)
buyOrderId = openLong(price - targetProfit * n, addAmount)
sellOrderId = coverLong(pos[0].Price + targetProfit, pos[0].Amount)
addCounter++
_G("addCounter", addCounter)
} else if (pos[0].Type == PD_SHORT) {
var n = ratio
var price = ticker.Last
var addAmount = isDoubling ? pos[0].Amount : (isAmountForUSDT ? (ceilToDecimals(amount * 1.01 / (price + targetProfit * n) / oneCtValue, amountPrecision)) : amount)
buyOrderId = coverShort(pos[0].Price - targetProfit, pos[0].Amount)
sellOrderId = openShort(price + targetProfit * n, addAmount)
addCounter++
_G("addCounter", addCounter)
}
if (!sellOrderId || !buyOrderId) {
cancelAll()
buyOrderId = null
sellOrderId = null
continue
}
while (1) {
var isFindBuyId = false
var isFindSellId = false
var orders = _C(exchange.GetOrders)
var buyOrder = null
var sellOrder = null
for (var i = 0 ; i < orders.length ; i++) {
if (buyOrderId == orders[i].Id) {
isFindBuyId = true
buyOrder = orders[i]
}
if (sellOrderId == orders[i].Id) {
isFindSellId = true
sellOrder = orders[i]
}
}
if (!isFindSellId && !isFindBuyId) {
cancelAll()
break
} else if (!isFindBuyId) {
Log("买单成交")
cancelAll()
break
} else if (!isFindSellId) {
Log("卖单成交")
cancelAll()
break
}
var acc = _C(exchange.GetAccount)
var tbl = {"type": "table", "title": "data", "cols": ["data", "symbol", "type", "price", "amount"], "rows": []}
if (buyOrder) {
tbl.rows.push(["订单", buyOrder.Symbol, buyOrder.Type == ORDER_TYPE_BUY ? "买入" : "卖出", buyOrder.Price, buyOrder.Amount])
}
if (sellOrder) {
tbl.rows.push(["订单", sellOrder.Symbol, sellOrder.Type == ORDER_TYPE_BUY ? "买入" : "卖出", sellOrder.Price, sellOrder.Amount])
}
if (pos && pos.length == 1) {
tbl.rows.push(["持仓", pos[0].Symbol, pos[0].Type == PD_LONG ? "多" : "空", pos[0].Price, pos[0].Amount])
}
logStatusMsgBuff = "当前权益:" + acc.Equity + ", 初始权益:" + totalEq + (!IsVirtual() ? ", 浮动盈亏:" + (acc.Equity - totalEq) : "") + ", 加仓次数:" + addCounter + "\n`" + JSON.stringify(tbl) + "`"
LogStatus(_D(), "当前权益:", acc.Equity, ", 初始权益:", totalEq, !IsVirtual() ? ", 浮动盈亏:" + (acc.Equity - totalEq) : "", ", 加仓次数:" + addCounter, "\n`" + JSON.stringify(tbl) + "`")
plotRecords(c, buyOrder, sellOrder, pos)
Sleep(interval)
}
Sleep(interval)
}
}
function onexit() {
Log("扫尾,撤销所有挂单")
cancelAll()
}
Für neue Studierende der FMZ-Plattform kann der Anblick eines solchen Codehaufens ein Gefühl der Verlegenheit auslösen. Anstatt den Code Zeile für Zeile zu studieren, können wir (faul sein) ihn auch der KI überlassen, ihn uns von der KI erklären lassen und so die Lerneffizienz verbessern.
Ich verwende hier GPT und der folgende Inhalt wird durch KI erklärt:
flowchart TD
开始 --> 初始化参数
初始化参数 --> 账户余额检查
账户余额检查 --> 计算EMA
计算EMA --> 判断是否锁仓
判断是否锁仓 -->|是| 暂停交易
判断是否锁仓 -->|否| 正常交易
正常交易 --> 是否有持仓
是否有持仓 -->|无| 首次挂单
是否有持仓 -->|有| 按持仓方向加仓与止盈挂单
首次挂单 --> 等待成交
按持仓方向加仓与止盈挂单 --> 等待成交
等待成交 --> 挂单成交检测
挂单成交检测 --> 成交后调整
成交后调整 --> 更新加仓次数
更新加仓次数 --> 是否超出最大加仓次数
是否超出最大加仓次数 -->|是| 平仓
是否超出最大加仓次数 -->|否| 继续交易
Zu GPT-Fragen:

Folgende Inhalte werden durch KI erklärt:
Bei dieser Strategie wird die Trendfilterung wie folgt erreicht:
var ema = TA.EMA(r, 60)
if (Math.abs(ticker.Last - ema[ema.length - 2]) / ema[ema.length - 2] > 0.03) {
cancelAll()
isLock = true
}
if (Math.abs(ticker.Last - ema[ema.length - 2]) / ema[ema.length - 2] < 0.02) {
isLock = false
}
if (isLock) {
LogStatus(_D(), "暂停, 检测阈值:", _N(Math.abs(ticker.Last - ema[ema.length - 2]) / ema[ema.length - 2], 3), logStatusMsgBuff)
plotRecords(c, null, null, pos)
Sleep(interval)
continue
}
Trend sperren und freigeben: Durch Vergleich der Differenz zwischen dem aktuellen Preis (Ticker.Last) und dem EMA-Wert der vorherigen Stunde wird der Prozentsatz berechnet, um den der Preis von der EMA abweicht. Math.abs(ticker.Last - ema[ema.length - 2]) / ema[ema.length - 2] berechnet die prozentuale Abweichung des aktuellen Preises vom EMA der vorherigen Stunde. Wenn die Abweichung 3 % (> 0,03) überschreitet, wird davon ausgegangen, dass sich der Markttrend erheblich geändert hat. In diesem Fall wird die Funktion cancelAll() aufgerufen, um alle ausstehenden Aufträge zu stornieren. Außerdem wird isLock auf „true“ gesetzt, d. h. die Position wird gesperrt, wodurch weiterer Handel verhindert wird. Wenn der Preis weniger als 2 % (< 0,02) vom EMA abweicht, wird der Sperrzustand aufgehoben und isLock auf „false“ gesetzt.
Handelsaussetzung: Wenn isLock wahr ist (was bedeutet, dass die Position derzeit gesperrt ist), werden keine weiteren Handelsvorgänge ausgeführt. Das Programm gibt Protokolldatensätze aus und ruft plotRecords() auf, um ein Diagramm zu zeichnen, das den aktuellen Trend und Positionsstatus anzeigt. Verwenden Sie Sleep(Intervall), um für eine bestimmte Zeit eine Pause einzulegen und dann die Schleife fortzusetzen.

Es scheint, dass einige Trends herausgefiltert werden können. Als ich den Code selbst las, stellte ich fest, dass die Erklärung der KI sehr klar war, sogar klarer, als wenn ich sie selbst erklärt hätte.
Indem wir die KI die Gesamtstrategie analysieren und erklären lassen und dann auf der Grundlage der Erklärung der KI zur Gesamtstrategie schrittweise die lokalen Details der Strategie analysieren, zerlegen und erklären und die Designideen erläutern. Die Erklärung, die wir erhielten, war relativ zutreffend. Die KI listete nahezu alle in der Strategie vorgesehenen Details ohne Auslassungen auf und führte durch weitere Befragungen eine detaillierte Analyse durch. Auf diese Weise lernen Sie das gesamte Strategiedenken und die Details des Codedesigns kennen und sammeln Erfahrungen im Strategiedesign. Das ist sehr hilfreich.
Auf dem Weg des quantitativen Handels kann KI für uns zu einem äußerst leistungsstarken Lern- und Wachstumspartner werden. Anstatt sich darauf zu verlassen, dass KI mit einem Klick fertige Strategien generiert, kann KI:
Nur dieser Weg kann unsere quantitativen Handelsfähigkeiten wirklich verbessern und unser eigenes systematisches Handelssystem etablieren. Auf der Inventor Quantitative Trading Platform können wir die Leistungsfähigkeit der KI voll ausnutzen und sie mit unserer eigenen Praxis kombinieren, um weiter zu kommen und höher zu fliegen.