σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft AcademyRutas
Ctrl K
AO
+1,2 k estudiantes
Iniciar sesiónUnirse ↗
Rutas
AO
+1,2 k estudiantes
Iniciar sesión
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Ruta de Python›Módulo 1 · Fundamentos de Python para quants›Tema 1.18·~35 minPrincipiante

Datos JSON

Posición en la rutaMódulo 1 de 11 · Tema 18 de 33
1.18 Datos JSON
—Puntuación del lab— / 100XP total—Racha—

Datos anidados como texto

JSON es el formato cotidiano de los archivos de configuración y de los datos que se envían entre programas y APIs web. Se compone de objetos {"clave": valor}, arreglos [1, 2], cadenas, números, true/false y null. Se corresponden directamente con Python: los objetos pasan a ser diccionarios, los arreglos listas, true/false pasan a True/False y null a None. A diferencia de una tabla CSV, JSON puede anidarse: una orden puede contener una lista de ejecuciones, cada una con sus propios campos.

import json

# Text to Python: loads() ("load string")
text = '{"symbol": "AAPL", "fills": [{"price": 184.25, "qty": 100}], "open": true, "note": null}'
order = json.loads(text)
print(order["fills"][0]["price"])   # 184.25
print(order["open"], order["note"]) # True None

# Python to text: dumps() ("dump string")
print(json.dumps({"symbol": "AAPL", "qty": 200}))  # {"symbol": "AAPL", "qty": 200}

Archivos: load y dump

Las versiones sin la s trabajan con archivos: json.load(file) lee y analiza un archivo abierto, y json.dump(data, file) lo escribe. Pasa indent=2 para que el archivo sea legible por personas y sort_keys=True para un orden de claves estable, lo que mantiene pequeñas las diferencias en el control de versiones. Abre siempre con with y encoding="utf-8".

import json

# Save a config, then load it back
config = {"fee": 0.001, "symbols": ["MSFT", "AAPL"], "limits": {"max_qty": 500}}
with open("config.json", "w", encoding="utf-8") as file:
    json.dump(config, file, indent=2, sort_keys=True)

with open("config.json", encoding="utf-8") as file:
    print(file.read())
    # {
    #   "fee": 0.001,
    #   "limits": {
    #     "max_qty": 500
    #   },
    #   "symbols": [
    #     "MSFT",
    #     "AAPL"
    #   ]
    # }

with open("config.json", encoding="utf-8") as file:
    print(json.load(file) == config)  # True

Lo que no sobrevive al viaje

JSON tiene pocos tipos, así que algunos valores de Python cambian por el camino. Las tuplas vuelven como listas, las claves de diccionario vuelven siempre como cadenas ({1: "a"} vuelve como {"1": "a"}), y los conjuntos, fechas y objetos personalizados no se pueden volcar (TypeError) hasta que los conviertas, por ejemplo una fecha con .isoformat() o un conjunto con sorted(...). Recuerda también que NaN e infinito no son JSON válido.

import json
from datetime import date

# Tuples become lists, int keys become strings
data = {"pair": (1, 2), 7: "seven"}
print(json.loads(json.dumps(data)))  # {'pair': [1, 2], '7': 'seven'}

# A date has to be converted by hand
today = date(2025, 1, 2)
print(json.dumps({"day": today.isoformat()}))  # {"day": "2025-01-02"}

Entrada inválida

Un texto que llega del exterior, como un mensaje de un mercado, puede no ser JSON válido en absoluto. json.loads lanza entonces json.JSONDecodeError, una clase de ValueError, y un JSON válido aún puede carecer de la clave que quieres (KeyError) o tener otra forma (TypeError). Envuelve el análisis en try/except y decide qué significa un mensaje malo para tu programa. El próximo tema cubre las excepciones por completo.

import json

# Bad input raises, so catch it where you parse
def get_price(text):
    try:
        return json.loads(text)["price"]
    except (ValueError, KeyError, TypeError):
        return None

print(get_price('{"price": 184.25}'))  # 184.25
print(get_price("not json"))           # None
print(get_price('{"symbol": "AAPL"}')) # None
Nunca construyas JSON pegando cadenasUna comilla, una barra invertida o una letra no ASCII dentro de un valor rompe un JSON hecho a mano. Construye un diccionario de Python y deja que json.dumps o json.dump produzcan el texto, y que json.loads o json.load lo lean. Lo mismo vale al combinar ajustes: copia antes de cambiar, para que una configuración no se filtre en otra.
  • json.loads(text) / json.dumps(data) trabajan con cadenas; json.load(file) / json.dump(data, file) con archivos.
  • indent=2 y sort_keys=True hacen los archivos legibles y estables.
  • La entrada inválida lanza ValueError, KeyError o TypeError: captura lo que esperas.

A continuación: excepciones y manejo de errores, para que tus programas fallen con claridad y se recuperen cuando deban.

Lab: qué se califica

  • Totalizar las órdenes de un archivo JSON con order_total25 pts
  • Guardar ajustes como JSON legible con save_config25 pts
  • Leer un mensaje de cotización con seguridad usando parse_quote25 pts
  • Superponer ajustes sobre los valores por defecto con merge_configs25 pts
Explorador · lab-18-1
▾ lab-18-1
…
bash · en el navegador
learner@quantcraft:~/lab-18-1$
Python aún no cargadoPythonLn 1, Col 1Spaces: 4UTF-8

¿Restablecer este tema?

Todo lo que hay en lab-18-1 vuelve a los archivos iniciales y se limpia el terminal. Tu solución actual se perderá: no se puede deshacer.

Se restablecerá
  • main.py → código inicial
  • Historial del terminal y salida de pruebas
  • Cambios sin enviar
Se conservará
  • Mejor puntuación del lab
  • Tu XP y tu racha
  • Progreso de la lección y notas

Inicia sesión para ejecutar tu código.

Todas las clases se pueden leer gratis. Crea una cuenta o inicia sesión para ejecutar código, lanzar las pruebas y enviar este lab.

  • IDE en el navegador con terminal bash — sin instalar nada
  • Corrección instantánea, XP y tu lugar en la ruta
Crear una cuentaIniciar sesión
O
Continuar con GitHub