Type/to search
2
Follow
490
Followers
Construire une stratégie de cartographie boursière basée sur l'IA avec un grand modèle : de la rotation sectorielle à l'analyse causale des prix
Discussions
Created 2026-06-26 15:14:58  Updated 2026-07-02 22:58:59
 0
 130

img

L'IA est vraiment en feu ces derniers temps.

Ces deux dernières années, la thématique la plus forte sur le marché tourne sans cesse autour de l'IA. Nvidia, AMD, Broadcom, TSMC, Micron, Microsoft, Google, Meta, CoreWeave, Supermicro… Tous les mois ou presque, une entreprise bondit soudainement grâce à des mots-clés comme résultats, commandes, dépenses d'investissement, HBM, GPU, cloud computing, centre de données.

Plus intéressant encore, elles ne montent généralement pas seules.

img

Parfois, Nvidia bouge en premier, puis le marché se met à creuser l'ASIC, les modules optiques, les serveurs, le refroidissement liquide, l'électricité ; d'autres fois, les résultats de Micron dépassent les attentes, et les capitaux se tournent vers le HBM, le stockage, les équipements semi-conducteurs, l'encapsulation avancée ; il arrive aussi que les fournisseurs de cloud relèvent leurs dépenses d'investissement, et toute la chaîne d'infrastructure IA est repricing.

Cela ressemble davantage à une rotation d'actifs au sein d'une même thématique IA. Le marché n'achète pas simplement une action, mais cherche constamment de nouvelles branches, de nouvelles explications et de nouvelles valeurs de rattrapage sous un grand récit.

D'où le problème : si tout cela devait être compilé manuellement, ce serait trop fatigant.

Une personne peut connaître Nvidia, AMD, Micron, Microsoft, Google, mais il est difficile de suivre en continu les changements d'activité, les actualités, les affiliations sectorielles et les corrélations de prix de dizaines, voire centaines de contrats d'actions TradFi. Plus gênant encore, beaucoup d'entreprises n'ont pas une seule étiquette. Google est à la fois cloud IA, Gemini et plateforme publicitaire ; Microsoft est à la fois cloud, Copilot et logiciel d'entreprise ; Broadcom possède à la fois de l'ASIC, des puces réseau et est lié aux centres de données IA.

J'ai donc commencé à essayer : est-ce qu'un grand modèle pourrait nous aider à construire une cartographie des actions IA ?

Non pas pour qu'il nous dise quoi acheter, mais pour qu'il fasse ce qu'il fait de mieux : comprendre les activités des entreprises, classer les sous-thèmes IA, organiser les actualités, expliquer les événements, et juger quelles actions thématiques pourraient être affectées par une variation d'une entreprise. La véritable décision de trading reste confiée aux prix, aux statistiques et à la gestion des risques.

img

Placer d'abord les actions dans le bon basket

La première étape de la stratégie n'est pas le trading, mais la construction de la cartographie.

La bourse propose désormais de nombreux contrats d'actions TradFi, qui permettent d'obtenir directement une série de contrats comme NVDA, AMD, MU, MSFT, GOOGL, SMCI. Le système filtre d'abord les contrats de type action, en ne conservant que les véritables sous-jacents EQUITY.

Un détail important : il ne faut pas mélanger les ETF, indices, ETF à effet de levier. Par exemple, QQQ, SOXL, EWT, bien que pouvant apparaître dans la liste des contrats, ne sont pas des actions d'entreprises. Si on les met dans le basket actions IA, les relations statistiques ultérieures seront polluées.

La logique de filtrage de base ressemble à ceci :

python
def refresh_equity_universe(store, force_reanalyze): ms = exchange.GetMarkets() symbols = [] for key, market in ms.items(): info = market.get("Info", {}) or {} sub_type = info.get("underlyingSubType", []) or [] underlying_type = info.get("underlyingType", "") if ".swap" not in key: continue if "TradFi" not in sub_type: continue if underlying_type != "EQUITY": continue symbol = normalize_symbol(key) store["markets"][symbol] = { "symbol": symbol, "contract": key, "underlyingType": underlying_type, "amountPrecision": market.get("AmountPrecision", 0), "pricePrecision": market.get("PricePrecision", 2), "ctVal": market.get("CtVal", 1) or 1, "minQty": market.get("MinQty", 0) or 0, } symbols.append(symbol)

Une fois le pool d'actions obtenu, le système fait appel au grand modèle pour dresser le profil de chaque action.

img

Le profil ne consiste pas simplement à écrire « c'est une action tech », mais à déterminer à quels sous-thèmes IA elle appartient. Par exemple, une action peut appartenir à plusieurs baskets en même temps. Google peut appartenir au cloud IA, aux applications de modèles IA, à la publicité sur plateforme IA ; Microsoft peut appartenir au cloud IA et aux applications IA pour entreprises ; Nvidia peut appartenir à la puissance de calcul IA et aux serveurs IA ; Micron peut appartenir au stockage IA.

Le point clé ici : à l'ère de l'IA, les actions ne portent pas une seule étiquette, mais plusieurs.

Chaque action possède plusieurs attributs : à quels baskets elle appartient, son degré d'exposition, si elle est plutôt leader ou follower dans ce basket, quelles entreprises peuvent l'influencer, et quelles entreprises elle peut influencer.

J'ai imposé une contrainte forte sur la structure de sortie du grand modèle :

python
schema = { "symbol": symbol, "asset_type": "stock|adr|etf|leveraged_etf|index|fund|other", "company_name": "", "sector": "", "business_summary": "", "tradable": False, "model_confidence": 0, "baskets": [ { "id": "ai_cloud", "exposure": 0.0, "role": "leader|follower|both|observer", "sub_theme": "", "reason": "" } ], "search_names": [], "event_keywords": [], "negative_keywords": [], "possible_leaders": [], "possible_followers": [], "brave_queries": [], "reason": "" }

Le plus important ici est asset_type. Seuls stock et adr peuvent entrer dans le basket ; les ETF, ETF à effet de levier, indices, fonds, matières premières ou ETF régionaux sont filtrés directement.

De plus, le reason doit être en chinois, les noms de champs doivent être cohérents, et le niveau de confiance est normalisé entre 0 et 100. Sinon, l'affichage sur la page réelle serait désordonné.

Les informations sectorielles ne peuvent pas être inventées

Il ne suffit pas d'avoir la classification des actions.

Le secteur IA évolue très rapidement. Aujourd'hui le marché spécul sur les GPU, demain sur le HBM, après-demain sur les modules optiques, et quelques jours plus tard sur le refroidissement liquide, l'électricité, les dépenses d'investissement des fournisseurs de cloud.

Si l'on se fie uniquement aux connaissances propres du grand modèle, il devient vite obsolète. Le système a donc besoin de sources d'information en temps réel.

J'ai intégré BraveSearch. Le système recherche périodiquement les informations sectorielles de chaque basket IA, ainsi que les actualités des actions clés au sein du basket.

Par exemple, pour le basket stockage IA, on consulte les mots-clés comme Micron, Western Digital, SanDisk, HBM, DRAM, NAND ; pour le basket communication optique IA, on consulte Ciena, Credo, Lumentum, AAOI, modules optiques 800G, 1.6T.

Le processus central des informations sectorielles est le suivant :

python
def refresh_basket_intelligence(store): if not BRAVE_KEY: return if not LLM_API_KEY: return intel = {} for bid, basket in store["baskets"].items(): members = sorted( basket["members"], key=lambda x: x.get("exposure", 0), reverse=True ) top_symbols = [m["symbol"] for m in members[:8]] basket_news = fetch_basket_news(basket, top_symbols) stock_news = {} for symbol in top_symbols[:6]: profile = store["profiles"].get(symbol, {}) stock_news[symbol] = fetch_stock_news(profile, bid) Sleep(800) analysis = analyze_basket_intel_with_llm( store, basket, top_symbols, basket_news, stock_news ) if analysis: analysis["basket"] = bid analysis["basket_name"] = basket["name"] analysis["symbols"] = top_symbols analysis["updatedAt"] = int(time.time()) intel[bid] = analysis store["basket_intel"] = intel

Cette étape permet d'établir un contexte dynamique pour chaque sous‑secteur AI.

Le grand modèle, à partir des actualités récupérées via BraveSearch, produit la tendance du secteur, les catalyseurs clés, les risques clés, le leader potentiel, le follower potentiel et les relations à vérifier ensuite.

Cela diffère d'une simple question du type « Que penses‑tu du stockage AI ? ». On lui fournit d'abord les actualités en temps réel, puis on lui demande de synthétiser.

Ce n’est pas un trading basé sur l’actualité, c’est le prix qui dévie d’abord

img

Au début, j’envisageais aussi une approche par l’actualité.

Par exemple, si les résultats d’une entreprise dépassent les attentes, le grand modèle devait identifier les actions favorisées et générer directement un signal. Mais en y réfléchissant, cette voie est très bruyante. Il y a trop de nouvelles ; beaucoup semblent importantes, mais le marché n’y réagit pas.

J’ai donc inversé la logique.

On regarde d’abord le prix, puis l’actualité.

Si toutes les actions d’un panier sont stables, le système se contente d’observer. Ce n’est que lorsqu’une action s’écarte nettement de la performance moyenne du secteur, devenant le leader du moment, que le système cherche à en comprendre la raison.

Pour cela, on utilise le ZScore interne au panier.

En résumé, on vérifie si une action est anormalement forte ou faible par rapport aux autres actions du même secteur. Si une action sort soudainement du lot alors que les autres du même panier n’ont pas encore réagi, il y a potentiellement une opportunité de diffusion.

Le cœur du calcul du ZScore du panier est le suivant :

python
def calc_basket_zscores(store, symbols): returns = {} min_len = 999999 for symbol in symbols: bars = get_records( store["markets"][symbol]["contract"], KLINE_PERIOD, SYNC_WINDOW + 10 ) if len(bars) < SYNC_WINDOW + 2: return None r = calc_returns(bars)[-SYNC_WINDOW:] returns[symbol] = r min_len = min(min_len, len(r)) latest = {s: returns[s][-1] for s in symbols} avg_latest = mean(list(latest.values())) dev_series = {s: [] for s in symbols} for i in range(min_len): row = [returns[s][-min_len + i] for s in symbols] row_avg = mean(row) for s in symbols: dev_series[s].append(returns[s][-min_len + i] - row_avg) zscores = {} max_abs = 0 for s in symbols: sigma = std(dev_series[s]) z = (latest[s] - avg_latest) / sigma if sigma > 0 else 0 zscores[s] = round(z, 3) max_abs = max(max_abs, abs(z)) return {"zscores": zscores, "maxAbs": max_abs}

Si l’écart maximum d’un panier dépasse le seuil de rupture, on entre dans l’état BREAKOUT_DETECTED.

Le système ne passe pas encore à l’exécution ; il commence par rechercher la cause.

L’actualité ne sert qu’à expliquer, les relations statistiques à valider

Lorsque le leader franchit un seuil de prix, le système récupère ses dernières actualités, puis demande au grand modèle si cette nouvelle peut expliquer le mouvement anormal.

Mais il ne s’agit pas simplement de demander « Cette nouvelle est‑elle positive ? ».

Le système fournit au grand modèle le panier actuel, les informations sectorielles, l’état des prix en temps réel, le ZScore du leader, les followers potentiels, les relations statistiques déjà vérifiées et les actualités récupérées via BraveSearch.

Le grand modèle doit répondre :

(1) Cette nouvelle peut‑elle expliquer l’anomalie de prix du leader ?
(2) La direction de la nouvelle est‑elle cohérente avec celle du prix ?
(3) Le trading est‑il autorisé ?
(4) Quels followers sont impactés ?
(5) Quel est l’impact pour chaque follower ?
(6) Pourquoi ces followers pourraient‑ils être affectés ?

La logique centrale de recherche de cause est la suivante :

python
def explain_breakout_with_news(store, bid, leader, direction, leader_z, followers, edges): if not BRAVE_KEY: return None if not LLM_API_KEY: return None profile = store["profiles"].get(leader, {}) news = fetch_stock_news(profile, bid) if not news: return None event = analyze_breakout_news_with_llm( store, bid, leader, direction, leader_z, followers, edges, news ) if not event: return None if not event.get("explains_price_move"): return None expected_direction = "bullish" if direction == "long" else "bearish" if event.get("direction") != expected_direction: return None event["confidence"] = normalize_confidence(event.get("confidence", 0)) if event["confidence"] < MIN_NEWS_CONFIDENCE: return None if not event.get("trade_allowed"): return None return event

Même si un grand modèle indique qu'un certain follower pourrait être affecté, on ne peut pas trader immédiatement.

Il faut aussi examiner les relations statistiques des bougies (K-line).

Le système calcule, au sein de chaque panier, les corrélations historiques entre les actions. Par exemple, après un breakout du source, la cible (target) suit-elle fréquemment ? Quelle est la corrélation ? Quelle est la période de décalage (lag) optimale ? Quel est le rendement moyen de suivi ?

Seules les relations source -> cible qui passent le test statistique deviennent des arêtes actives (active edges).

python
def rebuild_basket_stats(store): edges = [] for bid, basket in store["baskets"].items(): symbols = [ m["symbol"] for m in basket["members"] if m["symbol"] in store["markets"] ] for source in symbols: for target in symbols: if source == target: continue metric = validate_pair(store, source, target) if not metric: continue source_exp = basket_member_info(basket, source).get("exposure", 0) target_exp = basket_member_info(basket, target).get("exposure", 0) score = clamp( metric["corr"] * 0.3 + metric["follow"] * 0.4 + min(source_exp, target_exp) * 0.3, 0, 1 ) edge = { "basket": bid, "source": source, "target": target, "corr": round(metric["corr"], 3), "follow": round(metric["follow"], 3), "lag": metric["lag"], "avgReturn": round(metric["avgReturn"], 6), "sample": metric["sample"], "score": round(score, 3), "active": ( score >= MIN_EDGE_SCORE and metric["corr"] >= MIN_CORR and metric["follow"] >= MIN_FOLLOW_SUCCESS ), "updatedAt": int(time.time()), } edges.append(edge) store["edges"] = edges

Cette étape est cruciale.

Les grands modèles excellent dans la compréhension logique, mais le marché ne suit pas forcément la logique. Les relations statistiques servent à vérifier si cette logique a déjà été « tradée » par le marché dans le passé.

On trade la diffusion, pas la tendance haussière

Cette stratégie ne cherche pas à suivre le leader.

Le leader a déjà fait son breakout ; le suivre directement risquerait d'acheter après la hausse. Ce que la stratégie vise réellement, ce sont les opportunités de diffusion au sein du même panier AI.

Autrement dit : le leader a déjà bougé, les nouvelles l'expliquent logiquement, mais certains followers n'ont pas encore réagi complètement. Si ces followers ont historiquement montré une relation de corrélation avec le leader, il peut exister une opportunité de suivi à court terme.

Le scan des breakouts commence par rechercher des arêtes actives, puis les followers en retard :

python
def scan_price_breakouts(store): for bid, rt in store["realtime"].items(): if rt["state"] != "BREAKOUT_DETECTED": continue leader = rt["leader"] z = 0 for m in rt["members"]: if m["symbol"] == leader: z = m["z"] direction = "long" if z > 0 else "short" edges = [ e for e in store["edges"] if e["active"] and e["basket"] == bid and e["source"] == leader ] followers = [] for e in edges: target_rt = find_realtime_member(rt, e["target"]) if target_rt and abs(target_rt["z"]) < BREAKOUT_THRESHOLD * 0.75: followers.append(e["target"]) if not followers: continue

Ce n'est qu'après avoir validé le traçage causal via les actualités (news tracing) qu'un signal confirmé (confirmed signal) est généré.

Les objets de trading sont principalement les followers.

Si aucune position n'est ouverte actuellement, on ouvre une position dans le sens du signal. Si une position dans le même contrat existe déjà et dans le même sens, on l'augmente (ajout). Si une position existe déjà dans le sens inverse, on ferme d'abord la position existante, puis on ouvre une position dans le nouveau sens.

python
def execute_symbol_trade(store, signal, symbol, detail): direction = signal["direction"] if TRADE_MODE != "trade": return open_or_add_position(store, signal, symbol, detail, add_mode=False) pos = get_position_by_symbol(symbol) if pos: pos_dir = position_direction(pos) if pos_dir == direction: return open_or_add_position(store, signal, symbol, detail, add_mode=True) close_existing_position(store, symbol, pos, "reverse_signal") Sleep(1000) return open_or_add_position(store, signal, symbol, detail, add_mode=False)

Cela s'explique aussi par le fait que de nombreuses actions apparaissent simultanément dans plusieurs paniers. Une action peut être un follower dans le panier AI Cloud, et membre d'une autre logique dans le panier AI Application. Des signaux provenant de différents paniers peuvent l'affecter en même temps ; il faut donc traiter uniformément la direction pour un même contrat.

Contrôle des risques : d'abord simple, mais indispensable

En matière de contrôle des risques, on utilise actuellement un stop fixe (hard stop) et un stop suiveur (trailing stop).

Si la perte atteint le seuil, on sort ; après un certain gain, on active le stop suiveur : si le drawdown depuis le profit flottant maximal devient trop important, on verrouille les profits et on sort.

python
def monitor_positions(store): for pos in exchange.GetPosition() or []: symbol = position_symbol(pos) if symbol not in store["markets"]: continue state = _G(position_state_key(symbol)) or {} market = store["markets"][symbol] ticker = exchange.GetTicker(market["contract"]) direction = position_direction(pos) pnl_pct = ( (ticker["Last"] - pos["Price"]) / pos["Price"] * 100 * (1 if direction == "long" else -1) ) if pnl_pct > state.get("peakPnlPct", 0): state["peakPnlPct"] = pnl_pct if not state.get("trailActive") and state.get("peakPnlPct", 0) >= TRAIL_ACTIVATE_PCT: state["trailActive"] = True hard_stop = False if state.get("stop"): hard_stop = ( ticker["Last"] <= state["stop"] if direction == "long" else ticker["Last"] >= state["stop"] ) trail_hit = False if state.get("trailActive"): giveback = state.get("peakPnlPct", 0) - pnl_pct allowed = max( 1.5, state.get("peakPnlPct", 0) * TRAIL_GIVEBACK_PCT / 100.0 ) trail_hit = giveback >= allowed if hard_stop or trail_hit: close_existing_position( store, symbol, pos, "hard_stop" if hard_stop else "trailing_stop" )

Ce n'est pas la version finale de la gestion des risques, mais pour une première version d'observation en trading réel, c'est suffisant.

Ensuite, il faudra ajouter la position totale au niveau du compte, l'exposition par secteur, la limite de perte quotidienne, la confirmation d'exécution et la limitation du nombre d'ajouts de positions.

Où en est ce système actuellement ?

Ce système permet déjà de boucler un cycle de recherche assez complet.

Il peut scanner automatiquement les contrats actions TradFi, faire automatiquement un portrait des paniers long d'actions via le grand modèle, construire automatiquement des sous-secteurs IA, récupérer automatiquement les informations sectorielles et individuelles via BraveSearch, résumer automatiquement les actualités sectorielles, détecter en temps réel la force relative de chaque panier, analyser statistiquement les relations de suivi entre les actions d'un panier, et après un franchissement du prix du leader, remonter aux causes dans l'actualité.

Si l'explication par l'actualité tient, que la direction est cohérente et que les relations statistiques la soutiennent, le système génère un signal confirmé. En mode par défaut, il se contente d'alerter, sans passer en réel ; ce n'est qu'en basculant en mode trade qu'il exécutera les transactions.

La page de trading réel n'affiche plus seulement des logs : elle présente désormais sous forme de tableaux la vue d'ensemble du système, l'état en temps réel des paniers, les actualités sectorielles, les signaux récents, les transactions récentes et les étapes récentes. Cela permet de voir clairement à quelle étape le système bloque : simple anomalie de prix, absence d'explication dans l'actualité, conditions non remplies pour le suiveur, ou interception par la gestion des risques.

img

Ce qui n'est pas encore mature

Honnêtement, ce système ne peut pas encore être considéré comme une stratégie de trading automatisée mature.

C'est plutôt un framework de recherche sur le rotation thématique assistée par IA, qui parvient déjà à enchaîner « portraits d'actions, actualités sectorielles, anomalies de prix, recherche de causes dans l'actualité, validation statistique, signaux de trading », mais qui nécessite encore une validation continue.

Les principaux axes à améliorer sont les suivants.

  1. Qualité des portraits d'actions : le grand modèle inclut parfois des actions marginales dans les paniers. Il faut donc imposer asset_type pour éviter que des ETF, indices ou fonds régionaux ne soient mélangés.
  2. Qualité des actualités : les articles récupérés par BraveSearch ne sont pas toujours centraux. Le modèle doit juger si une actualité explique réellement le mouvement de prix.
  3. Relations statistiques : une relation historique de suivi ne garantit pas sa validité future ; un suivi continu est nécessaire.
  4. Gestion des risques en trading : avant le trading automatique, il est impératif d'ajouter les limites de position au niveau du compte, l'exposition sectorielle, les pertes quotidiennes et la confirmation d'exécution.

Aujourd'hui, il est donc plus raisonnable de commencer par le mode notify pour observer la qualité des signaux confirmés.

Si au bout d'un certain temps les signaux semblent réellement expliquer les mouvements de marché et que les suiveurs réagissent souvent par la suite, on pourra envisager un passage en réel avec de petites positions.

En conclusion

Cette stratégie ne consiste pas à laisser l'IA passer directement des ordres.

J'ai toujours pensé que la place la plus adaptée pour un grand modèle dans un système de trading n'est pas de « dire quoi acheter », mais de nous aider à traiter les structures d'information qu'il est difficile pour un humain de maintenir en continu : activité des entreprises, appartenance sectorielle, actualités en temps réel, interprétation d'événements, chemins de rotation des capitaux, entités potentiellement impactées.

Le trading réel doit rester confié aux prix, aux statistiques et à la gestion des risques.

Une stratégie quantitative à l'ère de l'IA ne devrait pas se contenter d'ajouter une interface vers un grand modèle, mais plutôt relier en un tout cohérent les données en temps réel, le graphe thématique, les actualités, la structure des prix, l'exécution des transactions et les explications post-mortem.

La stratégie AI Stock Graph est une tentative dans cette direction.

Code source de la stratégie : Système de trading sur contrats TradFi basé sur un graphe de chaîne industrielle IA

Comment
All comments (0)
No data
No data
  • 1
Forums
PINE Language
Get the app
iPhone Download
© 2015 - ∞ INVENTOR PTE LTD (SG)