API Reference¶
This section contains the complete API reference for JACTUS.
Core Modules¶
Core Types¶
Time and DateTime¶
Date and time handling for ACTUS contracts.
This module provides the ActusDateTime class and utilities for parsing, manipulating, and comparing dates according to ACTUS specifications.
Key features: - ISO 8601 datetime parsing with ACTUS-specific extensions - Support for 24:00:00 (end of day) and 00:00:00 (start of day) - Period/cycle arithmetic (e.g., adding ‘3M’ to a date) - Month-end handling and leap year support - JAX pytree registration for functional programming - Business day awareness
References
ACTUS Technical Specification v1.1, Section 3 (Time)
- class jactus.core.time.ActusDateTime(year, month, day, hour=0, minute=0, second=0)[source]¶
Bases:
objectImmutable datetime representation for ACTUS contracts.
ACTUS uses ISO 8601 datetime strings with special handling: - 24:00:00 represents end of day (midnight of next day) - 00:00:00 represents start of day (midnight) - Dates can be added/subtracted using cycle notation (e.g., ‘3M’, ‘1Y’)
Example
>>> dt = ActusDateTime.from_iso("2024-01-15T00:00:00") >>> dt.add_period("3M") ActusDateTime(2024, 4, 15, 0, 0, 0)
References
ACTUS Technical Specification v1.1, Section 3.1
- classmethod from_iso(iso_string)[source]¶
Parse ISO 8601 datetime string.
Supports formats: - YYYY-MM-DD - YYYY-MM-DDTHH:MM:SS - YYYY-MM-DD HH:MM:SS (space separator)
Special handling for 24:00:00 (end of day).
- Parameters:
iso_string (str) – ISO 8601 formatted datetime string
- Returns:
ActusDateTime instance
- Raises:
ValueError – If string format is invalid
- Return type:
Example
>>> ActusDateTime.from_iso("2024-01-15T24:00:00") ActusDateTime(2024, 1, 15, 24, 0, 0)
- to_iso()[source]¶
Convert to ISO 8601 string.
- Returns:
MM:SS)
- Return type:
ISO 8601 formatted string (YYYY-MM-DDTHH
Example
>>> dt = ActusDateTime(2024, 1, 15, 12, 30, 0) >>> dt.to_iso() '2024-01-15T12:30:00'
- to_datetime()[source]¶
Convert to Python datetime object.
Note: 24:00:00 is converted to 00:00:00 of the next day.
- Returns:
Python datetime object
- Return type:
Example
>>> dt = ActusDateTime(2024, 1, 15, 24, 0, 0) >>> dt.to_datetime() datetime(2024, 1, 16, 0, 0, 0)
- add_period(cycle, end_of_month_convention=EndOfMonthConvention.SD)[source]¶
Add a period to this datetime.
Periods are specified in ACTUS cycle notation: - NPS where N=number, P=period type, S=stub indicator - Period types: D=days, W=weeks, M=months, Q=quarters, H=half-years, Y=years - Stub indicator: ‘-’ for short stub, ‘+’ for long stub (optional)
- Parameters:
cycle (str) – Period to add (e.g., ‘3M’, ‘1Y’, ‘2W’)
end_of_month_convention (EndOfMonthConvention) – How to handle month-end dates
- Returns:
New ActusDateTime after adding period
- Return type:
Example
>>> dt = ActusDateTime(2024, 1, 31, 0, 0, 0) >>> dt.add_period("1M", EndOfMonthConvention.EOM) ActusDateTime(2024, 2, 29, 0, 0, 0) # Leap year
References
ACTUS Technical Specification v1.1, Section 3.2
- is_end_of_month()[source]¶
Check if this date is the last day of the month.
- Returns:
True if this is the last day of the month
- Return type:
Example
>>> ActusDateTime(2024, 2, 29, 0, 0, 0).is_end_of_month() True >>> ActusDateTime(2024, 2, 28, 0, 0, 0).is_end_of_month() False
- days_between(other)[source]¶
Calculate actual days between this date and another.
- Parameters:
other (ActusDateTime) – Other datetime
- Returns:
Number of days (can be negative if other is earlier)
- Return type:
Example
>>> dt1 = ActusDateTime(2024, 1, 15, 0, 0, 0) >>> dt2 = ActusDateTime(2024, 1, 18, 0, 0, 0) >>> dt1.days_between(dt2) 3
- years_between(other)[source]¶
Calculate approximate years between dates (actual days / 365.25).
- Parameters:
other (ActusDateTime) – Other datetime
- Returns:
Approximate years (can be negative)
- Return type:
Example
>>> dt1 = ActusDateTime(2024, 1, 15, 0, 0, 0) >>> dt2 = ActusDateTime(2025, 1, 15, 0, 0, 0) >>> abs(dt1.years_between(dt2) - 1.0) < 0.01 True
- __lt__(other)[source]¶
Check if this datetime is before another.
- Parameters:
other (ActusDateTime)
- Return type:
- __le__(other)[source]¶
Check if this datetime is before or equal to another.
- Parameters:
other (ActusDateTime)
- Return type:
- __gt__(other)[source]¶
Check if this datetime is after another.
- Parameters:
other (ActusDateTime)
- Return type:
- __ge__(other)[source]¶
Check if this datetime is after or equal to another.
- Parameters:
other (ActusDateTime)
- Return type:
- jactus.core.time.parse_iso_datetime(iso_string)[source]¶
Parse ISO 8601 datetime string into ActusDateTime.
Supports formats: - YYYY-MM-DD - YYYY-MM-DDTHH:MM:SS - YYYY-MM-DD HH:MM:SS
- Parameters:
iso_string (str) – ISO 8601 formatted string
- Returns:
ActusDateTime instance
- Raises:
ValueError – If format is invalid
- Return type:
Example
>>> parse_iso_datetime("2024-01-15T12:30:00") ActusDateTime(2024, 1, 15, 12, 30, 0)
- jactus.core.time.parse_cycle(cycle)[source]¶
Parse ACTUS cycle notation.
Cycle format: NPS - N: number (integer) - P: period type (D/W/M/Q/H/Y) - S: stub indicator (‘-’ short, ‘+’ long) - optional
- Parameters:
cycle (str) – Cycle string (e.g., ‘3M’, ‘1Y-’, ‘6M+’)
- Returns:
Tuple of (number, period_type, stub_indicator)
- Raises:
ValueError – If cycle format is invalid
- Return type:
Example
>>> parse_cycle("3M") (3, 'M', '') >>> parse_cycle("1Y-") (1, 'Y', '-')
References
ACTUS Technical Specification v1.1, Section 3.2
- jactus.core.time.add_period(dt, cycle, end_of_month_convention=EndOfMonthConvention.SD)[source]¶
Add a period to a datetime according to ACTUS conventions.
- Parameters:
dt (ActusDateTime) – Starting datetime
cycle (str) – Period to add (e.g., ‘3M’, ‘1Y’)
end_of_month_convention (EndOfMonthConvention) – How to handle month-end dates
- Returns:
New datetime after adding period
- Return type:
Example
>>> dt = ActusDateTime(2024, 1, 31, 0, 0, 0) >>> add_period(dt, "1M", EndOfMonthConvention.EOM) ActusDateTime(2024, 2, 29, 0, 0, 0)
References
ACTUS Technical Specification v1.1, Section 3.2, 3.3
- jactus.core.time.is_business_day(dt, calendar=Calendar.MONDAY_TO_FRIDAY)[source]¶
Check if a date is a business day according to the given calendar.
- Parameters:
dt (ActusDateTime) – Date to check
calendar (Calendar) – Business day calendar to use
- Returns:
True if date is a business day
- Return type:
Example
>>> dt = ActusDateTime(2024, 1, 15, 0, 0, 0) # Monday >>> is_business_day(dt) True
References
ACTUS Technical Specification v1.1, Section 3.4
- jactus.core.time.adjust_to_business_day(dt, convention, calendar=Calendar.MONDAY_TO_FRIDAY)[source]¶
Adjust a date to a business day according to the given convention.
ACTUS business day conventions have two components:
S (Shift): Move the payment/settlement date to a business day.
C (Calculate): Use the original (unadjusted) date for accrual calculations, even if the payment date was shifted.
Convention naming:
[S|CS][F|MF|P|MP]Sprefix = Shift only (both payment and calculation use shifted date)CSprefix = Calculate-Shift (payment is shifted, calculation uses original date)
Currently, all conventions implement the Shift (S) semantics for date adjustment. The CS distinction is documented for callers that need to track the original calculation date separately (see
get_calculation_date).- Parameters:
dt (ActusDateTime) – Date to adjust
convention (BusinessDayConvention) – Business day convention to use
calendar (Calendar) – Business day calendar
- Returns:
Adjusted (shifted) date (may be same as input if already a business day)
- Return type:
Example
>>> dt = ActusDateTime(2024, 1, 13, 0, 0, 0) # Saturday >>> adjust_to_business_day(dt, BusinessDayConvention.SCF) ActusDateTime(2024, 1, 15, 0, 0, 0) # Monday
References
ACTUS Technical Specification v1.1, Section 3.4
- jactus.core.time.is_shift_calculate(convention)[source]¶
Check if convention is Shift-Calculate (S prefix).
In SC conventions, both the payment date and the calculation date are shifted to a business day together.
- Parameters:
convention (BusinessDayConvention) – Business day convention
- Returns:
True if this is a Shift-only convention (SCF, SCMF, SCP, SCMP)
- Return type:
- jactus.core.time.is_calculate_shift(convention)[source]¶
Check if convention is Calculate-Shift (CS prefix).
In CS conventions, the payment date is shifted to a business day, but the calculation date remains the original (unadjusted) date. This means interest accrual uses the scheduled date, not the actual payment date.
- Parameters:
convention (BusinessDayConvention) – Business day convention
- Returns:
True if this is a Calculate-Shift convention (CSF, CSMF, CSP, CSMP)
- Return type:
- jactus.core.time.get_calculation_date(original_dt, shifted_dt, convention)[source]¶
Get the date to use for accrual calculations.
For SC (Shift-Calculate) conventions, returns the shifted date. For CS (Calculate-Shift) conventions, returns the original date. For NULL convention, returns the original date.
- Parameters:
original_dt (ActusDateTime) – The original scheduled date (before adjustment)
shifted_dt (ActusDateTime) – The business-day-adjusted date
convention (BusinessDayConvention) – Business day convention
- Returns:
Date to use for interest accrual calculations
- Return type:
Contract Attributes¶
Contract attributes for ACTUS contracts.
This module provides the ContractAttributes class, which represents all possible attributes (contract terms) for ACTUS contracts using Pydantic for validation.
References
ACTUS Technical Specification v1.1, Sections 4-5 (Contract Attributes)
- class jactus.core.attributes.ContractAttributes(*, contract_id, contract_type, contract_role, status_date, contract_deal_date=None, initial_exchange_date=None, maturity_date=None, purchase_date=None, termination_date=None, analysis_dates=None, notional_principal=None, nominal_interest_rate=None, nominal_interest_rate_2=None, currency='USD', currency_2=None, notional_principal_2=None, delivery_settlement=None, settlement_date=None, option_type=None, option_strike_1=None, option_strike_2=None, option_exercise_type=None, option_exercise_end_date=None, x_day_notice=None, exercise_date=None, exercise_amount=None, settlement_period=None, delivery_type=None, contract_structure=None, future_price=None, settlement_currency=None, fixing_period=None, quantity=None, unit=None, market_object_code=None, market_object_code_of_dividends=None, dividend_cycle=None, dividend_anchor=None, day_count_convention=None, business_day_convention=BusinessDayConvention.NULL, end_of_month_convention=EndOfMonthConvention.SD, calendar=Calendar.NO_CALENDAR, interest_payment_cycle=None, interest_payment_anchor=None, interest_capitalization_end_date=None, principal_redemption_cycle=None, principal_redemption_anchor=None, fee_payment_cycle=None, fee_payment_anchor=None, rate_reset_cycle=None, rate_reset_anchor=None, scaling_index_cycle=None, scaling_index_anchor=None, next_principal_redemption_amount=None, interest_calculation_base_cycle=None, interest_calculation_base_anchor=None, array_pr_anchor=None, array_pr_cycle=None, array_pr_next=None, array_increase_decrease=None, array_ip_anchor=None, array_ip_cycle=None, array_rr_anchor=None, array_rr_cycle=None, array_rate=None, array_fixed_variable=None, rate_reset_market_object=None, rate_reset_multiplier=None, rate_reset_spread=None, rate_reset_floor=None, rate_reset_cap=None, rate_reset_next=None, fee_rate=None, fee_basis=None, fee_accrued=None, prepayment_effect=PrepaymentEffect.N, penalty_type=None, penalty_rate=None, scaling_effect=ScalingEffect.S000, scaling_index_at_status_date=None, scaling_index_at_contract_deal_date=None, scaling_market_object=None, coverage=None, credit_event_type=None, credit_enhancement_guarantee_extent=None, accrued_interest=None, interest_calculation_base=None, interest_calculation_base_amount=None, amortization_date=None, contract_performance=ContractPerformance.PF, premium_discount_at_ied=None, price_at_purchase_date=None, price_at_termination_date=None)[source]¶
Bases:
BaseModelAll possible attributes for an ACTUS contract.
This class uses Pydantic for automatic validation. Not all attributes are required for all contract types - use validate_contract_type_compatibility() to ensure a valid configuration.
Attributes follow ACTUS naming conventions. See ACTUS documentation for the meaning and constraints of each attribute.
Example
>>> attrs = ContractAttributes( ... contract_id="LOAN-001", ... contract_type=ContractType.PAM, ... contract_role=ContractRole.RPA, ... status_date=ActusDateTime.from_iso("2024-01-01T00:00:00"), ... initial_exchange_date=ActusDateTime.from_iso("2024-01-15T00:00:00"), ... maturity_date=ActusDateTime.from_iso("2029-01-15T00:00:00"), ... notional_principal=100000.0, ... nominal_interest_rate=0.05, ... currency="USD" ... )
References
ACTUS Technical Specification v1.1, Section 4
- Parameters:
contract_id (str)
contract_type (ContractType)
contract_role (ContractRole)
status_date (ActusDateTime)
contract_deal_date (ActusDateTime | None)
initial_exchange_date (ActusDateTime | None)
maturity_date (ActusDateTime | None)
purchase_date (ActusDateTime | None)
termination_date (ActusDateTime | None)
analysis_dates (list[ActusDateTime] | None)
notional_principal (float | None)
nominal_interest_rate (float | None)
nominal_interest_rate_2 (float | None)
currency (str)
currency_2 (str | None)
notional_principal_2 (float | None)
delivery_settlement (str | None)
settlement_date (ActusDateTime | None)
option_type (str | None)
option_strike_1 (float | None)
option_strike_2 (float | None)
option_exercise_type (str | None)
option_exercise_end_date (ActusDateTime | None)
x_day_notice (str | None)
exercise_date (ActusDateTime | None)
exercise_amount (float | None)
settlement_period (str | None)
delivery_type (str | None)
contract_structure (str | None)
future_price (float | None)
settlement_currency (str | None)
fixing_period (str | None)
quantity (float | None)
unit (str | None)
market_object_code (str | None)
market_object_code_of_dividends (str | None)
dividend_cycle (str | None)
dividend_anchor (ActusDateTime | None)
day_count_convention (DayCountConvention | None)
business_day_convention (BusinessDayConvention)
end_of_month_convention (EndOfMonthConvention)
calendar (Calendar)
interest_payment_cycle (str | None)
interest_payment_anchor (ActusDateTime | None)
interest_capitalization_end_date (ActusDateTime | None)
principal_redemption_cycle (str | None)
principal_redemption_anchor (ActusDateTime | None)
fee_payment_cycle (str | None)
fee_payment_anchor (ActusDateTime | None)
rate_reset_cycle (str | None)
rate_reset_anchor (ActusDateTime | None)
scaling_index_cycle (str | None)
scaling_index_anchor (ActusDateTime | None)
next_principal_redemption_amount (float | None)
interest_calculation_base_cycle (str | None)
interest_calculation_base_anchor (ActusDateTime | None)
array_pr_anchor (list[ActusDateTime] | None)
array_ip_anchor (list[ActusDateTime] | None)
array_rr_anchor (list[ActusDateTime] | None)
rate_reset_market_object (str | None)
rate_reset_multiplier (float | None)
rate_reset_spread (float | None)
rate_reset_floor (float | None)
rate_reset_cap (float | None)
rate_reset_next (float | None)
fee_rate (float | None)
fee_basis (FeeBasis | None)
fee_accrued (float | None)
prepayment_effect (PrepaymentEffect)
penalty_type (str | None)
penalty_rate (float | None)
scaling_effect (ScalingEffect)
scaling_index_at_status_date (float | None)
scaling_index_at_contract_deal_date (float | None)
scaling_market_object (str | None)
coverage (float | None)
credit_event_type (ContractPerformance | None)
credit_enhancement_guarantee_extent (str | None)
accrued_interest (float | None)
interest_calculation_base (InterestCalculationBase | None)
interest_calculation_base_amount (float | None)
amortization_date (ActusDateTime | None)
contract_performance (ContractPerformance)
premium_discount_at_ied (float | None)
price_at_purchase_date (float | None)
price_at_termination_date (float | None)
- contract_type: ContractType¶
- contract_role: ContractRole¶
- status_date: ActusDateTime¶
- contract_deal_date: ActusDateTime | None¶
- initial_exchange_date: ActusDateTime | None¶
- maturity_date: ActusDateTime | None¶
- purchase_date: ActusDateTime | None¶
- termination_date: ActusDateTime | None¶
- analysis_dates: list[ActusDateTime] | None¶
- settlement_date: ActusDateTime | None¶
- option_exercise_end_date: ActusDateTime | None¶
- exercise_date: ActusDateTime | None¶
- dividend_anchor: ActusDateTime | None¶
- day_count_convention: DayCountConvention | None¶
- business_day_convention: BusinessDayConvention¶
- end_of_month_convention: EndOfMonthConvention¶
- interest_payment_anchor: ActusDateTime | None¶
- interest_capitalization_end_date: ActusDateTime | None¶
- principal_redemption_anchor: ActusDateTime | None¶
- fee_payment_anchor: ActusDateTime | None¶
- rate_reset_anchor: ActusDateTime | None¶
- scaling_index_anchor: ActusDateTime | None¶
- interest_calculation_base_anchor: ActusDateTime | None¶
- array_pr_anchor: list[ActusDateTime] | None¶
- array_ip_anchor: list[ActusDateTime] | None¶
- array_rr_anchor: list[ActusDateTime] | None¶
- prepayment_effect: PrepaymentEffect¶
- scaling_effect: ScalingEffect¶
- credit_event_type: ContractPerformance | None¶
- interest_calculation_base: InterestCalculationBase | None¶
- amortization_date: ActusDateTime | None¶
- contract_performance: ContractPerformance¶
- model_config = {'arbitrary_types_allowed': True, 'validate_assignment': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- classmethod validate_interest_rate(v)[source]¶
Validate that interest rate is greater than -1 (can be negative).
- get_attribute(actus_name)[source]¶
Get attribute value by ACTUS short name.
- Parameters:
actus_name (str) – ACTUS short name (e.g., ‘IPNR’, ‘NT’, ‘MD’)
- Returns:
Attribute value
- Raises:
KeyError – If ACTUS name not recognized
- Return type:
Example
>>> attrs.get_attribute('NT') 100000.0
Contract State¶
Contract state variables for ACTUS contracts.
This module provides the ContractState dataclass for representing the mutable state of a contract at a point in time. State variables are immutable and JAX-compatible for functional programming.
References
ACTUS Technical Specification v1.1, Section 6 (State Variables)
- class jactus.core.states.ContractState(tmd, sd, nt, ipnr, ipac, feac, nsc, isc, xd=None, ipac1=None, ipac2=None, prnxt=None, ipcb=None, xa=None, prf=ContractPerformance.PF)[source]¶
Bases:
objectImmutable contract state variables.
Represents the time-varying state of an ACTUS contract. All numerical values use JAX arrays for compatibility with automatic differentiation and JIT compilation.
State follows ACTUS naming conventions (lowercase versions of attribute names). See ACTUS documentation for detailed meaning of each state variable.
- Parameters:
tmd (ActusDateTime)
sd (ActusDateTime)
nt (Array)
ipnr (Array)
ipac (Array)
feac (Array)
nsc (Array)
isc (Array)
xd (ActusDateTime | None)
ipac1 (Array | None)
ipac2 (Array | None)
prnxt (Array | None)
ipcb (Array | None)
xa (Array | None)
prf (ContractPerformance)
- tmd¶
Maturity date state (Md)
- prf¶
Contract performance status
- sd¶
Status date
- xd¶
Exercise date (options/futures)
- Type:
Example
>>> import jax.numpy as jnp >>> state = ContractState( ... tmd=ActusDateTime(2029, 1, 15, 0, 0, 0), ... nt=jnp.array(100000.0), ... ipnr=jnp.array(0.05), ... ipac=jnp.array(0.0), ... feac=jnp.array(0.0), ... nsc=jnp.array(1.0), ... isc=jnp.array(1.0), ... prf=ContractPerformance.PF, ... sd=ActusDateTime(2024, 1, 1, 0, 0, 0), ... )
References
ACTUS Technical Specification v1.1, Section 6
- tmd: ActusDateTime¶
- sd: ActusDateTime¶
- xd: ActusDateTime | None = None¶
- prf: ContractPerformance = 'PF'¶
- replace(**changes)[source]¶
Create a new state with specified changes.
Since states are immutable, this creates a new ContractState instance with the specified fields replaced.
- Parameters:
**changes (Any) – Field names and new values
- Returns:
New ContractState with changes applied
- Return type:
Example
>>> new_state = state.replace(nt=jnp.array(90000.0)) >>> new_state.nt Array(90000., dtype=float32)
- to_dict()[source]¶
Convert to dictionary for serialization.
Example
>>> data = state.to_dict() >>> data['nt'] 100000.0
- classmethod from_dict(data)[source]¶
Create ContractState from dictionary.
- Parameters:
data (dict[str, Any]) – Dictionary with state variable values
- Returns:
New ContractState instance
- Return type:
Example
>>> data = {'tmd': '2029-01-15T00:00:00', 'nt': 100000.0, ...} >>> state = ContractState.from_dict(data)
- __init__(tmd, sd, nt, ipnr, ipac, feac, nsc, isc, xd=None, ipac1=None, ipac2=None, prnxt=None, ipcb=None, xa=None, prf=ContractPerformance.PF)¶
- Parameters:
tmd (ActusDateTime)
sd (ActusDateTime)
nt (Array)
ipnr (Array)
ipac (Array)
feac (Array)
nsc (Array)
isc (Array)
xd (ActusDateTime | None)
ipac1 (Array | None)
ipac2 (Array | None)
prnxt (Array | None)
ipcb (Array | None)
xa (Array | None)
prf (ContractPerformance)
- Return type:
None
- jactus.core.states.initialize_state(tmd, sd, nt=0.0, ipnr=0.0, prf=ContractPerformance.PF)[source]¶
Initialize a contract state with default values.
Convenience function for creating a new state with sensible defaults. All accrued amounts start at zero, scaling multipliers at 1.0.
- Parameters:
tmd (ActusDateTime) – Maturity date
sd (ActusDateTime) – Status date
nt (float) – Notional principal
ipnr (float) – Nominal interest rate
prf (ContractPerformance) – Performance status
- Returns:
New ContractState with initialized values
- Return type:
Example
>>> state = initialize_state( ... tmd=ActusDateTime(2029, 1, 15, 0, 0, 0), ... sd=ActusDateTime(2024, 1, 1, 0, 0, 0), ... nt=100000.0, ... ipnr=0.05, ... )
References
ACTUS Technical Specification v1.1, Section 6.2
Contract Events¶
Contract event structures for ACTUS contracts.
This module provides ContractEvent and EventSchedule classes for representing and managing contract events (cash flows and state transitions).
References
ACTUS Technical Specification v1.1, Section 2.5, 2.9 (Events)
- class jactus.core.events.ContractEvent(event_type, event_time, payoff, currency, state_pre=None, state_post=None, sequence=0, calculation_time=None)[source]¶
Bases:
objectRepresents a single contract event.
An event is a discrete occurrence on the timeline that may generate a cash flow (payoff) and/or change the contract state.
- Parameters:
event_type (EventType)
event_time (ActusDateTime)
payoff (Array)
currency (str)
state_pre (ContractState | None)
state_post (ContractState | None)
sequence (int)
calculation_time (ActusDateTime | None)
- event_type¶
Type of event (IED, IP, PR, MD, etc.)
- event_time¶
When the event occurs (τ operator)
- state_pre¶
Contract state before event
- Type:
- state_post¶
Contract state after event
- Type:
Example
>>> event = ContractEvent( ... event_type=EventType.IP, ... event_time=ActusDateTime(2024, 4, 15, 0, 0, 0), ... payoff=jnp.array(1250.0), ... currency="USD", ... sequence=EVENT_SEQUENCE_ORDER[EventType.IP], ... )
References
ACTUS Technical Specification v1.1, Section 2.5
- event_time: ActusDateTime¶
- state_pre: ContractState | None = None¶
- state_post: ContractState | None = None¶
- calculation_time: ActusDateTime | None = None¶
- __lt__(other)[source]¶
Compare by time, then sequence.
- Parameters:
other (ContractEvent)
- Return type:
- __le__(other)[source]¶
Compare by time, then sequence.
- Parameters:
other (ContractEvent)
- Return type:
- __gt__(other)[source]¶
Compare by time, then sequence.
- Parameters:
other (ContractEvent)
- Return type:
- __ge__(other)[source]¶
Compare by time, then sequence.
- Parameters:
other (ContractEvent)
- Return type:
- classmethod from_dict(data)[source]¶
Create ContractEvent from dictionary.
- Parameters:
- Returns:
New ContractEvent instance
- Return type:
- __init__(event_type, event_time, payoff, currency, state_pre=None, state_post=None, sequence=0, calculation_time=None)¶
- Parameters:
event_type (EventType)
event_time (ActusDateTime)
payoff (Array)
currency (str)
state_pre (ContractState | None)
state_post (ContractState | None)
sequence (int)
calculation_time (ActusDateTime | None)
- Return type:
None
- class jactus.core.events.EventSchedule(events, contract_id)[source]¶
Bases:
objectImmutable container for a sequence of events.
Represents the complete event schedule for a contract, maintaining events in chronological order.
- Parameters:
events (tuple[ContractEvent, ...])
contract_id (str)
- events¶
Immutable tuple of events
- Type:
Example
>>> events = [event1, event2, event3] >>> schedule = EventSchedule( ... events=tuple(sorted(events)), ... contract_id="LOAN-001", ... )
References
ACTUS Technical Specification v1.1, Section 2.9
- events: tuple[ContractEvent, ...]¶
- add_event(event)[source]¶
Add an event and return new schedule.
Since schedules are immutable, this creates a new schedule with the event added in sorted order.
- Parameters:
event (ContractEvent) – Event to add
- Returns:
New EventSchedule with event added
- Return type:
Example
>>> new_schedule = schedule.add_event(new_event)
- filter_by_type(event_type)[source]¶
Filter events by type.
- Parameters:
event_type (EventType) – Type to filter for
- Returns:
New EventSchedule with only matching events
- Return type:
Example
>>> ip_events = schedule.filter_by_type(EventType.IP)
- filter_by_time_range(start, end)[source]¶
Filter events by time range.
- Parameters:
start (ActusDateTime) – Start time (inclusive)
end (ActusDateTime) – End time (inclusive)
- Returns:
New EventSchedule with events in range
- Return type:
Example
>>> range_events = schedule.filter_by_time_range( ... ActusDateTime(2024, 1, 1, 0, 0, 0), ... ActusDateTime(2024, 12, 31, 0, 0, 0), ... )
- merge(other)[source]¶
Merge with another schedule.
Combines events from both schedules and sorts by time/sequence.
- Parameters:
other (EventSchedule) – Other schedule to merge
- Returns:
New EventSchedule with merged events
- Return type:
Example
>>> combined = schedule1.merge(schedule2)
- get_payoffs()[source]¶
Extract all payoffs as a JAX array.
- Returns:
Array of payoff values
- Return type:
Example
>>> payoffs = schedule.get_payoffs()
- get_times()[source]¶
Extract all event times.
- Returns:
List of event times
- Return type:
Example
>>> times = schedule.get_times()
- __init__(events, contract_id)¶
- Parameters:
events (tuple[ContractEvent, ...])
contract_id (str)
- Return type:
None
- jactus.core.events.tau(event)[source]¶
τ (tau) operator - Extract event time(s).
The τ operator extracts the time component of events.
- Parameters:
event (ContractEvent | EventSchedule) – Single event or event schedule
- Returns:
Event time(s)
- Return type:
Example
>>> t = tau(event) >>> times = tau(schedule)
References
ACTUS Technical Specification v1.1, Section 2.5
- jactus.core.events.phi(event)[source]¶
φ (phi) operator - Extract payoff(s).
The φ operator extracts the payoff (cash flow) component of events.
- Parameters:
event (ContractEvent | EventSchedule) – Single event or event schedule
- Returns:
Payoff(s) as JAX array
- Return type:
Example
>>> p = phi(event) >>> payoffs = phi(schedule)
References
ACTUS Technical Specification v1.1, Section 2.5
- jactus.core.events.sort_events(events)[source]¶
Sort events by time, then by sequence.
- Parameters:
events (list[ContractEvent]) – List of events to sort
- Returns:
Sorted list of events
- Return type:
Example
>>> sorted_events = sort_events([event3, event1, event2])
References
ACTUS Technical Specification v1.1, Section 2.9
- jactus.core.events.merge_congruent_events(event1, event2)[source]¶
Merge two events at the same time.
Used for composite contracts where multiple events occur simultaneously. Payoffs are summed, and the earliest event type takes precedence.
- Parameters:
event1 (ContractEvent) – First event
event2 (ContractEvent) – Second event
- Returns:
Merged event
- Raises:
ValueError – If events have different times or currencies
- Return type:
Example
>>> merged = merge_congruent_events(event1, event2)
References
ACTUS Technical Specification v1.1, Section 2.9
Contract Types¶
Type definitions and enumerations for ACTUS contract standard.
This module defines all enumerations and type aliases used throughout JACTUS. All enumerations inherit from str for JSON serializability and easy comparison.
References
ACTUS Technical Specification v1.1, Section 2 (Notations)
- class jactus.core.types.EventType(*values)[source]¶
-
ACTUS contract event types.
Event types define the nature of contract events that trigger state transitions and cash flows.
References
ACTUS Technical Specification v1.1, Table 4
- AD = 'AD'¶
- IED = 'IED'¶
- MD = 'MD'¶
- PR = 'PR'¶
- PI = 'PI'¶
- PP = 'PP'¶
- PY = 'PY'¶
- PRF = 'PRF'¶
- FP = 'FP'¶
- PRD = 'PRD'¶
- TD = 'TD'¶
- IP = 'IP'¶
- IPCI = 'IPCI'¶
- IPCB = 'IPCB'¶
- RR = 'RR'¶
- RRF = 'RRF'¶
- DV = 'DV'¶
- DVF = 'DVF'¶
- SC = 'SC'¶
- STD = 'STD'¶
- XD = 'XD'¶
- CE = 'CE'¶
- IPFX = 'IPFX'¶
- IPFL = 'IPFL'¶
- class jactus.core.types.ContractType(*values)[source]¶
-
ACTUS contract types.
Defines all standardized contract types in the ACTUS taxonomy.
References
ACTUS Technical Specification v1.1, Table 3
- PAM = 'PAM'¶
- LAM = 'LAM'¶
- LAX = 'LAX'¶
- NAM = 'NAM'¶
- ANN = 'ANN'¶
- CLM = 'CLM'¶
- UMP = 'UMP'¶
- CSH = 'CSH'¶
- STK = 'STK'¶
- COM = 'COM'¶
- FXOUT = 'FXOUT'¶
- SWPPV = 'SWPPV'¶
- SWAPS = 'SWAPS'¶
- CAPFL = 'CAPFL'¶
- OPTNS = 'OPTNS'¶
- FUTUR = 'FUTUR'¶
- CEG = 'CEG'¶
- CEC = 'CEC'¶
- class jactus.core.types.ContractRole(*values)[source]¶
-
Contract party role definition.
Defines the role of the contract creator, which determines the sign of cash flows (+1 for asset positions, -1 for liability).
References
ACTUS Technical Specification v1.1, Table 1
- RPA = 'RPA'¶
- RPL = 'RPL'¶
- LG = 'LG'¶
- ST = 'ST'¶
- BUY = 'BUY'¶
- SEL = 'SEL'¶
- RFL = 'RFL'¶
- PFL = 'PFL'¶
- COL = 'COL'¶
- CNO = 'CNO'¶
- GUA = 'GUA'¶
- OBL = 'OBL'¶
- UDL = 'UDL'¶
- UDLP = 'UDLP'¶
- UDLM = 'UDLM'¶
- get_sign()[source]¶
Get the sign convention for this role.
Returns +1 for asset/long/receive positions, -1 for liability/short/pay positions.
- Returns:
+1 or -1 according to ACTUS Table 1
- Return type:
Example
>>> ContractRole.RPA.get_sign() 1 >>> ContractRole.RPL.get_sign() -1
References
ACTUS Technical Specification v1.1, Table 1, Section 3.7
- class jactus.core.types.DayCountConvention(*values)[source]¶
-
Day count conventions for year fraction calculation.
Determines how time periods are calculated for interest accrual.
References
ACTUS Technical Specification v1.1, Section 3.6 ISDA Definitions
- AA = 'AA'¶
- A360 = 'A360'¶
- A365 = 'A365'¶
- E30360ISDA = '30E360ISDA'¶
- E30360 = '30E360'¶
- B30360 = '30360'¶
- BUS252 = 'BUS252'¶
- class jactus.core.types.BusinessDayConvention(*values)[source]¶
-
Business day adjustment conventions.
Defines how dates are adjusted when they fall on non-business days. Convention format: S/C + Direction + Modified - S = Shift, C = Calculate - F = Following, P = Preceding - M prefix = Modified (don’t cross month boundary)
References
ACTUS Technical Specification v1.1, Section 3.4
- NULL = 'NULL'¶
- SCF = 'SCF'¶
- SCMF = 'SCMF'¶
- CSF = 'CSF'¶
- CSMF = 'CSMF'¶
- SCP = 'SCP'¶
- SCMP = 'SCMP'¶
- CSP = 'CSP'¶
- CSMP = 'CSMP'¶
- class jactus.core.types.EndOfMonthConvention(*values)[source]¶
-
End of month adjustment convention.
Determines whether dates stay at month-end or maintain day number.
References
ACTUS Technical Specification v1.1, Section 3.3
- EOM = 'EOM'¶
- SD = 'SD'¶
- class jactus.core.types.Calendar(*values)[source]¶
-
Business day calendar definitions.
Defines which days are considered business days (non-holidays).
Note
Additional calendars (TARGET, NYSE, etc.) can be added as needed.
- NO_CALENDAR = 'NO_CALENDAR'¶
- MONDAY_TO_FRIDAY = 'MONDAY_TO_FRIDAY'¶
- TARGET = 'TARGET'¶
- US_NYSE = 'US_NYSE'¶
- UK_SETTLEMENT = 'UK_SETTLEMENT'¶
- CUSTOM = 'CUSTOM'¶
- class jactus.core.types.ContractPerformance(*values)[source]¶
-
Contract performance status.
Indicates the payment performance status of the contract.
References
ACTUS Technical Specification v1.1
- PF = 'PF'¶
- DL = 'DL'¶
- DQ = 'DQ'¶
- DF = 'DF'¶
- class jactus.core.types.FeeBasis(*values)[source]¶
-
Fee calculation basis.
Determines whether fees are absolute amounts or percentages of notional.
- A = 'A'¶
- N = 'N'¶
- class jactus.core.types.InterestCalculationBase(*values)[source]¶
-
Base for interest calculation.
Defines which notional value to use for interest calculations.
References
ACTUS Technical Specification v1.1
- NT = 'NT'¶
- NTIED = 'NTIED'¶
- NTL = 'NTL'¶
- class jactus.core.types.CyclePointOfInterestPayment(*values)[source]¶
-
When IP is calculated/paid in cycle.
Determines whether interest is paid at the beginning or end of each period.
- B = 'B'¶
- E = 'E'¶
- class jactus.core.types.PrepaymentEffect(*values)[source]¶
-
Effect of prepayment on schedule.
Determines how unscheduled principal payments affect the contract.
- N = 'N'¶
- A = 'A'¶
- M = 'M'¶
- class jactus.core.types.ScalingEffect(*values)[source]¶
-
Scaling index effect on contract.
Three-character code indicating which contract elements are scaled: - Position 1: Interest (I = scale, 0 = no scale) - Position 2: Notional (N = scale, 0 = no scale) - Position 3: Maturity (M = scale, 0 = no scale)
Example
‘IN0’ = Scale Interest and Notional, but not Maturity
References
ACTUS Technical Specification v1.1
- S000 = '000'¶
- I00 = 'I00'¶
- S0N0 = '0N0'¶
- IN0 = 'IN0'¶
- S00M = '00M'¶
- I0M = 'I0M'¶
- S0NM = '0NM'¶
- INM = 'INM'¶
Utilities¶
Schedule Generation¶
Schedule generation utilities for ACTUS contracts.
This module provides functions for generating event schedules according to ACTUS specifications, including handling of cycle notation, end-of-month conventions, and business day conventions.
References
ACTUS Technical Specification v1.1, Section 3 (Schedule Generation)
- jactus.utilities.schedules.generate_schedule(start, cycle, end, end_of_month_convention=EndOfMonthConvention.SD, business_day_convention=BusinessDayConvention.NULL, calendar=Calendar.NO_CALENDAR)[source]¶
Generate a regular event schedule S(s, c, T).
Generates dates starting from ‘start’, adding ‘cycle’ repeatedly until reaching or exceeding ‘end’. Applies end-of-month and business day conventions.
- Parameters:
start (ActusDateTime | None) – Schedule start date (anchor)
cycle (str | None) – Cycle string in NPS format (e.g., ‘3M’, ‘1Y’, ‘1Q+’)
end (ActusDateTime | None) – Schedule end date
end_of_month_convention (EndOfMonthConvention) – How to handle month-end dates
business_day_convention (BusinessDayConvention) – How to adjust non-business days
calendar (Calendar) – Business day calendar to use
- Returns:
List of dates in chronological order
- Return type:
Example
>>> schedule = generate_schedule( ... start=ActusDateTime(2024, 1, 15, 0, 0, 0), ... cycle="3M", ... end=ActusDateTime(2025, 1, 15, 0, 0, 0), ... )
References
ACTUS Technical Specification v1.1, Section 3.1
- jactus.utilities.schedules.generate_array_schedule(anchors, cycles, end, end_of_month_convention=EndOfMonthConvention.SD, business_day_convention=BusinessDayConvention.NULL, calendar=Calendar.NO_CALENDAR)[source]¶
Generate array schedule S~(~s, ~c, T).
Generates a schedule from multiple (anchor, cycle) pairs. Each pair generates a sub-schedule that ends at the next anchor or final end.
- Parameters:
anchors (list[ActusDateTime]) – List of anchor dates
cycles (list[str]) – List of cycle strings (same length as anchors)
end (ActusDateTime) – Final end date
end_of_month_convention (EndOfMonthConvention) – How to handle month-end dates
business_day_convention (BusinessDayConvention) – How to adjust non-business days
calendar (Calendar) – Business day calendar
- Returns:
Sorted list of all dates from all sub-schedules
- Return type:
Example
>>> schedule = generate_array_schedule( ... anchors=[ ... ActusDateTime(2024, 1, 15, 0, 0, 0), ... ActusDateTime(2024, 7, 15, 0, 0, 0), ... ], ... cycles=["3M", "6M"], ... end=ActusDateTime(2025, 1, 15, 0, 0, 0), ... )
References
ACTUS Technical Specification v1.1, Section 3.2
- jactus.utilities.schedules.apply_end_of_month_convention(dates, start, cycle, convention)[source]¶
Apply end-of-month convention to schedule.
The EOM convention only applies if: 1. Start date is the last day of a month with <31 days 2. Cycle is a multiple of 1 month
- Parameters:
dates (list[ActusDateTime]) – List of dates to adjust
start (ActusDateTime) – Original start date
cycle (str) – Cycle string
convention (EndOfMonthConvention) – EOM convention to apply
- Returns:
List of adjusted dates
- Return type:
References
ACTUS Technical Specification v1.1, Section 3.3
- jactus.utilities.schedules.apply_business_day_convention(dates, convention, calendar)[source]¶
Apply business day convention to schedule.
Adjusts each date according to the specified convention if it falls on a non-business day.
- Parameters:
dates (list[ActusDateTime]) – List of dates to adjust
convention (BusinessDayConvention) – Business day convention
calendar (Calendar) – Business day calendar
- Returns:
List of adjusted dates
- Return type:
References
ACTUS Technical Specification v1.1, Section 3.4
Business Day Conventions¶
Day count convention implementations for ACTUS contracts.
This module provides year fraction calculations according to various day count conventions used in financial contracts.
References
ACTUS Technical Specification v1.1, Section 4 (Day Count Conventions) ISDA 2006 Definitions
- jactus.utilities.conventions.year_fraction(start, end, convention, maturity=None, calendar=None)[source]¶
Calculate year fraction between two dates using specified convention.
- Parameters:
start (ActusDateTime) – Start date
end (ActusDateTime) – End date
convention (DayCountConvention) – Day count convention to use
maturity (ActusDateTime | None) – Maturity date (required for some conventions)
calendar (HolidayCalendar | None) – Holiday calendar for BUS/252 convention. If None, defaults to MondayToFridayCalendar (Mon-Fri only, no public holidays).
- Returns:
Year fraction as a float
- Return type:
Example
>>> start = ActusDateTime(2024, 1, 15, 0, 0, 0) >>> end = ActusDateTime(2024, 7, 15, 0, 0, 0) >>> year_fraction(start, end, DayCountConvention.AA) 0.5
References
ACTUS Technical Specification v1.1, Section 4.1
- jactus.utilities.conventions.days_between_30_360_methods(start, end, method='30E/360')[source]¶
Calculate days between two dates using 30/360 methods.
- Parameters:
start (ActusDateTime) – Start date
end (ActusDateTime) – End date
method (str) – One of “30E/360”, “30/360”, “30E/360 ISDA”
- Returns:
Number of days (can be negative if end < start)
- Return type:
Example
>>> start = ActusDateTime(2024, 2, 15, 0, 0, 0) >>> end = ActusDateTime(2024, 8, 15, 0, 0, 0) >>> days_between_30_360_methods(start, end, "30E/360") 180
Calendars¶
Business day calendar implementations for ACTUS contracts.
This module provides holiday calendar functionality for determining business days and adjusting dates according to business day conventions.
References
ACTUS Technical Specification v1.1, Section 3.4 (Business Day Conventions)
- class jactus.utilities.calendars.HolidayCalendar[source]¶
Bases:
ABCAbstract base class for holiday calendars.
A holiday calendar determines which dates are business days and provides navigation functions for working with business days.
- abstractmethod is_business_day(date)[source]¶
Check if a date is a business day.
- Parameters:
date (ActusDateTime) – Date to check
- Returns:
True if the date is a business day
- Return type:
Example
>>> cal = MondayToFridayCalendar() >>> cal.is_business_day(ActusDateTime(2024, 1, 15, 0, 0, 0)) # Monday True
- is_holiday(date)[source]¶
Check if a date is a holiday (not a business day).
- Parameters:
date (ActusDateTime) – Date to check
- Returns:
True if the date is a holiday
- Return type:
- next_business_day(date)[source]¶
Get the next business day on or after the given date.
- Parameters:
date (ActusDateTime) – Starting date
- Returns:
Next business day (may be the same date if already a business day)
- Return type:
Example
>>> cal = MondayToFridayCalendar() >>> saturday = ActusDateTime(2024, 1, 6, 0, 0, 0) >>> cal.next_business_day(saturday) ActusDateTime(2024, 1, 8, 0, 0, 0) # Monday
- previous_business_day(date)[source]¶
Get the previous business day on or before the given date.
- Parameters:
date (ActusDateTime) – Starting date
- Returns:
Previous business day (may be the same date if already a business day)
- Return type:
Example
>>> cal = MondayToFridayCalendar() >>> sunday = ActusDateTime(2024, 1, 7, 0, 0, 0) >>> cal.previous_business_day(sunday) ActusDateTime(2024, 1, 5, 0, 0, 0) # Friday
- add_business_days(date, days)[source]¶
Add a number of business days to a date.
- Parameters:
date (ActusDateTime) – Starting date
days (int) – Number of business days to add (can be negative)
- Returns:
Date after adding the specified business days
- Return type:
Example
>>> cal = MondayToFridayCalendar() >>> friday = ActusDateTime(2024, 1, 5, 0, 0, 0) >>> cal.add_business_days(friday, 1) # Next business day ActusDateTime(2024, 1, 8, 0, 0, 0) # Monday
- business_days_between(start, end, include_end=False)[source]¶
Count business days between two dates.
- Parameters:
start (ActusDateTime) – Start date
end (ActusDateTime) – End date
include_end (bool) – Whether to include the end date in the count
- Returns:
Number of business days
- Return type:
Example
>>> cal = MondayToFridayCalendar() >>> mon = ActusDateTime(2024, 1, 1, 0, 0, 0) >>> fri = ActusDateTime(2024, 1, 5, 0, 0, 0) >>> cal.business_days_between(mon, fri) 4
- class jactus.utilities.calendars.NoHolidayCalendar[source]¶
Bases:
HolidayCalendarCalendar with no holidays - every day is a business day.
Useful for theoretical calculations or contracts that don’t respect weekends.
- is_business_day(date)[source]¶
Every day is a business day.
- Parameters:
date (ActusDateTime) – Date to check
- Returns:
Always True
- Return type:
- class jactus.utilities.calendars.MondayToFridayCalendar[source]¶
Bases:
HolidayCalendarCalendar with Monday-Friday as business days (no holidays).
Treats weekends (Saturday/Sunday) as non-business days but doesn’t account for public holidays.
- is_business_day(date)[source]¶
Check if date is Monday-Friday.
- Parameters:
date (ActusDateTime) – Date to check
- Returns:
True if Monday-Friday, False if Saturday-Sunday
- Return type:
- class jactus.utilities.calendars.CustomCalendar(holidays=None, include_weekends=True)[source]¶
Bases:
HolidayCalendarCalendar with custom holiday dates.
Allows specifying specific dates as holidays in addition to weekends.
- Parameters:
holidays (list[ActusDateTime] | None)
include_weekends (bool)
- __init__(holidays=None, include_weekends=True)[source]¶
Initialize custom calendar.
- Parameters:
holidays (list[ActusDateTime] | None) – List of holiday dates (defaults to empty)
include_weekends (bool) – Whether weekends are also holidays (default True)
- add_holiday(date)[source]¶
Add a holiday to the calendar.
- Parameters:
date (ActusDateTime) – Date to mark as holiday
- Return type:
None
- remove_holiday(date)[source]¶
Remove a holiday from the calendar.
- Parameters:
date (ActusDateTime) – Date to remove from holidays
- Return type:
None
- load_from_list(holidays)[source]¶
Load holidays from a list of dates.
- Parameters:
holidays (list[ActusDateTime]) – List of holiday dates
- Return type:
None
- is_business_day(date)[source]¶
Check if date is a business day.
A business day is not a weekend (if include_weekends=True) and not in the custom holidays list.
- Parameters:
date (ActusDateTime) – Date to check
- Returns:
True if business day, False if weekend or holiday
- Return type:
- class jactus.utilities.calendars.TARGETCalendar[source]¶
Bases:
HolidayCalendarECB TARGET2 calendar.
TARGET (Trans-European Automated Real-time Gross Settlement Express Transfer) holidays: New Year’s Day, Good Friday, Easter Monday, Labour Day (May 1), Christmas Day, Boxing Day.
Holiday dates are pre-computed for years 2000-2100.
- is_business_day(dt)[source]¶
Check if date is a TARGET business day.
- Parameters:
dt (ActusDateTime)
- Return type:
- class jactus.utilities.calendars.NYSECalendar[source]¶
Bases:
HolidayCalendarNew York Stock Exchange calendar.
NYSE holidays: New Year’s Day, MLK Day (3rd Mon Jan), Presidents’ Day (3rd Mon Feb), Good Friday, Memorial Day (last Mon May), Juneteenth (Jun 19), Independence Day (Jul 4), Labor Day (1st Mon Sep), Thanksgiving (4th Thu Nov), Christmas Day.
Holiday dates are pre-computed for years 2000-2100.
- is_business_day(dt)[source]¶
Check if date is an NYSE business day.
- Parameters:
dt (ActusDateTime)
- Return type:
- class jactus.utilities.calendars.UKSettlementCalendar[source]¶
Bases:
HolidayCalendarUK Settlement (bank holidays) calendar.
UK bank holidays: New Year’s Day, Good Friday, Easter Monday, Early May Bank Holiday (1st Mon May), Spring Bank Holiday (last Mon May), Summer Bank Holiday (last Mon Aug), Christmas Day, Boxing Day.
Holiday dates are pre-computed for years 2000-2100.
- is_business_day(dt)[source]¶
Check if date is a UK Settlement business day.
- Parameters:
dt (ActusDateTime)
- Return type:
- jactus.utilities.calendars.get_calendar(calendar_name)[source]¶
Factory function to get a calendar by name.
- Parameters:
calendar_name (str) – Name of calendar (“NO_CALENDAR”, “MONDAY_TO_FRIDAY”, etc.)
- Returns:
HolidayCalendar instance
- Raises:
ValueError – If calendar name is unknown
- Return type:
Example
>>> cal = get_calendar("MONDAY_TO_FRIDAY") >>> cal.is_business_day(ActusDateTime(2024, 1, 6, 0, 0, 0)) # Saturday False
- jactus.utilities.calendars.is_weekend(date)[source]¶
Check if a date falls on a weekend (Saturday or Sunday).
- Parameters:
date (ActusDateTime) – Date to check
- Returns:
True if Saturday or Sunday
- Return type:
Example
>>> is_weekend(ActusDateTime(2024, 1, 6, 0, 0, 0)) # Saturday True >>> is_weekend(ActusDateTime(2024, 1, 8, 0, 0, 0)) # Monday False
Mathematical Functions¶
Financial mathematics utilities for ACTUS contracts.
This module provides mathematical functions for contract calculations including contract role signs, annuity calculations, and discount factors.
References
ACTUS Technical Specification v1.1, Table 1 (Contract Role Signs) ACTUS Technical Specification v1.1, Section 5 (Mathematical Functions)
- jactus.utilities.math.contract_role_sign(role)[source]¶
Get the sign (+1 or -1) for a contract role.
The contract role sign determines the direction of cash flows from the perspective of the contract holder.
- Parameters:
role (ContractRole) – Contract role
- Returns:
+1 for long/receiving positions, -1 for short/paying positions
- Return type:
Example
>>> contract_role_sign(ContractRole.RPA) # Receiving party A 1 >>> contract_role_sign(ContractRole.RPL) # Real position lender -1
References
ACTUS Technical Specification v1.1, Table 1
- jactus.utilities.math.contract_role_sign_vectorized(roles)[source]¶
Vectorized contract role sign calculation for JAX.
- Parameters:
roles (Array) – Array of contract role values (as integers)
- Returns:
Array of signs (+1 or -1)
- Return type:
Example
>>> roles = jnp.array([0, 1, 2]) # RPA, RPL, LG >>> signs = contract_role_sign_vectorized(roles) >>> signs Array([1, -1, 1], dtype=int32)
Note
This function is JIT-compiled for performance.
- jactus.utilities.math.annuity_amount(notional, rate, tenor, maturity, n_periods, day_count_convention)[source]¶
Calculate annuity payment amount.
Computes the periodic payment for an annuity given notional, rate, and term. Uses the formula: A = N * r / (1 - (1 + r)^(-n))
- Parameters:
notional (float) – Notional principal amount
rate (float) – Periodic interest rate (e.g., 0.05 for 5% per period)
tenor (ActusDateTime) – Start date for year fraction calculation (reserved for future use)
maturity (ActusDateTime) – End date for year fraction calculation (reserved for future use)
n_periods (int) – Number of payment periods
day_count_convention (DayCountConvention) – Day count convention (reserved for future use)
- Returns:
Annuity payment amount per period
- Return type:
Example
>>> # $100,000 loan at 5% annual rate, 12 monthly payments >>> tenor = ActusDateTime(2024, 1, 1, 0, 0, 0) >>> maturity = ActusDateTime(2025, 1, 1, 0, 0, 0) >>> amount = annuity_amount(100000, 0.05/12, tenor, maturity, 12, DayCountConvention.A360) >>> abs(amount - 8560.75) < 1 # Approximately $8,560.75 per month True
References
ACTUS Technical Specification v1.1, Section 5.1
- jactus.utilities.math.annuity_amount_vectorized(notional, rate, n_periods)[source]¶
Vectorized annuity calculation for JAX arrays.
- Parameters:
- Returns:
Array of annuity amounts
- Return type:
Example
>>> notionals = jnp.array([100000.0, 200000.0]) >>> rates = jnp.array([0.05/12, 0.04/12]) >>> periods = jnp.array([12, 24]) >>> amounts = annuity_amount_vectorized(notionals, rates, periods)
Note
This function is JIT-compiled for performance.
- jactus.utilities.math.discount_factor(rate, start, end, day_count_convention)[source]¶
Calculate discount factor for a time period.
Computes: DF = 1 / (1 + r * t) where t is the year fraction between start and end.
- Parameters:
rate (float) – Annual interest rate (e.g., 0.05 for 5%)
start (ActusDateTime) – Start date
end (ActusDateTime) – End date
day_count_convention (DayCountConvention) – Day count convention
- Returns:
Discount factor
- Return type:
Example
>>> start = ActusDateTime(2024, 1, 1, 0, 0, 0) >>> end = ActusDateTime(2024, 7, 1, 0, 0, 0) >>> df = discount_factor(0.05, start, end, DayCountConvention.AA) >>> abs(df - 0.9756) < 0.001 # Approximately 0.9756 True
References
ACTUS Technical Specification v1.1, Section 5.2
- jactus.utilities.math.discount_factor_vectorized(rate, year_fraction)[source]¶
Vectorized discount factor calculation.
- Parameters:
- Returns:
Array of discount factors
- Return type:
Example
>>> rates = jnp.array([0.05, 0.04, 0.06]) >>> yfs = jnp.array([0.5, 1.0, 0.25]) >>> dfs = discount_factor_vectorized(rates, yfs)
Note
This function is JIT-compiled for performance.
- jactus.utilities.math.compound_factor(rate, start, end, day_count_convention, compounding_frequency=1)[source]¶
Calculate compound factor for a time period.
Computes: CF = (1 + r/m)^(m*t) where m is the compounding frequency and t is the year fraction.
- Parameters:
rate (float) – Annual interest rate (e.g., 0.05 for 5%)
start (ActusDateTime) – Start date
end (ActusDateTime) – End date
day_count_convention (DayCountConvention) – Day count convention
compounding_frequency (int) – Number of compounding periods per year (default 1)
- Returns:
Compound factor
- Return type:
Example
>>> start = ActusDateTime(2024, 1, 1, 0, 0, 0) >>> end = ActusDateTime(2025, 1, 1, 0, 0, 0) >>> # Annual compounding >>> cf = compound_factor(0.05, start, end, DayCountConvention.AA, 1) >>> abs(cf - 1.05) < 0.001 True >>> # Monthly compounding >>> cf_monthly = compound_factor(0.05, start, end, DayCountConvention.AA, 12) >>> abs(cf_monthly - 1.05116) < 0.001 True
References
Standard financial mathematics
- jactus.utilities.math.compound_factor_vectorized(rate, year_fraction, compounding_frequency)[source]¶
Vectorized compound factor calculation.
- Parameters:
- Returns:
Array of compound factors
- Return type:
Example
>>> rates = jnp.array([0.05, 0.04]) >>> yfs = jnp.array([1.0, 1.0]) >>> freqs = jnp.array([1, 12]) >>> cfs = compound_factor_vectorized(rates, yfs, freqs)
Note
This function is JIT-compiled for performance. For continuous compounding (frequency=0), use a very large frequency instead.
- jactus.utilities.math.present_value(cash_flows, dates, valuation_date, discount_rate, day_count_convention)[source]¶
Calculate present value of a series of cash flows.
- Parameters:
dates (list[ActusDateTime]) – List of cash flow dates
valuation_date (ActusDateTime) – Date to discount to
discount_rate (float) – Annual discount rate
day_count_convention (DayCountConvention) – Day count convention
- Returns:
Present value of all cash flows
- Return type:
Example
>>> cfs = [100, 100, 100] >>> dates = [ ... ActusDateTime(2024, 1, 1, 0, 0, 0), ... ActusDateTime(2024, 7, 1, 0, 0, 0), ... ActusDateTime(2025, 1, 1, 0, 0, 0), ... ] >>> val_date = ActusDateTime(2024, 1, 1, 0, 0, 0) >>> pv = present_value(cfs, dates, val_date, 0.05, DayCountConvention.AA) >>> abs(pv - 295.14) < 1.0 True
References
Standard financial mathematics
- jactus.utilities.math.present_value_vectorized(cash_flows, year_fractions, discount_rate)[source]¶
Vectorized present value calculation.
- Parameters:
- Returns:
Present value (scalar JAX array)
- Return type:
Example
>>> cfs = jnp.array([100.0, 100.0, 100.0]) >>> yfs = jnp.array([0.0, 0.5, 1.0]) >>> pv = present_value_vectorized(cfs, yfs, 0.05)
Note
This function is JIT-compiled for performance. Assumes all cash flows are in the future (year_fractions >= 0).
- jactus.utilities.math.calculate_actus_annuity(start, pr_schedule, notional, accrued_interest, rate, day_count_convention)[source]¶
Calculate annuity amount using ACTUS specification formula.
- Implements the ACTUS annuity formula from Section 3.8:
A(s, T, n, a, r) = (n + a) / Σ[∏((1 + Y_i × r)^-1)]
- Where:
s = start time T = maturity (last PR date) n = notional principal a = accrued interest r = nominal interest rate Y_i = year fraction for period i Σ = sum over all PR events ∏ = product up to each PR event
This calculates the constant payment amount such that the total of all payments exactly amortizes the notional plus accrued interest.
- Parameters:
start (ActusDateTime) – Start time for calculation
pr_schedule (list[ActusDateTime]) – List of principal redemption dates
notional (float) – Notional principal amount
accrued_interest (float) – Already accrued interest
rate (float) – Annual interest rate (e.g., 0.05 for 5%)
day_count_convention (DayCountConvention) – Day count convention for year fractions
- Returns:
Annuity payment amount per period
- Return type:
Example
>>> # $100,000 loan at 5% for 12 months >>> start = ActusDateTime(2024, 1, 15, 0, 0, 0) >>> pr_dates = [ActusDateTime(2024, i, 15, 0, 0, 0) for i in range(2, 14)] >>> amount = calculate_actus_annuity( ... start, pr_dates, 100000.0, 0.0, 0.05, DayCountConvention.A360 ... ) >>> 8500 < amount < 8600 # Approximately $8,560 True
References
ACTUS Technical Specification v1.1, Section 3.8
- jactus.utilities.math.calculate_actus_annuity_jax(year_fractions, notional, accrued_interest, rate)[source]¶
JAX-compiled version of ACTUS annuity calculation.
- Implements the ACTUS annuity formula:
A(s, T, n, a, r) = (n + a) / Σ[∏((1 + Y_i × r)^-1)]
- Parameters:
- Returns:
Annuity payment amount
- Return type:
Example
>>> # 12 equal monthly periods (30/360 convention) >>> yfs = jnp.array([30/360] * 12) >>> amount = calculate_actus_annuity_jax(yfs, 100000.0, 0.0, 0.05)
Note
This function is JIT-compiled for performance.
References
ACTUS Technical Specification v1.1, Section 3.8
2D Surface Interpolation¶
2D surface interpolation for behavioral risk models.
This module provides JAX-compatible 2D surface interpolation, used primarily by behavioral risk models such as prepayment and deposit transaction models.
A Surface2D represents a function f(x, y) defined on a grid of (x, y)
margin values with corresponding z values. Given arbitrary query points
(x_q, y_q), it returns interpolated values using bilinear interpolation.
Key features:
- Bilinear interpolation on 2D grids
- Configurable extrapolation: "constant" (nearest edge) or "raise"
- JAX array storage for automatic differentiation compatibility
- Support for both numeric and label-based margins via LabeledSurface2D
References
ACTUS Risk Service v2.0 - TimeSeries<TimeSeries<Double>> surface model
- class jactus.utilities.surface.Surface2D(x_margins, y_margins, values, extrapolation='constant')[source]¶
Bases:
objectA 2D interpolation surface defined on a rectangular grid.
The surface is specified by: -
x_margins: Sorted 1D array of x-axis breakpoints (e.g., spread values) -y_margins: Sorted 1D array of y-axis breakpoints (e.g., age values) -values: 2D array of shape(len(x_margins), len(y_margins))Interpolation is bilinear within the grid, and extrapolation behavior is configurable.
- extrapolation¶
Extrapolation method:
"constant"(use nearest edge value) or"raise"(raise ValueError).- Type:
Example
>>> import jax.numpy as jnp >>> # Prepayment surface: spread (rows) × age (columns) >>> surface = Surface2D( ... x_margins=jnp.array([0.0, 1.0, 2.0, 3.0]), # spread % ... y_margins=jnp.array([0.0, 1.0, 3.0, 5.0]), # age years ... values=jnp.array([ ... [0.00, 0.00, 0.00, 0.00], # spread=0% ... [0.00, 0.01, 0.02, 0.00], # spread=1% ... [0.00, 0.02, 0.05, 0.01], # spread=2% ... [0.01, 0.05, 0.10, 0.02], # spread=3% ... ]), ... ) >>> rate = surface.evaluate(1.5, 2.0) # Bilinear interpolation
- evaluate(x, y)[source]¶
Evaluate the surface at a point using bilinear interpolation.
For points within the grid, standard bilinear interpolation is used. For points outside the grid, behavior depends on
self.extrapolation.- Parameters:
- Returns:
Interpolated value as a scalar JAX array.
- Raises:
ValueError – If
extrapolation="raise"and point is outside the grid.- Return type:
Example
>>> value = surface.evaluate(1.5, 2.0)
- static from_dict(data)[source]¶
Create a Surface2D from a dictionary representation.
- Parameters:
data (dict[str, Any]) – Dictionary with keys
"x_margins","y_margins","values", and optionally"extrapolation".- Returns:
New Surface2D instance.
- Return type:
Example
>>> surface = Surface2D.from_dict({ ... "x_margins": [0.0, 1.0, 2.0], ... "y_margins": [0.0, 1.0, 3.0], ... "values": [ ... [0.0, 0.01, 0.02], ... [0.01, 0.03, 0.05], ... [0.02, 0.05, 0.10], ... ], ... "extrapolation": "constant", ... })
- class jactus.utilities.surface.LabeledSurface2D(x_labels, y_labels, values)[source]¶
Bases:
objectA 2D surface with string-labeled margins.
Used for models where one or both dimensions are categorical rather than numeric (e.g., deposit transaction models where dimension 1 is contract ID and dimension 2 is a date label).
Each label maps to a numeric index. The underlying data is stored in a regular
Surface2Dfor interpolation.Example
>>> surface = LabeledSurface2D( ... x_labels=["DEPOSIT-001", "DEPOSIT-002"], ... y_labels=["2024-01-01", "2024-07-01", "2025-01-01"], ... values=jnp.array([ ... [1000.0, -500.0, 2000.0], ... [5000.0, -1000.0, 3000.0], ... ]), ... ) >>> amount = surface.get(x_label="DEPOSIT-001", y_label="2024-07-01")
- get(x_label, y_label)[source]¶
Get the value at exact label coordinates.
- Parameters:
- Returns:
Value as a scalar JAX array.
- Raises:
KeyError – If either label is not found.
- Return type:
Example
>>> value = surface.get("DEPOSIT-001", "2024-07-01")
Contract Implementations¶
Base Contract¶
Factory Function¶
Principal Contracts¶
PAM - Principal at Maturity¶
LAM - Linear Amortizer¶
LAX - Exotic Linear Amortizer¶
NAM - Negative Amortizer¶
ANN - Annuity¶
CLM - Call Money¶
UMP - Undefined Maturity Profile¶
Non-Principal Contracts¶
CSH - Cash¶
STK - Stock¶
COM - Commodity¶
Derivative Contracts¶
FXOUT - Foreign Exchange Outright¶
OPTNS - Options¶
FUTUR - Futures¶
SWPPV - Plain Vanilla Swap¶
SWAPS - Generic Swap¶
CAPFL - Cap/Floor¶
CEG - Credit Enhancement Guarantee¶
CEC - Credit Enhancement Collateral¶
Contract Functions¶
Payoff Functions¶
Payoff function framework for ACTUS contracts.
This module implements the payoff function (POF) framework as defined in Section 2.7 and 3.9 of the ACTUS specification v1.1.
The payoff function f(e, S, M, t, o_rf) calculates the cashflow amount for a contract event, applying contract role sign and FX rate adjustments.
References
ACTUS Technical Specification v1.1: - Section 2.7: Payoff Functions - Section 3.9: Canonical Contract Payoff Function F(x,t) - Section 3.10: Settlement Currency FX Rate X^CURS_CUR(t)
- class jactus.functions.payoff.PayoffFunction(*args, **kwargs)[source]¶
Bases:
ProtocolProtocol for payoff functions.
A payoff function calculates the cashflow amount for a contract event. All concrete POF implementations must implement this protocol.
- The payoff function signature is:
f(e, S, M, t, o_rf) -> payoff
- Where:
e = event type S = pre-event state M = contract attributes t = event time o_rf = risk factor observer
- Returns:
Payoff amount as JAX array (scalar)
- __call__(event_type, state, attributes, time, risk_factor_observer)[source]¶
Calculate payoff for an event.
- Parameters:
event_type (EventType) – Type of contract event
state (ContractState) – Pre-event contract state
attributes (ContractAttributes) – Contract attributes/terms
time (ActusDateTime) – Event time
risk_factor_observer (RiskFactorObserver) – Observer for market data
- Returns:
Payoff amount as JAX array (scalar)
- Return type:
References
ACTUS v1.1 Section 2.7
- __init__(*args, **kwargs)¶
- class jactus.functions.payoff.BasePayoffFunction(contract_role, currency, settlement_currency=None)[source]¶
Bases:
ABCBase class for payoff functions with common logic.
This abstract base class implements the common payoff calculation pipeline: 1. Calculate base payoff amount (contract-specific, abstract) 2. Apply contract role sign R(CNTRL) 3. Apply FX rate X^CURS_CUR(t) if settlement currency differs
Subclasses must implement calculate_payoff() with contract-specific logic.
- Parameters:
contract_role (ContractRole)
currency (str)
settlement_currency (str | None)
- contract_role¶
Contract role (RPA, RPL, etc.)
- currency¶
Contract currency
- settlement_currency¶
Settlement currency (None = same as contract currency)
References
ACTUS v1.1 Section 2.7, 3.10
- __init__(contract_role, currency, settlement_currency=None)[source]¶
Initialize base payoff function.
- Parameters:
contract_role (ContractRole) – Contract role for sign adjustment
currency (str) – Contract currency (e.g., “USD”)
settlement_currency (str | None) – Settlement currency (None = same as contract)
- abstractmethod calculate_payoff(event_type, state, attributes, time, risk_factor_observer)[source]¶
Calculate base payoff before role sign and FX adjustments.
This is the contract-specific payoff logic that subclasses must implement.
- Parameters:
event_type (EventType) – Type of contract event
state (ContractState) – Pre-event contract state
attributes (ContractAttributes) – Contract attributes/terms
time (ActusDateTime) – Event time
risk_factor_observer (RiskFactorObserver) – Observer for market data
- Returns:
Base payoff amount as JAX array (scalar)
- Return type:
- apply_role_sign(amount)[source]¶
Apply contract role sign R(CNTRL).
The contract role determines the sign of cashflows: - RPA, LG, BUY, etc.: +1 (receive cashflows) - RPL, ST, SEL, etc.: -1 (pay cashflows)
- Parameters:
amount (Array) – Unsigned payoff amount
- Returns:
Signed payoff amount
- Return type:
- Formula:
signed_amount = amount * R(CNTRL)
References
ACTUS v1.1 Table 1 (Contract Role Signs)
- apply_fx_rate(amount, time, risk_factor_observer)[source]¶
Apply FX rate X^CURS_CUR(t) if settlement currency differs.
If the settlement currency differs from the contract currency, the payoff must be converted using the FX rate observed at the event time.
- Parameters:
amount (Array) – Payoff in contract currency
time (ActusDateTime) – Event time
risk_factor_observer (RiskFactorObserver) – Observer for FX rates
- Returns:
Payoff in settlement currency
- Return type:
- Formula:
- If CURS != CUR:
payoff_settlement = payoff_contract * X^CURS_CUR(t)
- Else:
payoff_settlement = payoff_contract
References
ACTUS v1.1 Section 3.10
- __call__(event_type, state, attributes, time, risk_factor_observer)[source]¶
Calculate complete payoff with role sign and FX adjustments.
This method implements the complete payoff calculation pipeline: 1. Calculate base payoff (contract-specific) 2. Apply contract role sign 3. Apply FX rate if needed
- Parameters:
event_type (EventType) – Type of contract event
state (ContractState) – Pre-event contract state
attributes (ContractAttributes) – Contract attributes/terms
time (ActusDateTime) – Event time
risk_factor_observer (RiskFactorObserver) – Observer for market data
- Returns:
Final payoff amount as JAX array (scalar)
- Return type:
References
ACTUS v1.1 Section 2.7
- jactus.functions.payoff.settlement_currency_fx_rate(time, contract_currency, settlement_currency, risk_factor_observer)[source]¶
Get FX rate X^CURS_CUR(t) for settlement currency conversion.
Returns the FX rate to convert from contract currency (CUR) to settlement currency (CURS) at the given time.
- Parameters:
time (ActusDateTime) – Time at which to observe FX rate
contract_currency (str) – Contract currency code (e.g., “USD”)
settlement_currency (str | None) – Settlement currency code (None = same as contract)
risk_factor_observer (RiskFactorObserver) – Observer for FX rate data
- Returns:
FX rate as JAX array (1.0 if currencies are same)
- Return type:
- Logic:
If settlement_currency is None: return 1.0 If settlement_currency == contract_currency: return 1.0 Otherwise: observe FX rate “contract_currency/settlement_currency”
Example
>>> # Contract in EUR, settled in USD >>> fx_rate = settlement_currency_fx_rate( ... time=t, ... contract_currency="EUR", ... settlement_currency="USD", ... risk_factor_observer=observer ... ) >>> # Returns EUR/USD rate, e.g., 1.18
References
ACTUS v1.1 Section 3.10
- jactus.functions.payoff.canonical_contract_payoff(contract, time, risk_factor_observer)[source]¶
Calculate canonical contract payoff F(x, t).
The canonical contract payoff is the sum of all future event payoffs at time t, evaluated using the current risk factor conditions.
This function is used for contract valuation and mark-to-market calculations.
- Parameters:
contract (BaseContract) – Contract instance (must have get_events() and payoff_function)
time (ActusDateTime) – Valuation time
risk_factor_observer (RiskFactorObserver) – Observer for risk factors
- Returns:
Total payoff of all future events as JAX array (scalar)
- Return type:
- Formula:
F(x, t) = Σ f(e_i, S_i, M, t_i, o_rf) for all events e_i where t_i >= t
- Where:
e_i = i-th future event
S_i = state at event time
M = contract attributes
t_i = event time
o_rf = risk factor observer (frozen at current state)
Note
This uses current risk factor conditions for all future events, which may differ from the actual risk factors at those event times.
Example
>>> contract = PAMContract(attributes) >>> observer = MockRiskFactorObserver({'LIBOR': {t: 0.03}}) >>> f_xt = canonical_contract_payoff(contract, t, observer) >>> print(f"Contract value: {f_xt}")
References
ACTUS v1.1 Section 3.9
State Transition Functions¶
State transition functions for ACTUS contracts.
This module implements the State Transition Function (STF) framework, which defines how contract states evolve through events.
The STF has the signature: STF(e, S_pre, M, t, o_rf) -> S_post where: - e: Event type - S_pre: Pre-event contract state - M: Contract attributes (terms) - t: Event time - o_rf: Risk factor observer
References
ACTUS v1.1 Section 2.8 - State Transition Functions
- class jactus.functions.state.StateTransitionFunction(*args, **kwargs)[source]¶
Bases:
ProtocolProtocol for state transition functions.
- The state transition function signature is:
STF(e, S_pre, M, t, o_rf) -> S_post
All implementations must be JAX-compatible (pure functions, JIT-compilable).
- __call__(event_type, state_pre, attributes, time, risk_factor_observer)[source]¶
Transition contract state through an event.
- Parameters:
event_type (EventType) – Type of event triggering the transition
state_pre (ContractState) – Pre-event contract state
attributes (ContractAttributes) – Contract attributes (terms)
time (ActusDateTime) – Event time
risk_factor_observer (RiskFactorObserver) – Observer for risk factors
- Returns:
Post-event contract state
- Return type:
- __init__(*args, **kwargs)¶
- class jactus.functions.state.BaseStateTransitionFunction(day_count_convention=None)[source]¶
Bases:
ABCBase class for state transition functions with common logic.
This class provides a framework for implementing state transitions with standard patterns like interest accrual, fee accrual, and status date updates.
Subclasses must implement the abstract transition_state() method with contract-specific state transition logic.
- Parameters:
day_count_convention (DayCountConvention | None)
- __init__(day_count_convention=None)[source]¶
Initialize state transition function.
- Parameters:
day_count_convention (DayCountConvention | None) – Day count convention for time calculations (if None, uses contract’s DCC from attributes)
- abstractmethod transition_state(event_type, state_pre, attributes, time, risk_factor_observer)[source]¶
Implement contract-specific state transition logic.
This method should be implemented by subclasses to define how the contract state transitions for specific event types.
- Parameters:
event_type (EventType) – Type of event triggering the transition
state_pre (ContractState) – Pre-event contract state
attributes (ContractAttributes) – Contract attributes (terms)
time (ActusDateTime) – Event time
risk_factor_observer (RiskFactorObserver) – Observer for risk factors
- Returns:
Post-event contract state
- Return type:
Note
This method should typically: 1. Copy the pre-event state 2. Update state variables based on event type 3. Return the new state
Example
>>> def transition_state(self, event_type, state_pre, attributes, time, observer): ... # Create post-event state by copying pre-event state ... state_post = state_pre ... ... # Update state based on event type ... if event_type == EventType.IP: ... # Interest payment: reset accrued interest ... state_post = state_post.replace(ipac=jnp.array(0.0)) ... ... return state_post
- update_status_date(state, new_date)[source]¶
Update contract status date.
- Parameters:
state (ContractState) – Contract state to update
new_date (ActusDateTime) – New status date
- Returns:
Updated state with new status date
- Return type:
- accrue_interest(state, attributes, from_date, to_date)[source]¶
Calculate interest accrued over a period.
Accrual formula: IPAC += NT * IPNR * YearFraction(from, to, DCC)
- Parameters:
state (ContractState) – Current contract state
attributes (ContractAttributes) – Contract attributes
from_date (ActusDateTime) – Start of accrual period
to_date (ActusDateTime) – End of accrual period
- Returns:
Interest accrued as JAX array
- Return type:
jnp.ndarray
References
ACTUS v1.1 Section 3.4 - Interest Accrual
- accrue_fees(state, attributes, from_date, to_date, fee_rate, fee_basis)[source]¶
Calculate fees accrued over a period.
Fee accrual depends on the fee basis: - FeeBasis.A (Absolute): FEAC += FER * YearFraction(from, to, DCC) - FeeBasis.N (Notional): FEAC += NT * FER * YearFraction(from, to, DCC)
- Parameters:
state (ContractState) – Current contract state
attributes (ContractAttributes) – Contract attributes
from_date (ActusDateTime) – Start of accrual period
to_date (ActusDateTime) – End of accrual period
fee_rate (jnp.ndarray) – Fee rate (FER)
fee_basis (FeeBasis) – Fee basis (Absolute or Notional)
- Returns:
Fees accrued as JAX array
- Return type:
jnp.ndarray
References
ACTUS v1.1 Section 3.5 - Fee Accrual
- __call__(event_type, state_pre, attributes, time, risk_factor_observer)[source]¶
Execute complete state transition pipeline.
This method: 1. Calls the abstract transition_state() method 2. Updates the status date to the event time 3. Returns the post-event state
- Parameters:
event_type (EventType) – Type of event triggering the transition
state_pre (ContractState) – Pre-event contract state
attributes (ContractAttributes) – Contract attributes (terms)
time (ActusDateTime) – Event time
risk_factor_observer (RiskFactorObserver) – Observer for risk factors
- Returns:
Post-event contract state
- Return type:
References
ACTUS v1.1 Section 2.8
- jactus.functions.state.create_state_pre(tmd, sd, nt, ipnr, ipac=0.0, feac=0.0, nsc=1.0, isc=1.0)[source]¶
Create a pre-event contract state with default values.
This is a convenience function for creating initial contract states with common default values.
- Parameters:
tmd (ActusDateTime) – Time of maturity date
sd (ActusDateTime) – Status date
nt (float) – Notional principal
ipnr (float) – Nominal interest rate
ipac (float) – Accrued interest (default: 0.0)
feac (float) – Accrued fees (default: 0.0)
nsc (float) – Notional scaling multiplier (default: 1.0)
isc (float) – Interest scaling multiplier (default: 1.0)
- Returns:
Initial contract state
- Return type:
Example
>>> state = create_state_pre( ... tmd=ActusDateTime(2029, 1, 15, 0, 0, 0), ... sd=ActusDateTime(2024, 1, 15, 0, 0, 0), ... nt=100000.0, ... ipnr=0.05, ... )
- jactus.functions.state.validate_state_transition(state_pre, state_post, event_type)[source]¶
Validate that a state transition is consistent.
Performs basic sanity checks on state transitions: - Status date should not go backwards - Notional should not become negative (for most events) - Scaling factors should remain positive
- Parameters:
state_pre (ContractState) – Pre-event state
state_post (ContractState) – Post-event state
event_type (EventType) – Event type that caused the transition
- Returns:
True if transition is valid, False otherwise
- Return type:
Example
>>> is_valid = validate_state_transition(state_pre, state_post, EventType.IP) >>> if not is_valid: ... raise ValueError("Invalid state transition")
Observers¶
Risk Factor Observer¶
Risk factor observer for ACTUS contracts.
This module implements the Risk Factor Observer (O_rf) framework, which provides access to market data and risk factors needed for contract valuation.
The observer has two key methods: - O_rf(i, t, S, M): Observe risk factor i at time t - O_ev(i, k, t, S, M): Observe event-related data
References
ACTUS v1.1 Section 2.9 - Risk Factor Observer
- class jactus.observers.risk_factor.RiskFactorObserver(*args, **kwargs)[source]¶
Bases:
ProtocolProtocol for risk factor observers.
The risk factor observer provides access to market data and risk factors needed for contract calculations. It abstracts away the data source (historical data, real-time feeds, simulations, etc.).
All implementations must be JAX-compatible where possible.
- observe_risk_factor(identifier, time, state=None, attributes=None)[source]¶
Observe a risk factor at a specific time.
This is the O_rf(i, t, S, M) function from ACTUS specification.
- Parameters:
identifier (str) – Risk factor identifier (e.g., “USD/EUR”, “LIBOR-3M”)
time (ActusDateTime) – Time at which to observe the risk factor
state (ContractState | None) – Current contract state (optional, for state-dependent factors)
attributes (ContractAttributes | None) – Contract attributes (optional, for contract-dependent factors)
- Returns:
Risk factor value as JAX array
- Return type:
jnp.ndarray
Example
>>> observer = DictRiskFactorObserver({"USD/EUR": 1.18}) >>> fx_rate = observer.observe_risk_factor("USD/EUR", time) >>> # Returns 1.18
- observe_event(identifier, event_type, time, state=None, attributes=None)[source]¶
Observe event-related data.
This is the O_ev(i, k, t, S, M) function from ACTUS specification, where k is the event type.
- Parameters:
identifier (str) – Event data identifier
event_type (EventType) – Type of event
time (ActusDateTime) – Time at which to observe
state (ContractState | None) – Current contract state (optional)
attributes (ContractAttributes | None) – Contract attributes (optional)
- Returns:
Event-related data (type depends on identifier)
- Return type:
Any
Example
>>> observer = DictRiskFactorObserver(...) >>> rate = observer.observe_event("RESET_RATE", EventType.RR, time)
- __init__(*args, **kwargs)¶
- class jactus.observers.risk_factor.BaseRiskFactorObserver(name=None)[source]¶
Bases:
ABCBase class for risk factor observers with common functionality.
This class provides a framework for implementing risk factor observers with caching, error handling, and JAX compatibility.
- Parameters:
name (str | None)
- __init__(name=None)[source]¶
Initialize base risk factor observer.
- Parameters:
name (str | None) – Optional name for this observer (for debugging)
- observe_risk_factor(identifier, time, state=None, attributes=None)[source]¶
Observe a risk factor at a specific time.
This method wraps _get_risk_factor with error handling and logging.
- Parameters:
identifier (str) – Risk factor identifier
time (ActusDateTime) – Time at which to observe
state (ContractState | None) – Current contract state (optional)
attributes (ContractAttributes | None) – Contract attributes (optional)
- Returns:
Risk factor value as JAX array
- Raises:
KeyError – If risk factor is not found
- Return type:
jnp.ndarray
- observe_event(identifier, event_type, time, state=None, attributes=None)[source]¶
Observe event-related data.
This method wraps _get_event_data with error handling and logging.
- Parameters:
identifier (str) – Event data identifier
event_type (EventType) – Type of event
time (ActusDateTime) – Time at which to observe
state (ContractState | None) – Current contract state (optional)
attributes (ContractAttributes | None) – Contract attributes (optional)
- Returns:
Event-related data
- Return type:
Any
- class jactus.observers.risk_factor.ConstantRiskFactorObserver(constant_value, name=None)[source]¶
Bases:
BaseRiskFactorObserverRisk factor observer that returns constant values.
This is useful for testing or for contracts with fixed risk factors.
Example
>>> observer = ConstantRiskFactorObserver(1.0) >>> rate = observer.observe_risk_factor("ANY_RATE", time) >>> # Always returns 1.0
- class jactus.observers.risk_factor.DictRiskFactorObserver(risk_factors, event_data=None, name=None)[source]¶
Bases:
BaseRiskFactorObserverRisk factor observer backed by a dictionary.
This is useful for testing or for simple scenarios with a fixed set of risk factors.
Example
>>> data = { ... "USD/EUR": 1.18, ... "LIBOR-3M": 0.02, ... } >>> observer = DictRiskFactorObserver(data) >>> fx_rate = observer.observe_risk_factor("USD/EUR", time) >>> # Returns 1.18
- __init__(risk_factors, event_data=None, name=None)[source]¶
Initialize dictionary-backed risk factor observer.
- class jactus.observers.risk_factor.TimeSeriesRiskFactorObserver(risk_factors, event_data=None, interpolation='step', extrapolation='flat', name=None)[source]¶
Bases:
BaseRiskFactorObserverRisk factor observer backed by time series data with interpolation.
Maps identifiers to time-ordered sequences of (ActusDateTime, float) pairs. Supports step (piecewise constant) and linear interpolation, with flat or raising extrapolation behavior.
Example
>>> from jactus.core import ActusDateTime >>> ts = { ... "LIBOR-3M": [ ... (ActusDateTime(2024, 1, 1), 0.04), ... (ActusDateTime(2024, 7, 1), 0.045), ... (ActusDateTime(2025, 1, 1), 0.05), ... ] ... } >>> observer = TimeSeriesRiskFactorObserver(ts) >>> rate = observer.observe_risk_factor( ... "LIBOR-3M", ActusDateTime(2024, 4, 1) ... ) >>> # Returns 0.04 (step interpolation: last known value)
- Parameters:
- __init__(risk_factors, event_data=None, interpolation='step', extrapolation='flat', name=None)[source]¶
Initialize time series risk factor observer.
- Parameters:
risk_factors (dict[str, list[tuple[ActusDateTime, float]]]) – Dict mapping identifiers to time-value pairs.
event_data (dict[str, list[tuple[ActusDateTime, Any]]] | None) – Optional dict mapping identifiers to time-value pairs for events.
interpolation (str) – Interpolation method: “step” (piecewise constant) or “linear”.
extrapolation (str) – Extrapolation method: “flat” (nearest endpoint) or “raise” (KeyError).
name (str | None) – Optional name for this observer.
- class jactus.observers.risk_factor.CurveRiskFactorObserver(curves, reference_date=None, interpolation='linear', name=None)[source]¶
Bases:
BaseRiskFactorObserverRisk factor observer for yield/rate curves.
Maps identifiers to tenor-rate curves where each curve is a list of (tenor_years, rate) pairs. Given an observation time, the observer computes the tenor from the reference date and interpolates the curve.
Example
>>> from jactus.core import ActusDateTime >>> curve = { ... "USD-YIELD": [ ... (0.25, 0.03), # 3-month rate ... (1.0, 0.04), # 1-year rate ... (5.0, 0.05), # 5-year rate ... ] ... } >>> observer = CurveRiskFactorObserver( ... curves=curve, ... reference_date=ActusDateTime(2024, 1, 1), ... ) >>> rate = observer.observe_risk_factor( ... "USD-YIELD", ActusDateTime(2024, 7, 1) ... )
- Parameters:
- __init__(curves, reference_date=None, interpolation='linear', name=None)[source]¶
Initialize curve risk factor observer.
- Parameters:
curves (dict[str, list[tuple[float, float]]]) – Dict mapping identifiers to lists of (tenor_years, rate) pairs.
reference_date (ActusDateTime | None) – Base date for tenor calculation. Falls back to attributes.status_date if not set.
interpolation (str) – Interpolation method: “linear” or “log_linear”.
name (str | None) – Optional name for this observer.
- class jactus.observers.risk_factor.CallbackRiskFactorObserver(callback, event_callback=None, name=None)[source]¶
Bases:
BaseRiskFactorObserverRisk factor observer that delegates to user-provided callables.
Provides maximum flexibility by allowing arbitrary Python functions to produce risk factor values.
Example
>>> import math >>> def my_rate(identifier: str, time: ActusDateTime) -> float: ... years = ActusDateTime(2024, 1, 1).years_between(time) ... return 0.03 + 0.01 * math.log(1 + max(years, 0)) ... >>> observer = CallbackRiskFactorObserver(callback=my_rate) >>> rate = observer.observe_risk_factor("ANY", ActusDateTime(2025, 1, 1))
- Parameters:
callback (Callable[[str, ActusDateTime], float])
event_callback (Callable[[str, EventType, ActusDateTime], Any] | None)
name (str | None)
- __init__(callback, event_callback=None, name=None)[source]¶
Initialize callback risk factor observer.
- Parameters:
callback (Callable[[str, ActusDateTime], float]) – Function taking (identifier, time) and returning a float.
event_callback (Callable[[str, EventType, ActusDateTime], Any] | None) – Optional function taking (identifier, event_type, time) and returning event data.
name (str | None) – Optional name for this observer.
- class jactus.observers.risk_factor.CompositeRiskFactorObserver(observers, name=None)[source]¶
Bases:
BaseRiskFactorObserverRisk factor observer that chains multiple observers with fallback.
Tries each observer in order and returns the first successful result. If an observer raises KeyError, the next one is tried. Other exceptions propagate immediately.
Example
>>> ts_observer = TimeSeriesRiskFactorObserver({"LIBOR-3M": [...]}) >>> fallback = ConstantRiskFactorObserver(0.0) >>> composite = CompositeRiskFactorObserver([ts_observer, fallback]) >>> # Uses ts_observer for "LIBOR-3M", falls back to constant for others
- Parameters:
observers (list[RiskFactorObserver])
name (str | None)
- __init__(observers, name=None)[source]¶
Initialize composite risk factor observer.
- Parameters:
observers (list[RiskFactorObserver]) – List of observers to try in order. Must not be empty.
name (str | None) – Optional name for this observer.
- Raises:
ValueError – If observers list is empty.
- class jactus.observers.risk_factor.JaxRiskFactorObserver(risk_factors, default_value=0.0)[source]¶
Bases:
objectFully JAX-compatible risk factor observer.
This observer is designed for use with jax.jit and jax.grad. It uses integer indices instead of string identifiers and stores all data in JAX arrays.
Key features: - Pure functions (no side effects) - JIT-compilable - Differentiable with jax.grad - Vectorized with jax.vmap - No Python control flow in hot paths
Example
>>> # Create observer with 3 risk factors >>> risk_factors = jnp.array([1.18, 0.05, 100000.0]) >>> observer = JaxRiskFactorObserver(risk_factors) >>> >>> # Observe risk factor at index 0 (e.g., FX rate) >>> fx_rate = observer.get(0) # Returns 1.18 >>> >>> # Use with jax.grad for sensitivities >>> def contract_value(risk_factors): ... obs = JaxRiskFactorObserver(risk_factors) ... fx = obs.get(0) ... rate = obs.get(1) ... notional = obs.get(2) ... return notional * rate * fx >>> >>> # Compute gradient (sensitivities) >>> sensitivities = jax.grad(contract_value)(risk_factors) >>> # sensitivities[0] = d(value)/d(fx_rate) >>> # sensitivities[1] = d(value)/d(rate) >>> # sensitivities[2] = d(value)/d(notional)
Note
This observer does not implement the RiskFactorObserver protocol because the protocol uses string identifiers which are not JAX-compatible. Instead, it provides a simpler API with integer indices.
References
ACTUS v1.1 Section 2.9 - Risk Factor Observer
- Parameters:
risk_factors (jnp.ndarray)
default_value (float | jnp.ndarray)
- __init__(risk_factors, default_value=0.0)[source]¶
Initialize JAX-compatible risk factor observer.
- Parameters:
Example
>>> # Create observer with FX rate, interest rate, notional >>> risk_factors = jnp.array([1.18, 0.05, 100000.0]) >>> observer = JaxRiskFactorObserver(risk_factors)
- get(index)[source]¶
Get risk factor value at the given index.
This method is JIT-compilable and differentiable.
- Parameters:
index (int) – Integer index of the risk factor
- Returns:
Risk factor value as JAX array
- Return type:
Example
>>> observer = JaxRiskFactorObserver(jnp.array([1.18, 0.05])) >>> fx_rate = observer.get(0) # Returns 1.18 >>> rate = observer.get(1) # Returns 0.05
Note
Uses safe indexing with bounds checking via JAX operations. Out-of-bounds indices return the default value.
- get_batch(indices)[source]¶
Get multiple risk factors at once (vectorized).
This is useful for batch operations and is vmappable.
- Parameters:
indices (Array) – Array of integer indices
- Returns:
Array of risk factor values
- Return type:
Example
>>> observer = JaxRiskFactorObserver(jnp.array([1.18, 0.05, 100000.0])) >>> indices = jnp.array([0, 2]) # Get FX rate and notional >>> values = observer.get_batch(indices) >>> # Returns jnp.array([1.18, 100000.0])
- update(index, value)[source]¶
Create new observer with updated risk factor value.
This is a pure function - it returns a new observer without modifying the original.
- Parameters:
- Returns:
New JaxRiskFactorObserver with updated value
- Return type:
Example
>>> observer = JaxRiskFactorObserver(jnp.array([1.18, 0.05])) >>> new_observer = observer.update(0, 1.20) # Update FX rate >>> new_observer.get(0) # Returns 1.20 >>> observer.get(0) # Still returns 1.18 (original unchanged)
- update_batch(indices, values)[source]¶
Create new observer with multiple updated risk factors.
- Parameters:
- Returns:
New JaxRiskFactorObserver with updated values
- Return type:
Example
>>> observer = JaxRiskFactorObserver(jnp.array([1.18, 0.05, 100000.0])) >>> new_observer = observer.update_batch( ... jnp.array([0, 1]), ... jnp.array([1.20, 0.06]) ... )
- to_array()[source]¶
Get all risk factors as a JAX array.
- Returns:
Array of all risk factor values
- Return type:
Example
>>> observer = JaxRiskFactorObserver(jnp.array([1.18, 0.05])) >>> observer.to_array() # Returns jnp.array([1.18, 0.05])
- static from_dict(mapping, size=None, default_value=0.0)[source]¶
Create observer from a dictionary mapping indices to values.
This is a convenience method for initialization. The observer itself remains fully JAX-compatible.
- Parameters:
- Returns:
New JaxRiskFactorObserver
- Return type:
Example
>>> observer = JaxRiskFactorObserver.from_dict({ ... 0: 1.18, # FX rate ... 1: 0.05, # Interest rate ... 2: 100000.0 # Notional ... })
Child Contract Observer¶
Child contract observer for composite ACTUS contracts.
This module implements observers for child contracts in composite contract structures. In ACTUS, composite contracts can observe events, states, and attributes of their child contracts to determine their own behavior.
References
ACTUS v1.1 Section 2.10 - Child Contract Observer ACTUS v1.1 Section 3.4 - Composite Contract Types
- class jactus.observers.child_contract.ChildContractObserver(*args, **kwargs)[source]¶
Bases:
ProtocolProtocol for observing child contract data in composite contracts.
The child contract observer provides access to events, states, and attributes of child contracts within a composite structure. This enables parent contracts to make decisions based on child contract behavior.
Methods correspond to ACTUS observer functions: - observe_events: U_ev(i, t, a) - Observe child events at time t - observe_state: U_sv(i, t, x, a) - Observe child state at time t - observe_attribute: U_ca(i, x) - Observe child attribute value
Example
>>> observer = MockChildContractObserver() >>> observer.register_child("loan1", child_contract) >>> events = observer.observe_events("loan1", current_time, attributes) >>> state = observer.observe_state("loan1", current_time, None, attributes) >>> notional = observer.observe_attribute("loan1", "notional_principal")
Note
This protocol uses runtime_checkable to allow isinstance() checks. Implementations should handle missing child contracts gracefully.
References
ACTUS v1.1 Section 2.10 - Child Contract Observer
- observe_events(identifier, time, attributes=None)[source]¶
Observe events from a child contract.
Returns all events from the identified child contract that occur at or after the specified time. This allows parent contracts to react to child contract events.
- Parameters:
identifier (str) – Child contract identifier
time (ActusDateTime) – Observation time
attributes (ContractAttributes | None) – Optional parent contract attributes for filtering
- Returns:
List of child contract events
- Return type:
Example
>>> events = observer.observe_events("child1", t0, parent_attrs) >>> principal_events = [e for e in events if e.event_type == EventType.PR]
- observe_state(identifier, time, state=None, attributes=None)[source]¶
Observe state from a child contract.
Returns the state of the identified child contract at the specified time. This allows parent contracts to access child contract state variables.
- Parameters:
identifier (str) – Child contract identifier
time (ActusDateTime) – Observation time
state (ContractState | None) – Optional parent state for context
attributes (ContractAttributes | None) – Optional parent attributes for context
- Returns:
Child contract state at the specified time
- Return type:
Example
>>> child_state = observer.observe_state("child1", t0, parent_state, parent_attrs) >>> child_notional = child_state.nt
- observe_attribute(identifier, attribute_name)[source]¶
Observe an attribute value from a child contract.
Returns the value of a specific attribute from the identified child contract. This allows parent contracts to access child contract configuration.
- Parameters:
- Returns:
Attribute value as JAX array
- Return type:
Example
>>> notional = observer.observe_attribute("child1", "notional_principal") >>> rate = observer.observe_attribute("child1", "nominal_interest_rate")
- __init__(*args, **kwargs)¶
- class jactus.observers.child_contract.BaseChildContractObserver[source]¶
Bases:
ABCAbstract base class for child contract observers.
Provides a common implementation pattern with error handling and validation. Subclasses implement the abstract methods to define observation behavior.
Example
>>> class MyObserver(BaseChildContractObserver): ... def _get_events(self, identifier, time, attributes): ... return self.children[identifier].get_events() ... def _get_state(self, identifier, time, state, attributes): ... return self.children[identifier].get_state(time) ... def _get_attribute(self, identifier, attribute_name): ... return getattr(self.children[identifier].attributes, attribute_name)
References
ACTUS v1.1 Section 2.10 - Child Contract Observer
- observe_events(identifier, time, attributes=None)[source]¶
Observe events from a child contract with error handling.
Wrapper that adds validation and error handling around _get_events.
- Parameters:
identifier (str) – Child contract identifier
time (ActusDateTime) – Observation time
attributes (ContractAttributes | None) – Optional parent attributes
- Returns:
List of child contract events
- Raises:
KeyError – If child contract not found
ValueError – If observation fails
- Return type:
- observe_state(identifier, time, state=None, attributes=None)[source]¶
Observe state from a child contract with error handling.
Wrapper that adds validation and error handling around _get_state.
- Parameters:
identifier (str) – Child contract identifier
time (ActusDateTime) – Observation time
state (ContractState | None) – Optional parent state
attributes (ContractAttributes | None) – Optional parent attributes
- Returns:
Child contract state
- Raises:
KeyError – If child contract not found
ValueError – If observation fails
- Return type:
- observe_attribute(identifier, attribute_name)[source]¶
Observe attribute from a child contract with error handling.
Wrapper that adds validation and error handling around _get_attribute.
- Parameters:
- Returns:
Attribute value as JAX array
- Raises:
KeyError – If child contract not found
AttributeError – If attribute not found
- Return type:
- class jactus.observers.child_contract.MockChildContractObserver[source]¶
Bases:
BaseChildContractObserverMock implementation for child contract observation.
This observer stores child contract data in dictionaries and provides simple observation capabilities. Useful for testing and development.
- child_events¶
Dictionary mapping child IDs to event lists
- child_states¶
Dictionary mapping child IDs to states
- child_attributes¶
Dictionary mapping child IDs to attribute dicts
Example
>>> observer = MockChildContractObserver() >>> # Register child contract data >>> observer.register_child("loan1", ... events=[event1, event2], ... state=loan_state, ... attributes={"notional_principal": 100000.0} ... ) >>> # Observe child data >>> events = observer.observe_events("loan1", t0) >>> state = observer.observe_state("loan1", t0) >>> notional = observer.observe_attribute("loan1", "notional_principal")
Note
This is a simple mock implementation. Real implementations would integrate with actual contract simulation engines.
References
ACTUS v1.1 Section 2.10 - Child Contract Observer
- register_child(identifier, events=None, state=None, attributes=None)[source]¶
Register a child contract with its data.
- Parameters:
identifier (str) – Child contract identifier
events (list[ContractEvent] | None) – Optional list of child events
state (ContractState | None) – Optional child state
attributes (dict[str, float] | None) – Optional dictionary of attribute name -> value
- Return type:
None
Example
>>> observer.register_child("child1", ... events=[ContractEvent(...)], ... state=ContractState(...), ... attributes={"notional_principal": 100000.0} ... )
- apply_conditions(attributes, overrides)[source]¶
Apply conditional attribute overrides to contract attributes.
This method temporarily modifies contract attributes based on child contract observations. Used in composite contracts where parent attributes depend on child state.
- Parameters:
attributes (ContractAttributes) – Original contract attributes
overrides (dict[str, float]) – Dictionary of attribute names to new values
- Returns:
New ContractAttributes with overrides applied
- Return type:
Example
>>> # Override notional based on child contract >>> child_notional = observer.observe_attribute("child1", "notional_principal") >>> new_attrs = observer.apply_conditions( ... parent_attrs, ... {"notional_principal": float(child_notional)} ... )
Note
This creates a new ContractAttributes instance rather than modifying the original (immutability).
- class jactus.observers.child_contract.SimulatedChildContractObserver[source]¶
Bases:
BaseChildContractObserverChild contract observer backed by full simulation histories.
Stores the complete event history from simulated child contracts and provides time-aware state lookups (returns state at the most recent event at or before the query time).
Example
>>> from jactus.contracts import create_contract >>> observer = SimulatedChildContractObserver() >>> child_result = child_contract.simulate() >>> observer.register_simulation("child1", child_result.events, child_attrs) >>> state = observer.observe_state("child1", query_time)
- register_simulation(identifier, events, attributes=None, initial_state=None)[source]¶
Register a child contract’s simulation results.
- Parameters:
identifier (str) – Child contract identifier
events (list[ContractEvent]) – Full list of simulated events (with state_pre/state_post)
attributes (ContractAttributes | None) – Optional child contract attributes
initial_state (ContractState | None) – Optional initial state (for queries before first event)
- Return type:
None
Behavioral Observer Framework¶
Behavioral risk factor observers for ACTUS contracts.
This module implements the Behavioral Risk Factor Observer framework, which provides state-dependent risk modeling capabilities. Unlike market risk factor observers that return values based solely on identifiers and time, behavioral observers are aware of the contract’s internal state (notional, interest rate, age, performance status, etc.) and can dynamically inject events into the simulation timeline.
Key concepts:
CalloutEvent: An event that a behavioral model requests be added to the simulation schedule. When the simulation reaches that time, it calls back to the behavioral observer with the current contract state.
BehaviorRiskFactorObserver: Protocol extending RiskFactorObserver with a
contract_startmethod that returns callout events.BaseBehaviorRiskFactorObserver: Abstract base class providing the framework for implementing concrete behavioral models.
This architecture mirrors the ACTUS risk service’s separation of market risk (pure time-series observation) from behavioral risk (state-dependent models like prepayment and deposit transaction behavior).
References
ACTUS Risk Service v2.0 - BehaviorRiskModelProvider interface ACTUS Technical Specification v1.1, Section 2.9 - Risk Factor Observer
- class jactus.observers.behavioral.CalloutEvent(model_id, time, callout_type, metadata=None)[source]¶
Bases:
objectAn event requested by a behavioral risk model for injection into the simulation schedule.
Behavioral models return these from
contract_start()to register observation times. When the simulation engine reaches the specified time, it evaluates the behavioral observer with the current contract state.- Parameters:
model_id (str)
time (ActusDateTime)
callout_type (str)
- model_id¶
Identifier of the behavioral model requesting this event (e.g.,
"ppm01"for a prepayment model).- Type:
- time¶
The time at which this observation event should occur.
- Type:
- callout_type¶
Type code indicating the nature of the callout. Common types include: -
"MRD"(Multiplicative Reduction Delta) for prepayment models -"AFD"(Absolute Funded Delta) for deposit transaction models- Type:
- metadata¶
Optional additional data the model needs at callout time (e.g., reference rate identifier, surface parameters).
Example
>>> from jactus.core import ActusDateTime >>> event = CalloutEvent( ... model_id="prepayment-model-01", ... time=ActusDateTime(2025, 6, 1), ... callout_type="MRD", ... )
- time: ActusDateTime¶
- class jactus.observers.behavioral.BehaviorRiskFactorObserver(*args, **kwargs)[source]¶
Bases:
ProtocolProtocol for behavioral risk factor observers.
Extends the standard risk factor observer concept with state-dependent observation and dynamic event injection. Behavioral observers:
Are called at the start of contract simulation via
contract_start()to register observation times (callout events).At those times, are called via
observe_risk_factor()with the full contract state, enabling state-dependent calculations.
This mirrors the ACTUS risk service’s
BehaviorRiskModelProviderinterface, which separates behavioral models from pure market data.All implementations should be JAX-compatible where possible.
- observe_risk_factor(identifier, time, state=None, attributes=None)[source]¶
Observe a behavioral risk factor at a specific time.
Unlike market risk observers, behavioral observers typically use the
stateandattributesparameters to compute their output. For example, a prepayment model computes the spread between the contract’s nominal interest rate and the current market rate.- Parameters:
identifier (str) – Risk factor identifier (e.g., model ID).
time (ActusDateTime) – Time at which to observe.
state (ContractState | None) – Current contract state (used for state-dependent factors).
attributes (ContractAttributes | None) – Contract attributes (used for contract-dependent factors).
- Returns:
Risk factor value as JAX array.
- Return type:
jnp.ndarray
- observe_event(identifier, event_type, time, state=None, attributes=None)[source]¶
Observe event-related behavioral data.
- Parameters:
identifier (str) – Event data identifier.
event_type (EventType) – Type of event.
time (ActusDateTime) – Time at which to observe.
state (ContractState | None) – Current contract state.
attributes (ContractAttributes | None) – Contract attributes.
- Returns:
Event-related data.
- Return type:
Any
- contract_start(attributes)[source]¶
Called at the start of contract simulation.
The behavioral model inspects the contract attributes to determine when it needs to be evaluated during the simulation. It returns a list of
CalloutEventobjects that the simulation engine merges into the event schedule.For example, a prepayment model might return semi-annual observation events over the life of the contract.
- Parameters:
attributes (ContractAttributes) – Contract attributes (terms and conditions).
- Returns:
List of callout events to inject into the simulation schedule. May be empty if the model does not need scheduled observations.
- Return type:
Example
>>> events = observer.contract_start(attributes) >>> for e in events: ... print(f"{e.model_id} @ {e.time}: {e.callout_type}")
- __init__(*args, **kwargs)¶
- class jactus.observers.behavioral.BaseBehaviorRiskFactorObserver(name=None)[source]¶
Bases:
BaseRiskFactorObserverAbstract base class for behavioral risk factor observers.
Provides the framework for implementing state-dependent risk models that can inject callout events into the simulation schedule. Subclasses must implement:
_get_risk_factor(): State-aware risk factor computation_get_event_data(): Event data retrievalcontract_start(): Callout event generation
Example
>>> class MyBehavioralModel(BaseBehaviorRiskFactorObserver): ... def _get_risk_factor(self, identifier, time, state, attributes): ... # Use state.ipnr (contract rate) in computation ... spread = float(state.ipnr) - 0.03 ... return jnp.array(max(spread, 0.0) * 0.1) ... ... def _get_event_data(self, identifier, event_type, time, state, attributes): ... raise KeyError("No event data") ... ... def contract_start(self, attributes): ... return [CalloutEvent("my-model", attributes.status_date, "MRD")]
- Parameters:
name (str | None)
- __init__(name=None)[source]¶
Initialize behavioral risk factor observer.
- Parameters:
name (str | None) – Optional name for this observer (for debugging).
- abstractmethod contract_start(attributes)[source]¶
Called at the start of contract simulation.
Must be implemented by subclasses to return callout events that should be injected into the simulation schedule.
- Parameters:
attributes (ContractAttributes) – Contract attributes.
- Returns:
List of CalloutEvent objects.
- Return type:
Prepayment Surface Observer¶
Prepayment behavioral risk model for ACTUS contracts.
This module implements a 2D surface-based prepayment model that computes prepayment rates as a function of:
Spread (dimension 1): The difference between the contract’s nominal interest rate and the current market reference rate. A positive spread means the borrower has an incentive to refinance.
Loan age (dimension 2): Time elapsed since the initial exchange date. Prepayment behavior typically follows a seasoning pattern, peaking in the middle years of a loan’s life.
The model returns a Multiplicative Reduction Delta (MRD) — a fraction by which the notional principal is reduced at each prepayment observation time.
This mirrors the TwoDimensionalPrepaymentModel from the ACTUS risk service,
with the addition of JAX compatibility for automatic differentiation.
References
ACTUS Risk Service v2.0 - TwoDimensionalPrepaymentModel ACTUS Technical Specification v1.1 - PP (Principal Prepayment) events
- class jactus.observers.prepayment.PrepaymentSurfaceObserver(surface, market_rate_id=None, market_observer=None, fixed_market_rate=0.0, prepayment_cycle='6M', model_id='prepayment-model', name=None)[source]¶
Bases:
BaseBehaviorRiskFactorObserverPrepayment model using a 2D surface (spread x loan age).
At each prepayment observation time, the model: 1. Computes the spread =
state.ipnr - market_rate(time)2. Computes the loan age = years sinceattributes.initial_exchange_date3. Looks up the prepayment rate from the 2D surface 4. Returns the prepayment rate as a JAX arrayThe market reference rate is obtained from a companion market observer or from a fixed reference rate.
- Parameters:
- surface¶
2D surface mapping (spread, age) to prepayment rate.
- market_rate_id¶
Identifier for the market reference rate (e.g.,
"UST-5Y"). If not provided,fixed_market_rateis used.
- market_observer¶
Optional companion market risk factor observer for fetching the current market rate.
- fixed_market_rate¶
Fixed market rate used when no market observer is provided (default 0.0).
- prepayment_cycle¶
Cycle string for prepayment event frequency (e.g.,
"6M"for semi-annual). Used bycontract_start()to generate callout events.
- model_id¶
Identifier for this prepayment model instance.
Example
>>> import jax.numpy as jnp >>> from jactus.utilities.surface import Surface2D >>> surface = Surface2D( ... x_margins=jnp.array([-5.0, 0.0, 1.0, 2.0, 3.0]), ... y_margins=jnp.array([0.0, 1.0, 2.0, 3.0, 5.0, 10.0]), ... values=jnp.array([ ... [0.00, 0.00, 0.00, 0.00, 0.00, 0.00], # spread=-5% ... [0.00, 0.00, 0.01, 0.00, 0.00, 0.00], # spread= 0% ... [0.00, 0.01, 0.02, 0.00, 0.00, 0.00], # spread= 1% ... [0.00, 0.02, 0.05, 0.03, 0.005, 0.00], # spread= 2% ... [0.01, 0.05, 0.10, 0.07, 0.02, 0.00], # spread= 3% ... ]), ... ) >>> observer = PrepaymentSurfaceObserver( ... surface=surface, ... fixed_market_rate=0.04, ... prepayment_cycle="6M", ... )
- __init__(surface, market_rate_id=None, market_observer=None, fixed_market_rate=0.0, prepayment_cycle='6M', model_id='prepayment-model', name=None)[source]¶
Initialize prepayment surface observer.
- Parameters:
surface (Surface2D) – 2D surface mapping (spread, age) to prepayment rate.
market_rate_id (str | None) – Identifier for the market reference rate.
market_observer (Any | None) – Optional market risk factor observer.
fixed_market_rate (float) – Fixed market rate when no observer is provided.
prepayment_cycle (str) – Cycle for prepayment observation frequency.
model_id (str) – Unique model identifier.
name (str | None) – Optional observer name for debugging.
- contract_start(attributes)[source]¶
Generate prepayment observation events over the contract life.
Creates callout events at the specified prepayment cycle interval from the initial exchange date to the maturity date.
- Parameters:
attributes (ContractAttributes) – Contract attributes.
- Returns:
List of CalloutEvent objects with callout_type
"MRD".- Return type:
Deposit Transaction Observer¶
Deposit transaction behavioral risk model for ACTUS contracts.
This module implements a deposit transaction model for UMP (Undefined Maturity Profile) contracts. It models deposit inflows and outflows as a function of:
Dimension 1: Contract identifier (which specific deposit account)
Dimension 2: Date/time of the transaction
The model uses a labeled 2D surface where the x-axis is the contract ID and the y-axis is a date label, returning the transaction amount (an Absolute Funded Delta — the absolute change in the deposit balance).
This mirrors the TwoDimensionalDepositTrxModel from the ACTUS risk
service.
References
ACTUS Risk Service v2.0 - TwoDimensionalDepositTrxModel ACTUS Technical Specification v1.1 - UMP contract type
- class jactus.observers.deposit_transaction.DepositTransactionObserver(transactions, model_id='deposit-trx-model', name=None)[source]¶
Bases:
BaseBehaviorRiskFactorObserverDeposit transaction model for UMP contracts.
Models deposit inflows and outflows using a schedule of known or projected transactions. Each contract identifier has its own transaction schedule, looked up from a labeled surface or a simpler time-series mapping.
At each transaction observation time, the model returns the Absolute Funded Delta (AFD) — the change in the deposit balance (positive for inflows, negative for outflows).
- Parameters:
- transactions¶
Dictionary mapping contract identifiers to a sorted list of
(ActusDateTime, float)pairs (time, amount).
- model_id¶
Identifier for this deposit model instance.
Example
>>> from jactus.core import ActusDateTime >>> observer = DepositTransactionObserver( ... transactions={ ... "DEPOSIT-001": [ ... (ActusDateTime(2024, 1, 15), 10000.0), ... (ActusDateTime(2024, 4, 15), -2000.0), ... (ActusDateTime(2024, 7, 15), 5000.0), ... ], ... "DEPOSIT-002": [ ... (ActusDateTime(2024, 2, 1), 50000.0), ... (ActusDateTime(2024, 8, 1), -10000.0), ... ], ... }, ... )
- __init__(transactions, model_id='deposit-trx-model', name=None)[source]¶
Initialize deposit transaction observer.
- classmethod from_labeled_surface(surface, date_parser=None, model_id='deposit-trx-model', name=None)[source]¶
Create from a LabeledSurface2D.
The x-axis labels are contract IDs and y-axis labels are date strings.
- Parameters:
surface (LabeledSurface2D) – Labeled 2D surface with contract IDs and date labels.
date_parser (Any) – Optional callable to parse date labels into ActusDateTime. Defaults to
ActusDateTime.from_iso.model_id (str) – Unique model identifier.
name (str | None) – Optional observer name.
- Returns:
New DepositTransactionObserver instance.
- Return type:
- contract_start(attributes)[source]¶
Generate callout events for all scheduled transactions.
Returns a callout event for each transaction time associated with the contract’s
contract_id.- Parameters:
attributes (ContractAttributes) – Contract attributes (uses
contract_idto look up the transaction schedule).- Returns:
List of CalloutEvent objects with callout_type
"AFD".- Return type:
Scenario Management¶
Scenario management for ACTUS contract simulation.
A Scenario bundles together all the risk factor observers (both market
and behavioral) needed for a simulation run into a single, named,
reusable configuration.
This provides a higher-level abstraction over individual observers, enabling: - Named, reusable simulation configurations - Consistent bundling of market data with behavioral models - Easy scenario comparison (base case vs. stress scenarios)
The scenario automatically composes its market and behavioral observers
using a CompositeRiskFactorObserver so that a single unified observer
can be passed to the simulation engine.
References
ACTUS Risk Service v2.0 - Scenario API
- class jactus.observers.scenario.Scenario(scenario_id, description='', market_observers=<factory>, behavior_observers=<factory>)[source]¶
Bases:
objectA named simulation scenario bundling market and behavioral observers.
A scenario acts as a simulation environment, declaring which market data sources and behavioral models are available. It provides a unified risk factor observer that the simulation engine can use directly.
- Parameters:
scenario_id (str)
description (str)
market_observers (dict[str, RiskFactorObserver])
behavior_observers (dict[str, BehaviorRiskFactorObserver])
- market_observers¶
Dictionary mapping identifiers to market risk factor observers. These handle pure market data lookups (time series, curves, constants).
- behavior_observers¶
Dictionary mapping identifiers to behavioral risk factor observers. These are state-aware and can inject callout events into the simulation timeline.
Example
>>> from jactus.observers import ( ... ConstantRiskFactorObserver, ... TimeSeriesRiskFactorObserver, ... ) >>> from jactus.observers.prepayment import PrepaymentSurfaceObserver >>> >>> scenario = Scenario( ... scenario_id="base-case", ... description="Base case with 5Y UST falling and moderate prepayment", ... market_observers={ ... "rates": TimeSeriesRiskFactorObserver({ ... "UST-5Y": [ ... (ActusDateTime(2024, 1, 1), 0.045), ... (ActusDateTime(2025, 1, 1), 0.035), ... ], ... }), ... }, ... behavior_observers={ ... "prepayment": prepayment_observer, ... }, ... ) >>> # Get unified observer for simulation >>> observer = scenario.get_observer() >>> contract.simulate(risk_factor_observer=observer)
- market_observers: dict[str, RiskFactorObserver]¶
- behavior_observers: dict[str, BehaviorRiskFactorObserver]¶
- get_observer()[source]¶
Get a unified risk factor observer that combines all market observers.
Returns a
CompositeRiskFactorObserverthat chains all market observers in order, providing a single observer for the simulation engine.If only one market observer is configured, it is returned directly. If no market observers are configured, raises ValueError.
- Returns:
Unified RiskFactorObserver.
- Raises:
ValueError – If no market observers are configured.
- Return type:
- get_callout_events(attributes)[source]¶
Collect callout events from all behavioral observers.
Calls
contract_start()on each behavioral observer and aggregates the returned callout events.- Parameters:
attributes (ContractAttributes) – Contract attributes.
- Returns:
Combined list of callout events from all behavioral models, sorted by time.
- Return type:
- add_market_observer(identifier, observer)[source]¶
Add or replace a market risk factor observer.
- Parameters:
identifier (str) – Observer identifier.
observer (RiskFactorObserver) – Market risk factor observer.
- Return type:
None
- add_behavior_observer(identifier, observer)[source]¶
Add or replace a behavioral risk factor observer.
- Parameters:
identifier (str) – Observer identifier.
observer (BehaviorRiskFactorObserver) – Behavioral risk factor observer.
- Return type:
None
- __init__(scenario_id, description='', market_observers=<factory>, behavior_observers=<factory>)¶
- Parameters:
scenario_id (str)
description (str)
market_observers (dict[str, RiskFactorObserver])
behavior_observers (dict[str, BehaviorRiskFactorObserver])
- Return type:
None
Portfolio API¶
Simulation Engine¶
CLI¶
Exceptions¶
Custom exception classes for ACTUS-specific errors.
This module defines a hierarchy of exceptions used throughout the actus_jax package. All exceptions inherit from ActusException, which provides common functionality for error handling and context preservation.
- exception jactus.exceptions.ActusException(message, context=None)[source]¶
Bases:
ExceptionBase exception for all ACTUS-related errors.
This is the base class for all custom exceptions in the actus_jax package. It provides common functionality for storing context information about errors.
- message¶
Human-readable error description
- context¶
Additional context information about the error
- exception jactus.exceptions.ContractValidationError(message, context=None)[source]¶
Bases:
ActusExceptionException raised for invalid contract attributes or configuration.
This exception should be raised when: - Required contract attributes are missing - Attribute values are outside valid ranges - Attribute combinations are inconsistent - Contract type is not supported
Example
>>> raise ContractValidationError( ... "Nominal value must be positive", ... context={"contract_id": "PAM-001", "nominal": -1000} ... )
- exception jactus.exceptions.ScheduleGenerationError(message, context=None)[source]¶
Bases:
ActusExceptionException raised for errors during schedule generation.
This exception should be raised when: - Schedule generation algorithm fails - Date sequences are invalid - Calendar or business day adjustments fail - Cycle specifications are inconsistent
Example
>>> raise ScheduleGenerationError( ... "Invalid cycle specification for interest payment", ... context={"cycle": "P0M", "anchor_date": "2024-01-01"} ... )
- exception jactus.exceptions.StateTransitionError(message, context=None)[source]¶
Bases:
ActusExceptionException raised for invalid state transitions.
This exception should be raised when: - State transition function encounters invalid inputs - Numerical instability in state calculations - State values violate invariants - JAX compilation issues in state transitions
Example
>>> raise StateTransitionError( ... "Negative interest rate sensitivity detected", ... context={"event": "IP", "time": "2024-06-01", "state": {...}} ... )
- exception jactus.exceptions.PayoffCalculationError(message, context=None)[source]¶
Bases:
ActusExceptionException raised for errors in payoff calculations.
This exception should be raised when: - Payoff function produces invalid results (NaN, Inf) - Required market data is missing - Numerical overflow/underflow occurs - Business rules are violated
Example
>>> raise PayoffCalculationError( ... "Division by zero in fee calculation", ... context={"event": "FP", "time": "2024-03-15", "fee_basis": 0} ... )
- exception jactus.exceptions.ObserverError(message, context=None)[source]¶
Bases:
ActusExceptionException raised for risk factor or child contract observation errors.
This exception should be raised when: - Risk factor observer cannot provide required data - Market data is unavailable for the requested time - Child contract evaluation fails - Observer state is inconsistent
Example
>>> raise ObserverError( ... "No exchange rate data available for requested date", ... context={"currency_pair": "EUR/USD", "date": "2024-01-15"} ... )
- exception jactus.exceptions.DateTimeError(message, context=None)[source]¶
Bases:
ActusExceptionException raised for date/time parsing or calculation errors.
This exception should be raised when: - Date string parsing fails - Timezone conversion issues occur - Date arithmetic produces invalid results - Calendar operations fail
Example
>>> raise DateTimeError( ... "Unable to parse ISO date string", ... context={"date_string": "2024-13-45", "format": "ISO8601"} ... )
- exception jactus.exceptions.ConventionError(message, context=None)[source]¶
Bases:
ActusExceptionException raised for day count or business day convention errors.
This exception should be raised when: - Unknown day count convention specified - Business day adjustment fails - End-of-month rules produce invalid dates - Convention application is ambiguous
Example
>>> raise ConventionError( ... "Unsupported day count convention", ... context={"convention": "ACT/999", "supported": ["30E/360", "ACT/365"]} ... )
- exception jactus.exceptions.ConfigurationError(message, context=None)[source]¶
Bases:
ActusExceptionException raised for configuration and initialization errors.
This exception should be raised when: - Package configuration is invalid - Required environment variables are missing - Initialization parameters are inconsistent - Resource loading fails
Example
>>> raise ConfigurationError( ... "Invalid logging configuration", ... context={"log_level": "INVALID", "valid_levels": ["DEBUG", "INFO"]} ... )
- exception jactus.exceptions.EngineError(message, context=None)[source]¶
Bases:
ActusExceptionException raised for simulation and portfolio engine errors.
This exception should be raised when: - Portfolio simulation fails - Batch processing encounters errors - Resource allocation issues occur - Parallel execution fails
Example
>>> raise EngineError( ... "Portfolio simulation failed due to memory constraints", ... context={"num_contracts": 10000, "memory_gb": 8} ... )
Logging¶
Centralized logging configuration for jactus.
This module provides a flexible logging setup that can be configured via environment variables or programmatically. It supports multiple handlers, structured logging, and performance monitoring.
- class jactus.logging_config.StructuredFormatter(fmt=None, datefmt=None, style='%', validate=True, *, defaults=None)[source]¶
Bases:
FormatterFormatter that outputs log records as JSON for structured logging.
- jactus.logging_config.get_logger(name, level=None)[source]¶
Get a logger instance with the specified name and level.
- Parameters:
- Returns:
Configured logger instance
- Return type:
Example
>>> logger = get_logger(__name__) >>> logger.info("Processing contract", extra={"contract_id": "PAM-001"})
- jactus.logging_config.configure_logging(level=None, log_file=None, console=True, structured=False, max_bytes=10485760, backup_count=5)[source]¶
Configure logging for the entire jactus package.
This function sets up logging handlers and formatters for the package. It should typically be called once at application startup.
- Parameters:
level (str | None) – Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL). Defaults to environment variable or INFO.
log_file (str | None) – Path to log file. Defaults to environment variable or jactus.log in current directory.
console (bool) – Whether to log to console (stdout). Default: True
structured (bool) – Whether to use JSON structured logging. Default: False Can be overridden by ACTUS_JAX_STRUCTURED_LOGS env var.
max_bytes (int) – Maximum size of log file before rotation (default: 10MB)
backup_count (int) – Number of backup log files to keep (default: 5)
- Return type:
None
Example
>>> # Simple configuration >>> configure_logging(level="DEBUG") >>> >>> # Full configuration with file logging >>> configure_logging( ... level="INFO", ... log_file="/var/log/jactus.log", ... structured=True ... )
- jactus.logging_config.get_performance_logger(name)[source]¶
Get a logger configured for performance monitoring.
Performance loggers are typically used to log timing information, memory usage, and other performance metrics. They default to DEBUG level and can be controlled separately from regular loggers.
- Parameters:
name (str) – Name of the performance logger
- Returns:
Logger configured for performance monitoring
- Return type:
Example
>>> perf_logger = get_performance_logger("jactus.engine") >>> import time >>> start = time.time() >>> # ... do work ... >>> elapsed = time.time() - start >>> perf_logger.debug("Portfolio simulation completed", ... extra={"duration_ms": elapsed * 1000, ... "num_contracts": 1000})
Quick Reference¶
Contract Type Summary¶
Principal Contracts
PAM - Principal at Maturity (interest-only loans, bonds)
LAM - Linear Amortizer (fixed principal amortization)
LAX - Exotic Linear Amortizer (variable amortization schedules)
NAM - Negative Amortizer (negative amortization loans)
ANN - Annuity (level payment amortization)
CLM - Call Money (callable overnight lending)
UMP - Undefined Maturity Profile (open-ended deposits, revolving credit)
Non-Principal Contracts
CSH - Cash (money market accounts, escrow)
STK - Stock (equity positions)
COM - Commodity (physical commodities)
Derivative Contracts
FXOUT - Foreign Exchange Outright (FX forwards, swaps)
OPTNS - Options (calls, puts, European/American)
FUTUR - Futures (standardized forward contracts)
SWPPV - Plain Vanilla Swap (fixed vs floating interest rate swaps)
SWAPS - Generic Swap (cross-currency swaps, multi-leg swaps)
CAPFL - Cap/Floor (interest rate caps and floors)
CEG - Credit Enhancement Guarantee (credit protection)
CEC - Credit Enhancement Collateral (collateral management)
Key Classes and Functions¶
Creating Contracts:
from jactus.contracts import create_contract
from jactus.core import ContractAttributes, ContractType, ContractRole, ActusDateTime
from jactus.observers import ConstantRiskFactorObserver
attrs = ContractAttributes(
contract_id="LOAN-001",
contract_type=ContractType.PAM,
contract_role=ContractRole.RPA,
status_date=ActusDateTime(2024, 1, 1),
initial_exchange_date=ActusDateTime(2024, 1, 15),
maturity_date=ActusDateTime(2025, 1, 15),
notional_principal=100_000.0,
nominal_interest_rate=0.05,
)
rf_observer = ConstantRiskFactorObserver(constant_value=0.05)
contract = create_contract(attrs, rf_observer)
Running Simulations:
# Run simulation — returns SimulationHistory
result = contract.simulate()
# Access events
for event in result.events:
print(f"{event.event_time}: {event.event_type.name} ${event.payoff:,.2f}")
Working with Time:
from jactus.core import ActusDateTime
dt = ActusDateTime(2024, 1, 1, 0, 0, 0)
Schedule Generation:
from jactus.utilities.schedules import generate_schedule
schedule = generate_schedule(
start=start_date,
end=end_date,
cycle="3M" # Quarterly
)
See Also¶
Quick Start - Get started with JACTUS
User Guides - User guides and tutorials
ACTUS Specification Overview - ACTUS specification overview