> ## Documentation Index
> Fetch the complete documentation index at: https://docs.counsel.markets/llms.txt
> Use this file to discover all available pages before exploring further.

# Créer des bots sur counsel : automatisez votre stratégie de pari

> Les bots sont des citoyens de premier rang sur counsel. Récupérez des intentions de pari non signées, signez-les avec votre propre clé, puis soumettez-les : le SDK gère tout le cycle de vie XRPL en quelques lignes.

Les bots sont des citoyens de premier rang sur counsel. Un bot est un client XRPL ordinaire : il lit les marchés en direct, récupère un `Payment` de pari non signé, le signe avec sa propre clé, puis le soumet au ledger. counsel ne détient jamais de clé. Chaque pari porte le `SourceTag` de counsel, de sorte que le volume on-chain d'un bot compte dans l'attribution au classement de la même manière qu'un pari manuel. Comme les marchés counsel sont parimutuels, il n'y a pas de carnet d'ordres : les bots apportent de la valeur en corrigeant les erreurs de prix, en équilibrant les pools ou en arbitrant entre plateformes. Chacune de ces actions est un Payment natif taggé, qui génère du volume on-chain direct.

## Ce qu'un bot peut faire

* **Value-betting** : estimez la probabilité réelle de chaque issue et misez lorsque l'`implied_prob` du marché s'écarte de votre modèle d'une marge significative. Cela pousse la cote vers le prix juste, au bénéfice de tous les participants.
* **Équilibrage de pool** : les cotes parimutuelles dérivent continuellement jusqu'au `bet_cutoff`. Un bot peut repérer un pool déséquilibré proche de la clôture et miser sur le côté sous-pondéré, capturant de meilleures cotes tout en corrigeant le déséquilibre.
* **Arbitrage entre plateformes** : prenez une position sur counsel et couvrez-la sur le même événement sur une autre plateforme, verrouillant un écart lorsque les probabilités implicites divergent.

## Démarrage rapide : installation et configuration

Installez le SDK depuis le repo et configurez l'URL de base :

```typescript theme={null}
import { Counsel } from "./counsel";

const counsel = new Counsel({ baseUrl: "https://api.counsel.markets" });
```

<Tip>
  Définissez `COUNSEL_URL` sur `https://api.counsel.markets` et référencez-le avec `process.env.COUNSEL_URL` pour garder l'URL de base hors de votre code source.
</Tip>

## Lire les marchés en direct

Récupérez tous les marchés publics et inspectez l'état actuel de leur pool ainsi que les cotes indicatives :

```typescript theme={null}
const { markets } = await counsel.markets();
// Each market has: id, question, phase, status, outcomes[]
// Each outcome: index, label, implied_prob, payout_per_unit, pool_xrp
```

Filtrez sur les marchés qui acceptent actuellement des paris avant toute autre chose :

```typescript theme={null}
const open = (markets as any[]).filter(
  (m) => m.status === "open" && m.phase === "open"
);
```

## Récupérer une intention de pari

Avant de vous engager, récupérez une transaction non signée pour le pari précis que vous souhaitez placer. Cela renvoie également l'impact projeté de votre mise sur la cote :

```typescript theme={null}
const intent = await counsel.betIntent(marketId, walletAddress, outcomeIndex, amountXrp);
// intent.tx = unsigned XRPL Payment ready to sign
// intent.projected_implied_odds_after = { implied_prob, payout_per_unit }
```

`betIntent` correspond à :

```
GET /api/v1/markets/:id/bet-intent
  ?account=WALLET_ADDRESS
  &outcome=OUTCOME_INDEX
  &amount=AMOUNT_XRP
```

Le `tx` renvoyé est un objet XRPL `Payment` entièrement formé. Il ne reste plus qu'à compléter automatiquement les champs sequence/fee, à signer et à soumettre.

## Signer et soumettre

`placeBet` gère tout le cycle de vie : il appelle `betIntent` en interne, signe avec la seed fournie via `xrpl.js`, soumet, puis attend la validation par le ledger. Il renvoie le hash de la transaction confirmée.

```typescript theme={null}
const hash = await counsel.placeBet(process.env.BOT_SEED!, marketId, outcomeIndex, amountXrp);
console.log("tx:", hash);
```

<Warning>
  Utilisez uniquement des seeds de testnet. Ne committez jamais de seeds dans le contrôle de version. Chargez `BOT_SEED` exclusivement depuis des variables d'environnement ou un gestionnaire de secrets.
</Warning>

En interne, `placeBet` se connecte au nœud WebSocket XRPL spécifié dans `CounselOptions.wss` (par défaut `wss://s.altnet.rippletest.net:51233` pour le testnet), complète automatiquement la transaction, la signe avec `Wallet.fromSeed(seed)`, la soumet via `submitAndWait` et vérifie `tesSUCCESS` avant de renvoyer. La connexion WebSocket est fermée après chaque appel.

## Exemple complet de value-betting

Le bot suivant récupère tous les marchés ouverts, fait passer chaque issue dans un modèle de probabilité, puis mise lorsqu'il trouve un avantage suffisant. Il vérifie aussi les cotes projetées après la mise avant de s'engager, afin d'éviter de parier alors que la cote a déjà dépassé le prix juste :

```typescript theme={null}
import { Counsel } from "./counsel";

const counsel = new Counsel({ baseUrl: process.env.COUNSEL_URL! });
const SEED = process.env.BOT_SEED!; // testnet only

// Your model: the probability you believe each outcome has.
function myModel(question: string): number[] {
  // ...return [pYes, pNo]; here a naive 50/50
  return [0.5, 0.5];
}

const { markets } = await counsel.markets();
for (const m of markets as any[]) {
  if (m.status !== "open" || m.phase !== "open") continue;
  const fair = myModel(m.question);
  for (const o of m.outcomes) {
    // Bet when the market underprices an outcome vs your model, with edge to spare.
    if (fair[o.index] - o.implied_prob > 0.08) {
      const intent = await counsel.betIntent(m.id, walletAddress, o.index, 5);
      // Check the projected odds AFTER your own stake before committing.
      if (intent.projected_implied_odds_after.implied_prob < fair[o.index]) {
        await counsel.placeBet(SEED, m.id, o.index, 5);
      }
    }
  }
}
```

La vérification interne sur `projected_implied_odds_after.implied_prob` est importante : dans un petit pool, votre propre mise de 5 XRP peut déplacer la cote suffisamment pour éliminer l'avantage que vous aviez détecté à partir de l'`implied_prob` périmé figurant dans la liste des marchés.

## Anti-slippage

Les cotes parimutuelles ne sont pas fixes : chaque pari modifie le pool, et donc chaque payout ultérieur. Lorsque vous lisez l'`implied_prob` depuis `GET /markets`, ce chiffre reflète déjà tous les paris soumis avant votre lecture. Au moment où vous récupérez l'intention de pari, d'autres paris peuvent être arrivés.

Utilisez toujours `projected_implied_odds_after` comme critère de décision, et non les cotes de la liste des marchés :

```typescript theme={null}
const intent = await counsel.betIntent(marketId, walletAddress, outcomeIndex, amountXrp);

if (intent.projected_implied_odds_after.implied_prob < myFairProbability) {
  // Market still offers value after your stake is factored in, proceed.
  await counsel.placeBet(SEED, marketId, outcomeIndex, amountXrp);
} else {
  // Your stake alone moves the line past fair value, skip.
}
```

Pour des mises importantes par rapport à la taille du pool, envisagez de découper un seul pari en plusieurs paris séquentiels plus petits et de revérifier l'intention à chaque fois.

## Limites de débit

L'API publique ne nécessite aucune authentification. Aucune limite de débit n'est imposée, mais l'API est une ressource partagée. Interrogez `GET /markets` à une cadence raisonnable : **5 à 10 secondes** convient à la plupart des stratégies. Une interrogation à haute fréquence n'apporte aucun avantage sur les marchés parimutuels : les cotes changent quand les paris arrivent, pas selon un rythme régulier, et les payouts finaux sont déterminés à la clôture, quel que soit le moment où vous avez placé votre pari.

## Référence des méthodes du SDK

| Méthode                                   | Endpoint                                  |
| ----------------------------------------- | ----------------------------------------- |
| `markets()`                               | `GET /api/v1/markets`                     |
| `market(id)`                              | `GET /api/v1/markets/:id`                 |
| `betIntent(id, account, outcome, amount)` | `GET /api/v1/markets/:id/bet-intent`      |
| `positions(address)`                      | `GET /api/v1/accounts/:address/positions` |
| `leaderboard()`                           | `GET /api/v1/leaderboard`                 |
