Serialization#

Rateslib is an object oriented library requiring dynamic associations to create pricing and risk functionality. The objective of serialization and deserialization is to convert rateslib’s objects into a form that can be persisted or transported, with a view towards being able to recapture those dynamic associations (i.e. saved and loaded from a database, or sent between client and server over a network).

Warning

This feature is currently experimental, and in development. This page documents the objects that have, to date, had focused development for the two forms of serialization rateslib intends to offer. Other objects in rateslib may well have serialization methods in place but the stability and robustness of those may not have been properly tested.

Forms#

Serialization is a general term. The specific forms of serialization that rateslib aims to create is JSON serialization and Python pickling.

JSON serialization converts an object to a string and reconstructs it from that same string. The advantage of JSON is that it is human readable (and often editable) whilst a disadvantage is that it likely to be a lesser efficient form of transfer or storage. It is considered a safe form of serialization.

In [1]: from rateslib import from_json

rateslib.serialization.from_json(json)

Create an object from JSON string.

Objects in Scope#

We aim to keep the objects in scope synchronized with availability for both json and pickle serialization for the stated objects below.

Serializing

# --------------dual ---------------------
In [3]: dual.to_json()             # Dual
Out[3]: '{"Dual":{"real":3.141,"vars":["x","y"],"dual":{"v":1,"dim":[2],"data":[1.0,0.0]}}}'

In [4]: dual2.to_json()            # Dual2
Out[4]: '{"Dual2":{"real":3.141,"vars":["x","y"],"dual":{"v":1,"dim":[2],"data":[1.0,0.0]},"dual2":{"v":1,"dim":[2,2],"data":[0.0,0.0,0.0,0.0]}}}'

In [5]: variable.to_json()         # Variable
Out[5]: '{"PyNative": {"Variable": {"real": 3.141, "vars": ["z"], "dual": [1.0]}}}'

# ---------- scheduling ------------------
In [6]: cal.to_json()              # Cal
Out[6]: '{"Cal":{"holidays":[],"week_mask":["Sun","Sat"]}}'

In [7]: union_cal.to_json()        # UnionCal
Out[7]: '{"UnionCal":{"calendars":[{"holidays":[],"week_mask":["Sun","Sat"]}],"settlement_calendars":[]}}'

In [8]: named_cal.to_json()        # NamedCal
Out[8]: '{"NamedCal":{"name":"bus"}}'

In [9]: adjuster.to_json()         # Adjuster
Out[9]: '{"PyAdjuster":{"Following":{"_u8":1}}}'

In [10]: imm.to_json()              # Imm
Out[10]: '{"Imm":"Wed3"}'

In [11]: roll.to_json()             # RollDay
Out[11]: '{"RollDay":{"Day":31}}'

In [12]: frequency.to_json()        # Frequency
Out[12]: '{"Frequency":{"Months":{"number":4,"roll":{"Day":31}}}}'

In [13]: stub_inference.to_json()   # StubInference
Out[13]: '{"StubInference":"LongFront"}'

In [14]: schedule.to_json()         # Schedule
Out[14]: '{"PyWrapped":{"Schedule":{"ueffective":"2000-01-01T00:00:00","utermination":"2001-01-01T00:00:00","frequency":{"Months":{"number":6,"roll":{"Day":1}}},"ufront_stub":null,"uback_stub":null,"calendar":{"NamedCal":{"name":"all"}},"accrual_adjuster":{"ModifiedFollowing":{}},"payment_adjuster":{"BusDaysLagSettle":2}}}}'

# ------------ splines --------------------
In [15]: ppspline_f64.to_json()     # PPSplineF64
Out[15]: '{"PPSplineF64":{"inner":{"k":4,"t":[0.0,0.0,0.0,0.0,4.0,4.0,4.0,4.0],"c":{"v":1,"dim":[4],"data":[0.3,0.2,0.6,0.2]},"n":4}}}'

In [16]: ppspline_dual.to_json()    # PPSplineDual
Out[16]: '{"PPSplineDual":{"inner":{"k":3,"t":[0.0,0.0,0.0,1.0,1.0,1.0],"c":{"v":1,"dim":[3],"data":[{"real":0.1,"vars":[],"dual":{"v":1,"dim":[0],"data":[]}},{"real":0.2,"vars":[],"dual":{"v":1,"dim":[0],"data":[]}},{"real":0.3,"vars":[],"dual":{"v":1,"dim":[0],"data":[]}}]},"n":3}}}'

In [17]: ppspline_dual2.to_json()   # PPSplineDual2
Out[17]: '{"PPSplineDual2":{"inner":{"k":3,"t":[0.0,0.0,0.0,1.0,1.0,1.0],"c":{"v":1,"dim":[3],"data":[{"real":0.1,"vars":[],"dual":{"v":1,"dim":[0],"data":[]},"dual2":{"v":1,"dim":[0,0],"data":[]}},{"real":0.2,"vars":[],"dual":{"v":1,"dim":[0],"data":[]},"dual2":{"v":1,"dim":[0,0],"data":[]}},{"real":0.3,"vars":[],"dual":{"v":1,"dim":[0],"data":[]},"dual2":{"v":1,"dim":[0,0],"data":[]}}]},"n":3}}}'

# ------------ fx_rates -------------------
In [18]: fxr.to_json()              # FXRates
Out[18]: '{"PyWrapped":{"FXRates":{"fx_rates":[{"pair":[{"name":"eur"},{"name":"usd"}],"rate":{"F64":1.15},"settlement":"2000-01-01T00:00:00"}],"currencies":[{"name":"eur"},{"name":"usd"}]}}}'

Deserializing

# --------------dual ---------------------
In [19]: from_json(dual_json)
Out[19]: <Dual: 3.141000, (x, y), [1.0, 0.0]>

In [20]: from_json(dual2_json)
Out[20]: <Dual2: 3.141000, (x, y), [1.0, 0.0], [[...]]>

In [21]: from_json(variable_json)
Out[21]: <Variable: 3.141, (z), [1.0]>

# ---------- scheduling ------------------
In [22]: from_json(cal_json)
Out[22]: <rateslib.rs.Cal at 0x122ce6700>

In [23]: from_json(union_cal_json)
Out[23]: <rateslib.rs.UnionCal at 0x122d72510>

In [24]: from_json(named_cal_json)
Out[24]: <rateslib.rs.NamedCal at 0x122d6c030>

In [25]: from_json(adjuster_json)
Out[25]: <rl.Adjuster.Following at 0x122d2dcc0>

In [26]: from_json(imm_json)
Out[26]: <rl.Imm.Wed3 at 0x122d2dd00>

In [27]: from_json(roll_json)
Out[27]: <rl.RollDay.Day(31) at 0x122d2dd60>

In [28]: from_json(frequency_json)
Out[28]: <rl.Frequency.Months(4, Day(31)) at 0x122ce6200>

In [29]: from_json(stub_inference_json)
Out[29]: <rl.StubInference.LongFront at 0x122d2de20>

In [30]: from_json(schedule_json)
Out[30]: <rl.Schedule at 0x120eabb90>

# ------------ splines --------------------
In [31]: from_json(ppspline_f64_json)
Out[31]: <rl.PPSplineF64 at 0x122d68740>

In [32]: from_json(ppspline_dual_json)
Out[32]: <rl.PPSplineDual at 0x122d68a50>

In [33]: from_json(ppspline_dual2_json)
Out[33]: <rl.PPSplineDual2 at 0x122d68ba0>

# ------------ fx_rates -------------------
In [34]: from_json(fxr_json)
Out[34]: <rl.FXRates:[eur,usd] at 0x122d688a0>