New framework version

The SigTech platform is transitioning to framework version 8

Tip: there are now two versions of the user guide—use the dropdown in the top-left corner of the screen to toggle between them.

List of updates

To make the framework more intuitive, the following updates have been made:

Important: all deprecated methods, classes and modules will display an error in v8.

New to SigTech? Please switch to the version 8 User Guide.

Trading Manager calendar default set to none

Reason for change

The special calendar 'London,CHR CALENDAR' , which includes the Christmas holiday, will no longer be used as default for the Trading Manager.

The new default calendar for the Trading Manager is 'None'.

How to recover the old behaviour

The change of the default calendar for the Trading Manager may cause numerical mismatches. The old behaviour is replicated by setting the Trading Manager calendar after using sig.init() to:

import sigtech.framework as sig

env = sig.init() 
env[sig.config.TM_CALENDAR] = 'London,CHR CALENDAR'

Deactivate transaction costs as default to simplify onboarding

Reason for change

To make the use of the framework more intuitive and clear, transaction costs are not used by default.

How to recover the old behaviour

The change on the default value for the usage of transaction costs may cause numerical mismatches. The old behaviour is replicated by explicitly setting the transaction costs after using sig.init()to:

import sigtech.framework as sig

env = sig.init()
env[sig.config.IGNORE_T_COSTS] = False

Update to Greeks scaling

Greeks scaling has been changed to adhere to market expectations.

For Equity Index, Commodity or FX options:

  • Vega is now sensitivity to a 1% change in volatility. Old vega is multiplied by 0.01.

  • Vega target in Rolling Option strategies is adjusted accordingly—100 old is equivalent to 1 new.

  • Gamma is sensitivity to a delta change to 1% of underlying.

Example: for SPX at 4000, gamma is change in delta when SPX moves by 40. The old gamma times spot/100.

  • Dollar gamma is sensitivity to a change of dollar delta to 1% of underlying. Old dollar gamma times 2 / 100— the old derivative was previously / 2.

For swaptions:

  • Vega is sensitivity to a 1bp change in volatility. This is 0.0001 of old vega.

  • Delta is sensitivity to a 1bp change in swap rate. This is 0.0001 of old delta.

  • Gamma is change in delta per 1bp change in swap rate. This is 0.0001*0.0001 of old gamma.

  • Targets in options and swaptions strategies should be adjusted accordingly.

Deprecated methods or properties that will raise an exception if used in v8

Note: to help identify usages of these methods, if code is run on the latest version 7 with a log_level set to 'WARNING' their use will be flagged in reported warnings.

  • framework.infra.mu.calc()

  • framework.infra.analytics.fx.cross.FXCross.is_flipped_cross()

  • framework.indices.tradable_index.IntradayInstrument.intraday_db_field

  • framework.config.config.ConfiguredEnvironment._quant_bridge

  • framework.strategies.rolling_bond_strategy.RollingBondStrategy.get_roll_schedule()

  • framework.strategies.reinvestment_strategy.get_single_stock_strategy_name_parallel()

  • framework.strategies.reinvestment_strategy.get_reinvestment_strategy()

  • framework.strategies.strategy.Strategy.add_processor()

  • framework.strategies.strategy.Strategy.add_processor_with_priority()

  • framework.strategies.strategy.Strategy.set_weight()

  • framework.strategies.strategy.Strategy.clean_up_margin()

  • framework.strategies.strategy.Strategy.set_position()

  • framework.strategies.strategy.Strategy.add_position()

  • framework.strategies.strategy.Strategy.stop_processing()

  • framework.strategies.strategy.Strategy.ir_swap_trade()

  • framework.strategies.strategy.Strategy.tr_swap_trade()

  • framework.strategies.strategy.Strategy.index_swap_trade()

  • framework.strategies.strategy.Strategy.fx_forward_trade()

  • framework.strategies.strategy.Strategy.fx_spot_trade()

  • framework.strategies.strategy.Strategy.lme_forward_trade()

  • framework.strategies.strategy.Strategy.lme_spread_trade()

  • framework.strategies.strategy.Strategy.index_forward_trade()

  • framework.strategies.strategy.Strategy.brl_swap_trade()

  • framework.strategies.strategy.Strategy.credit_index_trade()

  • framework.strategies.strategy.Strategy.xccy_swap_trade()

  • framework.strategies.strategy.Strategy.excess_return_history()

  • framework.strategies.strategy.Strategy.total_return_valuation_history()

  • framework.strategies.strategy.Strategy.get_object()

  • framework.strategies.strategy.Strategy.pnl_breakdown()

  • framework.strategies.strategy.Strategy.turnover()

  • framework.strategies.strategy.Strategy.intraday_turnover()

  • framework.strategies.strategy.Strategy.cash_turnover()

  • framework.strategies.strategy.Strategy.turnover_stats()

  • framework.strategies.strategy.Strategy.evaluate_trades()

  • framework.strategies.strategy.Strategy.evaluate_positions()

  • framework.strategies.strategy.Strategy.historic_positions()

  • framework.strategies.strategy.Strategy.approximate_rounding_impact()

  • framework.strategies.strategy.Strategy.approximate_rounding_summary()

  • framework.strategies.strategy.Strategy.relative_attribution()

  • framework.strategies.strategy.Strategy.display_holdings()

  • framework.strategies.strategy.Strategy.display_run_details()

  • framework.strategies.strategy.Strategy.positions_df()

  • framework.strategies.strategy.Strategy.weights_df()

  • framework.strategies.strategy.Strategy.cash_df()

  • framework.strategies.strategy.Strategy.bottom_positions_df()

  • framework.strategies.strategy.Strategy.bottom_cash_df()

  • framework.strategies.strategy.Strategy.timeline_data()

  • framework.strategies.strategy.Strategy.interactive_tree_plot()

  • framework.strategies.strategy.Strategy.interactive_portfolio_table()

  • framework.strategies.strategy.Strategy.tree_df()

  • framework.strategies.strategy.Strategy.interactive_timeline_plot()

  • framework.strategies.strategy.Strategy.interactive_performance()

  • framework.instruments.options.OptionBase.pnl_breakdown()

  • framework.instruments.options.CommodityFutureOption.underlying_name

  • framework.instruments.fixes.IntradayFix.underlying_name

  • framework.instruments.ir_otc.InterestRateSwap.is_ir_swap()

  • framework.instruments.sig_master.SIGMasterBase.filter_to_last_corporate_event()

  • framework.instruments.index_swap.IndexSwap.is_index_swap()

  • framework.instruments.swaption.Swaption.pnl_breakdown()

  • framework.instruments.swaption.Swaption.underlying_name

  • framework.instruments.trs_otc.TotalReturnSwap.is_tr_swap()

  • framework.instruments.bonds.BondBase.is_bond()

  • framework.instruments.bonds.GovernmentBondRepo.is_bond_repo()

  • framework.instruments.bonds.GovernmentBondSwap.is_bond_swap()

  • framework.instruments.lme_otc.create_lme_forward()

  • framework.instruments.equities.rolling_dollar_vol()

  • framework.instruments.equities.SingleStock.is_equity_single_stock()

  • framework.instruments.equities.SingleStockSwap.is_equity_swap()

  • framework.instruments.equities.ExchangeTradedFund.is_etf()

  • framework.instruments.fx_otc.FXForward.is_fx_forward()

  • framework.instruments.base.ContractGroup.contract_product_type

  • framework.instruments.base.HistoricalFrameworkObject.underlying_str

  • framework.instruments.base.Instrument.is_future()

  • framework.instruments.base.Instrument.is_synthetic_swap()

  • framework.instruments.base.Instrument.is_equity_swap()

  • framework.instruments.base.Instrument.is_bond_repo()

  • framework.instruments.base.Instrument.is_bond_swap()

  • framework.instruments.base.Instrument.is_ir_swap()

  • framework.instruments.base.Instrument.is_index_swap()

  • framework.instruments.base.Instrument.is_ir_bh_swap()

  • framework.instruments.base.Instrument.is_tr_swap()

  • framework.instruments.base.Instrument.is_bond()

  • framework.instruments.base.Instrument.is_fx_forward()

  • framework.instruments.base.Instrument.is_order()

  • framework.instruments.base.Instrument.is_equity_single_stock()

  • framework.instruments.base.Instrument.is_etf()

  • framework.signal.library.allocation.factor_optimized_allocations()

The following methods or properties are deprecated on the Strategy class, but to continue using them the strategy can be derived from the DailyStrategy class instead:

  • framework.strategies.strategy.Strategy.size_date_from_decision_dt()

  • framework.strategies.strategy.Strategy.size_dt_from_date()

  • framework.strategies.strategy.Strategy.size_date_from_date()

  • framework.strategies.strategy.Strategy._decision_time()

  • framework.strategies.strategy.Strategy._decision_tzinfo()

  • framework.strategies.strategy.Strategy.size_time()

  • framework.strategies.strategy.Strategy.size_tzinfo()

  • framework.strategies.strategy.Strategy.execution_time()

  • framework.strategies.strategy.Strategy.execution_tzinfo()

  • framework.strategies.strategy.Strategy._size_dt_from_decision_dt_()

  • framework.strategies.strategy.Strategy._instrument_execution_dt_from_datetime()

  • framework.strategies.strategy.Strategy.decision_dt_from_execution_dt()

  • framework.strategies.strategy.Strategy.decision_dt_from_date()

Deprecated classes that will raise an exception if used in v8

  • framework.infra.calendar.business_calendar.Calendar

  • framework.infra.calendar.calendar.Calendar

  • framework.strategies.basket_strategies.DynamicGlobalBasket

  • framework.strategies.runner.metaflow.decorators.function_flow.FunctionFlow

  • framework.strategies.runner.metaflow.decorators.strategy_flow.StrategyFlow

  • framework.strategies.fx_forward_rolling_strategy.FXForwardRollingStrategy

  • framework.strategies.fx_forward_rolling_strategy.DynamicFXForwardRollingStrategy

  • framework.analytics.optimization.optimization_problem.FactorOptimizationProblem

  • framework.analytics.optimization.optimizer.FactorOptimizer

  • framework.analytics.performance.performance_report.TsPerformance

  • framework.analytics.performance.performance_report.CustomReport

Note: the deprecation message contains information regarding the upgrading process. If information isn't provided, the method or class may not be maintained anymore.

New strategy visualisation used as default

Reason for change

The new strategy visualisation allows for improved UX capability, and the ability to share performances with others.

The method: strategy.plot.performance()

Note: you can revert by passing in fallback=True

Change default margin cleanup action

Reason for change When trading instruments required margin directly in a strategy, the margin cleanup action needed to be added to manage the end of day margin calculations.

This is done in building blocks but could be missed in custom strategies. Now these actions are automatically added.

How to recover the old behaviour

Set an environment flag in the SigTech environment initialisation—in some cases this may result in a slight improvement in runtime:

sig.env()[sig.config.AUTOMATIC_MARGIN_CLEANUP] = False

Class definition update

The framework base class is being replaced to:

  • Align with changes available in Python version 3

  • Enable standard class syntax

For most users, this should only have an impact on defining a custom strategy. Full details can be found in the core documentation by querying the code below:

from sigtech.framework.internal.infra.objects import core 
core?

FrameworkObject is backward compatible with the old base DObject class.

Important: it is strongly recommended that new classes are defined in FrameworkObject syntax—the old methods will be deprecated in future.

The following code block is an example of inheriting from the Strategy class, which itself inherits from these base classes:

class OldStyle(Strategy):
    a = IntType(default=100, required=False)
    b = FloatType(default=3.0, db_name='another_b', required=True)
    c = ListType(StringType(), default=list)
    d = StringEnumType(['long', 'short'], default='long')

The following code block returns classes with the same functionality:

class NewStyle(Strategy):
    a: Optional[int] = 100
    b: float = 3.0
    c: List[str] = list
    d: Literal['long', 'short'] = 'long'

Key changes

  • Use of Python 3 typing or variable annotations, instead of BaseTypes.

  • Mutable defaults should be using factory method instead.

  • An __init__ can also be explicitly defined but will need to pass through all parameters to their super __init__.

  • Previous uses of __init__ to define additional instance variables should be replaced with __post_init__.

BaseType to Python 3 typing annotations equivalence

BaseTypeType annotation/class

BoolType

bool

IntType

int

FloatType

float

StringType

str

DateType

datetime.date

TimeType

datetime.time

DateTimeType

datetime.datetime

TimeDeltaType

datetime.timedelta

ListType(**type**)

List[**type**]

DictType(**type**)

Dict[str, **type**]

DataPointType

DataPoint

Change default single stock start dates to align with FX data

Reason for change When using the sig.get_single_stock_strategy method to retrieve single stock strategies, a default start date is used to cap the beginning of the history. The previous default was the 2nd Jan 2008.

This was before the standard FX data source, which would cause problems if an FX conversion is required and the data source wasn’t changed.

To prevent these issues, the default has been changed to 2nd Jan 2009 . This will shorten the default history length returned with these strategies.

How to recover the old behaviour To revert to the old setting, set the following flag in the SigTech environment initialisation:

import sigtech.framework as sig
import datetime as dtm

sig.env()[sig.config.DEFAULT_RS_START_DATE] = dtm.date(2008, 1, 2)

Change of default behaviour by history_df

The history_df method on instruments, which can be used to query multiple fields simultaneously, has changed the default behaviour to always have the multicolumn parameter set to False - calls to it will have columns giving the field names rather than a multi-level index.

Example: sig.obj.get('ESZ20 INDEX').history_df()

# is now equivalent to what is (and was previously available) by calling

sig.obj.get('ESZ20 INDEX').history_df(multicolumn=False)

Note: sig.obj.get('ESZ20 INDEX').history_df(multicolumn=True) is no longer supported. In a later version the multicolumn input will be removed.

Exception when using dicts in FrameworkObject constructors

Using dicts when constructing any instrument or strategy inheriting from FrameworkObject, formerly DObject, was displaying a warning in v7. This action will now raise an exception.

Outdated example using dict

import sigtech.framework as sig
import datetime as dtm

swap = sig.CrossCurrencySwap({ 
    'currency': 'JPY',
    'pay_currency': 'USD', 
    'trade_date': dtm.date(2018, 6, 15), 
    'pay_notional': 0.01,
    'tenor':'2Y', 
    'swap_type': 'FixedFloat', 
    'fixed_frequency': 'SA' 
})

New example using kwargs

import sigtech.framework as sig
import datetime as dtm

swap = sig.CrossCurrencySwap(
    currency='JPY', 
    pay_currency='USD',  
    trade_date=dtm.date(2018, 6, 15), 
    pay_notional=0.01,
    tenor='2Y',
    swap_type='FixedFloat', 
    fixed_frequency='SA'
)

More recent package versions dependencies

Reason for change The Python dependencies are being upgraded to a later version, and the Python version changed to Python 3.9. These upgrades include:

  • cvxpy==1.1.18

  • numpy==1.22.2

  • pandas==1.4.1

  • matplotlib==3.5.1

  • scipy==1.8.0

  • scikit-learn==1.0.2

How to upgrade The upgrade of Pandas does introduce some breaking changes and new deprecation warnings, but the solutions are provided in onscreen instructions.

Note: taking the .loc of a date, in a datetime indexed Series/DataFrame, is no longer supported. To fix this, use to_datetime:

import pandas as pd

value = series_x.loc[pd.to_datetime(date)]

Production

Good to know: strategies and other scripts can be deployed to Production using Framework v8, from the start of June 2022.

v8.1 additions

The following updates are scheduled for v8.1:

Adding method to retrieve dv01 from RollingFutureStrategy for bond futures

A spot_dv01 method has been introduced for RollingFutureStrategy and RFPriceIndex which will return a series of spot dv01 numbers for the full history.

Note: this is supported only when the underlying future is a Bond Future or an Interest Rate Future.

This improves upon the spot_dv01 methods in BondFuture and InterestRateFuture, which only return the dv01 number for a single day.

Code block example:

ty = sig.RFPriceIndex(
    currency='USD', 
    start_date=dtm.date(2020,1,4),
    contract_code='TY', 
    contract_sector='COMDTY', 
    rolling_rule='front',
    front_offset='-6:-5'
) 
ty.spot_dv01()

Reason for change

Previously, a user would have to call this method for the correct Future for every single day in the history of the strategy. This is complicated and slow. The new function is very quick in comparison and very simple to use.

Create initial default matplotlib theme

Reason for change

The previous default matplotlib styling isn’t suitable.

By importing the sigtech library, new defaults would now be set in the background, by running:

import sigtech.framework as sig

Note: these defaults may be adjusted in future releases.

In v8.1 there is also the option to activate additional environment specific rendering by calling:

sig.set_plot_mode()

CVaR and other risk metrics

Reason for change

To target specific quantities in terms of VaR and CVaR, for better risk control.

Code block example:

class MyStrategy(sig.DailyStrategy):  
    def strategy_initialization(self, dt): 
       self.add_position_target(dtm.date(2021,7,10), 
                instrument_name='1003331.SINGLE_STOCK.TRADABLE',  
                units=0.5,
                unit_type='HISTORICAL_CVAR') 

Note: this should work with any timeseries that has enough history.

Last updated