EdgeTennisMonitor

Les mouvements de cotes du tennis, book par book, depuis Edge / MadMarket. Base : /api

pmkpolymarketmollybfpin88
Deux niveaux d'accès, et l'API dit lequel elle a.

Le flux WebSocket donne le catalogue — tournois, joueurs — et la meilleure cote toutes books confondues.

Le détail par book et la liquidité passent par /v1/betslips/. ⚠️ L'authentification s'y fait par un en-tête session:, pas par le cookie root-session où le jeton est pourtant visible — le cookie seul rend 401. Si cet accès tombe (jeton expiré), les lignes retombent sur le book edge-meilleure-offre : pas un nom de book réel, parce qu'on ne saurait pas lequel des cinq porte ce prix. /api/sante dit où on en est.

Quatre choses à savoir avant de lire ce JSON

Une ligne n'est écrite que quand le prix CHANGE.

Ce n'est pas un échantillonnage régulier. Si c'en était un, ecart vaudrait zéro dans la quasi-totalité des lignes et le dernier vrai mouvement serait noyé.

Conséquence : deux lignes consécutives ne sont pas à intervalle fixe. C'est pour ça que ecart_secondes est publié plutôt que supposé.

Un prix peut avoir plusieurs heures.

Edge bride à ~20 secondes par création de betslip, et il en faut deux par match — un par joueur. Un match coûte donc 40 s, et suivre les 230 matchs ouverts demande plus de deux heures par tour. Mesuré : 4,6 lignes par minute, 21 matchs en 17 minutes.

Aucun réglage n'y change rien : le serveur refuse, et il dit lui-même combien de temps attendre (retry_after). Le seul levier est de choisir quels matchs suivre — variable TOURNOIS. Vingt matchs revus toutes les quinze minutes valent mieux que deux cent trente revus deux fois par jour.

Lis age_secondes avant de jouer un prix. Sans lui, une cote de vingt minutes ressemble exactement à une cote de l'instant.

null n'est pas 0.

ecart est null au premier relevé d'une sélection, parce qu'il n'y a rien à quoi comparer. Un 0 affirmerait que le prix n'a pas bougé.

liquidite est null quand le book n'a pas publié de mise max. Un 0 se lirait « marché sans profondeur », ce qui est une affirmation. Le champ liquidite_absente_car dit pourquoi.

« Live » est déduit, pas déclaré.

Le flux ne porte aucun drapeau. Un match est tenu pour live si son heure de début est passée, ou si des marchés par set sont proposés. C'est une heuristique.

Les routes

routece qu'elle répond
/apil'index, qui se documente lui-même
/api/santel'état de la source, et pourquoi il n'y a pas de donnée s'il n'y en a pas
/api/booksles books suivis, y compris ceux qui n'ont rien rendu
/api/tournoisles tournois, tels qu'Edge les nomme
/api/joueursles joueurs, tels qu'Edge les nomme
/api/matchsun match par ligne, les books qui le cotent
/api/cotesle grain fin : dernier prix par sélection, avec l'écart et la liquidité
/api/mouvementstout l'historique d'un match
/api/toursles rotations de collecte
/healthla sonde, publique
/api/docsle Swagger, pour les types exacts

Une ligne de /api/cotes

{
  "book": "pin88",
  "tournoi": "atp masters 1000 paris",
  "tournoi_ecrit_par_le_book": "ATP Masters 1000 Paris",
  "joueurs": ["Cameron Norrie", "Matteo Arnaldi"],
  "marche": "vainqueur",
  "selection": "Cameron Norrie",
  "cote": 1.75,

  "releve_a": "2026-11-02T14:58:12Z",   // le dernier CHANGEMENT
  "vu_a": "2026-11-02T15:02:40Z",       // le dernier passage, prix identique
  "age_secondes": 6,                    // depuis vu_a

  "cote_avant": 1.58,
  "ecart": 0.17,
  "ecart_pct": 10.759,
  "mesure_avant_a": "2026-11-02T14:57:42Z",
  "ecart_secondes": 30,                 // entre les deux prix

  "liquidite": 1240.0,                  // mise max à ce prix, en EUR
  "liquidite_devise": "EUR",
  "liquidite_absente_car": null,

  "cle_match": "atp masters 1000 paris|2026-11-02,10045364,10055688"
}

releve_a et vu_a ne disent pas la même chose

releve_a est l'instant du dernier changement. vu_a est l'instant du dernier passage où la cote était encore là, inchangée. Les confondre ferait passer un prix figé depuis deux heures pour un prix de l'instant.

La liquidité est par book et par sélection

C'est la mise maximale disponible à ce prix chez ce book. Elle est rafraîchie à chaque passage même quand la cote ne bouge pas : le carnet s'épaissit et s'assèche sans que le prix change, et garder l'ancienne valeur ferait croire qu'on peut encore jouer une taille qui n'est plus là.

En revanche un changement de liquidité n'ouvre pas une nouvelle ligne : ecart reste l'écart de cote.

Les montants sont convertis dans une devise unique (EUR) via les taux du flux. Si le taux d'une devise n'est pas encore connu, la liquidité est null plutôt que convertie au hasard.

Les filtres de /api/cotes

paramètreeffet
bookpmk | polymarket | molly | bf | pin88
tournoile libellé Edge plié, ex. atp masters 1000 paris
joueursous-chaîne, cherchée dans les libellés d'origine
marchevainqueur
min_ecart_pctne garder que les mouvements d'au moins N %
min_liquiditemise max minimale, en EUR. Écarte les lignes sans liquidité connue plutôt que de traiter null comme un grand nombre.
depuis_minutesne garder que ce qui a bougé récemment
limitenombre de lignes, 500 par défaut

À essayer

/api/sante /api/books /api/tournois /api/matchs /api/cotes?limite=20 min_ecart_pct=3 min_liquidite=500 /api/docs

Les noms sont ceux d'Edge, tels quels

Aucune traduction, aucun réordonnancement, aucun raccourci. /api/tournois affiche atp masters 1000 paris parce que c'est ce que la source envoie — seules la casse et les accents sont aplanis, pour que la clé d'URL tienne.

Ce service ne normalise rien, et c'est volontaire.

Il y avait ici une table de traduction, un réordonnancement des mots de catégorie et un appariement flou des patronymes. Tout a été retiré : ça servait à réconcilier six bookmakers qui écrivaient le même tournoi de cinq façons. Edge est la source unique, et une source unique est cohérente avec elle-même.

Deviner une divergence qui n'existe pas, c'est exactement la façon dont un appariement finit par fondre deux joueurs différents — et un écart de cote entre deux joueurs différents ressemble exactement à une opportunité.

L'identité d'un match vient d'Edge

cle_match est construite sur l'event_id du flux, pas sur les noms. C'est strictement mieux : l'identifiant ne bouge pas quand un prénom est abrégé, il distingue deux frères sans comparer d'initiales, et il n'a pas besoin de savoir si « Davidovich Fokina » est un nom ou deux.

Les betslips ne placent aucun pari

Pour obtenir le prix de chaque book, le service ouvre un betslip par sélection, lit les réponses, et le supprime immédiatement — y compris si une erreur survient en cours de route. Aucun pari n'est jamais placé.