schema — Data Contract Layer
The schema module is the data contract layer for all of sipQuant.
Every pricing, risk, index, and book function accepts validated schema objects
rather than raw arrays. This ensures consistent, validated inputs across the
entire stack regardless of which module is called.
All schema objects are plain Python dicts with a 'type' key. This keeps
them lightweight, serialisable, and framework-agnostic.
import sipQuant as sq
trade = sq.schema.TradeRecord(
date='2026-03-14', price=187.50, volume=500.0,
grade='premium_bale_14pct_moisture',
origin='lethbridge_ab', destination='red_deer_ab',
counterpartyId='CP_ANON_004',
)
errors = sq.schema.validate(trade)
assert errors == []
Schema Objects
PriceSeries
Regular, evenly-spaced price time series. Use for broker quotes, exchange settlements, or any daily/weekly series with consistent observation frequency.
ps = sq.schema.PriceSeries(
dates=np.array(['2026-01-06', '2026-01-13'], dtype='datetime64'),
values=np.array([182.0, 184.5]),
source='broker_prairie_ag',
market='alberta_hay_premium',
grade='premium_bale_14pct_moisture', # optional
)
Parameters
dates— array-like. Observation dates. Any comparable type.values— array-like of float. Must be same length asdates.source— str. Data source identifier (broker name, exchange, internal).market— str. Market identifier (e.g.'alberta_hay_premium').grade— str, optional. Grade specification.
Returns — dict with keys: type, dates, values, source, market, grade, n.
Raises — ValueError if lengths mismatch or values is empty.
SparsePriceSeries
Irregularly-spaced price series for thin markets with ad-hoc or infrequent
observations. Stores gap metadata for use in proxy and interpolation routines.
The majority of SIP Cluster markets (B through Z) require this type rather than
PriceSeries.
sparse_ps = sq.schema.SparsePriceSeries(
dates=dates,
values=prices,
source='internal_survey',
market='alberta_hay_feed',
maxGapDays=21, # flags gaps > 3 weeks in gapFlags array
)
Parameters
dates— array-like. Must be monotonically non-decreasing.values— array-like of float.source— str.market— str.maxGapDays— int, optional. If provided,gapFlagsarray marks gaps exceeding this threshold.
Returns — dict with keys: type, dates, values, source, market, maxGapDays, gapFlags, n.
TradeRecord
A single physical trade observation. Physical trades are the primary input
to index calculation (index.calculateIndex) and proxy regression
(index.proxyRegression). Each trade must pass validation before entering
the calculation pipeline.
trade = sq.schema.TradeRecord(
date='2026-03-14',
price=187.50,
volume=500.0, # tonnes
grade='premium_bale_14pct_moisture',
origin='lethbridge_ab',
destination='red_deer_ab',
counterpartyId='CP_ANON_004',
)
Parameters
date— any. Trade date.price— float. Must be positive.volume— float. Traded volume in any unit. Must be positive.grade— str. Quality specification at time of trade. Must matchIndexSpecconstituents for index inclusion.origin— str. Origin delivery point.destination— str. Destination delivery point.counterpartyId— str. Anonymised counterparty identifier.
Returns — dict with keys: type, date, price, volume, grade, origin, destination, counterpartyId.
Raises — ValueError if price <= 0 or volume <= 0.
QuoteSheet
An OTC broker quote with full bid/ask/mid metadata. Use when no physical trade has occurred but broker quotes are available as a mark-to-model input.
quote = sq.schema.QuoteSheet(
date='2026-03-14',
bid=186.00,
ask=189.00,
mid=187.50,
source='broker_prairie_ag',
market='alberta_hay_premium',
grade='premium_bale_14pct_moisture',
tenor=0.25, # 3-month quote
)
Parameters
date— any.bid— float or None.ask— float or None.mid— float. Required.source— str.market— str.grade— str.tenor— float. Contract tenor in years.
Returns — dict with keys: type, date, bid, ask, mid, source, market, grade, tenor.
Raises — ValueError if bid > ask (when both provided) or tenor < 0.
ForwardCurve
A validated forward price curve. The primary input to all OTC pricing
functions (otc.commoditySwap, otc.collar, etc.). Built from
commodity.localForwardCurve or bootstrap.forwardCurve.
curve = sq.schema.ForwardCurve(
tenors=np.array([0.25, 0.50, 0.75, 1.0]),
prices=np.array([188.0, 190.5, 192.0, 193.5]),
baseDate='2026-03-14',
market='alberta_hay_premium',
methodology='linear',
)
Parameters
tenors— array-like of float. In years. Must be monotonically non-decreasing and non-negative.prices— array-like of float. Must all be positive.baseDate— any. The as-of date for the curve.market— str.methodology— str, optional. Interpolation method. Default'linear'.
Returns — dict with keys: type, tenors, prices, baseDate, market, methodology, n.
Raises — ValueError if tenors not monotone, any price non-positive, or length mismatch.
OTCPosition
A live OTC position record for dealer book aggregation. All book functions
(book.netGreeks, book.pnlAttribution, etc.) operate on lists of
OTCPosition dicts.
pos = sq.schema.OTCPosition(
instrumentType='commodity_swap',
direction='receive_fixed', # long the index
notional=1000.0, # tonnes
strikeOrFixed=190.0,
expiry='2026-12-31',
counterpartyId='CP_ANON_004',
greeks={
'delta': 950.0,
'gamma': 0.0,
'vega': 0.0,
'theta': -50.0,
'rho': 0.3,
},
)
Parameters
instrumentType— str. E.g.'commodity_swap','collar','physical_forward'.direction— str. One of:'buy','sell','pay_fixed','receive_fixed','long','short'.notional— float. Must be positive.strikeOrFixed— float. Strike (options) or fixed rate (swaps).expiry— any. Contract expiry.counterpartyId— str.greeks— dict, optional. Keys:delta,gamma,vega,theta,rho. Defaults to all zeros.
Returns — dict with keys: type, instrumentType, direction, notional, strikeOrFixed, expiry, counterpartyId, greeks.
Raises — ValueError if direction not valid or notional non-positive.
IndexSpec
An immutable index methodology specification. Governs the index calculation
and is pinned to each audit record. Changing the methodology requires creating
a new IndexSpec with an incremented version string.
spec = sq.schema.IndexSpec(
name='SIP-AHI-001',
version='1.0',
constituents=['premium_bale_14pct_moisture', 'feed_grade'],
weightsMethod='volume',
rollRule='monthly_last_business_day',
effectiveDate='2026-01-01',
)
Parameters
name— str. Index name (e.g.'SIP-AHI-001').version— str. Methodology version.constituents— list of str. Grade identifiers that contribute to the index. Must matchTradeRecord.gradevalues.weightsMethod— str. One of:'equal','volume','liquidity','custom'.rollRule— str. Roll logic description.effectiveDate— any. Date from which this version is effective.
Returns — dict with keys: type, name, version, constituents, weightsMethod, rollRule, effectiveDate.
Raises — ValueError if weightsMethod not valid or constituents empty.
Validation
validate()
Universal validation dispatcher. Runs type-specific checks on any schema
object and returns a list of error strings. An empty list means the object
is valid. Always call validate() before passing objects to pricing
or index functions in production pipelines.
errors = sq.schema.validate(trade)
if errors:
raise ValueError(f"Invalid trade: {errors}")
# Validate multiple objects at once
for obj in [trade, ps, spec, curve, pos]:
errs = sq.schema.validate(obj)
if errs:
raise ValueError(f"{obj['type']} validation failed: {errs}")
Parameters
obj— dict. Any sipQuant schema object.
Returns — list of str. Empty if valid.
Valid Types
Type |
Use in |
|---|---|
PriceSeries |
commodity, sim, fit, econometrics |
SparsePriceSeries |
index (thin markets) |
TradeRecord |
index.calculateIndex |
QuoteSheet |
otc pricing mark-to-model |
ForwardCurve |
otc, book, bootstrap |
OTCPosition |
book (all functions) |
IndexSpec |
index (all functions) |