Framework v8
This page is about previous versions of the SigTech v8 framework.
Please see Release notes | SigTech framework v8: Latest for information on the latest framework version.
Pages in this category
- Release notes | SigTech framework v8: Previous (this page)
On this page
- SigTech framework v8.0.0 - v8.18.0:
In this release
The
custom_hedge_exposure
parameter allows you to customize the hedge exposure for each currency in your FXForwardHedgingStrategy
, enabling you to hedge specific portions of the underlying strategy's exposure based on your unique requirements. By passing a dictionary of currency exposures as {‘CCY’: exposure}
, you can now specify the desired hedge percentages for individual currencies. For example, you can hedge 50% of the GBP exposure and 20% of the JPY exposure by passing {‘GBP’:0.5, ‘JPY’:0.2}
. This new feature empowers users to tailor their hedging approach to better align with their risk management strategies and investment goals.Additionally, this update introduces further maturity options for the
roll_offset
parameter in the FXForwardHedgingStrategy
. The roll_offset parameter allows you to specify the tenor of the FX forwards used for hedging.With the
size_from_first_roll_trade
parameter, you now have the option to adjust how roll trades are sized in the strategy. By default, this feature is activated, meaning that all roll trades will be sized based on the first trade of the roll. This ensures a consistent sizing approach across roll trades.However, with the
size_from_first_roll_trade
parameter, you have the flexibility to customize trade sizes individually for each roll trade. When set to True
, each roll trade will be sized based on the first trade of the roll. On the other hand, if set to False
, you can size each trade separately, allowing for more fine-grained control over the trade sizes.By entering an integer appended by
BDOM
you can specify a specific business day of the month as for your schedule.For example
16BDOM
represents the 16th business day of the month.- Implemented a workaround to ensure accurate CVaR (Conditional Value at Risk) calculation for small datasets and a new trigger has been introduced to generate comprehensive summary reports for single transactions.
- Added support for AUDUSD cross-currency swap
fx_datapoint
. - The framework now performs a thorough check of initial rolls and automatically adjusts the first contract forward, if necessary.
- Added commodity futures groups to
F_0_table
- Enhanced the data parsing mechanism to ensure correct string ID extraction when the data source is available.
- Added informative error messages for early trading scenarios within
SignalStrategy
. - The computation of spot DV01 series now utilizes valuation points.
- Fixed an issue that caused potential field availability discrepancies during the reindexing process in
get_series
. The system now ensures that all relevant fields are available and correctly aligned. - The default value of
closing_only
in thebottom_trades_pnl_df
function has been updated.
In this release
New trade related statistics have been added to the performance report. These can be found within the trade_statistics table method. The new statistics added are as follows:
- Trades (number),
- Win (number),
- Loss (number),
- Win/loss ratio,
- Win probability
- Kelly Criterion
See the code example below for an example of how to run this new table.
Also available is a new inspect wrapper view called
bottom_trade_pnl_df
.Code Example:
start_date = dtm.date(2020, 1, 10)
end_date = dtm.date(2021, 1, 10)
etf_ids = [
'1001692.SINGLE_STOCK.TRADABLE',
]
etfs = sig.get_single_stock_strategy(etf_ids, {'start_date': start_date, 'end_date': end_date})
rs = {e.underlyer_object.exchange_ticker: e for e in etfs}
spy = rs['SPY']
signal_ts = np.sign(spy.history()-spy.history().rolling(20).mean()).fillna(1)
strat = sig.SignalStrategy(
currency='USD',
signal_name=sig.signal.library.from_ts(signal_ts.to_frame(spy.name)).name,
start_date=start_date,
end_date=end_date,
)
sig.PerformanceReport(strat, views='ALL').report()
To run the new
trade_statistics
method: strat.analytics.trades_statistics()
New inspect wrapper view: strat.inspect.bottom_trades_pnl_df(closing_only=False)
The QuantLib dependency has been updated from v1.28 to v1.30. For more information on this release, see the QuantLib release notes.
Before this release, the
risk_reversal
method was available only for FX vol surfaces. (this method returns the history of Call Vol
minus Put Vol
for a given vol surface).With this release, the
risk_reversal
method has been extended and is now available for equity and commodity vol surfaces.In addition, two optional parameters,
start_date
and end_date
have been added, allowing you to specify a date range for the returned historical date. This is useful if you want to get a small date range as it makes the calculations much quicker.Code Example
# Commodity vol surface
vs1 = sig.obj.get('GC COMDTY VOLSURFACE')
vs1.risk_reversal(tenor='1M',
delta=25,
start_date=dtm.date(2020, 1, 1),
end_date=dtm.date(2020, 2, 10))
# Equity vol surface
vs2 = sig.obj.get('SPX INDEX VOLSURFACE')
vs2.risk_reversal('1M', 25) # No range specified
- Any override of the rolling parameters is now correctly applied in the
RollingFutureStrategy
constructor. - The dependencies for the FX objects used in a basket strategy or signal strategy are now correctly updated according to their expected evaluation start date and end date.
- Strategies no longer fail when basktesting times are approaching midnight UTC.
- When using
CapADVOrderTransform
the volume parameter is now case-insensitive. - Before this release, the
optimized_allocations
andinstrument_mapping
parameters within theSignalStrategy
were not compatible. With this release,instrument_mapping
can be a parameter of the optimization function. - With this release, the
data_df
method no longer restructures the internal history data.
This release combines versions 8.18.0 and 8.17.0.
In this release
With this release, a
#
character has been added to swap tickers to distinguish if only valuing pre-start. If you have hard-coded the name of a swap, this could break your analysis notebook. For example, the following function obj.get('USD LIBIMM S3M 0.0254578 2010-06-15 U10X5Y IRS')
needs to be changed to obj.get('USD LIBIMM S3M 0.0254578 2010-06-15 U10X5Y # IRS')
to continue working.With this release, two child classes have been added to the
StopStrategy
building block, allowing you to create stop loss orders and take profit events. Below are code examples for StopLossStrategy
and TakeProfitStrategy
.import datetime as dtm
import sigtech.framework as sig
env = sig.init()
future = env.object.get('ESZ19 INDEX')
stop_loss = sig.StopLossStrategy(
currency='USD',
trade_date=dtm.date(2019,9,1),
instrument_name=future.name,
trigger_type='FIXED_PCT_PROFIT',
trigger_level=0.01,
)
take_profit = sig.TakeProfitStrategy(
currency='USD',
trade_date=dtm.date(2019,9,1),
instrument_name=future.name,
trigger_type='FIXED_PCT_PROFIT',
trigger_level=0.01,
)
In previous releases, the threshold function returned a boolean value that was passed into the
SignalStrategy
, serving as an “on/off switch” that controlled if the strategy rebalanced or not.In this release, the threshold output can either be a boolean value or a dictionary of strategy weighting, giving you greater control of the threshold you wish to apply.
A built-in threshold function called
signal_threshold_rebalance_dict
has been introduced. This requires an additional keyword argument in the form of a dictionary which contains float values that represent:- A threshold for a change in the weighting.
- How much of the strategy to rebalance (as a percentage).
For example, to achieve the following dynamic rebalancing of:
- 10% deviated from the target position, rebalance 100%,
- 30% deviated from the target position, rebalance 70%,
- 50% deviated from the target position, rebalance 50%.
Pass the following dictionary:
rebalance_dict = {0.1: 1.0, 0.3: 0.7, 0.5: 0.5, 1.0: 0.0}
To use this new threshold function, import it from the
signal_rebalancing
library.Below is a code example of this new threshold function used within a signal strategy.
from sigtech.framework.signal.signal_rebalancing import signal_threshold_rebalance_dict
rebalance_dict = {0.1: 1.0, 0.3: 0.7, 0.5: 0.5, 1.0: 0.0}
strategy = sig.SignalStrategy(
currency='USD',
start_date=start_date,
signal_name=signal_name,
rebalance_frequency='EOM',
allocation_function=sig.signal_library.allocation.equally_weighted,
threshold_function=signal_threshold_rebalance_dict,
threshold_kwargs={'rebalance_dict': rebalance_dict},
)
With this release, two new methods have been added that return yield curve data from a BondYieldCurve object.
get_yield_curve(date, tenor)
creates the yield curve for a reference date up to a specified tenor. By default, this tenor is 30Y.data_df()
returns a DataFrame containing all history dates for bonds that have aotr_tenor
(2Y, 3Y, 5Y, 7Y, 10Y, 30Y). As this function returns a lot of data, it may affect your runtimes.
Below is a code example of how to call these new methods:
US_bonds = sig.obj.get("US GOVT BOND GROUP")
curve = US_bonds.get_bond_yield_curve()
date = dtm.date(2023, 3, 31)
tenor = '10Y'
yield_curve = curve.get_yield_curve(date=date, tenor=tenor)
yield_df = curve.data_df()
With this release a new parameter
min_periods
has been added to the following performance metrics summary methods:summary_rolling_series
summary_rolling_ccy_series
min_periods
is the minimum number of observations in the period window that require a value.If this parameter is not set, the default value of
252
is used instead - this is the same value as the previous period parameter, where 252
is the number of business days in a year.In previous releases, the
description
property was missing from the CommodityIndex
sub-asset class, and was only available for EquityIndex
objects.With this release, the property has been moved to the parent class
Index
so all sub-classes can inherit this property. Therefore, the description
property can be called for all types of Index
objects.Below is a code example of how to call this property.
import sigtech.framework as sig
sig.init()
equity_index = sig.obj.get('SPX INDEX')
equity_index.description
cmdty_index = sig.obj.get('SPGSINTR INDEX')
cmdty_index.description
The following statistics have been added to the report function found in the
PerformanceReport
class:- Calmar Ratio
- VaR - 99% and 95% (both 1day)
- cVaR - 99% and 95% (both 1day)
To view these new parameters, run the following code:
import sigtech.framework as sig
sig.init()
from sigtech.framework.default_strategy_objects.rolling_futures import bo_comdty_f_0
data = bo_comdty_f_0().history()
sig.PerformanceReport(data).report()
- The
object_service
docstring has been updated. - Before this release, there were errors when creating an equity index option after a vol surface was assessed the with
data_df()
method. With this release, theDataLoadError
issues have been resolved. - The deprecated
exchange_open
property has been removed from theinfo()
method and replaced withexchange_open_on_day
. - Certain methods now cannot be accessed while a strategy is being built.
- The price series index has been converted to a
datetime
index in theRollingFutureStrategy
building block. - When plotting a volatility surface, adjustments have to be made to improve the ticks on the tenor axis.
- Decimal values have replaced commas in prices. For example,
1000,00
is now displayed as1000.00
. - Missing credibility fields have been added to
available_fields
method when usingDataCredibilityAdapter
.
This release was merged with 8.18. Please refer to the release notes for version v8.18.0 to see what was included in version 8.17.0.
In this release
With this release, you can use
sig.obj.get()
to query FX spot rates for any currency pair, even those which are not available in our data browser. Previously, sig.obj.get()
you could only query FX spot rates for currency pairs in our data browser.A couple of examples are shown below:
import sigtech.framework as sig
sig.init()
usdeur = sig.obj.get('USDEUR CURNCY')
usdeur
seknok = sig.obj.get('SEKNOK CURNCY')
seknok
You can save your Sigtech environment in your JupyterLab instance. This saves any variables or attributes that you have configured in your environment. JSON serialisable attributes are saved in a .JSON format and non-JSON serialisable attributes are saved in .PKL. Once an environment is saved, you can easily reload it in a new notebook.
See the code example below for an example:
import sigtech.framework as sig
# Saves environment config as 'env.json' and 'env.pkl'
env = sig.init()
env.save_config('env')
# Destroys the environment instance
sig.de_init()
# Loads environment config from 'env.json' and 'env.pkl'
loaded_env = sig.init(load_env=True, env_file='env')
A new
Minimalist View
option is available on the BuildingBlockBrowser
widget. Selecting this option reduces the list of the class attributes shown in the BuildingBlockBrowser
by only showing you the mandatory attributes. Not selecting/deselecting this option will result in all the attributes available for a class is visible.A new method
data_df()
has been added to all framework instruments. The data_df()
method replaces the history_df()
method as it returns improved data. This new method returns a pandas DataFrame containing all data available for this object.The
data_df()
method takes the following optional arguments:- data_point: Choose the data point from which to return the history of the object.
- multi_index: Set to
True
to index rows uniquely by a multi-index (if applicable). Default isFalse
. - drop_nan_cols: Set to
True
to drop all NaN columns. Default isFalse
.
data_df()
is an improvement over the previous history_df()
method as it can perform clean-up operations as the data is queried. Such clean-up operations include column rearrangement and renaming, reset of indices and forward filling of values when placeholders are set.See the code example below for how to use
data_df()
:import sigtech.framework as sig
sig.init()
# Single stock
sig.obj.get('1000045.SINGLE_STOCK.TRADABLE').data_df(drop_nan_cols=True)
# Credit index curve
sig.obj.get('CDX.NA CURVE').data_df(multi_index=True)
# Vol surface
sig.obj.get('EURUSD VOLSURFACE').data_df()
With this release, you can now pass a single or a mixed list of holiday calendar names and instruments objects into the
holidays
parameter of the SchedulePeriod
method. This generates a calendar that accommodates all the holidays in the passed list. If a list of instruments has been passed, then the calendar will accommodate the holidays for each of the instruments in the list. This is particularly useful if the list consists of different indices.See the code example below for how to create a weekly schedule:
instrument_list = ['ESH23 INDEX', 'COH22 COMDTY', '1000045.SINGLE_STOCK.TRADABLE']
basket = [sig.obj.get(ins) for ins in instrument_list]
weekly_schedule = sig.SchedulePeriodic(
start_date=dtm.date(2020, 2, 1),
end_date=dtm.date(2020, 3, 28),
holidays=basket,
frequency='1W-WED',
offset='1BD',
offset_backwards=True,
bdc=sig.calendar.BDC_MODIFIED_FOLLOWING)
print(weekly_schedule.get_holidays())
print(weekly_schedule.get_holidays().all_data_dates())
A
back_adjusted
parameter has been added to the price_series
method (belonging to the RollingFutureStrategy
class). This parameter calculates the back-adjusted prices for underlying futures.Furthermore, a new method
get_rf_price_index
has been added to RollingFutureStrategy
, it returns the corresponding rolling future price index object. Likewise, an additional method get_rolling_future_strategy
has been added to the RFPriceIndex class, it returns the corresponding rolling future strategy.See the code example below for how to pass the back_adjusted parameter:
rfs = sig.RollingFutureStrategy(
currency='USD',
start_date=dtm.date(2020, 1, 1),
end_date=dtm.date(2022, 1, 1),
contract_code='NG',
contract_sector='COMDTY',
rolling_rule='front',
front_offset='-2:-1'
)
rfs.price_series(back_adjusted=True)
The following example queries the rolling future price index from a back-adjusted rolling future strategy.
rfs_pi = rfs.get_rf_price_index(back_adjusted=True)
The following example gets a rolling futures strategy from the back-adjusted price index.
rfpi_strat = rfpi.get_rolling_future_strategy()
You can now pass an
execution_delay
argument to a signal strategy.This allows you to delay an order execution by a set period. In addition, you can use the
bump_execution_delay
parameter to ensure the order execution falls within trading hours. Set bump_execution_delay
to False
to ignore orders that would be executed out of trading hours. This means the order will not be executed if the delay causes it to execute outside of trading hours. Set bump_execution_delay
to True
(default) to ensure the order will be executed within trading hours by moving the execution time forward to the next available data point (that falls within trading hours).For example:
import pytz
import datetime as dtm
import pandas as pd
import numpy as np
import sigtech.framework as sig
env = sig.init()
rfs = sig.default_strategy_objects.rolling_futures.es_index_front()
rfs.history();
start_date = dtm.date(2023,3,1)
signal = pd.Series({d: np.random.uniform(0,1) for d in pd.date_range(start_date, env.asofdate)}).to_frame(rfs.name)
rfs = sig.default_strategy_objects.rolling_futures.es_index_front()
rfs.history();
# Use bump_execution_delay=False to skip trades that would execute outside trading hours based on the delay provided via execution_delay
strategy = sig.SignalStrategy(
currency='USD',
signal_name=sig.signal.library.from_ts(signal).name,
start_date=start_date,
execution_delay = dtm.timedelta(days=1),
bump_execution_delay = False,
)
strategy.plot.portfolio_table('TOP_ORDER_PTS', end_dt=dtm.date(2023,3,6))
# Use bump_execution_delay=True to bump trades that would execute outside trading hours to the EOD execution on the next day based on the delay provided via execution_delay
strategy = sig.SignalStrategy(
currency='USD',
signal_name=sig.signal.library.from_ts(signal).name,
start_date=start_date,
execution_delay = dtm.timedelta(days=1),
bump_execution_delay = True,
)
strategy.plot.portfolio_table('TOP_ORDER_PTS', end_dt=dtm.date(2023,3,6))
- The
copy code
issues inBuildingBlockBrowser
have been resolved. - Overridden attributes in the
BuildingBlockBrowser
have been updated. - The
data_date
andenv_date
in the intraday notebook have been updated so that they no longer return errors. - Bugs involving
abe_encryption_key
andstream_access
endpoints have been resolved. - Timeline retrieval is now prevented before a strategy is run.
- OTC instruments can now trade before the instrument’s start date.
- Use holidays to check the exchange open/close times and skip trades that occur outside of trading hours.
- FX forwards now include the current date in the history time series.
- The timestamp behaviour of the FX
convert_at_d
method has been corrected. - An attribute filter has been added to the
DataBrowser
widget. - The intraday argument can now be used in stoploss allocation functions.
- The
trading_decision_time
argument has been removed following its deprecation. - Interactive optimizers now clear correctly.
Fixes in this release
- Grouped strategy orders now execute at EOD.
- Conversion errors on FX objects causing FXFix datapoint retrieval issues have been fixed.
- The behavior of the
back_adjusted
parameter in theprice_series
function of theRollingFutureStrategy
building block has been fixed.
In this release
A new discount curve called
CollateralizedOISCurve
has been added to the framework. This new curve implements discounting on-the-fly using a collateral OIS discount curve and FX forwards. The curve applies the discounts based on collateral posted in a different currency (USD by default). The future cash flows are converted to the collateral currency using FX forwards and discounted using the collateral OIS curve.The following code creates a curve that discounts JPY cash flows assuming that USD collateral is used for the instrument.
CollateralizedOISCurve(currency='JPY',
curve_name='JPY.C',
group_name="OIS ICE CURVE GROUP",
interpolation_type='CS',
collateral_currency='USD')
Two new
start_date
and end_date
parameters have been added to the portfolio_greeks
and pnl_explain
functions (these functions belong to the rolling options/swaption strategies and also the DeltaHedgingStrategy
).Pass the start and end dates as a datetime. For example,
start_date=datetime.date(2020,1,1)
.This new feature has been introduced to increase the computation speeds. If a small date range is entered then the greeks and pnl are calculated for just this small date range, making the calculations faster.
A new optional parameter
data_points
has been added to the portfolio_greeks
function. When using this parameter in the rolling options strategies and the DeltaHedgingStrategy
, the reported greek times will be overridden with the times specified by the data points list passed to the data_points
parameter.An example of this is shown below:
# creates the strategy
ro=sig.RollingOption(
currency='USD',
start_date=dtm.date(2019,1,4),
group_name='EURUSD OTC OPTION GROUP',
maturity='3M',
rolling_frequencies=['1M'],
option_type='Call',
strike_type='SPOT',
strike='ATM+3%',
target_type='SpotNotionalAsProportionOfNAV',
target_quantity=-10,
end_date=dtm.date(2019,3,4)
)
# calls the function with the new data points
ro.portfolio_greeks(start_date=dtm.datetime(2019,1,8,17),
end_date=dtm.date(2019,1,10),
data_points=['LONDON_1600','LONDON_2000'])
The interface for the defined transaction costs has been improved. These improvements include:
- When entering parameters into a model, you must now enter them as a dictionary of parameter values. Previously, this was supported for only some transaction cost models but with this release, it is now available for all models.
- The docstrings for each model have been updated and now also provide an example of how these transaction costs work.
- Previously, some instruments (such as bonds and single stocks) used cost models defined on the objects instead of being defined via configured models. This made it harder to get additional information on the cost models. With this release, these cost models are now included.
Previously, when calling
plot.portfolio_table
with more than 100 rows the table would error.With this release, if there are more than 100 rows the table is still plotted but a warning message is provided telling you that only the last 100 rows of the
portfolio_table
have been plotted.If you want to view a DataFrame version of the
portfolio_table
, pass the argument as_df=True
. In previous releases, the DataFrame would also error if there were more than 100 nows. With this release, the DataFrame returns every row available, even if there are more than 100 rows.You can now pass additional keyword arguments for the basket creation strategy when creating a
DynamicOptionsStrategy
. Pass the optional keyword arguments as a dictionary. An example of how to pass these arguments is shown in the code below:# pass the additional keyword arguments in a dictionary.
bc_params = {'signal':signal,
'option_group':spx_option_name,
'strike':'SPOT',
'maturity':'2M'}
strategy = sig.DynamicOptionsStrategy(
currency='USD',
start_date=dtm.date(2022,1,1),
group_name=spx_option_name.name,
end_date=dtm.date(2022, 12, 5),
rolling_frequencies=['1BD',],
basket_creation_method=basket_creation_method,
basket_creation_kwargs=bc_params
)
A new parameter
net_trades
has been added to the inspect.bottom_trades_df
method. If set to True
, you can now see the aggregated orders for trades happening at the same time for the same instrument.An example of this is shown below:
from sigtech.framework.default_strategy_objects import rolling_futures
rfs = rolling_futures.es_index_front()
rfs1 = rfs.clone_object({'fixed_contracts': 1, 'ticker': 'C1'})
rfs2 = rfs.clone_object({'fixed_contracts': 2, 'ticker': 'C2'})
rfs1.build()
rfs2.build()
signal = pd.DataFrame({
'C1 STRATEGY': -1 + 0 * rfs1.history(),
'C2 STRATEGY': 1 + 0 * rfs2.history(),
}).loc['2018':].dropna()
ns = sig.SignalStrategy(
currency='USD',
start_date=signal.first_valid_index(),
end_date=signal.last_valid_index(),
signal_name=sig.signal_library.from_ts(signal).name,
rebalance_frequency='EOM',
)
ns.build()
ns.inspect.bottom_trades_df(net_trades=True).loc[:'2018-01-10']
ns.inspect.bottom_trades_df(net_trades=False).loc[:'2018-01-10'].sort_values(by='instrument_name')
Previously, the metrics used in the performance report and strategy widget were calculated using percentage returns or returns relative to a provided AUM.
With this release, these metrics are now calculated using the absolute P&L (with the P&L calculated in the strategy currency). By default, these metrics are chosen if the strategy valuation is negative at any point.
To access the metrics directly, use the
profit_metrics_only
parameter. An example of how to get the parameter is as follows:import sigtech.framework as sig
sig.init()
strat = sig.default_strategy_objects.rolling_futures.es_index_front()
sig.PerformanceReport(strat, profit_metrics_only=True).report()
strat.plot.performance(profit_metrics_only=True)
This new performance parameter can be included in the following custom report views:
View.SUMMARY_SINGLE_CCY,
View.HISTORY_CCY,
View.ROLLING_PLOTS_CCY,
View.DRAWDOWN_PLOT_CCY,
View.MONTHLY_STATS_HEATMAP_CCY
Please note, these views are independent of the entered reference AUM.
Previously, FX spot trades had to be entered by setting a trade of the cash instrument. If you were using a custom strategy, these FX spot trades have to be entered using an
add_fx_spot_trade
method.With this release, FX spot trades can be entered with an FX cross identifier, which are mapped to the cash exchange. This can then control which currencies are exchanged. Additional labels have also been added to FX orders to show the FX cross gaining exposure.
An example of this new input is shown for a basket strategy below:
import datetime as dtm
import sigtech.framework as sig
env = sig.init()
env[sig.config.FX_SPOT_EXECUTION_DELAY] = dtm.timedelta(hours=1)
strategy = sig.BasketStrategy(
currency='EUR',
start_date=dtm.date(2015, 1, 10),
constituent_names=[
'USDEUR CURNCY',
'GBPEUR CURNCY',
],
weights=[0.5, 0.5],
rebalance_frequency='EOM',
)
strategy.plot.portfolio_table('ACTION_PTS')
Prior to this release and when the framework was created, Python did not have native type hinting syntax. This meant that SigTech had to use custom type hints (defined in
sigtech.framework.infra.objects.dtypes
).With this release, a more up-to-date version of python has been utilized and we have now ported all typings to Python’s native type hinting.
In addition to using these native types, we have also enforced the use of beartype. This is a strict, runtime type checker. If you pass an unexpected value into a class using the beartype, an error will appear telling you the correct variable type to use instead.
The logic in our codebase tries to match an input and its type. An edge case for this logic involves the
Union
type. This Union
type is usually used to indicate a single variable can hold multiple types of values, for example, the date variable can hold a date as a str
or as a dt.datetime
, hence the date can be represented as date: Union[str, dt.datetime]
.However, the order of these inputs is important in the framework, as it would try to cast the variable to the type in the order given in the Union.
For example, with
Union[str, dt.datetime]
, the framework would try to cast the variable to a string first, then to the datetime. This behaviour can be incorrect if, for example, you used a dt.datetime
only as the framework would cast the variable to a string first. This may interfere with your code and cause errors.- If a strategy attempts to size a trade prior to the strategy start date, the framework will then change to sizing date to the valid start date of the strategy.
- If you exceed the time point limit when plotting a
portfolio_table
, the number of time points displayed is reduced to fit within this limit. The time points that are reduced are from the start of the table. - The
transaction_cost
notebook has been updated. - A new option group,
trading_group
, has been added to the rolling option strategies. Thetrading_group
lets you specify the type of traded options to use in the strategy. - Fill added to futures methods to fill
ctd
data inreindex
so that it can matchasof
calls for individual dates. - Corrections were added to several default dictionary inputs for strategies and signals.
- Several new calendars (
HolidayCalendar
,AuctionCalendar
,EconomicCalendar
) have been added to the API.
In this release
In previous releases, if different strategies were assigned the same name, the notebook could error when rerunning certain cells.
With this release, a version number is automatically added to the name of the strategy if the name provided is not unique. For example, if we have two rolling future strategies with the same ticker,
"RFS 2023 Q1"
, then the first strategy