Saltar al contenido principal

Snapshot API

La Snapshot API renderiza gráficos de analítica on-chain como imágenes PNG o gráficos vectoriales SVG. Envíe los IDs de las métricas y parámetros de visualización opcionales, y reciba una imagen de gráfico completamente renderizada lista para incrustar en informes, dashboards o conversaciones con IA. Actualmente admite métricas de Bitcoin, con una cobertura multi-cadena (ETH, TON, TRON) en expansión.

Endpoints

MétodoRutaDescripción
GET/v1/chart/snapshotGráficos simples mediante parámetros de consulta
POST/v1/chart/snapshotPersonalización completa mediante cuerpo JSON

Ambos endpoints devuelven image/png de forma predeterminada. Cambie a SVG (image/svg+xml) o metadatos JSON (application/json) configurando la cabecera de solicitud Accept, o —en POST— el campo format del cuerpo ("png", "svg", "json").

Las respuestas correctas en PNG y SVG incluyen una cabecera X-Render-Id para que el gráfico renderizado pueda volver a obtenerse por URL durante 1 hora:

SalidaCacheado en
PNGhttps://api.blocklens.co/v1/chart/renders/{X-Render-Id}.png
SVGhttps://api.blocklens.co/v1/chart/renders/{X-Render-Id}.svg

Autenticación

Todas las solicitudes requieren una clave API mediante la cabecera Authorization:

Authorization: Bearer YOUR_API_KEY

Consulte Autenticación para más detalles sobre cómo obtener claves API.

Acceso y límites de tasa

La Snapshot API requiere el nivel Pro o Enterprise. Las claves de los niveles Demo y Free reciben 403 Forbidden.

La Snapshot API sigue los mismos límites de tasa que la Data API. Consulte Límites de tasa para más detalles.

Cuando se aplica el límite de tasa, la API devuelve 429 Too Many Requests con un campo retry_after.

El acceso a las métricas también está restringido por grado: las métricas de grado 0 (precio, oferta, MVRV) están disponibles para todas las claves Pro+, las métricas de grado 1 (SOPR, P&L) requieren Pro, y las métricas de grado 2 (mapas de calor CBD) requieren Enterprise.


GET /v1/chart/snapshot

Genera un gráfico a partir de parámetros de consulta. Ideal para gráficos simples, de métrica única o basados en plantillas.

Parámetros

ParámetroTipoPredeterminadoDescripción
metricstring-ID de una sola métrica (p. ej., price, lth_supply). Mutuamente excluyente con metrics y template.
metricsstring-IDs de métricas separados por comas, máximo 6 (p. ej., lth_supply,sth_supply). Mutuamente excluyente con metric y template.
templatestring-ID de plantilla predefinida. Mutuamente excluyente con metric y metrics.
daysinteger365Días de datos históricos (7-10000).
start_datestring-Fecha de inicio (YYYY-MM-DD). Reemplaza a days.
end_datestring-Fecha de fin (YYYY-MM-DD). Por defecto, hoy.
stylestringautoEstilo del gráfico: line, area, bar. Detectado automáticamente del registro de métricas si se omite.
scalestringlinearEscala del eje Y: linear o log.
overlaystring-Añade una superposición de precio como una línea discontinua sutil en el eje derecho (use price). Actualmente, precio de BTC.
widthinteger1200Ancho de la imagen en píxeles (600-2400).
heightinteger600Alto de la imagen en píxeles (300-1200).
titlestringautoTítulo del gráfico. Generado automáticamente a partir de los nombres de las métricas si se omite.
themestringlightTema de color: light o dark.

Debe proporcionarse exactamente uno de metric, metrics o template.

Plantillas disponibles

PlantillaMétricas
pricePrecio de BTC
price_volumePrecio + Volumen
market_capMarket Cap
holder_supplyOferta LTH + Oferta STH
mvrv_ratioLTH MVRV + STH MVRV
realized_priceRealized Price LTH + Realized Price STH
realized_capRealized Cap LTH + Realized Cap STH
unrealized_plP/L no realizado LTH + P/L no realizado STH
realized_plP/L realizado LTH + P/L realizado STH
soprLTH SOPR + STH SOPR
block_heightAltura de bloque

Ejemplos

# Bitcoin example: BTC price, 1 year, line chart
curl -H "Authorization: Bearer YOUR_KEY" \
"https://api.blocklens.co/v1/chart/snapshot?metric=price" \
--output price.png

# Bitcoin example: two metrics with area style
curl -H "Authorization: Bearer YOUR_KEY" \
"https://api.blocklens.co/v1/chart/snapshot?metrics=lth_supply,sth_supply&style=area&days=730" \
--output supply.png

# Template with dark theme
curl -H "Authorization: Bearer YOUR_KEY" \
"https://api.blocklens.co/v1/chart/snapshot?template=mvrv_ratio&theme=dark" \
--output mvrv_dark.png

# Log scale with price overlay
curl -H "Authorization: Bearer YOUR_KEY" \
"https://api.blocklens.co/v1/chart/snapshot?metric=lth_supply&scale=log&overlay=price&days=1095" \
--output supply_with_price.png

# Get JSON metadata instead of image
curl -H "Authorization: Bearer YOUR_KEY" \
-H "Accept: application/json" \
"https://api.blocklens.co/v1/chart/snapshot?metric=price" | jq

# Get SVG instead of PNG
curl -H "Authorization: Bearer YOUR_KEY" \
-H "Accept: image/svg+xml" \
"https://api.blocklens.co/v1/chart/snapshot?metric=price" \
--output price.svg

Respuesta correcta

PNG (predeterminado):

HTTP/1.1 200 OK
Content-Type: image/png
Cache-Control: public, max-age=3600
X-Snapshot-Cache: HIT
X-Snapshot-Render-Ms: 0
X-Render-Id: 0a1b2c3d4e5f6789

<binary PNG data>

SVG (con Accept: image/svg+xml):

HTTP/1.1 200 OK
Content-Type: image/svg+xml
Cache-Control: public, max-age=3600
X-Snapshot-Cache: MISS
X-Snapshot-Render-Ms: 412
X-Render-Id: 0a1b2c3d4e5f6789
Content-Disposition: attachment; filename="chart.svg"

<svg xmlns="http://www.w3.org/2000/svg" ...>...</svg>

El valor de X-Render-Id puede usarse para volver a obtener la misma imagen en /v1/chart/renders/{render_id}.png o /v1/chart/renders/{render_id}.svg hasta 1 hora.


POST /v1/chart/snapshot

Personalización completa del gráfico mediante cuerpo JSON. Admite estilos por métrica, ejes personalizados, fórmulas, líneas de referencia, áreas de referencia y mucho más. Diseñado para agentes de IA (mediante MCP) y usuarios avanzados.

Cuerpo de la solicitud

Proporcione exactamente una fuente de datos (metric, metrics o template):

{
"metric": "price",

"days": 365,
"start_date": "2025-01-01",
"end_date": "2026-02-23",

"title": "Custom Chart Title",
"width": 1200,
"height": 600,
"theme": "light",
"format": "png",

"style": "line",
"scale": "linear",
"overlay": "price",

"y_axes": [
{"id": "axis-left", "side": "left", "scale": "linear", "format": "number"},
{"id": "axis-right", "side": "right", "scale": "log", "format": "currency"}
],

"formulas": [
{"expression": "sma(m1, 200)", "label": "200-day SMA", "color": "#9333ea", "style": "line"}
],

"reference_lines": [
{"y": 1.0, "stroke": "#9ca3af", "stroke_dasharray": "3 3", "label": "Break-even"}
],
"reference_areas": [
{"y1": 0, "y2": 0.85, "fill": "#16a34a", "fill_opacity": 0.08, "label": "Undervalued"}
]
}

Nota: Debe proporcionarse exactamente uno de metric, metrics o template.

Campo Metrics

El campo metrics admite tipos mixtos:

// String shorthand
["price", "lth_supply"]

// Full config objects
[{"id": "price", "axis": "right", "style": "line", "color": "#374151"}]

// Mixed
["price", {"id": "lth_supply", "axis": "left", "style": "area"}]

// With params for parameterized metrics
[
{"id": "funding_binance", "params": {"exchange": "binance"}},
{"id": "price"}
]

Algunas métricas requieren parámetros adicionales (p. ej., exchange, ticker, id). Incluya el objeto params de la definición de la métrica al usar estas métricas.

Opciones por métrica

CampoTipoDescripción
idstringObligatorio. ID de la métrica del registro.
paramsobjectParámetros para métricas parametrizadas (p. ej., {"exchange": "binance"}). Consulte la definición de la métrica para los parámetros requeridos.
axisleft / rightLado del eje Y. Asignado automáticamente si se omite.
y_axis_idstringVincular a un eje Y específico por ID (p. ej. axis-diff). Reemplaza a axis.
styleline / area / barEstilo del gráfico. Valor por defecto del registro si se omite.
colorstringColor hexadecimal (p. ej., #2563eb). Asignado automáticamente si se omite.
labelstringEtiqueta de visualización. Usa el nombre de la métrica si se omite.
stroke_widthintegerAncho de línea (0-5). Predeterminado: 2. Use 0 para barras sin bordes.
fill_opacityfloatOpacidad de relleno (0.0-1.0). Para barras transparentes, use valores bajos como 0.2.
stroke_dashstringPatrón de guiones (p. ej., 5 5).
stack_groupstringID de grupo de apilamiento para gráficos apilados.
show_in_legendbooleanSi se muestra en la leyenda del gráfico. Predeterminado: true.
visiblebooleanMostrar/ocultar. Predeterminado: true.

Ejes Y personalizados

El campo y_axes define los ejes Y disponibles para métricas y fórmulas. Cada eje tiene un id único que puede referenciarse mediante y_axis_id en métricas o fórmulas. Puede definir más de dos ejes —por ejemplo, un eje separado para diferencias calculadas:

"y_axes": [
{"id": "axis-left", "side": "left", "scale": "linear", "format": "number"},
{"id": "axis-right", "side": "right", "scale": "log", "format": "currency"},
{"id": "axis-diff", "side": "left", "scale": "linear", "format": "number"}
]
CampoTipoDescripción
idstringIdentificador único del eje. Referenciado por y_axis_id en métricas/fórmulas.
sideleft / rightEn qué lado del gráfico aparece el eje.
scalelinear / logEscala del eje. Predeterminado: linear.
formatnumber / currency / percentFormato numérico para las etiquetas del eje.
range[number, number]Zona vertical como [from%, to%]. 0 = abajo, 100 = arriba. Predeterminado: altura completa. Úselo para apilar ejes verticalmente (p. ej. volumen en el 20% inferior, precio en el 80% superior).
domain_minnumberLímite inferior fijo del dominio. El eje nunca bajará por debajo de este valor.
domain_maxnumberLímite superior fijo del dominio. El eje nunca subirá por encima de este valor.
no_padding"top" / "bottom" / "both"Elimina el relleno automático del 10% en los bordes. Útil cuando un límite de dominio es una frontera fija (p. ej. drawdown limitado a 0).

Si se omite y_axes, los ejes se generan automáticamente según los valores de axis de las métricas.

Ejemplo: Precio + Volumen con zonas verticales

Apile las barras de volumen en el 20% inferior y el precio en el espacio restante:

curl -X POST "https://api.blocklens.co/v1/chart/snapshot" \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"metrics": [
{"id": "price", "style": "line", "color": "#374151", "y_axis_id": "axis-price"},
{"id": "volume", "style": "bar", "color": "#3b82f6", "fill_opacity": 0.3, "stroke_width": 0, "y_axis_id": "axis-vol"}
],
"y_axes": [
{"id": "axis-price", "side": "right", "scale": "log", "format": "currency", "range": [20, 100]},
{"id": "axis-vol", "side": "left", "format": "number", "range": [0, 20], "no_padding": "bottom"}
],
"days": 365,
"title": "BTC Price + Volume (Zoned)"
}' --output price_volume_zones.png

Lo que esto produce:

  • Las barras de volumen llenan el 20% inferior del gráfico (range: [0, 20]) sin relleno en el borde inferior
  • El precio ocupa el 80% superior (range: [20, 100]) en una escala logarítmica
  • Las dos series nunca se superponen, creando un diseño apilado limpio

Ejemplo: Drawdown con límite de dominio

Limite el drawdown a 0 (borde superior) para que la línea toque la parte superior de su zona:

curl -X POST "https://api.blocklens.co/v1/chart/snapshot" \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"metrics": ["price"],
"formulas": [
{"expression": "drawdown(price)", "label": "Drawdown from ATH", "style": "area", "color": "#dc2626", "fill_opacity": 0.15, "y_axis_id": "axis-dd"}
],
"y_axes": [
{"id": "axis-right", "side": "right", "scale": "log", "format": "currency"},
{"id": "axis-dd", "side": "left", "format": "percent", "domain_max": 0, "no_padding": "top"}
],
"days": 1825,
"title": "BTC Price + Drawdown from ATH"
}' --output drawdown.png

Lo que esto produce:

  • El drawdown siempre es ≤ 0, por lo que domain_max: 0 fija el borde superior
  • no_padding: "top" elimina el relleno automático del 10% por encima de 0, haciendo que la línea toque la parte superior cuando el drawdown es del 0%
  • El precio está en el eje derecho con escala logarítmica

Fórmulas

El campo formulas le permite definir series calculadas derivadas de sus métricas. Las fórmulas pueden referenciar métricas por su id (p. ej. lth_supply) o por índice posicional (m1, m2, etc., según el orden en el array metrics).

"formulas": [
{
"expression": "lth_supply - shift(lth_supply, 30)",
"label": "LTH 30d Change",
"color": "#16a34a",
"style": "bar",
"y_axis_id": "axis-diff",
"fill_opacity": 0.2,
"stroke_width": 0
}
]

Funciones admitidas (30 en total):

Medias móviles y estadísticas móviles

FunciónSintaxisDescripción
smasma(series, period)Media móvil simple
emaema(series, period)Media móvil exponencial
medianmedian(series, period)Mediana móvil
sumsum(series, period)Suma móvil
stdstd(series, period)Desviación estándar móvil

Acumuladas

FunciónSintaxisDescripción
cumsumcumsum(series)Suma acumulada expansiva
cummeancummean(series)Media acumulada expansiva
cummediancummedian(series)Mediana acumulada expansiva
cumstdcumstd(series)Desviación estándar acumulada expansiva
cummaxcummax(series)Máximo acumulado histórico
cummincummin(series)Mínimo acumulado histórico

Cambios

FunciónSintaxisDescripción
percent_changepercent_change(series, period)Cambio porcentual (decimal: 0.20 = +20%)
diffdiff(series, period)Cambio en valor absoluto

Matemáticas

FunciónSintaxisDescripción
absabs(series)Valor absoluto
powpow(series, n)Elevar a la potencia n
loglog(series)Logaritmo en base 10
roundround(series, digits)Redondear a N decimales
maxmax(a, b, ...)Máximo puntual
minmin(a, b, ...)Mínimo puntual

Indicadores técnicos

FunciónSintaxisDescripción
rsirsi(series, period)Índice de fuerza relativa (0-100)
corrcorr(s1, s2, period)Correlación de Pearson (-1 a 1)
drawdowndrawdown(series)Drawdown desde el ATH (decimal negativo)

Riesgo y rentabilidad

FunciónSintaxisDescripción
mean_returnmean_return(series, period)Rentabilidad media móvil anualizada
realized_volrealized_vol(series, period)Volatilidad realizada anualizada
sharpe_ratio_arithmeticsharpe_ratio_arithmetic(series, period)Ratio de Sharpe (aritmético)
sharpe_ratio_geometricsharpe_ratio_geometric(series, period)Ratio de Sharpe (geométrico)

Manipulación de series

FunciónSintaxisDescripción
shiftshift(series, period)Desplazar la serie N periodos
ifif(a, "op", b, then, else)Condicional (op: =, !=, >, >=, <, <=)

Operadores

Aritméticos: +, -, *, / Agrupación: (, )

Referenciado

  • Métricas por nombre: lth_supply + sth_supply — use los IDs de las métricas directamente
  • Métricas por posición: m1 + m2 — referencias posicionales (m1 = primera métrica, m2 = segunda, etc.)
  • Otras fórmulas: f1 * 2 — referencia fórmulas anteriores (f1 = primera fórmula, etc.)
  • Las fórmulas se evalúan en orden, por lo que f2 puede referenciar a f1, pero no a la inversa.

Opciones de fórmula:

CampoTipoDescripción
expressionstringObligatorio. Expresión de la fórmula usando IDs de métricas o referencias posicionales (m1, m2).
labelstringObligatorio. Etiqueta de visualización para la leyenda.
colorstringColor hexadecimal. Asignado automáticamente si se omite.
styleline / area / barEstilo del gráfico. Predeterminado: line.
y_axis_idstringVincular a un eje Y específico por ID (p. ej. axis-diff). Reemplaza a axis.
axisleft / rightLado del eje Y. Predeterminado: left. Ignorado si se establece y_axis_id.
fill_opacityfloatOpacidad de relleno (0.0-1.0). Para barras transparentes, use valores bajos como 0.2.
stroke_widthintegerAncho de trazo (0-5). Use 0 para barras sin bordes.
stroke_dashstringPatrón de guiones (p. ej., 6 3).
stack_groupstringID de grupo de apilamiento para apilar varias series de fórmulas.

Líneas y áreas de referencia

Las líneas de referencia añaden líneas guía horizontales para resaltar valores específicos (p. ej. punto de equilibrio en 1.0, umbral de sobrecompra). Las áreas de referencia añaden zonas sombreadas para resaltar rangos de valores (p. ej. zona infravalorada, bandas tipo Bollinger). Ambas admiten valores estáticos y fórmulas dinámicas usando el mismo motor de fórmulas que el campo formulas.

Opciones de línea de referencia

CampoTipoDescripción
ynumberValor Y estático.
y_formulastringExpresión de fórmula para una Y dinámica (p. ej. "sma(m1, 200)"). Usa el mismo motor que formulas.
y_axis_idstringID del eje Y (por defecto, el primer eje izquierdo).
strokestringColor hexadecimal de la línea (predeterminado: #9ca3af).
stroke_dasharraystringPatrón de guiones, p. ej. "3 3" para discontinua.
labelstringTexto de la etiqueta.

Proporcione y (estático) o y_formula (dinámico), no ambos. Máximo 10 líneas de referencia por gráfico.

Opciones de área de referencia

CampoTipoDescripción
y1numberLímite Y inferior estático.
y2numberLímite Y superior estático.
y1_formulastringFórmula para el límite inferior dinámico.
y2_formulastringFórmula para el límite superior dinámico.
y_axis_idstringID del eje Y (por defecto, el primer eje izquierdo).
fillstringColor hexadecimal de relleno (predeterminado: #3b82f6).
fill_opacitynumberOpacidad de relleno 0–1 (predeterminado: 0.1).
labelstringTexto de la etiqueta.

Proporcione límites estáticos (y1/y2) o basados en fórmula (y1_formula/y2_formula) — puede combinarlos (p. ej. y1 estático con y2_formula dinámico). Máximo 10 áreas de referencia por gráfico.

Ejemplo: MVRV con zonas de valor

Añada una zona verde infravalorada (0–0.85), una zona roja sobrevalorada (8–100) y una línea de equilibrio discontinua en 1.0:

curl -X POST "https://api.blocklens.co/v1/chart/snapshot" \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"metric": "mvrv",
"days": 1825,
"title": "MVRV Ratio — Value Zones",
"reference_lines": [
{"y": 1.0, "stroke": "#9ca3af", "stroke_dasharray": "3 3", "label": "Break-even"}
],
"reference_areas": [
{"y1": 0, "y2": 0.85, "fill": "#16a34a", "fill_opacity": 0.08, "label": "Undervalued"},
{"y1": 8, "y2": 100, "fill": "#dc2626", "fill_opacity": 0.08, "label": "Overvalued"}
]
}' --output mvrv_zones.png

Ejemplo: Banda basada en fórmula

Cree una banda tipo Bollinger alrededor de la primera fórmula (envolvente de ±10%):

curl -X POST "https://api.blocklens.co/v1/chart/snapshot" \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"metrics": ["price"],
"days": 365,
"formulas": [
{"expression": "sma(m1, 50)", "label": "50-day SMA", "color": "#2563eb", "style": "line"}
],
"reference_areas": [
{"y1_formula": "f1 * 0.9", "y2_formula": "f1 * 1.1", "fill": "#2563eb", "fill_opacity": 0.06, "label": "±10% Band"}
],
"reference_lines": [
{"y_formula": "sma(m1, 200)", "stroke": "#9333ea", "stroke_dasharray": "6 3", "label": "200-day SMA"}
]
}' --output price_bands.png

Formato de salida

El campo format controla la salida:

FormatoContent-TypeDescripción
png (predeterminado)image/pngImagen de gráfico rasterizada
svgimage/svg+xmlGráficos vectoriales (escalables, incrustables)
jsonapplication/jsonMetadatos del gráfico (sin renderizado)

Alternativamente, use la cabecera Accept:

  • Accept: image/png - PNG (predeterminado)
  • Accept: image/svg+xml - SVG
  • Accept: application/json - Metadatos JSON

Respuesta de metadatos JSON

Cuando format=json o Accept: application/json:

{
"success": true,
"title": "BTC Price",
"metrics": [{"id": "price", "label": "BTC Price"}],
"days": 365,
"start_date": null,
"end_date": null,
"theme": "light",
"width": 1200,
"height": 600,
"formulas": [],
"data_points": 365,
"cached": false,
"render_time_ms": 0
}

Ejemplos

# POST with single metric
curl -X POST "https://api.blocklens.co/v1/chart/snapshot" \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"metric": "price", "days": 365}' \
--output price.png

# Multi-metric with custom styling
curl -X POST "https://api.blocklens.co/v1/chart/snapshot" \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"metrics": [
{"id": "price", "axis": "right", "style": "line", "color": "#374151"},
{"id": "lth_supply", "axis": "left", "style": "area", "color": "#2563eb"}
],
"days": 730,
"title": "BTC Price vs LTH Supply",
"theme": "dark"
}' \
--output chart.png

# SVG output
curl -X POST "https://api.blocklens.co/v1/chart/snapshot" \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"template": "mvrv_ratio", "format": "svg"}' \
--output mvrv.svg

# JSON metadata
curl -X POST "https://api.blocklens.co/v1/chart/snapshot" \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"metric": "price", "format": "json"}' | jq

Renderizado de mapas de calor

La Snapshot API puede renderizar mapas de calor para métricas basadas en distribución como la Distribución del Coste Base (Cost Basis Distribution). Los mapas de calor usan un conjunto de parámetros distinto al de los gráficos de métricas estándar.

Parámetros del mapa de calor

ParámetroTipoPredeterminadoDescripción
heatmap_idstring-Identificador del mapa de calor (p. ej., cost-basis-distribution)
heatmap_periodstring1yPeriodo de tiempo: 3m, 6m, 1y, 2y, 3y, 5y, all
heatmap_color_scalestringviridisEscala de color: viridis, plasma, inferno, magma, cividis
heatmap_y_scalestringlinearEscala del eje Y: linear o log
themestringlightTema de color: light o dark
titlestringautoTítulo del gráfico
widthinteger1200Ancho de la imagen en píxeles
heightinteger600Alto de la imagen en píxeles

Ejemplo

curl -X POST "https://api.blocklens.co/v1/chart/snapshot" \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"heatmap_id": "cost-basis-distribution",
"heatmap_period": "1y",
"heatmap_color_scale": "viridis",
"heatmap_y_scale": "log",
"theme": "dark",
"title": "Cost Basis Distribution"
}' --output cbd_heatmap.png

Nota: Los parámetros del mapa de calor (heatmap_id, etc.) son mutuamente excluyentes con los parámetros de métrica estándar (metric, metrics, template). Las métricas de mapa de calor requieren el nivel Enterprise.

La leyenda de la escala de color se incluye en la imagen renderizada, mostrando el rango de valores asignado a la paleta de colores seleccionada.


Gráficos de superposición de rendimiento de ciclos

Los gráficos de rendimiento de ciclos superponen varios ciclos de Bitcoin en el mismo eje X para que pueda compararlos en igualdad de condiciones. En lugar de representarse frente a fechas de calendario, el precio de cada ciclo se indexa a su propio evento ancla (mínimo del ciclo, ATH o halving) y se representa frente a los días transcurridos desde ese ancla.

Active el modo de superposición estableciendo x_axis: "day_offset" en una solicitud POST /v1/chart/snapshot y proporcionando métricas de ciclo en el array metrics. El renderizador usa el campo day_offset de cada punto de datos en lugar de date, de modo que todos los ciclos comienzan en el Día 0 del eje X.

Las etiquetas de las marcas muestran fechas de calendario del ciclo más reciente de la familia elegida. Por ejemplo, una superposición de ATH (cycle_ath_1cycle_ath_5) se ancla en 2025-10-06 y las marcas indican Oct '25, Jan '26, Apr '26, etc. — no Day 0, Day 90, Day 180. Otros ciclos del mismo gráfico se alinean en las mismas posiciones del eje X, de modo que un valor en la marca Apr '26 de cycle_ath_3 significa "qué hacía BTC 182 días después del inicio del ciclo de 2017". La numeración por días vuelve a aparecer como alternativa únicamente si el backend no puede determinar el ancla.

Tipos de ancla

Hay disponibles tres familias de métricas de ciclo, una por cada evento ancla:

AnclaPrefijo del ID de métricaDescripciónPista del endpoint
Mínimo del ciclo → siguiente mínimocycle_low_*Precio indexado al fondo del ciclo — cada serie comienza en 1.0 en la fecha del mínimo y se extiende hasta el mínimo del siguiente ciclo.endpoint: "cycle-performance?type=low"
ATH → ATHcycle_ath_*Precio indexado al máximo histórico del ciclo — cada serie comienza en 1.0 en la fecha del ATH y se extiende hasta el siguiente ATH.endpoint: "cycle-performance?type=ath"
Halving → halvingcycle_halving_*Precio indexado al bloque del halving — cada serie comienza en 1.0 en la fecha del halving y se extiende hasta el siguiente halving.endpoint: "cycle-performance?type=halving"

Dentro de una familia de ancla, cada ciclo tiene la misma forma de datos — un índice que comienza en 1.0 y rastrea price(t) / price(anchor) hasta el siguiente evento ancla (o, para el ciclo actual, hasta hoy). Eso es lo que hace que la comparación por superposición sea significativa: un valor de 5.0 en el día 200 de cycle_ath_3 significa "BTC valía 5× su ATH de 2017 a los 200 días de ese ATH".

Todas las métricas de ciclo disponibles

ID de métricaFecha anclaAncla → fecha de fin
cycle_low_12011-11-182011-11-18 → 2015-01-14
cycle_low_22015-01-142015-01-14 → 2018-12-15
cycle_low_32018-12-152018-12-15 → 2022-11-21
cycle_low_42022-11-212022-11-21 → hoy (ciclo actual)
cycle_ath_12011-06-112011-06-11 → 2013-11-30
cycle_ath_22013-11-302013-11-30 → 2017-12-17
cycle_ath_32017-12-172017-12-17 → 2021-11-10
cycle_ath_42021-11-102021-11-10 → 2025-10-06
cycle_ath_52025-10-062025-10-06 → hoy (ciclo actual)
cycle_halving_12012-11-282012-11-28 → 2016-07-09
cycle_halving_22016-07-092016-07-09 → 2020-05-11
cycle_halving_32020-05-112020-05-11 → 2024-04-20
cycle_halving_42024-04-202024-04-20 → hoy (ciclo actual)
Reglas de validación
  • Todas las metrics deben provenir de la misma familia de ancla. Mezclar cycle_ath_* con cycle_low_* (o cualquier cosa fuera de daily_cycle_performance) devuelve 400 invalid_params.
  • El indicador x_axis: "day_offset" solo es válido para métricas de ciclo — combinarlo con cualquier otra métrica devuelve 400 invalid_params.
  • Se aplica el límite estándar de "máximo 6 métricas por gráfico" — elija hasta 6 ciclos por superposición.

Parámetros de rendimiento de ciclos

Además de todos los parámetros estándar del gráfico (days, width, height, theme, scale, format, title, y_axes, reference_lines, reference_areas, formulas, etc.), el modo de superposición de ciclos usa estos campos:

CampoTipoPredeterminadoDescripción
x_axis"date" / "day_offset""date"Establézcalo en "day_offset" para activar la superposición de ciclos. De lo contrario, el eje X es de fecha de calendario.
metricsarrayobligatorio1–6 IDs de métricas de ciclo de la misma familia de ancla. Strings u objetos ({id, color, style, label, stroke_width, fill_opacity, show_in_legend, y_axis_id}).
daysinteger365Limita el desplazamiento de día máximo renderizado (rango del eje X, no días de calendario). Establézcalo en 1500 para ver ~4 años por ciclo.
scale"linear" / "log""linear"La escala logarítmica es casi siempre lo que querrá — los multiplicadores de los primeros ciclos pueden ser de 100×–500×, lo cual resulta ilegible en escala lineal.
theme"light" / "dark""light"El tema oscuro es el predeterminado del dashboard para estos gráficos.

Las líneas de referencia (reference_lines) son especialmente útiles en los gráficos de superposición — p. ej. una línea horizontal en y: 1.0 marca el nivel del ancla, y: 2.0 marca "2× el ancla", y así sucesivamente.

Ejemplo: Superposición anclada en ATH (colores personalizados por ciclo)

Esta receta reproduce el gráfico "Price Performance Since ATH" del dashboard — cinco ciclos, cada uno en un color distinto, en un eje logarítmico.

curl -X POST "https://api.blocklens.co/v1/chart/snapshot" \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"metrics": [
{"id": "cycle_ath_1", "color": "#8b5cf6", "label": "2011 ATH cycle"},
{"id": "cycle_ath_2", "color": "#3b82f6", "label": "2013 ATH cycle"},
{"id": "cycle_ath_3", "color": "#22c55e", "label": "2017 ATH cycle"},
{"id": "cycle_ath_4", "color": "#f59e0b", "label": "2021 ATH cycle"},
{"id": "cycle_ath_5", "color": "#ef4444", "label": "2025 ATH cycle (current)"}
],
"x_axis": "day_offset",
"scale": "log",
"y_axes": [
{"id": "left", "side": "left", "scale": "log", "format": "number"}
],
"reference_lines": [
{"y": 1.0, "stroke": "#9ca3af", "stroke_dasharray": "3 3", "label": "ATH = 1.0"}
],
"days": 1500,
"theme": "dark",
"title": "Price Performance Since ATH"
}' --output cycle_ath.png

Ejemplo: Superposición de mínimo de ciclo (forma abreviada)

Para una comparación rápida sin estilos por ciclo, pase los IDs de métrica como strings simples — los colores provienen automáticamente de la paleta del registro.

curl -X POST "https://api.blocklens.co/v1/chart/snapshot" \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"metrics": ["cycle_low_1", "cycle_low_2", "cycle_low_3", "cycle_low_4"],
"x_axis": "day_offset",
"scale": "log",
"days": 1500,
"title": "Price Since Cycle Low"
}' --output cycle_low.png

Ejemplo: Superposición anclada en halving

Misma forma, cuatro ciclos anclados en cada evento de halving.

curl -X POST "https://api.blocklens.co/v1/chart/snapshot" \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"metrics": [
"cycle_halving_1", "cycle_halving_2", "cycle_halving_3", "cycle_halving_4"
],
"x_axis": "day_offset",
"scale": "log",
"days": 1500,
"theme": "dark",
"title": "Price Since Halving"
}' --output cycle_halving.png

Equivalente con herramienta MCP

Desde un agente de IA conectado al servidor MCP, el mismo gráfico es una sola llamada a herramienta:

render_chart({
metrics: [
{ id: "cycle_ath_1", color: "#8b5cf6" },
{ id: "cycle_ath_2", color: "#3b82f6" },
{ id: "cycle_ath_3", color: "#22c55e" },
{ id: "cycle_ath_4", color: "#f59e0b" },
{ id: "cycle_ath_5", color: "#ef4444" }
],
x_axis: "day_offset",
scale: "log",
days: 1500,
theme: "dark",
title: "Price Performance Since ATH"
})

El servidor MCP acepta el mismo enum x_axis, los mismos IDs de métricas y las mismas reglas de validación que la API HTTP.


Control de leyenda por métrica

Use show_in_legend en los objetos de configuración de métricas individuales para controlar si una métrica aparece en la leyenda del gráfico. Esto es útil al combinar muchas series donde algunas son líneas de contexto/fondo.

{
"metrics": [
{"id": "price", "show_in_legend": true},
{"id": "sma_200", "show_in_legend": false}
]
}
CampoTipoPredeterminadoDescripción
show_in_legendbooleantrueSi la métrica aparece en la leyenda del gráfico

Valores predeterminados inteligentes

La Snapshot API usa valores predeterminados inteligentes para que pueda obtener gráficos con buen aspecto con una configuración mínima:

ParámetroCómo se determina el valor predeterminado
Estilo del gráficoDel registro de métricas (chart_types[0])
ColorDel registro de métricas, luego rotación de paleta
Lado del eje YPrimera métrica a la izquierda; las métricas del mismo formato comparten eje; el formato distinto a la derecha
Escala del eje Ylinear (anular con scale=log)
Rango temporalSegún categoría: 365 días para precio/valoración/beneficio, 730 para oferta, 180 para blockchain
TítuloMétrica única: nombre de la métrica. Múltiples: "Nombre1 vs Nombre2"
Tamaño de imagen1200 x 600 píxeles
Temalight

Respuestas de error

Todos los errores devuelven JSON:

// 400 Bad Request
{"success": false, "error": "invalid_params", "message": "Exactly one of 'metric', 'metrics', or 'template' must be provided"}

// 401 Unauthorized
{"success": false, "error": "unauthorized", "message": "API key required"}

// 403 Forbidden
{"success": false, "error": "insufficient_tier", "message": "Metric 'lth_sopr' requires Pro tier", "upgrade_url": "https://blocklens.co/pricing"}

// 429 Rate Limited
{"success": false, "error": "rate_limited", "message": "Snapshot rate limit exceeded. Max 60 per hour for pro tier.", "retry_after": 120}

// 504 Timeout
{"success": false, "error": "render_timeout", "message": "Chart rendering timed out after 20.0s. Try a shorter date range."}

Herramienta MCP: render_chart

El servidor MCP de Blocklens incluye una herramienta render_chart que permite a los agentes de IA generar imágenes de gráficos directamente en las conversaciones. La herramienta llama a la Snapshot API y devuelve la imagen en línea como PNG (ráster) o SVG (vectorial).

Parámetros

ParámetroTipoPredeterminadoDescripción
metricstring-ID de una sola métrica
metricsarray-Varias métricas (strings u objetos)
templatestring-ID de plantilla
daysinteger365Días de historial
start_datestring-Fecha de inicio (YYYY-MM-DD)
end_datestring-Fecha de fin (YYYY-MM-DD)
overlayprice-Añade superposición de precio (actualmente BTC)
themelight / darklightTema de color
widthinteger1200Ancho de la imagen
heightinteger600Alto de la imagen
titlestringautoTítulo del gráfico
styleline / area / barautoEstilo del gráfico
scalelinear / loglinearEscala del eje Y
formatpng / svg / jsonpngFormato de salida: png (imagen ráster), svg (imagen vectorial, escala sin pérdida de calidad) o json (solo metadatos — sin renderizado)
y_axesarray-Ejes Y personalizados con zonas (consulte Ejes Y personalizados)
x_axisdate / day_offsetdateModo del eje X. Use day_offset para superposiciones de rendimiento de ciclos — todas las metrics deben pertenecer a la misma familia de ciclo.
heatmap_idcost-basis-distribution-Renderiza un mapa de calor en lugar de un gráfico de líneas (consulte Renderizado de mapas de calor). Mutuamente excluyente con metric / metrics / template.
heatmap_period3m / 6m / 1y / 2y / 3y / 5y / all1yVentana de agrupación del mapa de calor.
heatmap_color_scaleviridis / plasma / inferno / magma / cividisviridisPaleta de colores del mapa de calor.
heatmap_y_scalelinear / loglinearEscala del eje Y de los intervalos de precio del mapa de calor.
paramsobject-Parámetros por llamada para métricas parametrizadas (p. ej. { "exchange": "binance" }, { "ticker": "IBIT" }, { "entity": "tesla" }).
reference_linesarray-Líneas de referencia horizontales (consulte Líneas y áreas de referencia)
reference_areasarray-Zonas de referencia sombreadas (consulte Líneas y áreas de referencia)

Ejemplos de uso

User: "Show me the MVRV ratio for the last 2 years"
Agent calls: render_chart({ template: "mvrv_ratio", days: 730 })
-> Returns PNG image inline

User: "Chart BTC price vs LTH supply"
Agent calls: render_chart({
metrics: [
{ id: "price", axis: "right" },
{ id: "lth_supply", axis: "left", style: "area" }
],
days: 365
})
-> Returns PNG image inline

User: "Is there capitulation? Show SOPR"
Agent calls: render_chart({ template: "sopr", days: 180, overlay: "price" })
-> Returns PNG image inline

User: "Render the MVRV chart as SVG so I can embed it in a slide deck"
Agent calls: render_chart({ template: "mvrv_ratio", format: "svg" })
-> Returns the chart inline as image/svg+xml and a /chart/renders/{id}.svg URL

Configuración de MCP

Añada esto a su configuración de Claude Desktop o Cursor para habilitar el renderizado de gráficos:

{
"mcpServers": {
"blocklens": {
"command": "npx",
"args": ["-y", "blocklens-mcp-server"],
"env": {
"BLOCKLENS_API_KEY": "your_api_key_here"
}
}
}
}

Consulte Servidor MCP para las instrucciones de configuración completas.


Ejemplo avanzado: gráfico de oferta de LTH

Este ejemplo reproduce el gráfico completo de Oferta de Holders a Largo Plazo (Long-Term Holder Supply) del dashboard de Blocklens — dos métricas, dos series de fórmula calculadas y tres ejes Y:

curl -X POST "https://api.blocklens.co/v1/chart/snapshot" \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"metrics": [
{"id": "price", "label": "BTC Price", "style": "line", "color": "#6b7280", "axis": "right", "fill_opacity": 0, "stroke_width": 1},
{"id": "lth_supply", "label": "LTH Supply", "style": "line", "color": "#2563eb", "axis": "left", "stroke_width": 2}
],
"y_axes": [
{"id": "axis-left", "side": "left", "scale": "linear"},
{"id": "axis-right", "side": "right", "scale": "log"},
{"id": "axis-diff", "side": "left", "scale": "linear"}
],
"formulas": [
{"expression": "max(lth_supply - shift(lth_supply, 30), 0)", "label": "LTH 30d+ diff", "color": "#16a34a", "style": "bar", "y_axis_id": "axis-diff", "fill_opacity": 0.2, "stroke_width": 0},
{"expression": "min(0, lth_supply - shift(lth_supply, 30))", "label": "LTH 30d- diff", "color": "#dc2626", "style": "bar", "y_axis_id": "axis-diff", "fill_opacity": 0.2, "stroke_width": 0}
],
"days": 730,
"title": "Long-Term Holder Supply"
}' --output lth_supply.png

Lo que esto produce:

  • BTC Price — línea gris en el eje derecho (escala logarítmica)
  • LTH Supply — línea azul en el eje izquierdo (lineal)
  • Acumulación positiva de 30 días — barras verdes semitransparentes en un eje axis-diff separado
  • Distribución de 30 días — barras rojas semitransparentes en el mismo eje axis-diff

Técnicas clave utilizadas:

  • shift(lth_supply, 30) calcula el valor retrospectivo de 30 días
  • max(..., 0) y min(0, ...) separan los cambios positivos y negativos en series distintas
  • y_axis_id: "axis-diff" vincula ambas barras de fórmula a un eje dedicado independiente de los ejes principales de las métricas
  • fill_opacity: 0.2 + stroke_width: 0 crea barras transparentes sutiles y sin bordes

Plantillas de gráficos

Las configuraciones completas de gráficos (incluyendo métricas, fórmulas, ejes y estilos) están disponibles como plantillas respaldadas por base de datos mediante:

GET /api/lab/templates

Estas plantillas pueden servir de referencia para construir sus propios cuerpos de solicitud POST. Cada plantilla contiene la configuración completa que produce un gráfico específico en el dashboard de Blocklens.


Marca de agua

Todas las imágenes de gráficos renderizadas incluyen una marca de agua blocklens.co y un aviso de copyright. Esto se aplica tanto al formato de salida PNG como SVG.


Caché

Los snapshots renderizados se cachean durante 1 hora en Redis. Comportamiento de la caché:

  • Las configuraciones de gráfico idénticas devuelven resultados cacheados al instante
  • La clave de caché se deriva de la configuración completa del gráfico (métricas, ejes, rango temporal, tema, tamaño) más el formato de salida — las variantes PNG y SVG del mismo gráfico se cachean de forma independiente
  • La cabecera de respuesta X-Snapshot-Cache indica HIT o MISS
  • La cabecera X-Snapshot-Render-Ms muestra el tiempo de renderizado (0 para aciertos de caché)
  • Los archivos renderizados también se persisten en disco bajo /v1/chart/renders/{render_id}.png y /v1/chart/renders/{render_id}.svg durante 1 hora, de modo que las URLs de gráfico devueltas en la cabecera X-Render-Id siguen siendo accesibles
  • Los gráficos populares se precalientan tras cada actualización diaria de datos (05:00 UTC)