Trading & Bots
Python es una opción común para la automatización de trading en Solana: consultar pools, construir transacciones de intercambio, firmar con billeteras activas y enviar con tarifas de prioridad. Los bots fiables simulan cada envío, actualizan los hashes de bloque y manejan explícitamente los mercados de tarifas de Agave 4.1.1.
Receta
Tarjeta de receta de referencia rápida, lista para copiar y pegar.
import asyncio
from solana.rpc.async_api import AsyncClient
async def bot_loop(rpc: str):
async with AsyncClient(rpc) as client:
while True:
slot = (await client.get_slot()).value
# 1. leer señales 2. construir ix 3. simular 4. enviar 5. confirmar
await asyncio.sleep(0.4) # respetar límites de tasaCuándo usar esto:
- Creación de mercado o arbitraje entre lugares de liquidez en cadena.
- Reequilibrio programado y automatización estilo órdenes límite.
- Monitorización de mempools/RPC para condiciones de activación (con soporte del proveedor).
- Bots de operaciones internas (barridos de tesorería, distribución de recompensas).
Ejemplo de Trabajo
import asyncio
import logging
from solders.compute_budget import set_compute_unit_limit, set_compute_unit_price
from solders.keypair import Keypair
from solders.pubkey import Pubkey
from solders.hash import Hash
from solders.message import Message
from solders.transaction import VersionedTransaction
from solana.rpc.async_api import AsyncClient
from solana.rpc.types import TxOpts
log = logging.getLogger("mm-bot")
RPC = "https://api.mainnet-beta.solana.com" # usar RPC privado en producción
class SimpleSender:
def __init__(self, client: AsyncClient, payer: Keypair):
self.client = client
self.payer = payer
async def send(self, instructions, micro_lamports: int):
bh = await self.client.get_latest_blockhash()
blockhash = Hash.from_string(str(bh.value.blockhash))
ixs = [
set_compute_unit_limit(200_000),
set_compute_unit_price(micro_lamports),
*instructions,
]
msg = Message.new_with_blockhash(ixs, self.payer.pubkey(), blockhash)
tx = VersionedTransaction(msg, [self.payer])
sim = await self.client.simulate_transaction(tx)
if sim.value.err:
log.warning("sim_fail err=%s logs=%s", sim.value.err, sim.value.logs)
return None
resp = await self.client.send_transaction(
tx, opts=TxOpts(skip_preflight=True, preflight_commitment="processed")
)
await self.client.confirm_transaction(resp.value, commitment="confirmed")
return resp.value
async def main():
payer = Keypair() # cargar de forma segura
async with AsyncClient(RPC) as client:
sender = SimpleSender(client, payer)
# instructions = [swap_ix_from_jupiter_api(...)]
# await sender.send(instructions, micro_lamports=10_000)
asyncio.run(main())Lo que esto demuestra:
- La clase
Senderaísla el hash de bloque, el presupuesto, la simulación, el envío y la confirmación. - La tarifa de prioridad a través de
set_compute_unit_pricees explícita por intento. - El registro captura los logs de simulación para análisis post-mortem.
- Estructura amigable para bucles asíncronos para múltiples estrategias.
Análisis Profundo
Cómo Funciona
- Los bots son intensivos en lectura (cotizaciones, saldos) y ráfagas de escritura (envío de txs).
- Jupiter y otros agregadores devuelven instrucciones serializadas o transacciones para firmar.
- Las tarifas de prioridad compiten por el espacio de bloque; ajustar micro-lamports según la congestión.
- Los paquetes Jito (opcional) se enrutan a través de motores de bloque para envíos conscientes de MEV.
Capas de Arquitectura de Bots
| Capa | Responsabilidad | Herramientas |
|---|---|---|
| Señal | Precios, diferenciales, inventario | RPC, websockets, APIs de venues |
| Construir | Instrucciones, ALTs | solders, API de Jupiter |
| Riesgo | Límites de tamaño, interruptor de emergencia | Lógica de la aplicación |
| Enviar | Tarifas, reintentos, confirmar | solana-py, RPC de Jito |
| Observar | PnL, fallos | logging, métricas |
Notas de Python
# Nunca bloquees el bucle de eventos en trabajo de CPU
await asyncio.to_thread(heavy_analytics, frame)
# Retroceso con jitter en errores 429 / blockhash
import random
await asyncio.sleep(0.2 + random.random() * 0.3)Trampas Comunes
- RPC público para bots de mainnet - límites de tasa y slots obsoletos. Solución: proveedor dedicado con SLA.
- Sin interruptor de emergencia - el bucle descontrolado agota la billetera. Solución: límites máximos de gasto diario e inventario.
- Ignorar fallos de aterrizaje - las txs expiran silenciosamente. Solución: rastrear tiempos de espera de confirmación y reenviar.
- Mismo hash de bloque en reintento - fallo garantizado después de la expiración. Solución: reconstruir cada intento.
- Almacenar claves en memoria del proceso - las volcados de memoria filtran secretos. Solución: billeteras activas con saldo mínimo, rotar claves.
Alternativas
| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
| Núcleo de bot Rust/Go | Latencia ultra baja | Velocidad del equipo en Python |
@solana/kit + serverless | Disparadores infrecuentes | Creación de mercado en bucle cerrado |
| Operaciones manuales CLI | Movimientos de tesorería raros | Reacciones sub-segundo |
| API de CEX totalmente custodiada | Rampas fiduciarias | Se requiere composabilidad en cadena |
Preguntas Frecuentes
¿Es Python lo suficientemente rápido?
A menudo sí para la escala humana y los tiempos de bloque de DeFi; perfila las rutas críticas y muévelas a Rust solo si es necesario.
¿Integración con Jupiter?
Llama a la API HTTP de cotización/intercambio de Jupiter, deserializa las instrucciones devueltas, firma localmente.
¿Cómo estimar las tarifas de prioridad?
Usa getRecentPrioritizationFees RPC o las utilidades del proveedor; consulta la sección de tarifas de prioridad.
¿Pruebas en Devnet?
Valida la lógica en devnet, pero el comportamiento del mercado de tarifas difiere de mainnet.
¿Múltiples billeteras?
Una Keypair por estrategia limita el radio de explosión.
¿Desincronización del reloj?
Usa el slot/tiempo del RPC, no el reloj del portátil, para la programación.
¿Cumplimiento?
Registra las operaciones con firmas para auditoría; respeta las reglas jurisdiccionales.
¿Websocket vs. polling?
Websockets para disparadores de cuentas; polling más simple para prototipos.
¿Surfpool para simulación?
Surfpool 0.12.0 ayuda a reproducir el estado de mainnet localmente antes de arriesgar fondos.
¿AnchorPy en bots?
Úsalo al llamar a tus propios programas Anchor; los agregadores devuelven bytes de ix crudos.
Relacionado
- Construcción de Transacciones en Python - ensamblaje de tx
- Intercambios con Jupiter - integración de intercambios
- Establecimiento de Tarifas de Prioridad - ajuste de tarifas
- Mejores Prácticas de Python para Solana - reglas de producción
Versiones de Stack: Esta página fue escrita para Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0, y LiteSVM 0.6.x.