[TOC]

Avec le développement rapide de la technologie de l’intelligence artificielle (IA), celle-ci a démontré une efficacité et une créativité extrêmement élevées dans de nombreux domaines. En tant que domaine hautement technique, le trading quantitatif explore naturellement aussi activement l’application de l’IA. Cependant, dans la pratique, nous constaterons qu’il existe encore de grands défis à relever pour s’appuyer uniquement sur l’IA pour générer directement des stratégies de trading complètes, stables et durablement rentables.
Surtout pour les nouveaux utilisateurs de la plateforme, en raison de leurs faibles compétences en programmation, il est difficile de mettre en œuvre leurs idées de trading dans des codes de stratégie. Bien que nous puissions actuellement communiquer nos idées à l’IA et la laisser produire des stratégies. Cependant, l’effet de la mise en œuvre n’a pas tout à fait répondu aux attentes. Je rencontre souvent des utilisateurs qui viennent poser des questions avec des codes générés par l’IA, et parfois je peux voir les stratégies générées par l’IA en un coup d’œil. Étant donné qu’il existe encore de nombreux problèmes avec les codes de stratégie générés par l’IA à ce stade, l’utilisation de l’IA de cette manière non seulement ne résout aucun problème, mais apporte également plus de confusion et de problèmes aux novices. Plus j’en apprenais, plus j’étais confus, et à la fin, j’ai « abandonné dès le début ».
Personnellement, je pense qu’il y a deux raisons principales aux problèmes actuels des stratégies de sortie directe de l’IA :
Alors, existe-t-il d’autres méthodes d’application plus efficaces ? Cet article souhaite partager une nouvelle façon de penser : laisser l’IA nous aider à apprendre les stratégies existantes, à comprendre la conception des stratégies, à extraire les détails et les techniques clés et à analyser plus en détail leur efficacité et leur marge d’amélioration. Cette méthode peut non seulement nous aider à saisir plus rapidement l’essence de la conception de la stratégie, mais également à améliorer systématiquement notre niveau de trading quantitatif.
En tirant parti de l’IA, l’IA peut avoir une compréhension relativement précise de l’analyse de code spécifique, car pour l’IA, les données de code sont « 1 est 1, 2 est 2 » et il n’y aura pas de confusion logique, d’ambiguïté ou d’autres problèmes causés par les exigences de description en langage naturel. Alors pourquoi ne pas utiliser les avantages de l’IA pour réduire la charge de travail manuelle et exploiter pleinement les avantages du travail manuel.
Elle peut être divisée en plusieurs étapes :
Sélectionnez une stratégie existante Il peut s’agir d’un document auto-écrit, open source ou d’un excellent exemple de stratégie sur la plateforme quantitative de l’inventeur.
Laissez l’IA nous aider à expliquer la stratégie
Comprendre l’idée générale
Trier les modules fonctionnels de chaque partie
Clarifier les indicateurs, les paramètres et la logique de trading utilisés
Dans quelles conditions de marché la stratégie est-elle plus performante ?
Quels sont les points de risque possibles ?
Quels domaines peuvent être optimisés et améliorés ?
Backtesting sur différents produits et périodes
Ajouter des filtres supplémentaires ou des mesures de contrôle des risques
Observez les changements de performance et formez-vous vos propres idées
Laissons l’IA apprendre une stratégie et nous l’expliquer pour voir si elle répond à nos attentes. Cela peut nous aider à apprendre la quantification.
Conception et mise en œuvre d’une stratégie de trading progressive d’augmentation de position basée sur le filtrage des tendances EMA Adresse de la stratégie : 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()
}
Pour les nouveaux étudiants de la plateforme FMZ, voir une telle pile de codes peut vous faire sentir perdu. Au lieu d’étudier le code ligne par ligne, nous pourrions tout aussi bien (être paresseux) et le confier à l’IA, laisser l’IA nous l’expliquer et améliorer l’efficacité de l’apprentissage.
J’utilise GPT ici, et le contenu suivant est expliqué par l’IA :
Une vue d’ensemble Cet article présentera une stratégie de trading d’augmentation de position étape par étape basée sur le filtrage des tendances EMA (moyenne mobile exponentielle). Cette stratégie est principalement utilisée sur Binance Futures (Futures_Binance), prend en charge le backtesting d’une heure et est basée sur l’agrégation de données K-line d’une minute. En surveillant en temps réel l’écart entre le prix et l’EMA, la stratégie change dynamiquement de mode de trading (trading normal/trading suspendu), augmente progressivement les positions sur un marché stable et suspend automatiquement les positions en cas de fluctuations anormales pour éviter les risques.
flowchart TD
开始 --> 初始化参数
初始化参数 --> 账户余额检查
账户余额检查 --> 计算EMA
计算EMA --> 判断是否锁仓
判断是否锁仓 -->|是| 暂停交易
判断是否锁仓 -->|否| 正常交易
正常交易 --> 是否有持仓
是否有持仓 -->|无| 首次挂单
是否有持仓 -->|有| 按持仓方向加仓与止盈挂单
首次挂单 --> 等待成交
按持仓方向加仓与止盈挂单 --> 等待成交
等待成交 --> 挂单成交检测
挂单成交检测 --> 成交后调整
成交后调整 --> 更新加仓次数
更新加仓次数 --> 是否超出最大加仓次数
是否超出最大加仓次数 -->|是| 平仓
是否超出最大加仓次数 -->|否| 继续交易
Cinquième résumé Cette stratégie d’augmentation de position étape par étape basée sur le filtrage EMA prend en compte à la fois les rendements et le contrôle des risques, et convient pour opérer sur un marché volatil et faiblement volatil. Grâce à des méthodes flexibles d’ajout de positions et à des mécanismes de pause de tendance, la probabilité de liquidation peut être efficacement réduite et l’efficacité de l’utilisation du capital peut être améliorée. Il prend en charge à la fois le backtesting et le trading réel, et sa conception modulaire facilite son extension. Par exemple, il peut introduire un ajustement dynamique supplémentaire du profit cible et du montant, ou ajouter d’autres indicateurs techniques pour améliorer l’effet de filtrage.
Concernant les questions GPT :

Le contenu suivant est expliqué par l’IA :
Dans cette stratégie, le filtrage des tendances est réalisé par :
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
}
Verrouillage et libération des tendances : En comparant la différence entre le prix actuel (ticker.Last) et la valeur EMA de l’heure précédente, le pourcentage selon lequel le prix s’écarte de l’EMA est calculé. Math.abs(ticker.Last - ema[ema.length - 2]) / ema[[ema.length - 2] calcule l’écart en pourcentage du prix actuel par rapport à l’EMA de l’heure précédente. Si l’écart dépasse 3 % (> 0,03), la tendance du marché est considérée comme ayant changé de manière significative et la fonction cancelAll() est appelée pour annuler tous les ordres en attente, et isLock est défini sur true, c’est-à-dire que la position est verrouillée, empêchant toute négociation ultérieure. Si le prix s’écarte de l’EMA de moins de 2 % (< 0,02), l’état de verrouillage est libéré et isLock est défini sur false.
Suspension des échanges : Si isLock est vrai (indiquant que la position est actuellement verrouillée), aucune autre opération de trading ne sera effectuée. Le programme générera des enregistrements de journal et appellera plotRecords() pour dessiner un graphique afin d’afficher la tendance actuelle et l’état de la position. Utilisez Sleep(intervalle) pour faire une pause pendant une certaine période de temps, puis continuer la boucle.

Il semble que certaines tendances puissent être filtrées. En lisant le code moi-même, j’ai trouvé que l’explication de l’IA était très claire, encore plus claire que si je l’avais expliquée moi-même.
En laissant l’IA analyser et expliquer la stratégie globale, puis en se basant sur l’explication de la stratégie globale par l’IA, en analysant, en démontant et en expliquant progressivement les détails locaux de la stratégie et en expliquant les idées de conception. L’explication que nous avons reçue était relativement précise. L’IA a répertorié presque tous les détails conçus dans la stratégie sans omissions et a effectué une analyse détaillée au moyen de questions plus approfondies. Cette façon d’apprendre l’ensemble de la réflexion stratégique, les détails de conception du code et d’accroître l’expérience de conception stratégique sont tous très utiles.
Sur la voie du trading quantitatif, l’IA peut devenir pour nous un partenaire d’apprentissage et de croissance extrêmement puissant. Plutôt que de compter sur l’IA pour générer des stratégies finies en un seul clic, l’IA peut :
Seule cette voie peut véritablement améliorer nos capacités de trading quantitatif et établir notre propre système de trading systématique. Sur la plateforme de trading quantitatif Inventor, nous pouvons exploiter pleinement la puissance de l’IA et la combiner avec notre propre pratique pour aller plus loin et voler plus haut.