Latest release notes#

For information on previous versions, please see:

v9.2#

New to v9?

See Introduction to v9.0 for help updating your code.

New features#

Options: Added risk_scenario function for single options and option strategies#

Simulate spot and implied volatility changes for both single options and option strategies. Shift spot prices over the entire duration of a single option or strategy, or a single day.

Code examples below—run each code block as a separate cell:

import datetime as dtm
import sigtech.framework as sig
env = sig.init()

group = sig.obj.get("USDJPY OTC OPTION GROUP")

Risk scenario for single option:

opt = group.get_option(
    start_date=dtm.date(2023, 1, 2),
    strike_type="Delta",
    strike=0.5,
    maturity=dtm.date(2023, 4, 3),
    option_type="Call",
)

# shift spot by +5% and calculate change in greeks
opt.risk_scenario(
    shift_type="spot",
    shift_bps=500,
    delta_from_base=True)

# shift spot by +5% and calculate new greeks
opt.risk_scenario(
    shift_type="spot",
    shift_bps=500,
    delta_from_base=False)

# shift vol by +5 vol points and calculate change in greeks
opt.risk_scenario(
    shift_type="spot",
    shift_bps=500,
    delta_from_base=True)

# shift vol by +5 vol points and calculate new greeks
opt.risk_scenario(
    shift_type="spot",
    shift_bps=500,
    delta_from_base=False)

Risk scenario for option strategy:

bf = sig.RollingButterflyOptionsStrategy(
    start_date=dtm.date(2021, 1, 4),
    end_date=dtm.date(2023, 1, 4),
    currency=group.underlying_obj.currency,
    group_name=group.name,
    rolling_frequencies=["3M"],
    maturity="12M",
    strike_type="SPOT",
    strike_1="ATM",
    strike_2="ATM+3%",
    strike_3="ATM+5%",
    option_type="Call",
    direction="long",
)

# shift spot by +5% and calculate change in greeks
bf.risk_scenario(
    shift_type="spot",
    shift_bps=500,
    delta_from_base=True)

# shift spot by +5% and calculate new greeks
bf.risk_scenario(
    shift_type="spot",
    shift_bps=500,
    delta_from_base=False)

# shift vol by +5 vol points and calculate change in greeks
bf.risk_scenario(
    shift_type="spot",
    shift_bps=500,
    delta_from_base=True)

# shift vol by +5 vol points and calculate new greeks
bf.risk_scenario(
    shift_type="spot",
    shift_bps=500,
    delta_from_base=False)

Options: Added risk matrix for single options#

Single options are now more sensitive to spot or implied volatility changes.

With the .risk_matrix function, users can simulate price shocks by shifting either spot or volatility (shift_type). This function calculates the change in Greeks and P&L (profit and loss explained), enabling users to observe the effect of spot or implied volatility changes on single options.

Code examples—run each code block in a separate cell:

import datetime as dtm
import sigtech.framework as sig
env = sig.init()

group = sig.obj.get("EURUSD OTC OPTION GROUP")
opt = group.get_option(
    start_date=dtm.date(2023, 1, 2),
    strike_type="Delta",
    strike=0.5,
    maturity=dtm.date(2023, 4, 3),
    option_type="Call",
)
# shift spot from -5% to +5% and calculate change in greeks
opt.risk_matrix(
    value_date=dtm.date(2023, 1, 2),
    shift_type="spot",
    num_steps=5,
    max_shift_bps=500,
    delta_from_base=True)
# shift spot from -5% to +5% and calculate new greeks
opt.risk_matrix(
    value_date=dtm.date(2023, 1, 2),
    shift_type="spot",
    num_steps=5,
    max_shift_bps=500,
    delta_from_base=False)
# shift vol from -5 vol points to +5 vol points and calculate change in greeks
opt.risk_matrix(
    value_date=dtm.date(2023, 1, 2),
    shift_type="vol",
    num_steps=5,
    max_shift_bps=500,
    delta_from_base=True)
# shift spot from -5 vol points to +5 vol points and calculate new greeks
opt.risk_matrix(
    value_date=dtm.date(2023, 1, 2),
    shift_type="vol",
    num_steps=5,
    max_shift_bps=500,
    delta_from_base=False)

Options: Added risk matrix for option strategies#

Options strategies are now more sensitive to spot or implied volatility changes.

With the .risk_matrix function, users can simulate price shocks by shifting either spot or volatility (shift_type). This function calculates the change in Greeks and P&L (profit and loss explained), enabling users to observe the effect of spot or implied volatility changes on option strategies.

Code examples—run each code block in a separate cell:

import datetime as dtm
import sigtech.framework as sig

env = sig.init()
group = sig.obj.get("USDJPY OTC OPTION GROUP")
bf = sig.RollingButterflyOptionsStrategy(
    start_date=dtm.date(2021, 1, 4),
    end_date=dtm.date(2023, 1, 4),
    currency=group.underlying_obj.currency,
    group_name=group.name,
    rolling_frequencies=["3M"],
    maturity="12M",
    strike_type="SPOT",
    strike_1="ATM",
    strike_2="ATM+3%",
    strike_3="ATM+5%",
    option_type="Call",
    direction="long",
)
bf.history().tail()
# shift spot from -5% to +5% and calculate change in greeks
bf.risk_matrix(
    value_date=dtm.date(2023, 1, 2),
    shift_type="spot",
    num_steps=5,
    max_shift_bps=500,
    delta_from_base=True)
# shift spot from -5% to +5% and calculate new greeks
bf.risk_matrix(
    value_date=dtm.date(2023, 1, 2),
    shift_type="spot",
    num_steps=5,
    max_shift_bps=500,
    delta_from_base=False)
# shift vol from -5 vol points to +5 vol points and calculate change in greeks
bf.risk_matrix(
    value_date=dtm.date(2023, 1, 2),
    shift_type="vol",
    num_steps=5,
    max_shift_bps=500,
    delta_from_base=True)
# shift vol from -5 vol points to +5 vol points and calculate new greeks
bf.risk_matrix(
    value_date=dtm.date(2023, 1, 2),
    shift_type="vol",
    num_steps=5,
    max_shift_bps=500,
    delta_from_base=False)

Futures: New parameter roll_on_calendar_days added to rolling rules#

You can now choose to roll on calendar days instead of business days when using the RollingFutureStrategy and RFPriceIndex classes. For example, you could choose to roll on the 20th of every month instead of the 20th business day.

When the roll_on_calendar_days parameter is set to True, the monthly_roll_days are taken as calendar days rather than business days.

Roll all contracts on the 20th calendar day of the month:

import datetime as dtm
import sigtech.framework as sig

env = sig.init()

rfs = sig.RollingFutureStrategy(
    start_date=dtm.date(2018, 10, 23),
    contract_code="NG",
    contract_sector="COMDTY",
    rolling_rule="f_0",
    roll_on_calendar_days=True,
    monthly_roll_days="20,20",
    total_return=False,
)
rfs.rolling_table

Improvements#

Futures: Added calculation_start_date method to RFPriceIndex#

Previously, users could create a RollingFutureStrategy without a start date, but not a RFPriceIndex. By adding a calculation_start_date method to the RFPriceIndex class, users no longer need to provide a start_date.

This ensures more consistent behavior between RollingFutureStrategy and RFPriceIndex.

Code example:

rfs = sig.RFPriceIndex(
        currency="USD",
        contract_code="ES",
        contract_sector="INDEX",
        rolling_rule="front",
        front_offset="-3,-2"
    )
rfs.history().tail()

Bug fixes#

Futures: Added holidays property to all futures instruments#

The holidays property, which contains a list of holiday calendars, has been added to futures classes. Previously it was missing, causing an error when calling .history with a futures class.

Code example:

sig.obj.get("ESH24 INDEX").holidays

Futures: Added rounded_units parameter to historic_positions and evaluate_positions methods#

Previously, the historic_positions method would return an error, as it would call the evaluate_trades method without setting the new rounded_units parameter.

To solve this problem, the rounded_units parameter has been added to the methods. Set rounded_units to False to obtain a more precise result.

Code example:

import datetime as dtm
import sigtech.framework as sig

rfs = sig.RollingFutureStrategy(
    currency='USD',
    start_date=dtm.date(2023, 1, 1),
    end_date=dtm.date(2024, 1, 1),
    contract_code='ES',
    contract_sector='INDEX',
    rolling_rule='front',
    front_offset='-6,-5'
)
rfs.inspect.historic_positions("TOP_ORDER_PTS", rounded_units=False)

Discounting and forecasting curves: Added new methods to calculate any forward and zero rate#

New forward_rate and zero_rate methods for discounting and forecasting curves let users get forward rate and zero rates:

Code examples—run each code block in a separate cell:

import sigtech.framework as sig
from sigtech.framework.instruments.ir_otc import IRSwapMarket
import datetime as dtm
env = sig.init()

Get USD discounting curve:

discounting_curve = sig.obj.get(IRSwapMarket.discounting_curve_name("USD")
discounting_curve

Get forward rate:

discounting_curve.forward_rate(
  effective_date=dtm.date(2024, 3, 13),
  start_date=dtm.date(2024, 3, 22),
  end_date=dtm.date(2024, 3, 28))

Get zero rate:

discounting_curve.zero_rate(
  effective_date=dtm.date(2024, 3, 13),
  end_date=dtm.date(2024, 3, 28))