Lección 1.3.5 · 55 min
Datos de cripto y on-chain
En cripto no hay una bolsa principal ni una cinta consolidada: cada exchange publica sus propios datos y la cadena de bloques publica los suyos. Esta lección lee el formato de velas de ccxt, lo valida, lo pagina contra un exchange simulado y separa lo que dan los exchanges, los agregadores y los datos on-chain.
- Módulo
- 1.3 · Fuentes de datos de mercado
- Duración
- 55 min
Lecciones del nivel 1
1.1 · Cómo funcionan los mercados
1.2 · Clases de activos
- 1.2.1 Acciones: splits, dividendos y eventos corporativos
- 1.2.2 ETFs: réplica, tracking error, apalancados y UCITS
- 1.2.3 Futuros: especificaciones, margen, roll y contango
- 1.2.4 Forex: pares, pips, lotes, rollover y CFD
- 1.2.5 Opciones: call, put, valor intrínseco y valor temporal
- 1.2.6 Cripto: spot, perpetuos, funding y custodia
- 1.2.7 Renta fija y tipos de interés; CFDs y productos apalancados
1.3 · Fuentes de datos de mercado
- 1.3.1 Tipos de datos de mercado: EOD, barras, ticks, libro y referencia
- 1.3.2 Fuentes de datos gratuitas
- 1.3.3 APIs de datos retail y prosumer
- 1.3.4 Proveedores de datos profesionales
- 1.3.5 Datos de cripto y on-chain
- 1.3.6 Brókeres como fuente de datos
- 1.3.7 Licencias y términos de uso de datos
- 1.3.8 Cómo elegir proveedor de datos
1.4 · Ingeniería de datos financieros
- 1.4.1 Descarga por REST y websockets: paginación, límites y reintentos
- 1.4.2 Limpieza de datos: faltantes, ticks erróneos, huecos y zonas horarias
- 1.4.3 Ajustes por splits y dividendos: precios ajustados y sin ajustar
- 1.4.4 Universos sin sesgo de supervivencia: deslistados, fusiones y cambios de símbolo
- 1.4.5 Construcción de barras: tiempo, ticks, volumen, dólar y desequilibrio
- 1.4.6 Series continuas de futuros: reglas de roll, ajuste por diferencia y ajuste por ratio
- 1.4.7 Almacenamiento: CSV, Parquet, particionado, DuckDB, TimescaleDB y ArcticDB
- 1.4.8 Pipeline reproducible: descarga, validación, actualización incremental y tests de calidad
1.5 · Datos fundamentales y macro
1.6 · Análisis exploratorio financiero
1.7 · Análisis técnico programado
Tres capas de datos
En acciones hay una bolsa principal, una cinta consolidada y un regulador que obliga a publicar cada operación (lección 1.1.1). En cripto no: cada exchange centralizado (CEX) es a la vez bolsa, bróker y, muchas veces, custodio, y publica sus propios precios con su propia API. Encima de ellos hay agregadores que combinan muchos exchanges, y debajo, la cadena de bloques, que registra las transferencias de verdad. Son tres capas que responden a preguntas distintas:
Fuente Mermaid
flowchart TB C[Cadena de bloques] --> N[Proveedor on-chain] C --> X[Exchanges CEX] X --> A[Agregadores] X --> T[Tu programa] A --> T N --> T
| Capa | Qué da | Pregunta que responde | Ejemplos |
|---|---|---|---|
| Exchange (CEX) | Velas, operaciones, libro, funding de los perpetuos del propio exchange | ¿A qué precio puedo operar aquí y ahora? | APIs de cada exchange, unificadas con ccxt |
| Agregador | Precio combinado, capitalización, volumen de muchos exchanges | ¿Cuánto vale el activo «en general»? | CoinGecko, CoinMarketCap; Kaiko para uso institucional |
| On-chain | Bloques, transacciones, direcciones, comisiones; métricas derivadas | ¿Quién mueve qué en la red? | Nodo propio, exploradores, Glassnode |
Para un sistema que opera en un exchange, la fuente de precios es ese exchange: es donde se ejecuta. El agregador sirve para comparar y para el universo (qué activos existen, cuánto capitalizan); el on-chain, para variables que no están en el precio.
ccxt: una API para más de cien exchanges
Cada exchange tiene su API, con sus nombres, sus formatos y sus límites. ccxt es una librería de código abierto (Python, JavaScript, PHP…) que las unifica: el mismo método devuelve el mismo formato en todos. Su documentación habla de más de cien exchanges soportados1Nota 1 · Documentación de ccxt, Manual: secciones «OHLCV Candlestick Charts» y «Rate Limit» (docs.ccxt.com), consultada el 21/10/2026.. No forma parte del entorno del curso porque necesita red; el uso típico es:
import ccxt
exchange = ccxt.binance() # enableRateLimit=True por defecto
exchange.load_markets() # mercados y símbolos unificados
print(exchange.has["fetchOHLCV"], list(exchange.timeframes)[:5])
desde = exchange.parse8601("2025-12-01T00:00:00Z") # milisegundos
velas = exchange.fetch_ohlcv("BTC/USDT", "1h", since=desde, limit=500)Los símbolos son unificados: BTC/USDT es el spot de bitcoin contra USDT en cualquier exchange, y un perpetuo lineal
se escribe BTC/USDT:USDT (base, cotización y divisa de liquidación). has["fetchOHLCV"] dice si el exchange da velas
y timeframes, qué intervalos acepta. fetch_ohlcv(símbolo, timeframe, since, limit) devuelve una lista de velas,
de la más antigua a la más reciente, cada una como [marca de tiempo en ms UTC, apertura, máximo, mínimo, cierre, volumen]1.
Leer el formato de fetch_ohlcv
xsn_ccxt_ohlcv.json es una respuesta con ese formato: las 200 últimas velas horarias de 2025 de XSN, el token ficticio
del curso. Es un ejemplo de formato, no una descarga real, pero se procesa exactamente igual que la de un exchange:
import json
from pathlib import Path
import pandas as pd
velas = json.loads(Path("xsn_ccxt_ohlcv.json").read_text())
print(type(velas).__name__, len(velas), "velas")
velas[:2]list 200 velas
[[1766502000000, 47.1217, 47.298, 46.9181, 46.9485, 115011.657], [1766505600000, 46.9485, 47.3096, 46.913, 47.2735, 156031.363]]Una lista de listas, sin nombres de columna: el orden es la especificación. El primer número es la apertura de la vela
en milisegundos desde 1970 en UTC. Convertirlo con unit="s" daría fechas en el año 57.000; olvidar utc=True
daría fechas sin zona, que se mezclarían mal con cualquier otra serie (lección 1.4.2).
cols = ["ts", "apertura", "maximo", "minimo", "cierre", "volumen"]
df = pd.DataFrame(velas, columns=cols)
df["ts"] = pd.to_datetime(df["ts"], unit="ms", utc=True)
df = df.set_index("ts")
print(df.index[0], "->", df.index[-1])
df.tail(3)2025-12-23 15:00:00+00:00 -> 2025-12-31 22:00:00+00:00
apertura maximo minimo cierre volumen
ts
2025-12-31 20:00:00+00:00 48.7692 48.8314 48.1571 48.1701 142982.716
2025-12-31 21:00:00+00:00 48.1701 48.2427 48.1480 48.1839 183139.453
2025-12-31 22:00:00+00:00 48.1839 48.2721 48.1744 48.2534 106840.362El volumen viene en unidades del activo base (XSN), no en dólares. Para comparar volúmenes entre activos, o con un agregador que da volumen en USD, hay que multiplicar por el precio, y eso ya es una estimación: cada operación de la vela tuvo su propio precio.
Validar antes de guardar
Una respuesta que se ha parseado bien puede estar mal. Tres comprobaciones baratas que conviene pasar a cada descarga:
pasos = df.index.to_series().diff().dropna().value_counts()
print("intervalos:", pasos.to_dict())
cuerpo_max = df[["apertura", "cierre"]].max(axis=1)
cuerpo_min = df[["apertura", "cierre"]].min(axis=1)
ok = (df["maximo"] >= cuerpo_max) & (df["minimo"] <= cuerpo_min)
print("velas OHLC coherentes:", ok.all())
ap, ci = df["apertura"].to_numpy(), df["cierre"].to_numpy()
seguida = ap[1:] == ci[:-1]
print(f"apertura = cierre anterior: {seguida.mean():.0%}")intervalos: {Timedelta('0 days 01:00:00'): 199}
velas OHLC coherentes: True
apertura = cierre anterior: 100%Todos los intervalos son de una hora, ninguna vela tiene el máximo por debajo del cuerpo y, en estos datos, cada vela abre en el cierre de la anterior. Lo último es propio de un mercado continuo 24/7 como cripto; en acciones no se cumple de un día a otro (hay subastas y huecos), y en un exchange real puede fallar por una operación suelta entre dos velas.
La cuarta comprobación es la más olvidada: la vela abierta. La mayoría de exchanges devuelven también la vela en curso, con su cierre, su máximo, su mínimo y su volumen todavía cambiando. Si la descarga se hace a las 22:30, la vela de las 22:00 no ha terminado:
def quitar_vela_abierta(df, ahora, intervalo="1h"):
fin = df.index + pd.Timedelta(intervalo)
return df[fin <= ahora]
ahora = pd.Timestamp("2025-12-31 22:30", tz="UTC")
cerradas = quitar_vela_abierta(df, ahora)
print(len(df), "velas;", len(cerradas), "cerradas a", ahora)
print("última cerrada:", cerradas.index[-1])200 velas; 199 cerradas a 2025-12-31 22:30:00+00:00
última cerrada: 2025-12-31 21:00:00+00:00Guardar la vela abierta como definitiva crea un histórico que nadie más puede reproducir: quien la descargue mañana verá otro cierre y otro volumen. En un backtest, además, es información parcial tratada como completa.
Re-muestrear: velas de 4 horas
Con el DataFrame en hora UTC, cambiar de intervalo es un resample. El detalle es el mismo que con la vela abierta: los
grupos de los extremos pueden estar incompletos. La primera vela del archivo empieza a las 15:00, así que el grupo de
las 12:00 a las 16:00 solo tiene una hora:
reglas = {"apertura": "first", "maximo": "max", "minimo": "min",
"cierre": "last", "volumen": "sum"}
grupos = df.resample("4h")
v4 = grupos.agg(reglas)
v4["horas"] = grupos["cierre"].count()
print(v4["horas"].value_counts().sort_index().to_dict())
v4 = v4[v4["horas"] == 4].drop(columns="horas")
print(len(v4), "velas de 4 h completas")
v4.round(2).tail(3){1: 1, 3: 1, 4: 49}
49 velas de 4 h completas
apertura maximo minimo cierre volumen
ts
2025-12-31 08:00:00+00:00 48.17 48.77 48.04 48.48 709687.91
2025-12-31 12:00:00+00:00 48.48 48.68 48.33 48.36 539446.43
2025-12-31 16:00:00+00:00 48.36 48.81 48.32 48.77 701424.06La figura de la cabecera dibuja el resultado. En lugar de 51 grupos quedan 49 velas completas de 4 horas: las de los extremos tenían 1 y 3 horas. resample agrupa
por el inicio del intervalo (con 4h, pandas alinea los grupos con la medianoche UTC), que es también la convención de ccxt y de la
mayoría de exchanges. No todos los proveedores la siguen, como se ve más abajo con CoinGecko.
Paginar con since y limit
Un exchange no devuelve años de velas en una sola petición: cada respuesta tiene un máximo de velas (limit), que
depende del exchange. Para descargar un periodo largo hay que pedir por páginas, avanzando since hasta la última vela
recibida, y esperar entre peticiones para no superar el límite. En ccxt, exchange.rateLimit es la pausa en
milisegundos que el limitador interno mantiene entre peticiones (multiplicada por el «coste» de cada llamada), y el
limitador viene activado por defecto1.
Fuente Mermaid
flowchart TB
S[since = inicio] --> P[fetch_ohlcv]
P --> V{¿Velas nuevas?}
V -- no --> F[Fin]
V -- sí --> G[Guardar]
G --> A[since = última+1h]
A --> E[Esperar rateLimit]
E --> PPara que el bucle se ejecute de verdad sin red, un exchange simulado sirve las 200 velas del archivo con las mismas
reglas: un máximo de 60 velas por llamada, velas desde since en adelante y un rateLimit de 100 ms, que aquí se
suma en un reloj virtual en lugar de dormir:
class ExchangeSimulado:
rateLimit = 100 # ms entre peticiones, como en ccxt
max_velas = 60
def __init__(self, velas):
self.velas = velas
self.llamadas = 0
self.reloj_ms = 0
def fetch_ohlcv(self, symbol, timeframe="1h", since=None,
limit=None):
self.llamadas += 1
self.reloj_ms += self.rateLimit
n = min(limit or self.max_velas, self.max_velas)
nuevas = [v for v in self.velas
if since is None or v[0] >= since]
return nuevas[:n]
def descargar(ex, symbol, since, paso_ms=3_600_000):
todas = []
while True:
lote = ex.fetch_ohlcv(symbol, "1h", since=since, limit=1000)
if not lote:
break
todas += lote
since = lote[-1][0] + paso_ms
return todas
ex = ExchangeSimulado(velas)
bajadas = descargar(ex, "XSN/USDT", since=velas[0][0])
print(len(bajadas), "velas en", ex.llamadas, "llamadas,",
ex.reloj_ms, "ms de espera")
print("iguales al original:", bajadas == velas)200 velas en 5 llamadas, 500 ms de espera
iguales al original: TrueCuatro llamadas con datos (60 + 60 + 60 + 20 velas) y una quinta que llega vacía y termina el bucle. Aunque se pidieron 1.000 velas por llamada, el exchange solo dio 60: el código no debe suponer que recibe lo que pide, sino avanzar desde lo que recibe. Dos errores frecuentes en este bucle:
- Avanzar
sincesumandolimit × intervaloen lugar de partir de la última vela recibida. Si el exchange devuelve menos velas de las pedidas, se salta un tramo sin darse cuenta. - No deduplicar. Si
sincese fija en la última vela y no en la siguiente, cada página repite una vela. Con+ paso_msno ocurre; aun así, convienedf[~df.index.duplicated()]al final.
A escala real, 200 velas son minutos de espera; un año de velas de 1 minuto son 525.600 velas, cientos de llamadas por símbolo. El límite de peticiones marca cuánto tarda una descarga histórica, y superarlo suele acabar en un error de «demasiadas peticiones» o en un bloqueo temporal de la IP. La lección 1.4.1 trata los reintentos con espera creciente.
Huecos: el exchange también para
Un mercado 24/7 no garantiza velas 24/7. Los exchanges tienen mantenimientos, caídas y, en pares poco líquidos, horas sin operaciones. Cada exchange decide qué devolver entonces: algunos no devuelven la vela; otros, una vela con volumen cero. Para simularlo, se quitan tres horas de la descarga:
con_hueco = df.drop(df.index[100:103])
rejilla = pd.date_range(con_hueco.index[0], con_hueco.index[-1],
freq="1h")
faltan = rejilla.difference(con_hueco.index)
print(len(con_hueco), "velas;", len(faltan), "huecos:")
print(list(faltan.strftime("%Y-%m-%d %H:%M")))197 velas; 3 huecos:
['2025-12-27 19:00', '2025-12-27 20:00', '2025-12-27 21:00']Comparar con la rejilla completa es la forma fiable de encontrar huecos; contar filas no dice dónde están. Qué hacer con ellos es una decisión que hay que documentar: dejarlos como faltantes, o rellenarlos con una vela plana (apertura = máximo = mínimo = cierre = cierre anterior, volumen 0) si el exchange estaba abierto y simplemente no hubo operaciones. Si estaba caído, la vela plana es falsa: nadie podía operar a ese precio. La lección 1.4.2 trata la limpieza completa.
No hay un precio de XSN: hay uno por exchange
Cada exchange tiene su libro y sus participantes, así que el precio de un mismo token difiere un poco de un sitio a
otro. Por eso los perpetuos calculan el funding y las liquidaciones contra un índice compuesto de varios exchanges
(lección 1.2.6). xsn_1h.parquet trae el spot de un exchange y ese índice:
xsn = pd.read_parquet("xsn_1h.parquet").set_index("ts")
dif_pb = 1e4 * (xsn["spot"] / xsn["indice"] - 1)
dif_pb.describe().round(2)[["mean", "std", "min", "max"]]mean -0.07
std 4.00
min -15.62
max 14.80
dtype: float64En los datos del curso el spot se separa del índice unos 4 puntos básicos de desviación típica, con extremos de unos 15. Es poco para un sistema diario, pero es del orden de la comisión de un exchange y mucho para uno intradía. La consecuencia práctica: un backtest debe usar los precios del exchange donde va a operar, y una señal calculada con el precio de un agregador puede no ser ejecutable a ese precio en ningún exchange concreto.
Agregadores: CoinGecko, CoinMarketCap y Kaiko
Los agregadores recogen precios y volúmenes de muchos exchanges y los combinan. Son útiles para construir un universo (qué tokens existen, su capitalización, en qué exchanges cotizan) y para precios de referencia, no para ejecutar.
- CoinGecko tiene un plan Demo gratuito con clave, de 100 llamadas por minuto y 10.000 créditos al mes, con un año de historia, según su página de precios y su documentación a fecha de 21/10/20262Nota 2 · CoinGecko API: precios, errores y límites y Coin OHLC Chart by ID, consultados el 21/10/2026..
- CoinMarketCap tiene un plan Basic gratuito de 15.000 créditos al mes; en ese plan hay cotizaciones históricas diarias de un año, pero no velas OHLCV históricas, que empiezan en planes de pago3Nota 3 · CoinMarketCap API Pricing Plans, consultada el 21/10/2026..
- Kaiko se dirige a clientes institucionales (operaciones y libros de más de cien exchanges, tipos de referencia e índices) y no publica tarifas: hace planes a medida4Nota 4 · Kaiko: Pricing and Licenses y Level 1 and Level 2 Data, consultadas el 21/10/2026..
Cada agregador tiene su formato, y no siempre coincide con el de los exchanges. El endpoint de velas de CoinGecko
(/coins/{id}/ohlc) devuelve cinco valores por vela, sin volumen, y su marca de tiempo indica el cierre de la
vela, no la apertura. Además elige la granularidad según el número de días pedido (30 minutos para 1 o 2 días, 4 horas
hasta 30 días, 4 días por encima)2. Con una muestra ilustrativa en ese formato:
import os
import requests
r = requests.get(
"https://api.coingecko.com/api/v3/coins/bitcoin/ohlc",
params={"vs_currency": "usd", "days": 7},
headers={"x-cg-demo-api-key": os.environ["CG_DEMO_KEY"]},
timeout=10,
)
r.raise_for_status()
ohlc = r.json() # [[ms de cierre, apertura, máximo, mínimo, cierre]]muestra_cg = [ # muestra ilustrativa con el formato documentado
[1767225600000, 48.37, 48.83, 48.15, 48.25],
[1767240000000, 48.25, 48.41, 47.90, 48.02],
]
cg = pd.DataFrame(muestra_cg, columns=cols[:5])
cg["cierre_ts"] = pd.to_datetime(cg["ts"], unit="ms", utc=True)
cg["apertura_ts"] = cg["cierre_ts"] - pd.Timedelta("4h")
cg[["apertura_ts", "cierre_ts", "cierre"]] apertura_ts cierre_ts cierre
0 2025-12-31 20:00:00+00:00 2026-01-01 00:00:00+00:00 48.25
1 2026-01-01 00:00:00+00:00 2026-01-01 04:00:00+00:00 48.02Si se mezclan velas de ccxt (hora de apertura) con velas de CoinGecko (hora de cierre) sin convertir, una de las dos series queda desplazada un intervalo entero. Es un sesgo de anticipación de manual: la vela «de las 04:00» de CoinGecko contiene precios que en la convención de ccxt pertenecen a las 00:00–04:00.
Datos on-chain
La cadena de bloques es pública: cualquiera con un nodo puede leer cada bloque, cada transacción, cada dirección y su saldo. A partir de eso, los proveedores on-chain calculan métricas: direcciones activas, volumen transferido, flujos de entrada y salida de exchanges, beneficios y pérdidas realizados. Glassnode, por ejemplo, documenta más de 800 métricas, entre ellas el MVRV (capitalización de mercado entre capitalización «realizada») y el SOPR (grado de beneficio o pérdida realizado de las monedas que se mueven); el acceso completo a su API está en el plan Professional y el plan Advanced solo tiene una API limitada5Nota 5 · Glassnode: documentación y precios, consultadas el 21/10/2026..
La cadena dice qué direcciones movieron qué cantidad, pero no de quién son. Una métrica como «entradas en exchanges» depende de qué direcciones ha etiquetado el proveedor como de exchanges. Un ejemplo pequeño y ficticio, con cuatro transferencias:
transfer = pd.DataFrame({
"origen": ["w1", "w2", "ex_a", "w3"],
"destino": ["ex_a", "ex_b", "w4", "w5"],
"xsn": [5_000, 3_000, 2_000, 4_000],
})
def flujo_neto(t, etiquetas_exchange):
entra = t["destino"].isin(etiquetas_exchange)
sale = t["origen"].isin(etiquetas_exchange)
return int(t.loc[entra, "xsn"].sum() - t.loc[sale, "xsn"].sum())
print("etiquetado v1:", flujo_neto(transfer, {"ex_a"}))
print("etiquetado v2:", flujo_neto(transfer, {"ex_a", "ex_b", "w5"}))etiquetado v1: 3000
etiquetado v2: 10000Las mismas cuatro transferencias dan un flujo neto de 3.000 XSN hacia exchanges con un etiquetado y de 10.000 con otro,
que ha identificado una dirección más de un exchange (ex_b) y otra que el primero no conocía (w5). Cuando el
proveedor mejora su etiquetado, suele recalcular la historia: la serie que se descargó hace un año ya no es la de hoy.
Para un backtest es el mismo problema que las revisiones de datos macro (lección 1.5.2): hay que saber si la métrica es
la que se conocía en cada fecha o la revisada después.
Ejercicios
- Con
df, construye velas diarias (UTC) y quédate solo con los días completos. ¿Cuántas quedan y por qué no son 9?
Solución
g = df.resample("1D")
diarias = g.agg(reglas)
diarias["horas"] = g["cierre"].count()
print(diarias["horas"].tolist())
diarias = diarias[diarias["horas"] == 24]
print(len(diarias), "días completos")[9, 24, 24, 24, 24, 24, 24, 24, 23]
7 días completosLas 200 velas abarcan del 23 de diciembre a las 15:00 al 31 de diciembre a las 22:00: nueve fechas, pero el primer día solo tiene 9 horas y el último 23 (falta la vela de las 23:00). Quedan 7 días completos. Un «día» cripto en UTC no es el día de Madrid ni el de Nueva York; si el sistema razona en otra zona, hay que re-muestrear en esa zona (lección 1.4.2).
- Cambia
ExchangeSimulado.max_velasa 50 y vuelve a descargar. ¿Cuántas llamadas hacen falta? ¿Qué pasaría sidescargaravanzarasinceen1000 × 1 hen lugar de desde la última vela?
Solución
ExchangeSimulado.max_velas = 50
ex = ExchangeSimulado(velas)
bajadas = descargar(ex, "XSN/USDT", since=velas[0][0])
print(len(bajadas), "velas en", ex.llamadas, "llamadas")
def descargar_mal(ex, since, limit=1000, paso_ms=3_600_000):
todas = []
while lote := ex.fetch_ohlcv("XSN/USDT", "1h", since, limit):
todas += lote
since += limit * paso_ms
return todas
print("avanzando por limit:", len(descargar_mal(ex, velas[0][0])))
ExchangeSimulado.max_velas = 60200 velas en 5 llamadas
avanzando por limit: 50Con páginas de 50 velas hacen falta cinco llamadas (cuatro con datos y una vacía). Avanzando since en 1.000 horas,
la segunda llamada ya pide velas posteriores a la última del archivo: solo se descargan las 50 primeras y el resto se
pierde sin ningún error. Es el fallo más peligroso de la paginación, porque el resultado parece correcto.
- Vas a construir un sistema que opera el perpetuo de XSN en un exchange. Di de qué capa sacarías el precio de las señales, el funding y el universo de tokens, y qué comprobarías de cada fuente.
Solución
Precio de las señales y funding: del propio exchange donde se opera (velas y tasas de funding con ccxt), porque es el precio ejecutable y el funding que se paga o se cobra (lección 1.2.6). Comprobaciones: intervalos y vela abierta, huecos frente a la rejilla, y la hora de corte del funding en UTC. El índice compuesto del exchange, si lo publica, para entender liquidaciones. Universo: de un agregador (qué tokens existen y su capitalización), comprobando que cada token del universo tiene mercado en el exchange y desde cuándo, para no meter en el pasado tokens que todavía no cotizaban allí (sesgo de supervivencia, lección 1.4.4). On-chain, solo si se va a investigar una métrica concreta y sabiendo cómo etiqueta el proveedor.
Footnotes
-
Documentación de ccxt, Manual: secciones «OHLCV Candlestick Charts» y «Rate Limit» (docs.ccxt.com), consultada el 21/10/2026. ↩ ↩2 ↩3
-
CoinGecko API: precios, errores y límites y Coin OHLC Chart by ID, consultados el 21/10/2026. ↩ ↩2
-
CoinMarketCap API Pricing Plans, consultada el 21/10/2026. ↩
-
Kaiko: Pricing and Licenses y Level 1 and Level 2 Data, consultadas el 21/10/2026. ↩
-
Glassnode: documentación y precios, consultadas el 21/10/2026. ↩
Respuesta plegada en cada pregunta
Autoevaluación
fetch_ohlcvdevuelve[1766502000000, 47.1217, 47.298, 46.9181, 46.9485, 115011.657]. ¿Qué es el primer número?- AUn identificador de vela
- BLa marca de tiempo de apertura de la vela en milisegundos desde 1970 (UTC)
- CLa marca de tiempo en segundos
- DEl volumen en USD
Ver respuesta
Respuesta B. La marca de tiempo de apertura de la vela en milisegundos desde 1970 (UTC)
ccxt usa milisegundos UTC en todas sus marcas de tiempo.
pd.to_datetime(…, unit="ms", utc=True)lo convierte; conunit="s"saldrían fechas absurdas.Descargas las velas de 1 hora a las 22:30 UTC. ¿Qué pasa con la vela de las 22:00?
- AEs una vela completa como las demás
- BPuede estar todavía abierta: su cierre, máximo, mínimo y volumen cambiarán hasta las 23:00
- CEl exchange nunca la devuelve
- DEs la vela de las 21:00 con otro nombre
Ver respuesta
Respuesta B. Puede estar todavía abierta: su cierre, máximo, mínimo y volumen cambiarán hasta las 23:00
Muchos exchanges devuelven la vela en curso. Si se guarda como definitiva, el histórico tendrá una vela distinta de la que verá cualquier otro que la descargue más tarde. Hay que descartar las velas cuyo final es posterior al momento de la descarga.
¿Por qué el precio de XSN en un exchange no coincide exactamente con su índice compuesto?
- APorque uno de los dos está mal
- BPorque cada exchange tiene su propio libro y sus propios participantes; el índice combina varios exchanges y por eso lo usan el funding y las liquidaciones
- CPorque el índice va con un día de retraso
- DPorque el exchange cobra comisiones dentro del precio
Ver respuesta
Respuesta B. Porque cada exchange tiene su propio libro y sus propios participantes; el índice combina varios exchanges y por eso lo usan el funding y las liquidaciones
No hay un precio único de un criptoactivo: hay un precio por exchange. En los datos del curso, el spot de un exchange se separa del índice unos 4 puntos básicos de desviación típica.
Un agregador dice que han entrado 10.000 XSN en exchanges hoy. ¿De qué depende esa cifra?
- ASolo de la cadena de bloques, que es pública y exacta
- BDe qué direcciones ha etiquetado el proveedor como de exchanges: la cadena dice qué direcciones movieron qué, no de quién son
- CDel precio del día
- DDe la comisión de la red
Ver respuesta
Respuesta B. De qué direcciones ha etiquetado el proveedor como de exchanges: la cadena dice qué direcciones movieron qué, no de quién son
Las transacciones son públicas, pero los dueños de las direcciones no. Cada proveedor de datos on-chain mantiene su propio etiquetado; si cambia o se amplía, la serie histórica cambia con él.
Un exchange declara
rateLimit = 100en ccxt. ¿Qué significa?- A100 peticiones por segundo
- BUn mínimo de 100 milisegundos entre peticiones, que ccxt respeta si el limitador está activado
- C100 velas por petición
- D100 peticiones al día
Ver respuesta
Respuesta B. Un mínimo de 100 milisegundos entre peticiones, que ccxt respeta si el limitador está activado
En ccxt,
rateLimites el intervalo mínimo en milisegundos entre peticiones. ConenableRateLimitactivado (el valor por defecto), la propia librería espera lo necesario.
Ideas clave
- Los datos cripto vienen de tres capas: exchanges (el precio y el volumen de cada sitio), agregadores (un precio combinado de muchos) y la cadena (transferencias, direcciones, comisiones).
- ccxt unifica las APIs de los exchanges:
fetch_ohlcvdevuelve listas[ms UTC, apertura, máximo, mínimo, cierre, volumen]. - Una descarga seria comprueba los intervalos, la coherencia OHLC y descarta la vela abierta antes de guardar.
- Las descargas largas se paginan con
sinceylimit, y el ritmo lo marca el límite de peticiones de cada exchange. - No hay un precio único: cada exchange tiene el suyo. Para comparar o para el funding, se usa un índice compuesto.
- Las métricas on-chain dependen del etiquetado de direcciones del proveedor: hay que saber cuál es y si se revisa hacia atrás.