Todo sistema multidivisa acaba topándose con un contable. Y este plantea una pregunta que suena trivial pero no lo es: «¿Qué tipo de cambio habéis usado en esta factura?» Si la respuesta sincera es «el que devolviera la API aquella tarde, y no lo guardamos», tienes un problema que ningún código limpio va a resolver el día de la presentación.
Acertar con los tipos de cambio para la declaración de impuestos tiene menos que ver con elegir el tipo correcto —la mayoría de las administraciones son sorprendentemente flexibles en eso— y mucho más con poder demostrar, años después, qué tipo usaste, de dónde salió y que has aplicado la misma regla a todas las demás operaciones del periodo. Eso es un problema de modelado de datos, y es la parte de la que nadie escribe.
Esta guía cubre lo que exigen realmente el IRS, HMRC y la Directiva del IVA de la UE, los cinco errores de conversión que acaban en reformulaciones contables y un esquema de instantáneas de tipos que puedes implementar esta misma semana.
Nadie se pone de acuerdo sobre «el» tipo de cambio, y ahí está la clave
La frase más útil de todo este ámbito viene del propio IRS:
«El Internal Revenue Service no tiene un tipo de cambio oficial. Por lo general, acepta cualquier tipo de cambio publicado que se utilice de forma coherente.»
Léelo dos veces, porque el mismo patrón se repite en casi todas las jurisdicciones. La obligación rara vez es usa este número concreto. Es usa una fuente defendible y úsala de forma coherente. La coherencia es una propiedad de tu sistema, no de tu proveedor de tipos. Si tu código recurre en silencio a otra fuente los fines de semana, has incumplido el requisito sin haber descargado jamás un número incorrecto.
Estados Unidos: contado por defecto, media anual por concesión
El punto de partida del IRS es el tipo de contado: «Por lo general, utilice el tipo de cambio vigente (es decir, el tipo de contado) cuando reciba, pague o devengue la partida.» Cuando la renta se devenga de forma continuada —salarios, alquileres, ingresos recurrentes de la actividad—, el IRS publica una tabla de tipos de cambio medios anuales e indica a los declarantes que «divida el importe en moneda extranjera entre el tipo de cambio medio anual aplicable.» En la última actualización de esa página, del 24 de febrero de 2026, la tabla abarca los ejercicios fiscales de 2021 a 2025.
Fíjate en la dirección de esa operación. La tabla del IRS se cotiza en unidades de moneda extranjera por un dólar estadounidense, de ahí la división. Si la inviertes por error, no te equivocas por poco: te equivocas por el cuadrado del tipo. En una cifra en yenes, eso son unos cuatro órdenes de magnitud. Más abajo volvemos sobre la dirección del tipo, porque es el fallo de integración más habitual de este ámbito.
Para la información de las agencias federales estadounidenses existe una segunda serie oficial: los Treasury Reporting Rates of Exchange, publicados trimestralmente en FiscalData.Treasury.gov en CSV, JSON y XML. El Tesoro los describe como reflejo de los «tipos de cambio a los que el Gobierno de EE. UU. puede adquirir divisas para gastos oficiales, según lo comunicado por los responsables de pagos de cada destino el último día hábil del mes anterior a la fecha del informe publicado.» Si los tipos en vivo se alejan un 10% o más de un tipo publicado, el Tesoro emite una modificación a mitad de trimestre. La API de Fiscal Data es abierta y no requiere cuenta ni token: conviene saberlo si necesitas una serie de referencia de origen gubernamental contra la que conciliar.
Reino Unido: el §7.6 de VAT Notice 700 tiene fuerza de ley
El Reino Unido es más prescriptivo, y el texto pertinente tiene fuerza legal en virtud del anexo 6, apartado 11, de la VAT Act 1994. La VAT Notice 700 ofrece a las empresas tres vías para convertir a libras esterlinas las entregas en moneda extranjera:
- El tipo vendedor del mercado británico en el momento de la entrega. Es la opción por defecto. La Notice indica que «los tipos publicados en la prensa nacional serán aceptables como prueba de los tipos vigentes en el momento pertinente.»
- El tipo de cambio de periodo de HMRC, publicado a efectos aduaneros. Puedes adoptarlo «para todas tus entregas o para todas las entregas de una clase o descripción concreta.» No hace falta notificación previa, pero «una vez ejercida esa opción, no puedes cambiarla sin obtener antes la conformidad escribiendo al VAT Written Enquiries Team.»
- Un tipo o método comercial propio, que exige una solicitud por escrito. HMRC valora si el tipo se «determina por referencia al mercado de divisas del Reino Unido», si es «objetivamente verificable» y con qué frecuencia se actualiza. Y algo fundamental: «no se aceptan los tipos a plazo ni los métodos derivados de tipos a plazo», un límite estricto que conviene entender junto con la diferencia entre tipos de contado y tipos a plazo.
Y la frase que gobierna tu capa de caché: «Sea cual sea el tipo o el método que adoptes, el tipo aplicable a cualquier entrega es el vigente en el momento de la entrega.» Momento de la entrega: ni el de la facturación, ni el del pago y, desde luego, ni el de tu proceso por lotes nocturno.
Si eliges la vía 2, la mecánica resulta muy cómoda de automatizar. HMRC publica tipos mensuales el penúltimo jueves de cada mes; se aplican al mes natural siguiente y corresponden a los tipos del mediodía del día anterior a la publicación. Los ficheros están en una URL predecible; ojo, porque el mes no lleva cero a la izquierda:
https://www.trade-tariff.service.gov.uk/exchange_rates/view/files/monthly_csv_2026-9.csv
https://www.trade-tariff.service.gov.uk/exchange_rates/view/files/monthly_xml_2026-9.xmlUna descarga al mes, cacheada durante todo el mes, y cualquier conversión de IVA británico de ese periodo es reproducible a partir de un fichero que puedes entregar a un inspector.
Unión Europea: el artículo 91 de la Directiva del IVA
Para las entregas intracomunitarias, el artículo 91(2) de la Directiva 2006/112/CE del Consejo fija la regla como «el último tipo vendedor registrado, en el momento en que el IVA sea exigible, en el mercado o mercados de cambios más representativos del Estado miembro de que se trate, o un tipo determinado por referencia a dicho mercado o mercados.»
Eso sería difícil de implementar en 27 Estados miembros, así que la Directiva añade una válvula de escape práctica: los Estados miembros «aceptarán en su lugar el uso del último tipo de cambio publicado por el Banco Central Europeo en el momento en que el impuesto sea exigible.» La conversión entre dos monedas distintas del euro se realiza «utilizando el tipo de cambio del euro de cada una de las monedas»; dicho de otro modo, se cruza vía EUR en lugar de cotizar el par directamente. Los Estados miembros pueden exigir que se notifique el ejercicio de esta opción.
En el caso de las importaciones, el artículo 91(1) remite en cambio a las normas aduaneras de cálculo del valor en aduana: un tipo genuinamente distinto, en una fecha genuinamente distinta, dentro del mismo libro mayor. Si tu sistema trata el «IVA de la UE» como una única regla de conversión, ya está mal.
Por debajo de todo esto: la IAS 21
Las normas fiscales se apoyan en tu política contable y, para quienes reportan bajo NIIF, esa política es la IAS 21. Cuatro disposiciones hacen casi todo el trabajo:
- Una transacción en moneda extranjera se reconoce inicialmente al tipo de contado de la fecha de la transacción (IAS 21.21).
- Se permite un tipo medio como simplificación, pero solo «mientras los tipos de cambio no fluctúen de forma significativa» (IAS 21.22). Es una condición, no una opción por defecto, y es la cláusula que falla calladamente en un trimestre volátil.
- Las partidas monetarias se reconvierten al tipo de cierre en la fecha de cierre (IAS 21.23).
- Las partidas no monetarias valoradas a coste histórico se mantienen al tipo de la fecha de la transacción y no se reconvierten.
Los US GAAP llegan a conclusiones muy parecidas bajo la ASC 830. La consecuencia práctica para un desarrollador es que una sola transacción puede requerir legítimamente dos o tres tipos distintos a lo largo de su vida —uno en el reconocimiento, otro en el cierre del periodo y otro en la liquidación—, y tu esquema necesita espacio para todos ellos. Nuestra guía sobre gestión del riesgo de divisa para empresas explica qué significan comercialmente las ganancias y pérdidas resultantes.
Cinco errores de conversión que acaban en reformulaciones contables
1. La dirección del tipo
base=USD&symbols=EUR devuelve euros por dólar. base=EUR&symbols=USD devuelve dólares por euro. La tabla anual del IRS es moneda-extranjera-por-USD, así que divides; una respuesta de Finexly con base=EUR es USD-por-EUR, así que multiplicas. Ambas son correctas; mezclarlas no lo es.
La solución es aburrida y eficaz: nunca llames rate a una columna. Llámala quote_per_base y haz que la dirección sea inequívoca en el esquema, no en un comentario.
2. Volver a consultar en lugar de reproducir
Una auditoría en 2029 pregunta por una transacción de 2026. Si tu código de informes llama a un endpoint en vivo en el momento de generar el informe, dos ejecuciones del mismo informe producen dos cifras distintas. El tipo aplicado a una transacción es un hecho sobre esa transacción, no una consulta: persístelo en el momento de la conversión. Los endpoints históricos existen para rellenar y conciliar, no para sustituir al almacenamiento; consulta nuestra guía de la API de tipos de cambio históricos para ver los patrones de relleno retroactivo.
3. Media donde se exige contado
Las medias mensuales son cómodas y a menudo están permitidas, pero la IAS 21.22 les impone una condición y, con carácter general, las transacciones puntuales requieren el tipo de la fecha de la operación según las directrices del IRS. Guarda el método junto al tipo para poder responder a «¿por qué esta cifra?» sin recurrir a la arqueología.
4. Días sin cotización
Los fines de semana, los festivos nacionales y los días no TARGET no tienen tipo publicado. Todo sistema necesita una regla explícita —normalmente «el último tipo publicado en la fecha o antes de ella»— y necesita registrar qué regla se activó. Un repliegue silencioso es indistinguible de un fallo seis meses después. Esto se solapa directamente con las buenas prácticas de caché y gestión de errores.
5. Precisión y redondeo
Almacena más decimales de los que muestras y redondea exactamente una vez, en el paso final de presentación o contabilización. Redondear en cada paso intermedio a lo largo de unos miles de facturas produce un desfase de conciliación tedioso de explicar e imposible de revertir. Tratamos la aritmética en detalle en redondeo de divisas y decimales.
Diseña la instantánea del tipo, no la consulta del tipo
Todo el problema se desmorona si dejas de pensar en la conversión como una llamada a una función y empiezas a pensarla como un registro inmutable. Este es un esquema mínimo que satisface todos los requisitos comentados hasta aquí:
CREATE TABLE fx_rate_snapshot (
id BIGSERIAL PRIMARY KEY,
transaction_id BIGINT NOT NULL,
-- direction is in the name, not in a comment
base_currency CHAR(3) NOT NULL, -- e.g. 'EUR'
quote_currency CHAR(3) NOT NULL, -- e.g. 'USD'
quote_per_base NUMERIC(20,10) NOT NULL,
rate_date DATE NOT NULL, -- the date the rate APPLIES to
method TEXT NOT NULL, -- 'spot' | 'monthly_period' | 'yearly_average'
fallback_applied TEXT, -- 'previous_business_day' | NULL
source TEXT NOT NULL, -- 'finexly' | 'hmrc_monthly' | 'irs_yearly'
source_reference TEXT, -- file name, request id, or table year
retrieved_at TIMESTAMPTZ NOT NULL, -- when WE obtained it
amount_base NUMERIC(20,4) NOT NULL,
amount_quote NUMERIC(20,4) NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
-- one authoritative conversion per transaction per purpose
CREATE UNIQUE INDEX ux_fx_snapshot_txn_method
ON fx_rate_snapshot (transaction_id, method, rate_date);Tres columnas soportan casi todo el peso de la auditoría. rate_date es la fecha a la que se aplica el tipo y está deliberadamente separada de retrieved_at, el momento en que lo obtuviste: un tipo del 13 de marzo descargado durante un relleno retroactivo de septiembre es perfectamente legítimo, y ese par de timestamps lo dice con honestidad. fallback_applied convierte tu regla de fin de semana de comportamiento invisible en evidencia registrada.
Fíjate en que las filas nunca se actualizan. Si se corrige un tipo, inserta una fila nueva y deja obsoleta la anterior. Una pista de auditoría que puedes editar no es una pista de auditoría.
Obtener un tipo histórico defendible
Para el tipo de la fecha de la transacción, solicita la fecha concreta en lugar de la actual:
curl "https://api.finexly.com/v1/historical?date=2026-03-13&base=EUR&symbols=USD" \
-H "Authorization: Bearer YOUR_API_KEY"{
"base": "EUR",
"date": "2026-03-13",
"rates": {
"USD": 1.0842
}
}Con base=EUR, el valor son dólares por euro, así que una factura de €10,000 se convierte en $10,842.00 mediante multiplicación. Este es el patrón de instantánea en la escritura en Python, incluyendo el repliegue para días sin cotización y los campos que espera el esquema anterior:
import requests
from datetime import date, timedelta
from decimal import Decimal, ROUND_HALF_UP
API = "https://api.finexly.com/v1/historical"
HEADERS = {"Authorization": "Bearer YOUR_API_KEY"}
def fetch_rate(base: str, quote: str, on: date, max_lookback: int = 5):
"""Return (quote_per_base, rate_date, fallback) for a given date.
Walks back to the most recent published rate if `on` is a weekend
or a market holiday, and reports which day it actually landed on.
"""
for offset in range(max_lookback + 1):
d = on - timedelta(days=offset)
r = requests.get(
API,
params={"date": d.isoformat(), "base": base, "symbols": quote},
headers=HEADERS,
timeout=10,
)
r.raise_for_status()
rates = r.json().get("rates", {})
if quote in rates:
fallback = "previous_business_day" if offset else None
return Decimal(str(rates[quote])), d, fallback
raise LookupError(f"No {base}/{quote} rate within {max_lookback} days of {on}")
def convert_for_filing(amount_base, base, quote, transaction_date):
"""Convert once, and return everything an auditor will ask for."""
rate, rate_date, fallback = fetch_rate(base, quote, transaction_date)
amount = Decimal(str(amount_base))
converted = (amount * rate).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
return {
"base_currency": base,
"quote_currency": quote,
"quote_per_base": rate,
"rate_date": rate_date.isoformat(),
"method": "spot",
"fallback_applied": fallback,
"source": "finexly",
"amount_base": amount,
"amount_quote": converted,
}
snapshot = convert_for_filing(10000, "EUR", "USD", date(2026, 3, 13))
print(snapshot["amount_quote"], snapshot["rate_date"], snapshot["fallback_applied"])
# -> 10842.00 2026-03-13 NoneLa función convierte y documenta de un mismo golpe. Sea cual sea tu capa de persistencia, escribe ese diccionario en ella antes de que nada aguas abajo vea la cifra. La misma disciplina compensa en facturación multidivisa, facturación SaaS y nóminas transfronterizas, y todas ellas terminan en la misma declaración de impuestos.
Conciliar con el tipo oficial publicado
Para el IVA británico por la vía 2, descarga el fichero mensual de HMRC una vez al mes y guárdalo como fuente de verdad de ese periodo:
import csv, io, requests
from datetime import date
def hmrc_monthly_rates(year: int, month: int) -> dict:
"""HMRC monthly rates for VAT/customs. Note: month is NOT zero-padded."""
url = (
"https://www.trade-tariff.service.gov.uk/exchange_rates/view/files/"
f"monthly_csv_{year}-{month}.csv"
)
resp = requests.get(url, timeout=15)
resp.raise_for_status()
reader = csv.DictReader(io.StringIO(resp.text))
# Don't hard-code the header text: find the ISO-4217 code column by shape.
code_col = next(
c for c in reader.fieldnames if "code" in c.strip().lower()
)
return {
row[code_col].strip(): row
for row in reader
if row.get(code_col) and len(row[code_col].strip()) == 3
}Después ejecuta una comprobación periódica de desviación: compara cada instantánea almacenada con el tipo oficial de su periodo y marca todo lo que quede fuera de una tolerancia que hayas elegido de forma deliberada. Las pequeñas divergencias entre un tipo de mercado y un tipo administrativo publicado son esperables y suelen ser aceptables, pero conviene conocer el tamaño de la brecha antes de que un inspector la calcule por ti. Si vas a conectar esto a un libro mayor, nuestras notas sobre integración con software de contabilidad y sobre de dónde obtienen sus datos las APIs de tipos de cambio abordan las cuestiones de procedencia que vienen a continuación.
Lista de comprobación previa a la declaración para datos multidivisa
- Todo importe convertido tiene un tipo almacenado. Ningún informe recalcula una conversión histórica en tiempo de ejecución.
- La dirección del tipo es inequívoca en los nombres de las columnas, no en la documentación.
rate_dateyretrieved_atson campos separados, y ambos están rellenos.- La regla de días sin cotización es explícita y queda registrada, no es un reintento implícito.
- Un método por clase de transacción, aplicado de forma coherente a todo el periodo: el requisito legal real tanto en EE. UU. como en el Reino Unido.
- El redondeo ocurre una sola vez, en el paso final, con un modo documentado.
- Las filas de instantánea son solo de anexado. Las correcciones sustituyen; nunca sobrescriben.
Repasa esos siete puntos y la pregunta del contable deja de dar miedo. La respuesta pasa a ser una consulta.
Preguntas frecuentes
¿Qué tipo de cambio exige el IRS para la declaración de impuestos? Ninguno en concreto. El IRS afirma con claridad que «no tiene un tipo de cambio oficial» y que «por lo general acepta cualquier tipo de cambio publicado que se utilice de forma coherente.» La opción por defecto es el tipo de contado vigente cuando recibes, pagas o devengas la partida; para las rentas que se devengan de forma continuada, el IRS publica una tabla de medias anuales e indica a los declarantes que dividan el importe extranjero entre el tipo listado.
¿Puedo usar una API de divisas en lugar de los tipos publicados por HMRC para el IVA? Sí, con límites. El §7.6 de VAT Notice 700 convierte el tipo vendedor del mercado británico en el momento de la entrega en la opción por defecto, de modo que un tipo de API basado en el mercado encaja en esa vía siempre que lo apliques de forma coherente. El tipo de periodo de la propia HMRC es una alternativa explícita que puedes adoptar sin notificación previa, pero una vez adoptada no puedes volver atrás sin acuerdo por escrito. Un tipo o método que quede fuera de ambas vías requiere una solicitud por escrito, y los tipos a plazo no se aceptan.
¿Necesito almacenar el tipo de cambio o puedo volver a consultarlo más adelante? Almacénalo. Un tipo almacenado hace que la conversión sea reproducible; volver a consultarlo la convierte en un cálculo nuevo que puede no coincidir con la declaración que ya presentaste. Guardar el tipo, su fecha, su fuente y el momento en que lo obtuviste es lo que convierte un número en una prueba.
¿Qué tipo debo usar cuando la fecha de la transacción cae en fin de semana o festivo? No hay tipo publicado para un día sin negociación, así que necesitas una regla declarada; lo más habitual es el último tipo publicado en la fecha de la transacción o antes de ella. Importa más que esté documentada, se aplique de manera uniforme y quede registrada en cada fila afectada que cuál sea la regla elegida.
¿Cuántos decimales debo almacenar a efectos fiscales? Almacena toda la precisión que devuelva tu proveedor —de seis a diez decimales es un ancho de columna sensato— y redondea solo al contabilizar o mostrar. Redondear pronto y de forma repetida es la causa habitual de los desfases de conciliación que luego nadie puede rastrear.
¿El tipo del BCE cumple los requisitos del IVA de la UE? El artículo 91(2) de la Directiva del IVA obliga a los Estados miembros a aceptar el último tipo del BCE publicado en el momento en que el impuesto sea exigible, con las conversiones entre divisas canalizadas a través del tipo en euros de cada moneda. Algunos Estados miembros exigen que se notifique el uso de esta opción, y las importaciones siguen en cambio las normas de valoración en aduana.
Prepara tus tipos para la auditoría
¿Listo para integrar tipos de cambio en tiempo real e históricos en tu proyecto? Consigue tu clave gratuita de la API de Finexly: sin tarjeta de crédito. Empieza con 1,000 peticiones gratuitas al mes y amplía a medida que creces. Consulta la documentación de la API para la referencia completa del endpoint histórico, prueba el conversor de divisas para comprobaciones puntuales, compara APIs de divisas si estás evaluando proveedores y revisa los planes de precios cuando crezca tu volumen de informes.
Este artículo es una guía técnica para desarrolladores que construyen sistemas multidivisa. No es asesoramiento fiscal: confirma tu política de conversión con un asesor cualificado en cada jurisdicción en la que presentes declaraciones.
Explore More
Vlado Grigirov
Senior Currency Markets Analyst & Financial Strategist
Vlado Grigirov is a senior currency markets analyst and financial strategist with over 14 years of experience in foreign exchange markets, cross-border finance, and currency risk management. He has wo...
View full profile →