Blueshift Library

Blueshift library functions (from blueshift.library) provide a select set of functionalities unique to the platform, or wrapped from other packages for ease of use on the platform. These functions are divided in categories as follow:

  • Technicals

    Includes technical indicators and automatic technical pattern identification functionalities.

  • Statistical

    Include perceptually important points and change points algorithms. Also include a collection of functions that wraps various functionalities from other useful packages.

  • Pipelines

    A useful collection of ready-to-use pipeline filtering and factoring functions.

  • Timeseries

    A collection of functions and models useful for timeseries analysis and timeseries transformations.

  • Machine learning

    A useful collection of ready-to-use machine learning functionalities that wraps various other useful packages.

  • Models

    A useful collection of statistical and pricing models.

  • Execution Algorithms

    A selection of useful execution algorithms that can be directly used in a strategy to place orders.

The features and functionalities of the blueshift library functions are frequently updated and revised.

Technical Indicators

You can import all the technical indicators supported by the TA-Lib module from blueshift.library.technicals.indicators.

Note

Use the uppercase name (as defined by TA-Lib) for functions that return vectorized computation. Use the lowercase name (with the same signature) for functions that return the last observation. The latter is useful for writing event-driven strategy.

The TA-Lib functions, when imported from blueshift.library.technicals.indicators, can automatically identify required columns from pandas DataFrame and have additional error handling. See examples below.

import talib as ta
from blueshift.library.technicals.indicators import ADX, adx

def initialize(context):
    ...

def signal_function(asset, price):
    # we assume price is a dataframe with OHLC columns

    # to call the TA-Lib function, we must extract the required
    # columns
    x1 = ta.ADX(price.high, price.low, price.close)

    # not needed for the blueshift library version, the required
    # columns will be automatically extracted
    x2 = ADX(price)

    # but we can still use the TA-Lib signature if we want to
    # both will work
    x3 = ADX(price.high, price.low, price.close)

    # X1, X2 and X3 above are pandas Series. To get the last computed
    # value, use the lowercase version. X4 is a float.
    x4 = adx(price)

Additional Indicators

Apart from the TA-Lib indicators, a few additional indicators are available as below.

blueshift.library.technicals.indicators.MA_XOVER(real[, ltma=?, stma=?, **kwargs=?])

Moving Average Cross-over

Inputs:

real: (any ndarray)

Parameters:

ltma: 20 stma: 5

Outputs:

real

blueshift.library.technicals.indicators.EMA_XOVER(real[, ltma=?, stma=?, **kwargs=?])

Exponential Moving Average Cross-over

Inputs:

real: (any ndarray)

Parameters:

ltma: 20 stma: 5

Outputs:

real

blueshift.library.technicals.indicators.BOLLINGER_BAND_DIST(real[, timeperiod=?, nbdevup=?, nbdevdn=?, matype=?])

Bollinger Bands Distance From Upper (percentage)

Inputs:

prices: [‘high’, ‘low’, ‘close’]

Parameters:

timeperiod: 10 mult: 3

Outputs:

real

blueshift.library.technicals.indicators.HEIKIN_ASHI(real[, precision=?])

Heikin-Ashi

Returns heikin-ashi candles. The input price must be a dataframe with ‘open’, ‘high’, ‘low’ and ‘close’ columns. The ‘volume’ column, if present, will be added to the returned dataframe.

Args:

price(dataframe): input OHLC (or OHLCV) prices.

Returns:

Dataframe (OHLC or OHLCV depending on the input).

blueshift.library.technicals.indicators.ICHIMOKU_CLOUD(real[, timeperiod1=?, timeperiod2=?, timeperiod3=?, timeperiod4=?])

Ichimoku Cloud

Returns Ichimoku cloud lines in this order - conversion, base, spanA, spanB and lagging.

Args:

price(dataframe): input OHLC (or OHLCV) prices.

timeperiod1(int): timeperiod for conversion line.

timeperiod2(int): timeperiod for base line.

timeperiod3(int): timeperiod for leading span B.

timeperiod4(int): timeperiod for lagging span.

Returns:

Tuple of real.

blueshift.library.technicals.indicators.TREND_STALL(high, low, close[, bandwidth=?, timeperiod2=?, threshold=?])

Trend Stall indicator checks the stalling of the momentum in the price based on ADX indicator and then determines if it is a stalling of bullish or bearish trend based on ROC. If ADX has peaked out and ROC is positive (negative), it signifies stalling of a bullish (bearish) trend and has signal value -1 (+1). Ideally this signal needs further confirmation. The bandwidth is used to smooth the raw ADX signal and the extreme points are determines based on a neighbourhood of 2*bandwidth+1 points. Note: the timeperiod must be greater than bandwidth.

Returns Trend Stall signals.

Inputs:

price: (HLC Dataframe)

Parameters:

bandwidth=5 timeperiod: 14 threshold: 0.001

Outputs:

real

blueshift.library.technicals.indicators.TREND_SET(high, low, close[, bandwidth=?, timeperiod2=?, threshold=?])

Trend Set indicator checks the beginning of a new trend in the prices based on ADX indicator and then determines if it is a starting a bullish or bearish trend based on ROC. If ADX has bottomed out and ROC is positive (negative), it signifies start of a bullish (bearish) trend and has signal value +1 (-1). Ideally this signal needs further confirmation. The bandwidth is used to smooth the raw ADX signal and the extreme points are determines based on a neighbourhood of 2*bandwidth+1 points. Note: the timeperiod must be greater than bandwidth.

Returns Trend Stall signals.

Inputs:

price: (HLC Dataframe)

Parameters:

bandwidth=5 timeperiod: 14 threshold: 0.001

Outputs:

real

blueshift.library.technicals.indicators.SUPER_TREND(price[, timeperiod=?, mult=?])

SuperTrend indicator returns upper and lower bands.

Inputs:

real: (any ndarray)

Parameters:

timeperiod: 5 nbdevup: 2 nbdevdn: 2 matype: 0 (Simple Moving Average)

Outputs:

upperband lowerband signal

These functions follow the same naming convention, i.e. the uppercase function names return vectorized output, and lower case for the last observation. An exception is HEIKIN_ASHI (returns DataFrame) which has no lowercase implementation.

Technical patterns

blueshift.library.technicals.find_support_resistance(x, type_='pip', R=None, scale=[1.75, 2, 2.5, 3, 5, 7], tolerance=0.001)

Find support(s) and Resistance(s) lines based on either Fibonacci or the ‘PIP’ method.

The parameter R is used in the case of the ‘PIP’ support and resistance method. This is the same parameter used to find the perceptually important points and should be in the form of 1+x, where x is the percentage move determining a peak or trough. For e.g. to use 2% move, use R = 1.02. R value will be automatically determined based on the input series, if set to None.

The parameter tolerance is used to determine the support lines. To consider a collection of peak (trough) points forming a single resistance (support) line, each point must not deviate by more than the tolerance value from a linear fit.

Args:

x (Dataframe or Series): Input data.

type_ (str): Can be either ‘fibonacci’ or ‘pip’

R (float): The returns ratio for the PIP method.

scale(float): Multiple of volatility for PIP identification.

tolerance (float): Tolerance for finding support lines.

Returns:

A list of lines object of type Line. For the pip method, always a pair of lines are returned. For the Fibonacci method, 6 lines, corresponding to the Fibonacci levels are returned.

blueshift.library.technicals.search_chart_patterns(data, pattern, R=None, scale=[1.75, 2, 2.5, 3, 5, 7], tolerance=None, find_all=False, adjust_trend=False)

function to find important points based patterns. This is made for daily returns. For other frequencies, the default values of R may not be suitable. Scale range is used only when R is None or empty list.

Args:

data (frame or series): input price data.

pattern(obj or str): A pattern definition object.

R(float): R range for searching important points.

scale(float): Scale range for searching important points.

tolerance(float): For fine-tuning pattern matching.

find_all(bool): Return all or the last pattern in the sample.

adjust_trend(bool): If true, de-trend the points before matching.

Returns:

List. A list of pattern objects (empty list if no match found).

Statistical Functions

blueshift.library.statistical.find_imp_points()

Find perceptually important points (see https://www.cs.cmu.edu/~eugene/research/full/search-series.pdf)

Note

PIPs are an effort to algorithmically derive a set of important points as perceived by a human to describe a time series. This typically can be a set of minima or maxima points or a set of turning points which are important from a feature extraction perspective. Traditional technical analysis - like technical pattern identification - relies heavily on PIPs. In addition, a set of PIPs can be used to compress a time series in a very useful way. This compressed representation then can be used for comparing segments of time series (match finding) or other purposes.

Args:

x(frame or series): Input price data.

R(float): (1+x) to identify PIP with minimum x move.

scale(float): Multiple of volatility for PIP identification.

Returns:

Tuple. The first element is a list of indices for the minimum points, second is the same for maximum points. The third element of the tuple returns the compressed data (with only the peak and valleys).

Find change point in price levels or variance. This implements a unique change point analysis for non-stationary time series to identify multiple changes in the deterministic linear trends. The implementation is based on identifying change in simple regression coefficients (with penalty) and extends to multiple change point identification using the popular binary segmentation methodology.

Args:

x (Dataframe or Series): Input pricing data.

type_ (str): Can be either “price” or “variance”.

Q (int): The maximum number of segments.

minseglen (int): The minimum length of a trend segment.

penalty (int): A penalty specifications usually between 2 to 10.

Returns:

A list of lines (of LineType.trends type).

blueshift.library.statistical.get_hmm_state(x, covariance_type='full', n_iter=100)

Market classification based on hidden market model. The state with the lowest return is 0, and highest is 2. If we have only a single state identified, it is assigned state 1. If only two states are identified, they are assigned 0 and 2. Else 0, 1 and 2 based on the conditional expected returns.

Args:

` x (Series)`: Input pricing data.

covariance_type (str): Passed on to the underlying `hmm.GaussianHMM call.

n_iter (int): Passed on to the underlying hmm.GaussianHMM call.

Returns:

A Series with the inferred state of the market.

blueshift.library.statistical.hedge_ratio(Y, X)

Returns the ADF p-value and regression coefficient (without intercept) of regression of y (dependent) against x (explanatory).

Args:

Y (series or ndarray or list): input y series X (series or ndarray or list): input x series

Returns:

Tuple. p-Value of Augmented Dickey Fuller test on the regression residuals, and the regression coefficient.

blueshift.library.statistical.z_score(Y, X=None, lookback=None, coeff=None)

Given two series Y and X, and a lookback, computes the latest z-score of the regression residual (ratio of deviation from the mean and standard deviation of the residuals).

Note:

X and Y must be of equal length, lookback must be less than or equal to the length of these series.

Args:

Y (series or ndarray or list): input y series X (series or ndarray or list): input x series lookback (int): lookback for computation. coeff (float): regression coefficient.

Returns:

z-score of the regression residuals.

Timeseries Functions and Models

blueshift.library.timeseries.intraday_seasonality_func(series, period=None, calendar=None, bandwidth=1.0, infer_frequency=True, drop_first_minute=True)

Generate the intraday seasonality function. The input series is resampled to the target frequency, and a smoothed intraday seasonality is estimated. The returned function takes in an intraday series index (pandas DatetimeIndex) and computes the seasonality factors to be applied. The reciprocals of these factors can be used to de-seasonalize. The bandwidth parameter is passed on to scipy.ndimage.gaussian_filter1d function for kernel smoothing.

Args:

series (pd.Series): Input series.

period (str): Valid pandas period string for resampling.

calendar (TradingCalendar): Calendar for session filtering.

bandwidth (float): Bandwidth for smoothing.

infer_frequency (bool): Infer input frequency (must be intraday).

Returns:

A callable of signature f(index) that accepts an input DatetimeIndex and returns the seasonality factor weight (not normalized) for each timestamp in the index.

Warning

The input data as well as the input index to the returned function must have intraday frequency, which must be higher than the frequency implied by period.

blueshift.library.timeseries.deseasonalize(series, seasonality_func, period, minutes_per_day=None, calendar=None)

Given a seasonality_func, deasonalize an input series ( multiplicative). The seasonality_func must be obtained using intraday_seasonality_func. The number of trading minutes per day (implied from the calendar object) should be divisible by the period.

Args:

series (Series): Input timeseries to deseasonalize.

seasonality_func (callable): See intraday_seasonality_func.

period (str): A valid pandas period string (e.g. “5T”).

calendar (TradingCalendar): A valid trading calendar.

Returns:

Deseasonalized input timeseries.

Warning

Input series must be indexed by DatetimeIndex and should have an intraday frequency.

blueshift.library.timeseries.reseasonalize(series, seasonality_func, period, calendar)

Given a seasonality_func, re-seasonalize an input series ( previously deseasonalized). The seasonality_func must be obtained using intraday_seasonality_func (and should be the same to deseasonalize it before). The number of trading minutes per day (implied from the calendar object) should be divisible by the period.

Args:

series (Series): Input timeseries to deseasonalize.

seasonality_func (callable): See intraday_seasonality_func.

period (str): A valid pandas period string (e.g. “5T”).

calendar (TradingCalendar): A valid trading calendar.

Returns:

Deseasonalized input timeseries.

Warning

Input series must be indexed by DatetimeIndex and should have an intraday frequency.

class blueshift.library.timeseries.OnlineAutoARIMA(max_coeffs=5, period=None, calendar=None)

An online auto-arima model (compatible with sklearn) that uses blueshift.library.timeseries.auto_arima function to fit an initial model. The model can be updated with new incoming data by calling the update method

Args:

max_coeffs (int): Maximum coefficents (AR + MA).

blueshift.library.timeseries.auto_arima(series, max_terms=5)

Auto-ARMA model for timeseries. Parameter max_terms determine the total coefficients to estimates (MA + AR). This function search all combinations given a max_terms and selects the mode with the minimum AIC. The input series must be stationary (else raises exception). Also the selected model must have residuals with durbin-watson stats in the range of 1.95 to 2.05 (else raises exception). Returns the selected model.

Args:

series (Series): Input time series.

max_terms (int): Maximum coefficients (MA + AR).

Returns:

statsmodels.tsa.arima.model.ARIMA - the estimated ARIMA model.

Raises:

blueshift.errors.ModelError in case the model fit fails.

blueshift.library.timeseries.transform.resample(df, period, fill_value=None, fill_method='ffill', limit=None, default_func=<function mean>, calendar=None)

Base function to resample pandas dataframe or series to different periods.

Args:

df (dataframe or serues): Input time-series.

period (str): Target period string.

fill_value (number or dict): Fill value in fillna (None).

fill_method (str): Deafault fill method in fillna (ffill).

limit (int): max number to fill with method (None).

default_func (function): Function to aggregate with (numpy.mean).

calendar (TradingCalendar): Calendar for filtering non-trading minutes (None).

Returns:

Series or DataFrame. Aggregated and na-filled. If calendar is specified, returned series will include only trading hours and sessions.

Note

In addition to this function, a host of derived functions to convert to specific frequencies are available. They are to_yearly, to_quarterly, to_monthly, to_weekly, to_daily, to_hourly, to_minutes30, to_minutes15, to_minutes10 and to_minutes5. All this accepts the first argument as a Series (or Frame) and compute the resampling based on the above defaults. Functions with period equal to or lower than daily (i.e. from to_daily to to_minute5) also accepts a calendar object for filtering trading days and trading minutes.

blueshift.library.timeseries.transform.endpoints(df, on)

get a DatetimeIndex resampled from the input series based on the period specified by on.

Args:

df (dataframe or serues): Input time-series.

on (str): Period specification.

Returns:

pandas.DatetimeIndex. Timestamp of the last observation for each period.

blueshift.library.timeseries.transform.split(df, on)

Split a dataframe by time periods and get a list of data frames for further analysis.

Args:

df (dataframe or series): Input time-series.

on (str): Period specification.

Returns:

List. A list of dataframe (series) after the split.

blueshift.library.timeseries.transform.period_apply(df, on, func)

Apply aggregation on by periods. The parameter on must be a valid Pandas period string. The function must accept a series and produce a single salar value.

Args:

df (dataframe or serues): Input time-series.

on (str): Period specification.

func (str, function, dict): Method specification

Returns:

Dataframe. Aggregated dataframe.

Note

In addition to this base function, a host of useful derivatives are also available, namely period_mean, period_max, period_min, period_median, period_prod, period_sum, period_std, period_var. These accepts the input series and the on parameter. The functions applied to each of these cases are obvious from the function names.

blueshift.library.timeseries.transform.rollapply(df, width, func, y=None, by=0, by_column=True, fill=True, partial=False, align='right', coredata=False, **kwargs)

Roll apply for Pandas, with R-like functionalities. If by_column is False, entire dataframe subset for the window will be available for the user supplied function func, otherwise func is applied separately to each column.

Note:

User supplied function (func) must return a scalar. The function must accept an input array/frame/series and optional kwargs. If y is not None, the second argument must be y.

Args:

df (dataframe or series): Input time-series.

width (int): Width of the window.

func (function): A Function that returns a scalar.

y (dataframe or series): Optional second input time-series.

by (int): Rows to skip (will be filled with NA).

by_column (bool): Applies func to each column if True

fill (bool): Fill missing values if true.

partial (bool): See R rollapply documentation.

align (bool): See R rollapply documentation.

coredata (bool): Feeds the numpy array to func if true.

Returns:

Dataframe or series. Returns results of applying func.

Note

In addition to this base function, a list of derivatives are available as well, namely run_sum, run_prod, run_min, run_max, run_mean, run_median, run_std, run_var, run_skew, run_kurt, run_cov, run_corr. These functions accept an input series (or frame) and a window size (n). If the third parameter cumulative is True, the result if cumulative application with minimum size n (all values before becoming NaN).

blueshift.library.timeseries.transform.cumulative_apply(df, func, min_period=1, by_column=True, fill=True, partial=False, align='right', coredata=False, **kwargs)

R-style reduce for Pandas, with R-like functionalities. If by_column is False, entire dataframe subset for the window will be available for the user supplied function func, otherwise func is applied separately to each column.

Note:

User supplied function (func) must return a scalar.

Args:

df (dataframe or series): Input time-series.

func (function): A Function that returns a scalar.

min_period (int): Mimimum width of the window.

by_column (bool): Applies func to each column if True

fill (bool): Fill missing values if true (locf).

partial (bool): Ignored.

aligh (bool): See R rollapply documentation.

coredata (bool): Feeds the numpy array to func if true.

Returns:

Dataframe or series. Returns results of applying func.

Note

For the derivative functions, see roll_apply.

Statstical and Pricing Models

blueshift.library.models.bs.bs_plain_vanilla_option(atmf, strike, imp_vol, time, option_type, annualization_factor)

Black 76 plain vanilla European options pricing. Parameter time can be a float (in years to expiry) or a pandas Timedelta object or a Timestamp (tz-aware). Parameter option_type can be either a OptionType enumeration or one of [“CALL”, “PUT”].

Inputs:

atmf: (float) strike: (float) imp_vol: (float) time: (float) option_type: (str) annualization_factor: (float)

Outputs:

real

blueshift.library.models.bs.bs_implied_vol(atmf, strike, price, time, option_type, annualization_factor)

Black 76 plain vanilla European options implied volatility. Parameter time can be a float (in years to expiry) or a pandas Timedelta object or a Timestamp (tz-aware). Parameter option_type can be either a OptionType enumeration or one of [“CALL”, “PUT”].

Inputs:

atmf: (float) strike: (float) price: (float) time: (float) option_type: (str) annualization_factor: (float)

Outputs:

real

blueshift.library.models.bs.bs_plain_vanilla_greek(atmf, strike, imp_vol, time, option_type, annualization_factor)

Black 76 plain vanilla European options greek. Parameter time can be a float (in years to expiry) or a pandas Timedelta object or a Timestamp (tz-aware). Parameter option_type can be either a OptionType enumeration or one of [“CALL”, “PUT”]. Supported greeks are one of [‘DELTA’, ‘VEGA’,’THETA’ and ‘GAMMA’].

Inputs:

atmf: (float) strike: (float) imp_vol: (float) time: (float) option_type: (str) greek: (str) annualization_factor: (float)

Outputs:

real

Machine Learning Functions

blueshift.library.ml.estimate_random_forest(df)

Estimate random forest regression for input DataFrame, assuming the last column to be the predicted variable, and everything else are predictors.

Args:

df (DataFrame): Merged frame of X and Y of training set.

Returns:

A random forest fitted model based on the input dataframe.

blueshift.library.ml.predict_random_forest(regr, df)

Forecast using a fitted model, assuming the last row in the input DataFrame are the observations to be predicted and the last but one column are the predictors in the model.

Args:

regr (object): A model object for prediction

df (DataFrame):

Pipeline Functions

blueshift.library.pipelines.select_universe(lookback, size)

Returns a custom filter object for volume-based filtering.

Args:

lookback (int): lookback window size size (int): Top n assets to return.

Returns:

A custom filter object

# from library.pipelines.pipelines import select_universe

pipe = Pipeline()
top_100 = select_universe(252, 100)
pipe.set_screen(top_100)
blueshift.library.pipelines.average_volume_filter(lookback, amount)

Returns a custom filter object for volume-based filtering.

Args:

lookback (int): lookback window size amount (int): amount to filter (high-pass)

Returns:

A custom filter object

# from library.pipelines.pipelines import average_volume_filter

pipe = Pipeline()
volume_filter = average_volume_filter(200, 1000000)
pipe.set_screen(volume_filter)
blueshift.library.pipelines.filter_assets(func=None)

Returns a custom filter object to filter assets based on a user supplied function. The function must return True for assets that are selected and False for assets to be filtered out. It should accept a single argument (an asset object).

Args:

func (callable): A function for filtering.

Returns:

A custom filter object

# from library.pipelines.pipelines import filter_assets
# from blueshift.assets import Equity
# context.universe = [symbol(AAPL), symbol(MSFT)]

pipe = Pipeline()
# filter out non-Equity assets
func = lambda asset:isinstance(asset, Equity)
asset_filter = filter_assets(func)
pipe.set_screen(asset_filter)
blueshift.library.pipelines.filter_universe(universe)

Returns a custom filter object to filter based on a user supplied list of assets objects. This is useful where we still want to use the underlying pipeline computation facilities, but want to specify assets explicitly.

Args:

universe (list): A list of asset objects to keep.

Returns:

A custom filter object

# from library.pipelines.pipelines import filter_universe
# context.universe = [symbol(AAPL), symbol(MSFT)]

pipe = Pipeline()
universe_filter = filter_universe(context.universe)
pipe.set_screen(universe_filter)
blueshift.library.pipelines.exclude_assets(universe)

Returns a custom filter object to filter based on a user supplied list of assets objects to exclude.

Args:

universe (list): A list of asset objects to exclude.

Returns:

A custom filter object.

# from library.pipelines.pipelines import filter_universe
# context.exclude = [symbol(AAPL), symbol(MSFT)]

pipe = Pipeline()
exclude_filter = filter_universe(context.exclude)
pipe.set_screen(exclude_filter)
blueshift.library.pipelines.returns_factor(lookback, offset=0)

Returns a custom factor object for computing simple returns over a period (lookback).

Args:

lookback (int): lookback window size offset (int): offset from the end of the window

Returns:

A custom factor object.

# from library.pipelines.pipelines import returns_factor
pipe = Pipeline()
momentum = returns_factor(200)
pipe.add(momentum,'momentum')
blueshift.library.pipelines.filtered_returns_factor(lookback, filter_, offset=0)

Returns a custom factor object for computing simple returns over a period (lookback), with a volume filter applied. Equivalent to separately applying period_returns and average_volume_filter above.

Args:

lookback (int): lookback window size filter_ (CustomFilter): a custom volume filter offset (int): offset from the end of the window

Returns:

A custom factor object.

# from library.pipelines.pipelines import average_volume_filter, period_returns2

pipe = Pipeline()
volume_filter = average_volume_filter(200, 1000000)
momentum = filtered_returns_factor(200,volume_filter)
pipe.add(momentum,'momentum')
blueshift.library.pipelines.technical_factor(lookback, indicator_fn, indicator_lookback=None)

A factory function to generate a custom factor by applying a user-defined function over asset returns.

Args:

lookback (int): lookback window size indicator_fn (function): user-defined function indicator_lookback (int): lookback for user-defined function.

Returns:

A custom factor object applying the supplied function.

Note:

The indicator_fn must be of the form f(px, n), where px is numpy ndarray and lookback is an n. Also the lookback argument above must be greater than or equal to the other argument indicator_lookback. If None it is set as the same value of lookback.

# from library.pipelines.pipelines import technical_factor

pipe = Pipeline()
rsi_factor = technical_factor(14, rsi)
pipe.add(rsi_factor,'rsi')

Strategy Templates

These strategy template class makes it easier to develop and test strategies quickly. In general, to use a template, instantiate an object of the tempalte you need, and then make sure you call the object’s initialize and before_trading_start methods in the corresponding functions of your strategy. For finer control you can call the run_strategy or other methods directly. Please read the caveats in the documentation of the respective methods to see if this will work for your particular case.

class blueshift.library.algos.strategies.SimpleStrategy(position_function=None, signal_function=None, order_size=0, frequency=None, order_function=None, entry_time=None, on_entry=None, stop_time=None, on_stop=None, exit_time=None, slippage=None, commission=None, margin=None, stoploss=None, stoploss_type=ExitMethod.PERCENT, on_stoploss=None, takeprofit=None, takeprofit_type=ExitMethod.PERCENT, on_takeprofit=None, cooloff_period=30, long_only=False, product_type=None)

Indicator based simple technical strategy template. The strategy must define position_function(context, data) that returns the target positions for each asset in the universe.

To use this template class, import it in your strategy and then instantiate an instance in your initialize function with approrpiate parameters. Then, call the initialze method of the object from your initialize function and before_trading_start method from the strategy before_trading_start function. Finally, implement the position_function to define the core strategy logic. This function must return a dictionary with assets as keys and values as the corresponding desired position. The values must be consistent with the order function used (i.e. values are target position if the order function is targetting, incremental otherwise). If an empty dictionary is returned, it will be ignored. This is useful when no trades to be done (no entry or exits) based on the current signals.

The main trading function is the run(context, data) method. This is invoked automatically, based on the frequency parameter chosen. For custom logic, directly call this function (for e.g. with the schedule_later or schedule_once API functions) to run the strategy logic.

The below sample rebalances a 50-50 portfolio in AAPL and MSFT every day at 11:00 AM. Since the default frequency is None, the rebalance function is invoked everyday only once, at the entry time, which is set at 11:00 AM.

from blueshift.library.algos.strategies import PositionalStrategy
from blueshift.api import symbol, order_target_percent

def initialize(context):
    strategy = PositionalStrategy(rebalance, entry_time="11:00",order_function=order_target_percent)
    context.strategy = strategy
    context.strategy.initialize(context)

def before_trading_start(context, data):
    context.strategy.before_trading_start(context, data)

def rebalance(context, data):
    aapl = symbol('AAPL')
    msft = symbol('MSFT')
    return {aapl:0.5, msft:0.5}

Note

We should instantiate only one object of this class per strategy in case the intraday option is turned on (i.e. exit-time is specified). This is because, the exit-all function will use the sqaure_off api method that will square of all positions in the strategy context.

Note

You can optionally specify the product type, in case the asset you want to trade is different that what is supplied in either the signal_function or the position_function. If a product type is specified, the algo will try to place and order of that type. In case a particular asset is not convertible to the given product type, the order placement will fail.

Important

You should either specify the position_function or the signal_function along with the order_size. If the former is specified, signal_function or the order_size are ignored and orders are placed directly using the quantities returned from the position_function. In the case the latter are specified, eah returned signal values must be of enum type Signal. The order value to use with the order function is based on the value of the signal return (with sign) multiplied by the order_size. Also in this case, the order_function must be of targetting type to avoid any unintentional order machine-gunning.

Important

Behaviour when the entry is stopped (either stop time is reached or the stop_entry method is called explicitly by the user strategy) is different when a the signal_funcion is specified instead of position_function. In case of signal_function, all entry signals will be ignored. In case of position_function, orders for any new assets (that has not been traded before), will be ignored, but the order will not be checked for entry or exit.

Args:
position_function (callable): The position function with a

signature f(context, data) that implements the strategy logic. Must return a dictionary with keys as asset and values as positions. The positions will be passed on to the ordering function, hence must be consistent with the order function used.

signal_function (callable): The signal function with a

signature f(context, data) that returns the current signals. Must return a dictionary with keys as asset and values as Signal. If both position_function and signal_function is supplied, signal_function will be ignored. Else the position_function is implied from the signal_function.

order_size (number): Used to convert the signal to position.

Must be consistent with the order function. Ignored if position_function is supplied directly. The order size will be multiplied by the asset multiplier (lot size for futures and options) if any.

frequency (number or str): Signal check frequency. Can be str

(like ‘5T’ or ‘5m’), or number of minutes. If None, the strategy function is invoked only once every day (at the time of the entry). If not None, the equivalent minute value must not exceed 60 (1 hour).

order_function (str or callable): The order function to

use. This must be a targetting order function and should be consistent with the returned values from position_function.

entry_time (number of str): Can be either in HH:MM format or

a number (minutes from market open) to turn on the entry for the day. If None, entry is turned on as soon as possible.

on_entry (callable): A callable to run at entry.

stop_time (number or str): HH:MM or number of minutes (from

market close). Defaults to 30 minutes from market close if None. Turns off any further entry orders.

on_stop (callable): A callable to run at stop.

exit_time (number or str): HH:MM or number of minutes (from

market close). Defaults to 30 minutes from market close if None. Cancel all open orders and squares off positions for the rest of the day. For live mode, this will also trigger algo termination.

slippage (SlippageModel): A slippage model specification

(will be ignored in live modes).

commission (CostModel): A cost model specification

(will be ignored in live modes).

margin (MarginModel): A margin model specification

(will be ignored in live modes).

stoploss (number): Stoploss target specification. None means

no stoploss.

stoploss_type (ExitMethod): Either PERCENT, MOVE or PRICE.

on_stoploss (callable): Handler if stoploss is triggered.

takeprofit (number): Take-profit target specification. None means

no take-profit.

takeprofit_type (ExitMethod): Either PERCENT, MOVE or PRICE.

on_takeprofit (callable): Handler if take-profit is triggered.

cooloff_period (number): Cool-off period in minutes, following

an exit through stoploss, take-profit or square-off.

long_only (bool): Raises error for short selling if True.

product_type (ProductType): Product Type for orders.

run_strategy(context, data)

run_strategy method invokes the user function signal_function or position_function to compute the current target positions and placing orders to achieve those positions. It skips any operation if the trading flag is off.

Note

This function is invoked by a schedule_function call if the frequency parameter is specified, else it is invoked only once on entry. User defined function can use schedule_later to call this function (from either the signal or the position function) to implement complex behaviours.

is_initialized()

If the strategy is properly initialized (i.e. both the initialize and the before_trading_start methods have been duly called.

is_complete()

If the strategy run is marked complete.

start_entry(context, data, run_strategy=True)

Turn the entry flag on. Also invoke the main strategy funtion if frequency is None.

Args:

run_strategy (bool): If also run the main run_strategy method.

Important

This function is automatically called based on the input parameters. This executes the on_entry routine from the input and also call the run_strategy method if the frequency input parameter is None. If you are calling it directly, and do not want to run the`run_strategy` method, specify run_strategy as False in the argument.

stop_entry(context, data)

Mark the entry flag as false to stop any further entry orders for the day.

Note

Call this method to stop any further entry for the rest of the day. This will be automatically reset next day.

exit_all(context, data)

Exit from all exiting positions (and cancel all open orders). Also mark the trading flag as false to stop any further trading for the day.

Note

Call this method to exit from the strategy (useful for intraday strategy).

terminate(msg=None, check_orders=True, check_positions=True)

Terminate checks for and wait for any open orders or open positions to be closed out, and then terminate the strategy. If the strategy is marked as complete (done is True), it calls terminate right away. Returns True if terminate was initiated, else returns False.

Note

Check the return value to determine if the call succeeded. If returned False, you probably want to wait and call this method again to try and terminate. Call the API terminate function directly to force stop the strategy.

class blueshift.library.algos.strategies.IntradayStrategy(position_function=None, signal_function=None, order_size=0, frequency=None, order_function=None, entry_time=None, on_entry=None, stop_time=None, on_stop=None, exit_time=None, slippage=None, commission=None, margin=None, stoploss=None, stoploss_type=ExitMethod.PERCENT, on_stoploss=None, takeprofit=None, takeprofit_type=ExitMethod.PERCENT, on_takeprofit=None, cooloff_period=30, long_only=False, product_type=None)

Intraday strategy template derived from SimpleStrategy. This is suitable for strategies that trade daily (either once a day or based on a fixed signal check frequency), and close all positions before the market close each day (i.e. do not carry any overnight positions).

Note

If exit time is not specified, exit time defaults to 30 minutes before the close of trading time.

class blueshift.library.algos.strategies.PositionalStrategy(position_function=None, signal_function=None, order_size=0, frequency=None, order_function=None, entry_time=None, on_entry=None, stop_time=None, on_stop=None, exit_time=None, slippage=None, commission=None, margin=None, stoploss=None, stoploss_type=ExitMethod.PERCENT, on_stoploss=None, takeprofit=None, takeprofit_type=ExitMethod.PERCENT, on_takeprofit=None, cooloff_period=30, long_only=False, product_type=None)

Positional strategy template derived from SimpleStrategy. This is suitable for strategies that trade daily (either once a day or based on a fixed signal check frequency), and may carry overnight positions.

Note

If exit time is not specified, no exits are triggered at the end of the day - which creates overnight positions. Also, unlike its super class, it re-initiates all stoploss and take-profits at the start of each trading day for the overnight positions.

Execution Algorithms

These execution algorithms are designed to be used with the order to place advanced algorithmic orders. These advanced order objects are different from the simpler Order object, but follow similar interface and attributes with equivalent meaning.

class blueshift.library.algos.executions.VanillaOrder(asset: Asset, quantity: int, limit_price: float = 0, timeout: int = 30, **kwargs)

Algo Order that represents a vanilla (regular) order with optional timeout. The parameter limit_price defaults to 0 (market order) and timeout defaults to 30 (minutes). Set timeout to 0 for no timeout (i.e. default order validity of DAY).

Args:

asset (Asset): Asset for the order.

quantity (int): Quantity for the order (negative means sell).

limit_price (number): Limit price for the order.

timeout (int): Timeout in minutes before cancellation.

Optional keywords arguments as applicable for ordering functions can be passed on as well. A positive quantity is a buy order.

class blueshift.library.algos.executions.PassiveAggressiveOrder(asset: Asset, quantity: int, limit_price: float, timeout: int = 30, convert_to_market: bool = False, **kwargs)

Algo Order that places a limit order, and waits for the duration of the order as specified (timeout). At the end of the specified duration, if the order is still not complete, we cancel the limit order, and optionally replace the remaining part to a market order.

Args:

asset (Asset): Asset for the order.

quantity (int): Quantity for the order (negative means sell).

limit_price (number): Limit price for the order.

timeout (int): Timeout in minutes before cancellation.

convert_to_market (bool): Convert to market order if not filled.

Optional keywords arguments as applicable for ordering functions can be passed on as well. A positive quantity is a buy order.

class blueshift.library.algos.executions.AdaptiveOrder(asset: Asset, quantity: int, price_offset: float, timeout: int = 30, delay: float = 1, convert_to_market: bool = True, offset_decay=None, **kwargs)

Adaptive Order is a passive-aggressive style where we first place a limit order off by offset amount of from the best bid (offer) for a buy (sell) order (in the favour of the direction of the order). For the duration of the strategy (timeout), we periodically (delay) look at the fill and update the order limit price - by adjusting the bid (offer) at the current market level. If by the end of timeout the period, the order is still not filled (or partially filled), we cancel the initial limit order and optionally replace it with a market order with the remaining amount. If offset_decay is supplied, it must be a positive number less than 1, and for each order modification, the current price offset is multiplied by this value. A low offset decay moves fast to the best bid/offer and a high value moves to the best bid/offer slowly. Omit this parameter to keep the same offset for all order modification requests.

Note

Fractional values are allowed for delay.

Args:

asset (Asset): Asset for the order.

quantity (int): Quantity for the order (negative means sell).

price_offset (number): Offset from the best bid or offer.

timeout (int): Timeout in minutes before cancellation.

delay (number): Number of minutes to wait before update.

convert_to_market (bool): Convert to market order if not filled.

offset_decay (number): A number between 0 to 1.

Optional keywords arguments as applicable for ordering functions can be passed on as well. A positive quantity is a buy order.

class blueshift.library.algos.executions.MarketIfTouched(asset: Asset, quantity: int, target_price: float, timeout: int = 30, delay: float = 1, **kwargs)

Conditional order waits for a specific condition to meet before placing the order (at limit or at market). The algo waits for a timeout number of minutes before the condition is met, else gets cancelled. It accepts a callable (condition) of the signature f(context, data) and must evaluate to True if the condition is fulfilled. The parameter delay determines the delay (minutes) between two successive condition checks. For Market-If-Touched orders, if the specified target_price is reached, a market order is triggered.

Note

Fractional values are allowed for delay.

Args:

asset (Asset): Asset for the order.

quantity (int): Quantity for the order (negative means sell).

target_price (float): Price that triggers the order.

timeout (int): Timeout in minutes before cancellation.

delay (number): Number of minutes between consecutive checks.

Optional keywords arguments as applicable for ordering functions can be passed on as well. A positive quantity is a buy order.

class blueshift.library.algos.executions.LimitIfTouched(asset: Asset, quantity: int, target_price: float, limit_price: float, timeout: int = 30, delay: float = 1, **kwargs)

Conditional order waits for a specific condition to meet before placing the order (at limit or at market). The algo waits for a timeout number of minutes before the condition is met, else gets cancelled. It accepts a callable (condition) of the signature f(context, data) and must evaluate to True if the condition is fulfilled. The parameter delay determines the delay (minutes) between two successive condition checks. For Limit-If-Touched orders, if the specified target_price is reached, a limit order is triggered at the limit_price.

Note

Fractional values are allowed for delay.

Args:

asset (Asset): Asset for the order.

quantity (int): Quantity for the order (negative means sell).

target_price (float): Price that triggers the order.

limit_price (number): Limit price for the order.

timeout (int): Timeout in minutes before cancellation.

delay (number): Number of minutes between consecutive checks.

Optional keywords arguments as applicable for ordering functions can be passed on as well. A positive quantity is a buy order.

class blueshift.library.algos.executions.ConditionalOrder(asset: Asset, quantity: int, condition: callable, limit_price: float = 0, timeout: int = 30, delay: float = 1, **kwargs)

Conditional order waits for a specific condition to meet before placing the order (at limit or at market). The algo waits for a timeout number of minutes before the condition is met, else gets cancelled. It accepts a callable (condition) of the signature f(context, data) and must evaluate to True if the condition is fullfilled. The parameter delay determines the delay (minutes) between two successive condition checks.

Note

Fractional values are allowed for delay.

Args:

asset (Asset): Asset for the order.

quantity (int): Quantity for the order (negative means sell).

condition (callable): A callable to evaluate the condition.

limit_price (number): Limit price for the order.

timeout (int): Timeout in minutes before cancellation.

delay (number): Number of minutes between consecutive checks.

Optional keywords arguments as applicable for ordering functions can be passed on as well. A positive quantity is a buy order.

class blueshift.library.algos.executions.IcebergOrder(asset: ~blueshift_objects.assets._assets.Asset, quantity: int, slices: int, order_type: ['market', 'limit', <OrderType.MARKET: 0>, <OrderType.LIMIT: 1>] = 'market', price_offset: float = 0, timeout: int = 30, delay: float = 1, cancel_on_timeout: bool = False, **kwargs)

Iceberg order breaks up a large order to a number of (slices) smaller orders and place each of them one by one. The individual order can be either market or limit (order_type). For limit orders, price_offset is required - the offset (in our favour, can be negative) to apply to the current best bid (buy or offer (sell). If the whole order is not complete by the time specified by timeout (in minutes), the pending orders are cancelled if cancel_on_timeout is True, else they are left as is. The delay parameters determines the minimum delay between successive orders. The next order is sent if the previous order is filled AND the delay time has elapsed. If delay is 0, the next order is sent as soon as the previous one is filled.

Args:

asset (Asset): Asset for the order.

quantity (int): Quantity for the order (negative means sell).

slices (int): Number of slices.

order_type (str): Order type, can be either ‘market’ or ‘limit’.

price_offset (number): Limit price offset for the order.

timeout (int): Timeout in minutes before cancellation.

delay (number): Number of minutes between consecutive checks.

cancel_on_timeout (bool): Cancel pending orders if timed-out.

Optional keywords arguments as applicable for ordering functions can be passed on as well. A positive quantity is a buy order.

class blueshift.library.algos.executions.TwapOrder(asset: ~blueshift_objects.assets._assets.Asset, quantity: int, slices: int, order_type: ['market', 'limit', <OrderType.MARKET: 0>, <OrderType.LIMIT: 1>] = 'market', price_offset: float = 0, timeout: int = 30, delay: float = 1, cancel_on_timeout: bool = False, **kwargs)

TWAP order breaks up a large order to a number of (slices) smaller orders and place each of them one by one at a specified time interval. The individual order can be either market or limit (order_type). For limit orders, price_offset is required - the offset (in our favour, can be negative) to apply to the current best bid (buy or offer (sell). If the whole order is not complete by the time specified by timeout (in minutes), the pending orders are cancelled if cancel_on_timeout is True, else they are left as is. The delay parameters determines the minimum delay between successive orders. The next order is sent if the delay time has elapsed.

Args:

asset (Asset): Asset for the order.

quantity (int): Quantity for the order (negative means sell).

slices (int): Number of slices.

order_type (str): Order type, can be either ‘market’ or ‘limit’.

price_offset (number): Limit price offset for the order.

timeout (int): Timeout in minutes before cancellation.

delay (number): Number of minutes between consecutive checks.

cancel_on_timeout (bool): Cancel pending orders if timed-out.

Optional keywords arguments as applicable for ordering functions can be passed on as well. A positive quantity is a buy order.

class blueshift.library.algos.executions.PairOrder(long_asset: ~blueshift_objects.assets._assets.Asset, short_asset: ~blueshift_objects.assets._assets.Asset, long_quantity: int, short_quantity: int = 0, method=None, lookback=None, target=None, condition=None, order_type: ['market', 'limit', <OrderType.MARKET: 0>, <OrderType.LIMIT: 1>] = 'market', price_offset: float = 0, timeout=None, delay: float = 1, **kwargs)

Algo order to place pair order. One leg is a long and the other is short. On top of the basket functionality, this algo order provides automatic sizing for the second leg, and conditional entry based on the spread value.

Note

If the short_quantity is specified, it must be an positive integer and the method should be None. Specifiy method as equal-quantity to have the long and the short quantities same. Use equal-value for dollar-neutral pair and beta-neutral for using linear regression-based hedge ratio. The later uses lookback sized window for estimation and does a log transform on the prices before the regression. For cases of equal quantity, equal value or hedge ratio based pairs, short_quantity input will be ignored (and will be estimated internally).

Note

The entry is triggered if the spread value is less than the target specified. For example to enter the pair trade at a spread less than 50.0, enter target as 50.0. For any other logic, directly specify the condition callable (must be of a signature like f(context, data)). If condition is specified, target is ignored. If both condition and target is None, an entry is triggered as soon as the order is initiated.

Args:

long_asset (Asset): asset of the long leg.

short_asset (Asset): asset of the short leg.

long_quantity (int): The long leg quantity (> 0)

short_quantity (int): The short leg quantity (> 0 or None)

method (str): Method of pair - see note.

lookback (int): Lookback for hedge ratio estimation - see note.

target (number): Target for entry condition - see note.

condition (callable): Entry condition function - see note.

order_type (str): Order type - “market” or “limit”.

price_offset (number): Offset from the best bid or offer (for limit orders).

timeout (int): Timeout in minutes before cancellation.

delay (number): Frequency (in minutes) for entry condition and timeout checks.

class blueshift.library.algos.executions.BasketOrder(basket, condition=None, order_type: ['market', 'limit'] = 'market', price_offset: float = 0, timeout=None, delay: float = 1, **kwargs)

AlgoOrder interface for managing a basket of assets. Here all the orders to be placed are completely known at the beginning. The order placement is done based on the condition function. Basket is a dictionary keyed by assets and values determine the order quantity. A negative value means sell order. Condition is a callable with the signature f(context, data) that returns True to trigger the order entry. If no condition function is supplied, the order triggers as soon as possible.

Note

The quantity of a basket order is quantity of the asset in the constituent basket with maximum quantity.

Args:

basket (dict): A dictionary of assets and (signed) quantities.

condition (callable): A function that triggers the order.

order_type (str): Order type - “market” or “limit”.

price_offset (number): Offset from the best bid or offer (for limit orders).

timeout (int): Timeout in minutes before cancellation.

delay (number): Frequency (in minutes) for entry condition and timeout checks.

An example of use case is shown below

from blueshift.api import symbol, schedule_function, date_rules, time_rules
from blueshift.api import get_datetime, order, terminate, schedule_once

from blueshift.library.algos import IcebergOrder

def initialize(context):
    asset = symbol('ACC')

    algo = IcebergOrder(asset, 50, 10, order_type='market', timeout=300)
    context.algo = algo

    schedule_once(place_order)
    schedule_function(strategy,
                      date_rules.every_day(),
                      time_rules.every_nth_minute(1))

def place_order(context, data):
    order(context.algo)

def strategy(context, data):
    if not context.algo.is_open():
        msg = f'{get_datetime()}:exiting strategy, algo execution terminated.'
        terminate(msg)

In the above example, the strategy instantiates an Iceberg order and places the order as soon as possible. Once the order is placed, it periodically checks the status, and once completed, exits the strategy.

Library Objects

class blueshift.library.common.Signal(value)

An enum for trading signal. You can use the values of these enums for placing order directly. Although all three of EXIT, LONG_EXIT and SHORT_EXIT has numerical value of 0, they still are distinct enumerations. No value is defined for the member NO_SIGNAL, do not attempt to use its value for any computation.

LONG_ENTRY = 1
LONG_ENTRY_STRONG = 2
SHORT_ENTRY = -1
SHORT_ENTRY_STRONG = -2
LONG_EXIT = 0
SHORT_EXIT = 0
EXIT = 0
NO_SIGNAL = NO_SIGNAL
class blueshift.library.common.LineType(value)

Enum for line types generated by find_support_resistance as well as find_trends functions.

SUPPORT = 'support'
RESISTANCE = 'resistance'
TREND = 'trend'
class blueshift.library.common.Line(points, type_, score=0, fit=True)

A class to capture important points technical support or resistance lines. The param points is a series (of points that makes up the line). The parameter type_ can be either string “support” or “resistance” or of Enum type SupportType.

type

Line type of this line.

line

Returns the pandas Series that represents the line.

score

User defined score, or the R-squared fit for the given points.

slope

The slope of the line.

intercept

The intercept of the line.

is_breakout(level, dt)

Given the current level and current date (date-like or timestamp), find if we have a break-out. This is only applicable for line types SUPPORT and RESISTANCE. A break is breaking below support or breaking above resistance.

get_level(dt)

Given a date-like or timestamp, find the implied level from the line.

plot()

Use Pandas plot method to plot the underlying line.

class blueshift.library.common.Pattern(name, points, lines, level, aspect)

A class to capture important points based patterns. This has the following attributes

  • name: is the name of the pattern type,

  • points: are the price points (important points) that make the pattern.

  • lines: A list of lines that define the pattern.

  • level: is usually the level that is watched for breach.

  • aspect is any (usually dimension-less) feature of the particular pattern that is deemed important.

The lines parameters are a list of Line objects (may be an empty list for patterns purely defined by important points).

plot()

Use Pandas plot method to plot the pattern.

Library utility functions

blueshift.library.common.str2bool(value)

Convert string input to boolean.

blueshift.library.common.get_upfront_capital(context, asset, quantity, product_type=None, pct_margin=0.15)

Get upfront capital requirement for a new position in the asset with the given quantity, side and product_type; either in cash upfront or as margin (or both, e.g. for short position in options).

Args:

context (AlgoContext): Algorithm context.

asset (Asset): An asset object.

quantity (number): Quantity of the intended position (negative for sell).

product_type (ProductType): Product type (enum or string e.g. ‘margin’).

pct_margin (number): Percetage flat margin for margin products.

Returns:

Number. The required capital (including margin and cash upfront).