Esa no es mucha información y ciertamente no es suficiente para hacer esto con la precisión suficiente para el trading, pero de todos modos podemos hacer el ejercicio.
Información
Supondré que también tienes información adicional, por lo que tu conjunto completo es algo así como:
-
La tasa SOFR actual: 5.25%
-
La tasa SONIA actual: 5.25%
-
La tasa spot GBPUSD: 1.275.
-
Algunas tasas forward GBPUSD (de tus futuros), por ejemplo
- 1y fwd: 1.276
- 2y fwd: 1.279
- 3y fwd: 1.281
-
Tasas de bonos del tesoro de 10 años y 5 años de EE. UU.: 4.52% y 4.51%
-
Tasa del bono del tesoro de 10 años del Reino Unido: 4.32%
Curva de EE. UU.
Procede primero construyendo una curva del tesoro de EE. UU., a partir de las tres tasas de EE. UU. que tienes. Dado que esto es particularmente escaso, usaré una interpolación log-cúbica y obtendré algo como lo siguiente:
# PYTHON
from rateslib import * # requiere >= 1.3.0
usd = Curve(
# Nodos de factor de descuento a los 6M, 5Y y 10Y
nodes={dt(2000, 1, 1): 1.0, dt(2000, 7, 1): 1.0, dt(2005, 1, 1): 1.0, dt(2010, 1, 5): 1.0},
# Especificar puntos de anclaje para una spline cúbica
t=[dt(2000, 1, 1), dt(2000, 1, 1), dt(2000, 1, 1), dt(2000, 1, 1),
dt(2000, 7, 1), dt(2005, 1, 1),
dt(2010, 1, 5), dt(2010, 1, 5), dt(2010, 1, 5), dt(2010, 1, 5)],
)
solver = Solver(
curves=[usd],
instruments=[
IRS(dt(2000, 1, 4), "1b", spec="usd_irs", curves=usd),
(FixedRateBond(dt(2000, 1, 1), "5y", spec="ust", curves=usd, fixed_rate=2.0), (), {"metric": "ytm"}),
(FixedRateBond(dt(2000, 1, 1), "10y", spec="ust", curves=usd, fixed_rate=2.0), (), {"metric": "ytm"}),
],
s=[5.25, 4.52, 4.51] # <- Tasa SOFR + rendimientos de bonos del tesoro de EE. UU.
)
ÉXITO: `func_tol` alcanzada después de 5 iteraciones (levenberg_marquardt), `f_val`: 4.9611913959284605e-12, `tiempo`: 0.0374s
Esto producirá una curva de tasas overnight que se verá así:
usd.plot("1b")
Curva GBP
Ahora viene la parte difícil. Estás haciendo 2 suposiciones clave que son muy malas en la práctica:
- Las tasas del tesoro están afectando los cálculos de paridad FX. (Las tasas RFR generalmente se utilizan para los cálculos de paridad FX, no las tasas del tesoro, ya que las tasas del Tesoro y las RFR divergen en términos de vencimientos)
- La base de moneda cruzada es cero. Las ecuaciones de paridad FX suelen ser impactadas por la base de moneda pero no tienes esa información así que asumimos que es cero. Sin embargo, puede ser bastante significativa.
Por lo tanto, construiremos una curva GBP que intente afirmar la paridad FX bajo estas suposiciones.
gbp = Curve(
# Mismos nodos de factor de descuento a los 6M, 5Y y 10Y
nodes={dt(2000, 1, 1): 1.0, dt(2000, 7, 1): 1.0, dt(2005, 1, 1): 1.0, dt(2010, 1, 5): 1.0},
# Mismos puntos de anclaje de la spline
t=[dt(2000, 1, 1), dt(2000, 1, 1), dt(2000, 1, 1), dt(2000, 1, 1),
dt(2000, 7, 1), dt(2005, 1, 1),
dt(2010, 1, 5), dt(2010, 1, 5), dt(2010, 1, 5), dt(2010, 1, 5)],
)
# Crear un mercado de forwards de FX a partir del spot y las curvas de tasas.
fxf = FXForwards(
fx_rates=FXRates({"gbpusd": 1.275}, settlement=dt(2000, 1, 1)),
fx_curves={"gbpgbp": gbp, "usdusd": usd, "gbpusd": gbp}
)
# Resolver todo coincidiendo con todos los instrumentos conocidos.
solver2 = Solver(
pre_solvers=[solver],
curves=[gbp],
instruments=[
IRS(dt(2000, 1, 4), "5b", spec="gbp_irs", curves=gbp),
(FixedRateBond(dt(2000, 1, 1), "10y", spec="ukt", curves=gbp, fixed_rate=2.0), (), {"metric": "ytm"}),
FXExchange(pair="gbpusd", settlement=dt(2001, 1, 1), curves=[None, gbp, None, usd]),
FXExchange(pair="gbpusd", settlement=dt(2002, 1, 1), curves=[None, gbp, None, usd]),
FXExchange(pair="gbpusd", settlement=dt(2003, 1, 1), curves=[None, gbp, None, usd]),
],
s=[5.25, 4.32, 1.276, 1.279, 1.281],
fx=fxf,
)
ÉXITO: `conv_tol` alcanzado después de 10 iteraciones (levenberg_marquardt), `f_val`: 1.3783402897407275e-06, `tiempo`: 0.0493s
El proceso de resolución intenta encontrar una curva GBP adecuada que coincida con toda la información conocida y volver a calcular las tasas de GBP conocidas y también resolver las ecuaciones de paridad FX (aunque no exactamente en este caso, ya que la curva está sobrespecificada)
Tus curvas ahora lucen así:
usd.plot("1b", comparadores=[gbp], etiquetas=["usd", "gbp"])
Con esta curva puedes estimar el rendimiento del Gilt a 5 años (y convertirlo en un posible precio de futuros)
FixedRateBond(dt(2000, 1, 1), "5y", spec="ukt", fixed_rate=2.0).rate(gbp, metric="ytm")
# 4.296175
Entonces la mejor estimación para toda esta información es 4.296%.