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":["Sat","Sun"]}}'

In [7]: union_cal.to_json()        # UnionCal
Out[7]: '{"UnionCal":{"calendars":[{"holidays":[],"week_mask":["Sat","Sun"]}],"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 0x12210b2d0>

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

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

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

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

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

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

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

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

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

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

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

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