EvalItUp expose une API HTTP locale sur le port 8080. Envoyez un POST JSON depuis n'importe quel script Python — pas de SDK propriétaire, pas de wrapper complexe, juste du HTTP standard.
Pourquoi Python pour le Trading Automatisé ?
Python est le langage de prédilection pour le trading algorithmique grâce à ses bibliothèques puissantes (pandas, numpy, scikit-learn, TensorFlow). Avec EvalItUp, vos scripts Python peuvent exécuter directement sur vos comptes Rithmic prop firm.
De votre modèle ML à l'exécution Rithmic en une seule ligne de code : requests.post()Pourquoi Utiliser Python avec EvalItUp ?
Les plateformes de trading traditionnelles ne s'intègrent pas facilement avec Python. EvalItUp offre une API HTTP simple qui fonctionne avec n'importe quel script.
Intégrations Traditionnelles
- SDK propriétaires complexes avec documentation limitée
- Dépendances C++ ou Java difficiles à installer
- Latence élevée via des bridges ou des APIs cloud
- Pas de support multi-comptes natif
- Maintenance constante lors des mises à jour de la plateforme
Avec EvalItUp
- Simple POST HTTP — fonctionne avec requests, httpx, aiohttp
- Aucune dépendance : pip install requests et c'est parti
- Latence < 5ms en local — idéal pour le HFT
- Dispatch vers des comptes illimités avec une seule requête
- API stable — pas de breaking changes
Référence API Complète
Endpoint
application/jsonhttp://127.0.0.1:8080/signal/{workflow_id}Max size: 64 KB
Champs Obligatoires
- schema_version
- "1.0" ou "1.1" — Version du schéma (1.1 ajoute action, order_id, parent_order_id)
- signal_id
- Identifiant unique du signal (UUID recommandé)
- workflow_id
- Nom du pool/workflow cible (sensible à la casse)
- instrument
- Objet {exchange, symbol} — ex: {"exchange": "CME", "symbol": "ESU6"}
- side
- Direction : BUY, SELL, LONG, SHORT
- qty
- Nombre de contrats (entier positif)
Champs Optionnels
- order_type
- MARKET (défaut), LIMIT, STOP, STOP_LIMIT
- limit_price
- Prix limite (requis si LIMIT ou STOP_LIMIT)
- trigger_price
- Prix de déclenchement (requis si STOP ou STOP_LIMIT)
- bracket
- Objet {take_profit, stop_loss} pour ordres brackets
- open_close
- OPEN ou CLOSE — indique si l'ordre ouvre ou ferme une position
Réponses HTTP
{"status": "accepted", "signal_id": "abc-123"}{"error": "Missing required field: qty"}{"error": "Workflow not found: xyz"}Exemples de Code Python
Copiez-collez ces exemples dans vos scripts. Tous utilisent la bibliothèque requests (pip install requests).
Signal Basique
Envoie un ordre market simple
import requests
import uuid
def send_signal(pool, symbol, side, qty):
url = f"http://127.0.0.1:8080/signal/{pool}"
signal = {
"schema_version": "1.0",
"signal_id": str(uuid.uuid4()),
"workflow_id": pool,
"instrument": {
"exchange": "CME",
"symbol": symbol
},
"side": side,
"qty": qty
}
response = requests.post(url, json=signal, timeout=5)
return response.json()
# Exemple
result = send_signal("mon-pool", "MESU6", "BUY", 2)
print(result)Signal avec Take Profit et Stop Loss
Génère 3 ordres liés automatiquement (entrée + TP + SL)
import requests
import uuid
def send_bracket_order(pool, symbol, side, qty, tp_price, sl_price):
url = f"http://127.0.0.1:8080/signal/{pool}"
signal = {
"schema_version": "1.0",
"signal_id": str(uuid.uuid4()),
"workflow_id": pool,
"instrument": {
"exchange": "CME",
"symbol": symbol
},
"side": side,
"qty": qty,
"bracket": {
"take_profit": {
"limit_price": tp_price
},
"stop_loss": {
"trigger_price": sl_price
}
}
}
response = requests.post(url, json=signal, timeout=5)
return response.json()
# Exemple : Buy 1 MES avec TP +20 points et SL -10 points
entry_price = 5070.00
result = send_bracket_order(
pool="scalping-mes",
symbol="MESU6",
side="BUY",
qty=1,
tp_price=entry_price + 20,
sl_price=entry_price - 10
)
print(result)Ordre Limite
Achète uniquement si le prix atteint votre limite
import requests
import uuid
def send_limit_order(pool, symbol, side, qty, limit_price):
url = f"http://127.0.0.1:8080/signal/{pool}"
signal = {
"schema_version": "1.0",
"signal_id": str(uuid.uuid4()),
"workflow_id": pool,
"instrument": {
"exchange": "CME",
"symbol": symbol
},
"side": side,
"qty": qty,
"order_type": "LIMIT",
"limit_price": limit_price
}
response = requests.post(url, json=signal, timeout=5)
return response.json()
# Exemple : Acheter 1 ES à 5050 ou moins
result = send_limit_order("swing-es", "ESU6", "BUY", 1, 5050.00)
print(result)Classe EvalItUp Complète
Wrapper Python réutilisable pour tous vos projets de trading
import requests
import uuid
from typing import Optional, Literal
class EvalItUpClient:
def __init__(self, base_url: str = "http://127.0.0.1:8080"):
self.base_url = base_url
self.session = requests.Session()
self.session.headers.update({"Content-Type": "application/json"})
def send_signal(
self,
pool: str,
symbol: str,
side: Literal["BUY", "SELL"],
qty: int,
exchange: str = "CME",
order_type: str = "MARKET",
limit_price: Optional[float] = None,
trigger_price: Optional[float] = None,
tp_price: Optional[float] = None,
sl_price: Optional[float] = None
) -> dict:
signal = {
"schema_version": "1.0",
"signal_id": str(uuid.uuid4()),
"workflow_id": pool,
"instrument": {
"exchange": exchange,
"symbol": symbol
},
"side": side,
"qty": qty
}
if order_type != "MARKET":
signal["order_type"] = order_type
if limit_price:
signal["limit_price"] = limit_price
if trigger_price:
signal["trigger_price"] = trigger_price
if tp_price or sl_price:
signal["bracket"] = {}
if tp_price:
signal["bracket"]["take_profit"] = {"limit_price": tp_price}
if sl_price:
signal["bracket"]["stop_loss"] = {"trigger_price": sl_price}
url = f"{self.base_url}/signal/{pool}"
response = self.session.post(url, json=signal, timeout=5)
return response.json()
def close_position(self, pool: str, symbol: str, side: Literal["BUY", "SELL"], qty: int) -> dict:
signal = {
"schema_version": "1.0",
"signal_id": str(uuid.uuid4()),
"workflow_id": pool,
"instrument": {"exchange": "CME", "symbol": symbol},
"side": side,
"qty": qty,
"open_close": "CLOSE"
}
url = f"{self.base_url}/signal/{pool}"
return self.session.post(url, json=signal, timeout=5).json()
# Utilisation
client = EvalItUpClient()
client.send_signal("mon-pool", "MESU6", "BUY", 2)
client.send_signal("mon-pool", "MESU6", "BUY", 1, tp_price=5100, sl_price=5050)
client.close_position("mon-pool", "MESU6", "SELL", 2)Version Asynchrone (asyncio + aiohttp)
Pour les bots haute performance avec traitement parallèle
import aiohttp
import asyncio
import uuid
async def send_signal_async(pool, symbol, side, qty):
url = f"http://127.0.0.1:8080/signal/{pool}"
signal = {
"schema_version": "1.0",
"signal_id": str(uuid.uuid4()),
"workflow_id": pool,
"instrument": {"exchange": "CME", "symbol": symbol},
"side": side,
"qty": qty
}
async with aiohttp.ClientSession() as session:
async with session.post(url, json=signal) as response:
return await response.json()
# Envoyer plusieurs signaux en parallèle
async def main():
tasks = [
send_signal_async("pool-1", "MESU6", "BUY", 1),
send_signal_async("pool-2", "MNQU6", "BUY", 1),
send_signal_async("pool-3", "MESU6", "SELL", 1),
]
results = await asyncio.gather(*tasks)
for r in results:
print(r)
asyncio.run(main())Cas d'Usage Python
Trading Machine Learning
Connectez vos modèles scikit-learn, TensorFlow ou PyTorch. Quand votre modèle prédit une opportunité, envoyez le signal à EvalItUp.
if model.predict(features) > threshold: send_signal('ml-pool', 'MESU6', 'BUY', 1)Du Backtest au Live
Utilisez le même code pour backtest et live. Changez simplement l'execution handler pour appeler l'API EvalItUp.
Mode backtest: simulated_fill() | Mode live: send_signal()Analyse de Données Temps Réel
Combinez pandas et numpy avec des flux de données temps réel. Détectez les patterns et exécutez immédiatement.
WebSocket market data → pandas analysis → signal si condition remplieOrchestration Multi-Stratégies
Exécutez plusieurs stratégies Python en parallèle, chacune ciblant un pool différent.
Thread 1: scalping → pool-scalp | Thread 2: swing → pool-swingTrading Programmé
Utilisez schedule ou APScheduler pour des exécutions à heures fixes.
schedule.every().day.at('09:30').do(execute_open_strategy)Intégrations avec Frameworks Python
Backtrader
Framework de backtesting populaire. Créez un broker custom qui appelle l'API EvalItUp.
Zipline / Zipline-Reloaded
Utilisé par Quantopian. Implémentez un execution handler custom.
VectorBT
Backtesting vectorisé ultra-rapide. Idéal pour le prototypage.
Jupyter Notebooks
Prototypez vos stratégies interactivement et exécutez depuis le notebook.
Bonnes Pratiques
Gestion des Erreurs
Toujours wrapper vos appels API dans try/except
try:
result = send_signal(...)
if result.get('status') != 'accepted':
logger.error(f"Signal rejeté: {result}")
except requests.Timeout:
logger.error("Timeout API EvalItUp")
except requests.ConnectionError:
logger.error("EvalItUp non accessible")Logging
Loggez chaque signal avec son signal_id pour le debugging
Tests sur Simulation
Testez toujours sur compte simulation avant le live
Rate Limiting
Évitez d'envoyer trop de signaux trop rapidement
Tutoriel : Premier Signal Python
Suivez ce guide pour envoyer votre premier signal depuis un script Python.
1. Installer la bibliothèque requests
La bibliothèque HTTP standard pour Python
pip install requests2. Lancer EvalItUp
Ouvrez EvalItUp et connectez-vous à vos comptes Rithmic. L'API locale démarre automatiquement sur http://127.0.0.1:8080
3. Créer un Pool de Test
Dans EvalItUp, créez un pool nommé 'python-test' et ajoutez-y un compte de simulation.
4. Envoyer un Signal Test
Exécutez ce code. Vous devriez voir status 200 et le signal dans EvalItUp → Activité.
import requests
response = requests.post(
"http://127.0.0.1:8080/signal/python-test",
json={
"schema_version": "1.0",
"signal_id": "test-001",
"workflow_id": "python-test",
"instrument": {"exchange": "CME", "symbol": "MESU6"},
"side": "BUY",
"qty": 1
}
)
print(response.status_code) # 200
print(response.json()) # {"status": "accepted", ...}5. Vérifier dans EvalItUp
Ouvrez l'onglet Activité dans EvalItUp. Vous verrez votre signal 'test-001' et les ordres envoyés aux comptes du pool.
Questions Fréquentes Python Trade Copier
EvalItUp doit-il être ouvert pour que l'API fonctionne ?
Oui. L'API HTTP est hébergée par l'application EvalItUp. Si l'app est fermée, les requêtes échoueront avec ConnectionError.
Puis-je utiliser l'API depuis un serveur distant ?
Par défaut, l'API écoute sur 127.0.0.1 (localhost). Pour un accès distant, utilisez un tunnel SSH ou configurez un reverse proxy sécurisé.
Quelle est la latence de l'API ?
< 5ms en local. Le temps inclut la validation et l'envoi aux comptes Rithmic. L'exécution Rithmic ajoute 1-5ms.
Puis-je envoyer plusieurs signaux en parallèle ?
Oui. Utilisez asyncio avec aiohttp, ou ThreadPoolExecutor. Chaque signal est traité indépendamment.
L'API supporte-t-elle l'authentification ?
Optionnellement. Configurez un Bearer token dans EvalItUp → Paramètres → API, puis ajoutez l'header Authorization: Bearer VOTRE_TOKEN.
Comment déboguer si mes signaux ne s'exécutent pas ?
1) Vérifiez le code HTTP (200=OK, 400=erreur JSON, 404=pool introuvable). 2) Consultez les logs EvalItUp. 3) Vérifiez que workflow_id = nom exact du pool.
Puis-je utiliser cette API avec d'autres langages ?
Oui. C'est une API HTTP standard. Elle fonctionne avec curl, JavaScript, C#, Go, Rust, ou tout langage capable d'envoyer des POST HTTP.
Comment intégrer avec un backtest Backtrader ou Zipline ?
Créez un broker/execution handler custom qui appelle send_signal() au lieu de simuler les fills. Gardez la même logique de stratégie.