signature:
def days_to_liquidate_positions ( positions , market_data , max_bar_consumption = 0.2 , capital_base = 1e6 , mean_volume_window = 5 ) :
    """Compute the number of days that would have been required
 to fully liquidate each position on each day based on the
 trailing n day mean daily bar volume and a limit on the proportion
 of a daily bar that we are allowed to consume .
 This analysis uses portfolio allocations and a provided capital base
 rather than the dollar values in the positions DataFrame to remove the
 effect of compounding on days to liquidate . In other words , this function
 assumes that the net liquidation portfolio value will always remain
 constant at capital _ base .
 Parameters
 positions : pd . DataFrame
 Contains daily position values including cash
 - See full explanation in tears . create _ full _ tear _ sheet
 market _ data : pd . Panel
 Panel with items axis of ' price ' and ' volume ' DataFrames .
 The major and minor axes should match those of the
 the passed positions DataFrame ( same dates and symbols ) .
 max _ bar _ consumption : float
 Max proportion of a daily bar that can be consumed in the
 process of liquidating a position .
 capital _ base : integer
 Capital base multiplied by portfolio allocation to compute
 position value that needs liquidating .
 mean _ volume _ window : float
 Trailing window to use in mean volume calculation .
 Returns
 days _ to _ liquidate : pd . DataFrame
 Number of days required to fully liquidate daily positions .
 Datetime index , symbols as columns ."""

implementation:
DV = market_data [ 'volume' ] * market_data [ 'price' ]
roll_mean_dv = DV . rolling ( window = mean_volume_window , center = False ) . mean ( ) . shift ( )
roll_mean_dv = roll_mean_dv . replace ( 0 , np . nan )
positions_alloc = pos . get_percent_alloc ( positions )
positions_alloc = positions_alloc . drop ( 'cash' , axis = 1 )
days_to_liquidate = ( positions_alloc * capital_base ) / ( max_bar_consumption * roll_mean_dv )
return days_to_liquidate . iloc [ mean_volume_window : ]


signature:
def get_max_days_to_liquidate_by_ticker ( positions , market_data , max_bar_consumption = 0.2 , capital_base = 1e6 , mean_volume_window = 5 , last_n_days = None ) :
    """Finds the longest estimated liquidation time for each traded
 name over the course of backtest ( or last n days of the backtest ) .
 Parameters
 positions : pd . DataFrame
 Contains daily position values including cash
 - See full explanation in tears . create _ full _ tear _ sheet
 market _ data : pd . Panel
 Panel with items axis of ' price ' and ' volume ' DataFrames .
 The major and minor axes should match those of the
 the passed positions DataFrame ( same dates and symbols ) .
 max _ bar _ consumption : float
 Max proportion of a daily bar that can be consumed in the
 process of liquidating a position .
 capital _ base : integer
 Capital base multiplied by portfolio allocation to compute
 position value that needs liquidating .
 mean _ volume _ window : float
 Trailing window to use in mean volume calculation .
 last _ n _ days : integer
 Compute for only the last n days of the passed backtest data .
 Returns
 days _ to _ liquidate : pd . DataFrame
 Max Number of days required to fully liquidate each traded name .
 Index of symbols . Columns for days _ to _ liquidate and the corresponding
 date and position _ alloc on that day ."""

implementation:
dtlp = days_to_liquidate_positions ( positions , market_data , max_bar_consumption = max_bar_consumption , capital_base = capital_base , mean_volume_window = mean_volume_window )
if last_n_days is not None :
    dtlp = dtlp . loc [ dtlp . index . max ( ) - pd . Timedelta ( days = last_n_days ) : ]
pos_alloc = pos . get_percent_alloc ( positions )
pos_alloc = pos_alloc . drop ( 'cash' , axis = 1 )
liq_desc = pd . DataFrame ( )
liq_desc [ 'days_to_liquidate' ] = dtlp . unstack ( )
liq_desc [ 'pos_alloc_pct' ] = pos_alloc . unstack ( ) * 100
liq_desc . index . levels [ 0 ] . name = 'symbol'
liq_desc . index . levels [ 1 ] . name = 'date'
worst_liq = liq_desc . reset_index ( ) . sort_values ( 'days_to_liquidate' , ascending = False ) . groupby ( 'symbol' ) . first ( )
return worst_liq


signature:
def get_low_liquidity_transactions ( transactions , market_data , last_n_days = None ) :
    """For each traded name , find the daily transaction total that consumed
 the greatest proportion of available daily bar volume .
 Parameters
 transactions : pd . DataFrame
 Prices and amounts of executed trades . One row per trade .
 - See full explanation in create _ full _ tear _ sheet .
 market _ data : pd . Panel
 Panel with items axis of ' price ' and ' volume ' DataFrames .
 The major and minor axes should match those of the
 the passed positions DataFrame ( same dates and symbols ) .
 last _ n _ days : integer
 Compute for only the last n days of the passed backtest data ."""

implementation:
txn_daily_w_bar = daily_txns_with_bar_data ( transactions , market_data )
txn_daily_w_bar . index . name = 'date'
txn_daily_w_bar = txn_daily_w_bar . reset_index ( )
if last_n_days is not None :
    md = txn_daily_w_bar . date . max ( ) - pd . Timedelta ( days = last_n_days )
    txn_daily_w_bar = txn_daily_w_bar [ txn_daily_w_bar . date > md ]
bar_consumption = txn_daily_w_bar . assign ( max_pct_bar_consumed = ( txn_daily_w_bar . amount / txn_daily_w_bar . volume ) * 100 ) . sort_values ( 'max_pct_bar_consumed' , ascending = False )
max_bar_consumption = bar_consumption . groupby ( 'symbol' ) . first ( )
return max_bar_consumption [ [ 'date' , 'max_pct_bar_consumed' ] ]


signature:
def apply_slippage_penalty ( returns , txn_daily , simulate_starting_capital , backtest_starting_capital , impact = 0.1 ) :
    """Applies quadratic volumeshare slippage model to daily returns based
 on the proportion of the observed historical daily bar dollar volume
 consumed by the strategy ' s trades . Scales the size of trades based
 on the ratio of the starting capital we wish to test to the starting
 capital of the passed backtest data .
 Parameters
 returns : pd . Series
 Time series of daily returns .
 txn _ daily : pd . Series
 Daily transaciton totals , closing price , and daily volume for
 each traded name . See price _ volume _ daily _ txns for more details .
 simulate _ starting _ capital : integer
 capital at which we want to test
 backtest _ starting _ capital : capital base at which backtest was
 origionally run . impact : See Zipline volumeshare slippage model
 impact : float
 Scales the size of the slippage penalty .
 Returns
 adj _ returns : pd . Series
 Slippage penalty adjusted daily returns ."""

implementation:
mult = simulate_starting_capital / backtest_starting_capital
simulate_traded_shares = abs ( mult * txn_daily . amount )
simulate_traded_dollars = txn_daily . price * simulate_traded_shares
simulate_pct_volume_used = simulate_traded_shares / txn_daily . volume
penalties = simulate_pct_volume_used ** 2 * impact * simulate_traded_dollars
daily_penalty = penalties . resample ( 'D' ) . sum ( )
daily_penalty = daily_penalty . reindex ( returns . index ) . fillna ( 0 )
# Since we are scaling the numerator of the penalties linearly
# by capital base , it makes the most sense to scale the denominator
# similarly . In other words , since we aren ' t applying compounding to
# simulate _ traded _ shares , we shouldn ' t apply compounding to pv .
portfolio_value = ep . cum_returns ( returns , starting_value = backtest_starting_capital ) * mult
adj_returns = returns - ( daily_penalty / portfolio_value )
return adj_returns


signature:
def map_transaction ( txn ) :
    """Maps a single transaction row to a dictionary .
 Parameters
 txn : pd . DataFrame
 A single transaction object to convert to a dictionary .
 Returns
 dict
 Mapped transaction ."""

implementation:
if isinstance ( txn [ 'sid' ] , dict ) :
    sid = txn [ 'sid' ] [ 'sid' ]
    symbol = txn [ 'sid' ] [ 'symbol' ]
else :
    sid = txn [ 'sid' ]
    symbol = txn [ 'sid' ]
return { 'sid' : sid , 'symbol' : symbol , 'price' : txn [ 'price' ] , 'order_id' : txn [ 'order_id' ] , 'amount' : txn [ 'amount' ] , 'commission' : txn [ 'commission' ] , 'dt' : txn [ 'dt' ] }


signature:
def make_transaction_frame ( transactions ) :
    """Formats a transaction DataFrame .
 Parameters
 transactions : pd . DataFrame
 Contains improperly formatted transactional data .
 Returns
 df : pd . DataFrame
 Daily transaction volume and dollar ammount .
 - See full explanation in tears . create _ full _ tear _ sheet ."""

implementation:
transaction_list = [ ]
for dt in transactions . index :
    txns = transactions . loc [ dt ]
    if len ( txns ) == 0 :
        continue
    for txn in txns :
        txn = map_transaction ( txn )
        transaction_list . append ( txn )
df = pd . DataFrame ( sorted ( transaction_list , key = lambda x : x [ 'dt' ] ) )
df [ 'txn_dollars' ] = - df [ 'amount' ] * df [ 'price' ]
df . index = list ( map ( pd . Timestamp , df . dt . values ) )
return df


signature:
def get_txn_vol ( transactions ) :
    """Extract daily transaction data from set of transaction objects .
 Parameters
 transactions : pd . DataFrame
 Time series containing one row per symbol ( and potentially
 duplicate datetime indices ) and columns for amount and
 price .
 Returns
 pd . DataFrame
 Daily transaction volume and number of shares .
 - See full explanation in tears . create _ full _ tear _ sheet ."""

implementation:
txn_norm = transactions . copy ( )
txn_norm . index = txn_norm . index . normalize ( )
amounts = txn_norm . amount . abs ( )
prices = txn_norm . price
values = amounts * prices
daily_amounts = amounts . groupby ( amounts . index ) . sum ( )
daily_values = values . groupby ( values . index ) . sum ( )
daily_amounts . name = "txn_shares"
daily_values . name = "txn_volume"
return pd . concat ( [ daily_values , daily_amounts ] , axis = 1 )


signature:
def adjust_returns_for_slippage ( returns , positions , transactions , slippage_bps ) :
    """Apply a slippage penalty for every dollar traded .
 Parameters
 returns : pd . Series
 Daily returns of the strategy , noncumulative .
 - See full explanation in create _ full _ tear _ sheet .
 positions : pd . DataFrame
 Daily net position values .
 - See full explanation in create _ full _ tear _ sheet .
 transactions : pd . DataFrame
 Prices and amounts of executed trades . One row per trade .
 - See full explanation in create _ full _ tear _ sheet .
 slippage _ bps : int / float
 Basis points of slippage to apply .
 Returns
 pd . Series
 Time series of daily returns , adjusted for slippage ."""

implementation:
slippage = 0.0001 * slippage_bps
portfolio_value = positions . sum ( axis = 1 )
pnl = portfolio_value * returns
traded_value = get_txn_vol ( transactions ) . txn_volume
slippage_dollars = traded_value * slippage
adjusted_pnl = pnl . add ( - slippage_dollars , fill_value = 0 )
adjusted_returns = returns * adjusted_pnl / pnl
return adjusted_returns


signature:
def get_turnover ( positions , transactions , denominator = 'AGB' ) :
    """- Value of purchases and sales divided
 by either the actual gross book or the portfolio value
 for the time step .
 Parameters
 positions : pd . DataFrame
 Contains daily position values including cash .
 - See full explanation in tears . create _ full _ tear _ sheet
 transactions : pd . DataFrame
 Prices and amounts of executed trades . One row per trade .
 - See full explanation in tears . create _ full _ tear _ sheet
 denominator : str , optional
 Either ' AGB ' or ' portfolio _ value ' , default AGB .
 - AGB ( Actual gross book ) is the gross market
 value ( GMV ) of the specific algo being analyzed .
 Swapping out an entire portfolio of stocks for
 another will yield 200 % turnover , not 100 % , since
 transactions are being made for both sides .
 - We use average of the previous and the current end - of - period
 AGB to avoid singularities when trading only into or
 out of an entire book in one trading period .
 - portfolio _ value is the total value of the algo ' s
 positions end - of - period , including cash .
 Returns
 turnover _ rate : pd . Series
 timeseries of portfolio turnover rates ."""

implementation:
txn_vol = get_txn_vol ( transactions )
traded_value = txn_vol . txn_volume
if denominator == 'AGB' : # Actual gross book is the same thing as the algo ' s GMV
# We want our denom to be avg ( AGB previous , AGB current )
    AGB = positions . drop ( 'cash' , axis = 1 ) . abs ( ) . sum ( axis = 1 )
    denom = AGB . rolling ( 2 ) . mean ( )
    # Since the first value of pd . rolling returns NaN , we
    # set our " day 0 " AGB to 0.
    denom . iloc [ 0 ] = AGB . iloc [ 0 ] / 2
elif denominator == 'portfolio_value' :
    denom = positions . sum ( axis = 1 )
else :
    raise ValueError ( "Unexpected value for denominator '{}'. The " "denominator parameter must be either 'AGB'" " or 'portfolio_value'." . format ( denominator ) )
denom . index = denom . index . normalize ( )
turnover = traded_value . div ( denom , axis = 'index' )
turnover = turnover . fillna ( 0 )
return turnover


signature:
def _groupby_consecutive ( txn , max_delta = pd . Timedelta ( '8h' ) ) :
    """Merge transactions of the same direction separated by less than
 max _ delta time duration .
 Parameters
 transactions : pd . DataFrame
 Prices and amounts of executed round _ trips . One row per trade .
 - See full explanation in tears . create _ full _ tear _ sheet
 max _ delta : pandas . Timedelta ( optional )
 Merge transactions in the same direction separated by less
 than max _ delta time duration .
 Returns
 transactions : pd . DataFrame"""

implementation:
def vwap ( transaction ) :
    if transaction . amount . sum ( ) == 0 :
        warnings . warn ( 'Zero transacted shares, setting vwap to nan.' )
        return np . nan
    return ( transaction . amount * transaction . price ) . sum ( ) / transaction . amount . sum ( )
out = [ ]
for sym , t in txn . groupby ( 'symbol' ) :
    t = t . sort_index ( )
    t . index . name = 'dt'
    t = t . reset_index ( )
    t [ 'order_sign' ] = t . amount > 0
    t [ 'block_dir' ] = ( t . order_sign . shift ( 1 ) != t . order_sign ) . astype ( int ) . cumsum ( )
    t [ 'block_time' ] = ( ( t . dt . sub ( t . dt . shift ( 1 ) ) ) > max_delta ) . astype ( int ) . cumsum ( )
    grouped_price = ( t . groupby ( ( 'block_dir' , 'block_time' ) ) . apply ( vwap ) )
    grouped_price . name = 'price'
    grouped_rest = t . groupby ( ( 'block_dir' , 'block_time' ) ) . agg ( { 'amount' : 'sum' , 'symbol' : 'first' , 'dt' : 'first' } )
    grouped = grouped_rest . join ( grouped_price )
    out . append ( grouped )
out = pd . concat ( out )
out = out . set_index ( 'dt' )
return out


signature:
def extract_round_trips ( transactions , portfolio_value = None ) :
    """Group transactions into " round trips " . First , transactions are
 grouped by day and directionality . Then , long and short
 transactions are matched to create round - trip round _ trips for which
 PnL , duration and returns are computed . Crossings where a position
 changes from long to short and vice - versa are handled correctly .
 Under the hood , we reconstruct the individual shares in a
 portfolio over time and match round _ trips in a FIFO - order .
 For example , the following transactions would constitute one round trip :
 index amount price symbol
 2004-01-09 12:18:01 10 50 ' AAPL '
 2004-01-09 15:12:53 10 100 ' AAPL '
 2004-01-13 14:41:23 - 10 100 ' AAPL '
 2004-01-13 15:23:34 - 10 200 ' AAPL '
 First , the first two and last two round _ trips will be merged into a two
 single transactions ( computing the price via vwap ) . Then , during
 the portfolio reconstruction , the two resulting transactions will
 be merged and result in 1 round - trip trade with a PnL of
 (150 * 20 ) - ( 75 * 20 ) = 1500.
 Note , that round trips do not have to close out positions
 completely . For example , we could have removed the last
 transaction in the example above and still generated a round - trip
 over 10 shares with 10 shares left in the portfolio to be matched
 with a later transaction .
 Parameters
 transactions : pd . DataFrame
 Prices and amounts of executed round _ trips . One row per trade .
 - See full explanation in tears . create _ full _ tear _ sheet
 portfolio _ value : pd . Series ( optional )
 Portfolio value ( all net assets including cash ) over time .
 Note that portfolio _ value needs to beginning of day , so either
 use . shift ( ) or positions . sum ( axis = ' columns ' ) / ( 1 + returns ) .
 Returns
 round _ trips : pd . DataFrame
 DataFrame with one row per round trip . The returns column
 contains returns in respect to the portfolio value while
 rt _ returns are the returns in regards to the invested capital
 into that partiulcar round - trip ."""

implementation:
transactions = _groupby_consecutive ( transactions )
roundtrips = [ ]
for sym , trans_sym in transactions . groupby ( 'symbol' ) :
    trans_sym = trans_sym . sort_index ( )
    price_stack = deque ( )
    dt_stack = deque ( )
    trans_sym [ 'signed_price' ] = trans_sym . price * np . sign ( trans_sym . amount )
    trans_sym [ 'abs_amount' ] = trans_sym . amount . abs ( ) . astype ( int )
    for dt , t in trans_sym . iterrows ( ) :
        if t . price < 0 :
            warnings . warn ( 'Negative price detected, ignoring for' 'round-trip.' )
            continue
        indiv_prices = [ t . signed_price ] * t . abs_amount
        if ( len ( price_stack ) == 0 ) or ( copysign ( 1 , price_stack [ - 1 ] ) == copysign ( 1 , t . amount ) ) :
            price_stack . extend ( indiv_prices )
            dt_stack . extend ( [ dt ] * len ( indiv_prices ) )
        else : # Close round - trip
            pnl = 0
            invested = 0
            cur_open_dts = [ ]
            for price in indiv_prices :
                if len ( price_stack ) != 0 and ( copysign ( 1 , price_stack [ - 1 ] ) != copysign ( 1 , price ) ) : # Retrieve first dt , stock - price pair from
                # stack
                    prev_price = price_stack . popleft ( )
                    prev_dt = dt_stack . popleft ( )
                    pnl += - ( price + prev_price )
                    cur_open_dts . append ( prev_dt )
                    invested += abs ( prev_price )
                else : # Push additional stock - prices onto stack
                    price_stack . append ( price )
                    dt_stack . append ( dt )
            roundtrips . append ( { 'pnl' : pnl , 'open_dt' : cur_open_dts [ 0 ] , 'close_dt' : dt , 'long' : price < 0 , 'rt_returns' : pnl / invested , 'symbol' : sym , } )
roundtrips = pd . DataFrame ( roundtrips )
roundtrips [ 'duration' ] = roundtrips [ 'close_dt' ] . sub ( roundtrips [ 'open_dt' ] )
if portfolio_value is not None : # Need to normalize so that we can join
    pv = pd . DataFrame ( portfolio_value , columns = [ 'portfolio_value' ] ) . assign ( date = portfolio_value . index )
    roundtrips [ 'date' ] = roundtrips . close_dt . apply ( lambda x : x . replace ( hour = 0 , minute = 0 , second = 0 ) )
    tmp = roundtrips . join ( pv , on = 'date' , lsuffix = '_' )
    roundtrips [ 'returns' ] = tmp . pnl / tmp . portfolio_value
    roundtrips = roundtrips . drop ( 'date' , axis = 'columns' )
return roundtrips


signature:
def add_closing_transactions ( positions , transactions ) :
    """Appends transactions that close out all positions at the end of
 the timespan covered by positions data . Utilizes pricing information
 in the positions DataFrame to determine closing price .
 Parameters
 positions : pd . DataFrame
 The positions that the strategy takes over time .
 transactions : pd . DataFrame
 Prices and amounts of executed round _ trips . One row per trade .
 - See full explanation in tears . create _ full _ tear _ sheet
 Returns
 closed _ txns : pd . DataFrame
 Transactions with closing transactions appended ."""

implementation:
closed_txns = transactions [ [ 'symbol' , 'amount' , 'price' ] ]
pos_at_end = positions . drop ( 'cash' , axis = 1 ) . iloc [ - 1 ]
open_pos = pos_at_end . replace ( 0 , np . nan ) . dropna ( )
# Add closing round _ trips one second after the close to be sure
# they don ' t conflict with other round _ trips executed at that time .
end_dt = open_pos . name + pd . Timedelta ( seconds = 1 )
for sym , ending_val in open_pos . iteritems ( ) :
    txn_sym = transactions [ transactions . symbol == sym ]
    ending_amount = txn_sym . amount . sum ( )
    ending_price = ending_val / ending_amount
    closing_txn = { 'symbol' : sym , 'amount' : - ending_amount , 'price' : ending_price }
    closing_txn = pd . DataFrame ( closing_txn , index = [ end_dt ] )
    closed_txns = closed_txns . append ( closing_txn )
closed_txns = closed_txns [ closed_txns . amount != 0 ]
return closed_txns


signature:
def apply_sector_mappings_to_round_trips ( round_trips , sector_mappings ) :
    """Translates round trip symbols to sectors .
 Parameters
 round _ trips : pd . DataFrame
 DataFrame with one row per round trip trade .
 - See full explanation in round _ trips . extract _ round _ trips
 sector _ mappings : dict or pd . Series , optional
 Security identifier to sector mapping .
 Security ids as keys , sectors as values .
 Returns
 sector _ round _ trips : pd . DataFrame
 Round trips with symbol names replaced by sector names ."""

implementation:
sector_round_trips = round_trips . copy ( )
sector_round_trips . symbol = sector_round_trips . symbol . apply ( lambda x : sector_mappings . get ( x , 'No Sector Mapping' ) )
sector_round_trips = sector_round_trips . dropna ( axis = 0 )
return sector_round_trips


signature:
def gen_round_trip_stats ( round_trips ) :
    """Generate various round - trip statistics .
 Parameters
 round _ trips : pd . DataFrame
 DataFrame with one row per round trip trade .
 - See full explanation in round _ trips . extract _ round _ trips
 Returns
 stats : dict
 A dictionary where each value is a pandas DataFrame containing
 various round - trip statistics .
 See also
 round _ trips . print _ round _ trip _ stats"""

implementation:
stats = { }
stats [ 'pnl' ] = agg_all_long_short ( round_trips , 'pnl' , PNL_STATS )
stats [ 'summary' ] = agg_all_long_short ( round_trips , 'pnl' , SUMMARY_STATS )
stats [ 'duration' ] = agg_all_long_short ( round_trips , 'duration' , DURATION_STATS )
stats [ 'returns' ] = agg_all_long_short ( round_trips , 'returns' , RETURN_STATS )
stats [ 'symbols' ] = round_trips . groupby ( 'symbol' ) [ 'returns' ] . agg ( RETURN_STATS ) . T
return stats


signature:
def print_round_trip_stats ( round_trips , hide_pos = False ) :
    """Print various round - trip statistics . Tries to pretty - print tables
 with HTML output if run inside IPython NB .
 Parameters
 round _ trips : pd . DataFrame
 DataFrame with one row per round trip trade .
 - See full explanation in round _ trips . extract _ round _ trips
 See also
 round _ trips . gen _ round _ trip _ stats"""

implementation:
stats = gen_round_trip_stats ( round_trips )
print_table ( stats [ 'summary' ] , float_format = '{:.2f}' . format , name = 'Summary stats' )
print_table ( stats [ 'pnl' ] , float_format = '${:.2f}' . format , name = 'PnL stats' )
print_table ( stats [ 'duration' ] , float_format = '{:.2f}' . format , name = 'Duration stats' )
print_table ( stats [ 'returns' ] * 100 , float_format = '{:.2f}%' . format , name = 'Return stats' )
if not hide_pos :
    stats [ 'symbols' ] . columns = stats [ 'symbols' ] . columns . map ( format_asset )
    print_table ( stats [ 'symbols' ] * 100 , float_format = '{:.2f}%' . format , name = 'Symbol stats' )


signature:
def perf_attrib ( returns , positions , factor_returns , factor_loadings , transactions = None , pos_in_dollars = True ) :
    """Attributes the performance of a returns stream to a set of risk factors .
 Preprocesses inputs , and then calls empyrical . perf _ attrib . See
 empyrical . perf _ attrib for more info .
 Performance attribution determines how much each risk factor , e . g . ,
 momentum , the technology sector , etc . , contributed to total returns , as
 well as the daily exposure to each of the risk factors . The returns that
 can be attributed to one of the given risk factors are the
 ` common _ returns ` , and the returns that _ cannot _ be attributed to a risk
 factor are the ` specific _ returns ` , or the alpha . The common _ returns and
 specific _ returns summed together will always equal the total returns .
 Parameters
 returns : pd . Series
 Returns for each day in the date range .
 - Example :
 2017-01-01 - 0.017098
 2017-01-02 0.002683
 2017-01-03 - 0.008669
 positions : pd . DataFrame
 Daily holdings ( in dollars or percentages ) , indexed by date .
 Will be converted to percentages if positions are in dollars .
 Short positions show up as cash in the ' cash ' column .
 - Examples :
 AAPL TLT XOM cash
 2017-01-01 34 58 10 0
 2017-01-02 22 77 18 0
 2017-01-03 - 15 27 30 15
 AAPL TLT XOM cash
 2017-01-01 0.33333 0.568627 0.098039 0.0
 2017-01-02 0.188034 0.658120 0.153846 0.0
 2017-01-03 0.208333 0.375000 0.416667 0.0
 factor _ returns : pd . DataFrame
 Returns by factor , with date as index and factors as columns
 - Example :
 momentum reversal
 2017-01-01 0.002779 - 0.005453
 2017-01-02 0.001096 0.010290
 factor _ loadings : pd . DataFrame
 Factor loadings for all days in the date range , with date and ticker as
 index , and factors as columns .
 - Example :
 momentum reversal
 dt ticker
 2017-01-01 AAPL - 1.592914 0.852830
 TLT 0.184864 0.895534
 XOM 0.993160 1.149353
 2017-01-02 AAPL - 0.140009 - 0.524952
 TLT - 1.066978 0.185435
 XOM - 1.798401 0.761549
 transactions : pd . DataFrame , optional
 Executed trade volumes and fill prices . Used to check the turnover of
 the algorithm . Default is None , in which case the turnover check is
 skipped .
 - One row per trade .
 - Trades on different names that occur at the
 same time will have identical indicies .
 - Example :
 index amount price symbol
 2004-01-09 12:18:01 483 324.12 ' AAPL '
 2004-01-09 12:18:01 122 83.10 ' MSFT '
 2004-01-13 14:12:23 - 75 340.43 ' AAPL '
 pos _ in _ dollars : bool
 Flag indicating whether ` positions ` are in dollars or percentages
 If True , positions are in dollars .
 Returns
 tuple of ( risk _ exposures _ portfolio , perf _ attribution )
 risk _ exposures _ portfolio : pd . DataFrame
 df indexed by datetime , with factors as columns
 - Example :
 momentum reversal
 dt
 2017-01-01 - 0.238655 0.077123
 2017-01-02 0.821872 1.520515
 perf _ attribution : pd . DataFrame
 df with factors , common returns , and specific returns as columns ,
 and datetimes as index
 - Example :
 momentum reversal common _ returns specific _ returns
 dt
 2017-01-01 0.249087 0.935925 1.185012 1.185012
 2017-01-02 - 0.003194 - 0.400786 - 0.403980 - 0.403980"""

implementation:
( returns , positions , factor_returns , factor_loadings ) = _align_and_warn ( returns , positions , factor_returns , factor_loadings , transactions = transactions , pos_in_dollars = pos_in_dollars )
# Note that we convert positions to percentages * after * the checks
# above , since get _ turnover ( ) expects positions in dollars .
positions = _stack_positions ( positions , pos_in_dollars = pos_in_dollars )
return ep . perf_attrib ( returns , positions , factor_returns , factor_loadings )


signature:
def compute_exposures ( positions , factor_loadings , stack_positions = True , pos_in_dollars = True ) :
    """Compute daily risk factor exposures .
 Normalizes positions ( if necessary ) and calls ep . compute _ exposures .
 See empyrical . compute _ exposures for more info .
 Parameters
 positions : pd . DataFrame or pd . Series
 Daily holdings ( in dollars or percentages ) , indexed by date , OR
 a series of holdings indexed by date and ticker .
 - Examples :
 AAPL TLT XOM cash
 2017-01-01 34 58 10 0
 2017-01-02 22 77 18 0
 2017-01-03 - 15 27 30 15
 AAPL TLT XOM cash
 2017-01-01 0.33333 0.568627 0.098039 0.0
 2017-01-02 0.188034 0.658120 0.153846 0.0
 2017-01-03 0.208333 0.375000 0.416667 0.0
 dt ticker
 2017-01-01 AAPL 0.417582
 TLT 0.010989
 XOM 0.571429
 2017-01-02 AAPL 0.202381
 TLT 0.535714
 XOM 0.261905
 factor _ loadings : pd . DataFrame
 Factor loadings for all days in the date range , with date and ticker as
 index , and factors as columns .
 - Example :
 momentum reversal
 dt ticker
 2017-01-01 AAPL - 1.592914 0.852830
 TLT 0.184864 0.895534
 XOM 0.993160 1.149353
 2017-01-02 AAPL - 0.140009 - 0.524952
 TLT - 1.066978 0.185435
 XOM - 1.798401 0.761549
 stack _ positions : bool
 Flag indicating whether ` positions ` should be converted to long format .
 pos _ in _ dollars : bool
 Flag indicating whether ` positions ` are in dollars or percentages
 If True , positions are in dollars .
 Returns
 risk _ exposures _ portfolio : pd . DataFrame
 df indexed by datetime , with factors as columns .
 - Example :
 momentum reversal
 dt
 2017-01-01 - 0.238655 0.077123
 2017-01-02 0.821872 1.520515"""

implementation:
if stack_positions :
    positions = _stack_positions ( positions , pos_in_dollars = pos_in_dollars )
return ep . compute_exposures ( positions , factor_loadings )


signature:
def create_perf_attrib_stats ( perf_attrib , risk_exposures ) :
    """Takes perf attribution data over a period of time and computes annualized
 multifactor alpha , multifactor sharpe , risk exposures ."""

implementation:
summary = OrderedDict ( )
total_returns = perf_attrib [ 'total_returns' ]
specific_returns = perf_attrib [ 'specific_returns' ]
common_returns = perf_attrib [ 'common_returns' ]
summary [ 'Annualized Specific Return' ] = ep . annual_return ( specific_returns )
summary [ 'Annualized Common Return' ] = ep . annual_return ( common_returns )
summary [ 'Annualized Total Return' ] = ep . annual_return ( total_returns )
summary [ 'Specific Sharpe Ratio' ] = ep . sharpe_ratio ( specific_returns )
summary [ 'Cumulative Specific Return' ] = ep . cum_returns_final ( specific_returns )
summary [ 'Cumulative Common Return' ] = ep . cum_returns_final ( common_returns )
summary [ 'Total Returns' ] = ep . cum_returns_final ( total_returns )
summary = pd . Series ( summary , name = '' )
annualized_returns_by_factor = [ ep . annual_return ( perf_attrib [ c ] ) for c in risk_exposures . columns ]
cumulative_returns_by_factor = [ ep . cum_returns_final ( perf_attrib [ c ] ) for c in risk_exposures . columns ]
risk_exposure_summary = pd . DataFrame ( data = OrderedDict ( [ ( 'Average Risk Factor Exposure' , risk_exposures . mean ( axis = 'rows' ) ) , ( 'Annualized Return' , annualized_returns_by_factor ) , ( 'Cumulative Return' , cumulative_returns_by_factor ) , ] ) , index = risk_exposures . columns , )
return summary , risk_exposure_summary


signature:
def show_perf_attrib_stats ( returns , positions , factor_returns , factor_loadings , transactions = None , pos_in_dollars = True ) :
    """Calls ` perf _ attrib ` using inputs , and displays outputs using
 ` utils . print _ table ` ."""

implementation:
risk_exposures , perf_attrib_data = perf_attrib ( returns , positions , factor_returns , factor_loadings , transactions , pos_in_dollars = pos_in_dollars , )
perf_attrib_stats , risk_exposure_stats = create_perf_attrib_stats ( perf_attrib_data , risk_exposures )
percentage_formatter = '{:.2%}' . format
float_formatter = '{:.2f}' . format
summary_stats = perf_attrib_stats . loc [ [ 'Annualized Specific Return' , 'Annualized Common Return' , 'Annualized Total Return' , 'Specific Sharpe Ratio' ] ]
# Format return rows in summary stats table as percentages .
for col_name in ( 'Annualized Specific Return' , 'Annualized Common Return' , 'Annualized Total Return' , ) :
    summary_stats [ col_name ] = percentage_formatter ( summary_stats [ col_name ] )
# Display sharpe to two decimal places .
summary_stats [ 'Specific Sharpe Ratio' ] = float_formatter ( summary_stats [ 'Specific Sharpe Ratio' ] )
print_table ( summary_stats , name = 'Summary Statistics' )
print_table ( risk_exposure_stats , name = 'Exposures Summary' , # In exposures table , format exposure column to 2 decimal places , and
# return columns as percentages .
formatters = { 'Average Risk Factor Exposure' : float_formatter , 'Annualized Return' : percentage_formatter , 'Cumulative Return' : percentage_formatter , } , )


signature:
def plot_returns ( perf_attrib_data , cost = None , ax = None ) :
    """Plot total , specific , and common returns .
 Parameters
 perf _ attrib _ data : pd . DataFrame
 df with factors , common returns , and specific returns as columns ,
 and datetimes as index . Assumes the ` total _ returns ` column is NOT
 cost adjusted .
 - Example :
 momentum reversal common _ returns specific _ returns
 dt
 2017-01-01 0.249087 0.935925 1.185012 1.185012
 2017-01-02 - 0.003194 - 0.400786 - 0.403980 - 0.403980
 cost : pd . Series , optional
 if present , gets subtracted from ` perf _ attrib _ data [ ' total _ returns ' ] ` ,
 and gets plotted separately
 ax : matplotlib . axes . Axes
 axes on which plots are made . if None , current axes will be used
 Returns
 ax : matplotlib . axes . Axes"""

implementation:
if ax is None :
    ax = plt . gca ( )
returns = perf_attrib_data [ 'total_returns' ]
total_returns_label = 'Total returns'
cumulative_returns_less_costs = _cumulative_returns_less_costs ( returns , cost )
if cost is not None :
    total_returns_label += ' (adjusted)'
specific_returns = perf_attrib_data [ 'specific_returns' ]
common_returns = perf_attrib_data [ 'common_returns' ]
ax . plot ( cumulative_returns_less_costs , color = 'b' , label = total_returns_label )
ax . plot ( ep . cum_returns ( specific_returns ) , color = 'g' , label = 'Cumulative specific returns' )
ax . plot ( ep . cum_returns ( common_returns ) , color = 'r' , label = 'Cumulative common returns' )
if cost is not None :
    ax . plot ( - ep . cum_returns ( cost ) , color = 'k' , label = 'Cumulative cost spent' )
ax . set_title ( 'Time series of cumulative returns' )
ax . set_ylabel ( 'Returns' )
configure_legend ( ax )
return ax


signature:
def plot_alpha_returns ( alpha_returns , ax = None ) :
    """Plot histogram of daily multi - factor alpha returns ( specific returns ) .
 Parameters
 alpha _ returns : pd . Series
 series of daily alpha returns indexed by datetime
 ax : matplotlib . axes . Axes
 axes on which plots are made . if None , current axes will be used
 Returns
 ax : matplotlib . axes . Axes"""

implementation:
if ax is None :
    ax = plt . gca ( )
ax . hist ( alpha_returns , color = 'g' , label = 'Multi-factor alpha' )
ax . set_title ( 'Histogram of alphas' )
ax . axvline ( 0 , color = 'k' , linestyle = '--' , label = 'Zero' )
avg = alpha_returns . mean ( )
ax . axvline ( avg , color = 'b' , label = 'Mean = {: 0.5f}' . format ( avg ) )
configure_legend ( ax )
return ax


signature:
def plot_factor_contribution_to_perf ( perf_attrib_data , ax = None , title = 'Cumulative common returns attribution' , ) :
    """Plot each factor ' s contribution to performance .
 Parameters
 perf _ attrib _ data : pd . DataFrame
 df with factors , common returns , and specific returns as columns ,
 and datetimes as index
 - Example :
 momentum reversal common _ returns specific _ returns
 dt
 2017-01-01 0.249087 0.935925 1.185012 1.185012
 2017-01-02 - 0.003194 - 0.400786 - 0.403980 - 0.403980
 ax : matplotlib . axes . Axes
 axes on which plots are made . if None , current axes will be used
 title : str , optional
 title of plot
 Returns
 ax : matplotlib . axes . Axes"""

implementation:
if ax is None :
    ax = plt . gca ( )
factors_to_plot = perf_attrib_data . drop ( [ 'total_returns' , 'common_returns' ] , axis = 'columns' , errors = 'ignore' )
factors_cumulative = pd . DataFrame ( )
for factor in factors_to_plot :
    factors_cumulative [ factor ] = ep . cum_returns ( factors_to_plot [ factor ] )
for col in factors_cumulative :
    ax . plot ( factors_cumulative [ col ] )
ax . axhline ( 0 , color = 'k' )
configure_legend ( ax , change_colors = True )
ax . set_ylabel ( 'Cumulative returns by factor' )
ax . set_title ( title )
return ax


signature:
def plot_risk_exposures ( exposures , ax = None , title = 'Daily risk factor exposures' ) :
    """Parameters
 exposures : pd . DataFrame
 df indexed by datetime , with factors as columns
 - Example :
 momentum reversal
 dt
 2017-01-01 - 0.238655 0.077123
 2017-01-02 0.821872 1.520515
 ax : matplotlib . axes . Axes
 axes on which plots are made . if None , current axes will be used
 Returns
 ax : matplotlib . axes . Axes"""

implementation:
if ax is None :
    ax = plt . gca ( )
for col in exposures :
    ax . plot ( exposures [ col ] )
configure_legend ( ax , change_colors = True )
ax . set_ylabel ( 'Factor exposures' )
ax . set_title ( title )
return ax


signature:
def _align_and_warn ( returns , positions , factor_returns , factor_loadings , transactions = None , pos_in_dollars = True ) :
    """Make sure that all inputs have matching dates and tickers ,
 and raise warnings if necessary ."""

implementation:
missing_stocks = positions . columns . difference ( factor_loadings . index . get_level_values ( 1 ) . unique ( ) )
# cash will not be in factor _ loadings
num_stocks = len ( positions . columns ) - 1
missing_stocks = missing_stocks . drop ( 'cash' )
num_stocks_covered = num_stocks - len ( missing_stocks )
missing_ratio = round ( len ( missing_stocks ) / num_stocks , ndigits = 3 )
if num_stocks_covered == 0 :
    raise ValueError ( "Could not perform performance attribution. " "No factor loadings were available for this " "algorithm's positions." )
if len ( missing_stocks ) > 0 :
    if len ( missing_stocks ) > 5 :
        missing_stocks_displayed = ( " {} assets were missing factor loadings, including: {}..{}" ) . format ( len ( missing_stocks ) , ', ' . join ( missing_stocks [ : 5 ] . map ( str ) ) , missing_stocks [ - 1 ] )
        avg_allocation_msg = "selected missing assets"
    else :
        missing_stocks_displayed = ( "The following assets were missing factor loadings: {}." ) . format ( list ( missing_stocks ) )
        avg_allocation_msg = "missing assets"
    missing_stocks_warning_msg = ( "Could not determine risk exposures for some of this algorithm's " "positions. Returns from the missing assets will not be properly " "accounted for in performance attribution.\n" "\n" "{}. " "Ignoring for exposure calculation and performance attribution. " "Ratio of assets missing: {}. Average allocation of {}:\n" "\n" "{}.\n" ) . format ( missing_stocks_displayed , missing_ratio , avg_allocation_msg , positions [ missing_stocks [ : 5 ] . union ( missing_stocks [ [ - 1 ] ] ) ] . mean ( ) , )
    warnings . warn ( missing_stocks_warning_msg )
    positions = positions . drop ( missing_stocks , axis = 'columns' , errors = 'ignore' )
missing_factor_loadings_index = positions . index . difference ( factor_loadings . index . get_level_values ( 0 ) . unique ( ) )
missing_factor_loadings_index = positions . index . difference ( factor_loadings . index . get_level_values ( 0 ) . unique ( ) )
if len ( missing_factor_loadings_index ) > 0 :
    if len ( missing_factor_loadings_index ) > 5 :
        missing_dates_displayed = ( "(first missing is {}, last missing is {})" ) . format ( missing_factor_loadings_index [ 0 ] , missing_factor_loadings_index [ - 1 ] )
    else :
        missing_dates_displayed = list ( missing_factor_loadings_index )
    warning_msg = ( "Could not find factor loadings for {} dates: {}. " "Truncating date range for performance attribution. " ) . format ( len ( missing_factor_loadings_index ) , missing_dates_displayed )
    warnings . warn ( warning_msg )
    positions = positions . drop ( missing_factor_loadings_index , errors = 'ignore' )
    returns = returns . drop ( missing_factor_loadings_index , errors = 'ignore' )
    factor_returns = factor_returns . drop ( missing_factor_loadings_index , errors = 'ignore' )
if transactions is not None and pos_in_dollars :
    turnover = get_turnover ( positions , transactions ) . mean ( )
    if turnover > PERF_ATTRIB_TURNOVER_THRESHOLD :
        warning_msg = ( "This algorithm has relatively high turnover of its " "positions. As a result, performance attribution might not be " "fully accurate.\n" "\n" "Performance attribution is calculated based " "on end-of-day holdings and does not account for intraday " "activity. Algorithms that derive a high percentage of " "returns from buying and selling within the same day may " "receive inaccurate performance attribution.\n" )
        warnings . warn ( warning_msg )
return ( returns , positions , factor_returns , factor_loadings )


signature:
def _stack_positions ( positions , pos_in_dollars = True ) :
    """Convert positions to percentages if necessary , and change them
 to long format .
 Parameters
 positions : pd . DataFrame
 Daily holdings ( in dollars or percentages ) , indexed by date .
 Will be converted to percentages if positions are in dollars .
 Short positions show up as cash in the ' cash ' column .
 pos _ in _ dollars : bool
 Flag indicating whether ` positions ` are in dollars or percentages
 If True , positions are in dollars ."""

implementation:
if pos_in_dollars : # convert holdings to percentages
    positions = get_percent_alloc ( positions )
# remove cash after normalizing positions
positions = positions . drop ( 'cash' , axis = 'columns' )
# convert positions to long format
positions = positions . stack ( )
positions . index = positions . index . set_names ( [ 'dt' , 'ticker' ] )
return positions


signature:
def _cumulative_returns_less_costs ( returns , costs ) :
    """Compute cumulative returns , less costs ."""

implementation:
if costs is None :
    return ep . cum_returns ( returns )
return ep . cum_returns ( returns - costs )


signature:
def format_asset ( asset ) :
    """If zipline asset objects are used , we want to print them out prettily
 within the tear sheet . This function should only be applied directly
 before displaying ."""

implementation:
try :
    import zipline . assets
except ImportError :
    return asset
if isinstance ( asset , zipline . assets . Asset ) :
    return asset . symbol
else :
    return asset


signature:
def vectorize ( func ) :
    """Decorator so that functions can be written to work on Series but
 may still be called with DataFrames ."""

implementation:
def wrapper ( df , * args , ** kwargs ) :
    if df . ndim == 1 :
        return func ( df , * args , ** kwargs )
    elif df . ndim == 2 :
        return df . apply ( func , * args , ** kwargs )
return wrapper


signature:
def extract_rets_pos_txn_from_zipline ( backtest ) :
    """Extract returns , positions , transactions and leverage from the
 backtest data structure returned by zipline . TradingAlgorithm . run ( ) .
 The returned data structures are in a format compatible with the
 rest of pyfolio and can be directly passed to
 e . g . tears . create _ full _ tear _ sheet ( ) .
 Parameters
 backtest : pd . DataFrame
 DataFrame returned by zipline . TradingAlgorithm . run ( )
 Returns
 returns : pd . Series
 Daily returns of strategy .
 - See full explanation in tears . create _ full _ tear _ sheet .
 positions : pd . DataFrame
 Daily net position values .
 - See full explanation in tears . create _ full _ tear _ sheet .
 transactions : pd . DataFrame
 Prices and amounts of executed trades . One row per trade .
 - See full explanation in tears . create _ full _ tear _ sheet .
 Example ( on the Quantopian research platform )
 > > > backtest = my _ algo . run ( )
 > > > returns , positions , transactions =
 > > > pyfolio . utils . extract _ rets _ pos _ txn _ from _ zipline ( backtest )
 > > > pyfolio . tears . create _ full _ tear _ sheet ( returns ,
 > > > positions , transactions )"""

implementation:
backtest . index = backtest . index . normalize ( )
if backtest . index . tzinfo is None :
    backtest . index = backtest . index . tz_localize ( 'UTC' )
returns = backtest . returns
raw_positions = [ ]
for dt , pos_row in backtest . positions . iteritems ( ) :
    df = pd . DataFrame ( pos_row )
    df . index = [ dt ] * len ( df )
    raw_positions . append ( df )
if not raw_positions :
    raise ValueError ( "The backtest does not have any positions." )
positions = pd . concat ( raw_positions )
positions = pos . extract_pos ( positions , backtest . ending_cash )
transactions = txn . make_transaction_frame ( backtest . transactions )
if transactions . index . tzinfo is None :
    transactions . index = transactions . index . tz_localize ( 'utc' )
return returns , positions , transactions


signature:
def print_table ( table , name = None , float_format = None , formatters = None , header_rows = None ) :
    """Pretty print a pandas DataFrame .
 Uses HTML output if running inside Jupyter Notebook , otherwise
 formatted text output .
 Parameters
 table : pandas . Series or pandas . DataFrame
 Table to pretty - print .
 name : str , optional
 Table name to display in upper left corner .
 float _ format : function , optional
 Formatter to use for displaying table elements , passed as the
 ` float _ format ` arg to pd . Dataframe . to _ html .
 E . g . ` ' { 0 : . 2 % } ' . format ` for displaying 100 as ' 100.00 % ' .
 formatters : list or dict , optional
 Formatters to use by column , passed as the ` formatters ` arg to
 pd . Dataframe . to _ html .
 header _ rows : dict , optional
 Extra rows to display at the top of the table ."""

implementation:
if isinstance ( table , pd . Series ) :
    table = pd . DataFrame ( table )
if name is not None :
    table . columns . name = name
html = table . to_html ( float_format = float_format , formatters = formatters )
if header_rows is not None : # Count the number of columns for the text to span
    n_cols = html . split ( '
' ) [ 1 ] . split ( '
' ) [ 0 ] . count ( '' )
    # Generate the HTML for the extra rows
    rows = ''
    for name , value in header_rows . items ( ) :
        rows += ( '\n
%s	' + '%s
' ) % ( name , n_cols , value )
    # Inject the new HTML
    html = html . replace ( '
' , '
' + rows )
display ( HTML ( html ) )


signature:
def detect_intraday ( positions , transactions , threshold = 0.25 ) :
    """Attempt to detect an intraday strategy . Get the number of
 positions held at the end of the day , and divide that by the
 number of unique stocks transacted every day . If the average quotient
 is below a threshold , then an intraday strategy is detected .
 Parameters
 positions : pd . DataFrame
 Daily net position values .
 - See full explanation in create _ full _ tear _ sheet .
 transactions : pd . DataFrame
 Prices and amounts of executed trades . One row per trade .
 - See full explanation in create _ full _ tear _ sheet .
 Returns
 boolean
 True if an intraday strategy is detected ."""

implementation:
daily_txn = transactions . copy ( )
daily_txn . index = daily_txn . index . date
txn_count = daily_txn . groupby ( level = 0 ) . symbol . nunique ( ) . sum ( )
daily_pos = positions . drop ( 'cash' , axis = 1 ) . replace ( 0 , np . nan )
return daily_pos . count ( axis = 1 ) . sum ( ) / txn_count < threshold


signature:
def check_intraday ( estimate , returns , positions , transactions ) :
    """Logic for checking if a strategy is intraday and processing it .
 Parameters
 estimate : boolean or str , optional
 Approximate returns for intraday strategies .
 See description in tears . create _ full _ tear _ sheet .
 returns : pd . Series
 Daily returns of the strategy , noncumulative .
 - See full explanation in create _ full _ tear _ sheet .
 positions : pd . DataFrame
 Daily net position values .
 - See full explanation in create _ full _ tear _ sheet .
 transactions : pd . DataFrame
 Prices and amounts of executed trades . One row per trade .
 - See full explanation in create _ full _ tear _ sheet .
 Returns
 pd . DataFrame
 Daily net position values , adjusted for intraday movement ."""

implementation:
if estimate == 'infer' :
    if positions is not None and transactions is not None :
        if detect_intraday ( positions , transactions ) :
            warnings . warn ( 'Detected intraday strategy; inferring positi' + 'ons from transactions. Set estimate_intraday' + '=False to disable.' )
            return estimate_intraday ( returns , positions , transactions )
        else :
            return positions
    else :
        return positions
elif estimate :
    if positions is not None and transactions is not None :
        return estimate_intraday ( returns , positions , transactions )
    else :
        raise ValueError ( 'Positions and txns needed to estimate intraday' )
else :
    return positions


signature:
def estimate_intraday ( returns , positions , transactions , EOD_hour = 23 ) :
    """Intraday strategies will often not hold positions at the day end .
 This attempts to find the point in the day that best represents
 the activity of the strategy on that day , and effectively resamples
 the end - of - day positions with the positions at this point of day .
 The point of day is found by detecting when our exposure in the
 market is at its maximum point . Note that this is an estimate .
 Parameters
 returns : pd . Series
 Daily returns of the strategy , noncumulative .
 - See full explanation in create _ full _ tear _ sheet .
 positions : pd . DataFrame
 Daily net position values .
 - See full explanation in create _ full _ tear _ sheet .
 transactions : pd . DataFrame
 Prices and amounts of executed trades . One row per trade .
 - See full explanation in create _ full _ tear _ sheet .
 Returns
 pd . DataFrame
 Daily net position values , resampled for intraday behavior ."""

implementation:
# Construct DataFrame of transaction amounts
txn_val = transactions . copy ( )
txn_val . index . names = [ 'date' ]
txn_val [ 'value' ] = txn_val . amount * txn_val . price
txn_val = txn_val . reset_index ( ) . pivot_table ( index = 'date' , values = 'value' , columns = 'symbol' ) . replace ( np . nan , 0 )
# Cumulate transaction amounts each day
txn_val [ 'date' ] = txn_val . index . date
txn_val = txn_val . groupby ( 'date' ) . cumsum ( )
# Calculate exposure , then take peak of exposure every day
txn_val [ 'exposure' ] = txn_val . abs ( ) . sum ( axis = 1 )
condition = ( txn_val [ 'exposure' ] == txn_val . groupby ( pd . TimeGrouper ( '24H' ) ) [ 'exposure' ] . transform ( max ) )
txn_val = txn_val [ condition ] . drop ( 'exposure' , axis = 1 )
# Compute cash delta
txn_val [ 'cash' ] = - txn_val . sum ( axis = 1 )
# Shift EOD positions to positions at start of next trading day
positions_shifted = positions . copy ( ) . shift ( 1 ) . fillna ( 0 )
starting_capital = positions . iloc [ 0 ] . sum ( ) / ( 1 + returns [ 0 ] )
positions_shifted . cash [ 0 ] = starting_capital
# Format and add start positions to intraday position changes
txn_val . index = txn_val . index . normalize ( )
corrected_positions = positions_shifted . add ( txn_val , fill_value = 0 )
corrected_positions . index . name = 'period_close'
corrected_positions . columns . name = 'sid'
return corrected_positions


signature:
def clip_returns_to_benchmark ( rets , benchmark_rets ) :
    """Drop entries from rets so that the start and end dates of rets match those
 of benchmark _ rets .
 Parameters
 rets : pd . Series
 Daily returns of the strategy , noncumulative .
 - See pf . tears . create _ full _ tear _ sheet for more details
 benchmark _ rets : pd . Series
 Daily returns of the benchmark , noncumulative .
 Returns
 clipped _ rets : pd . Series
 Daily noncumulative returns with index clipped to match that of
 benchmark returns ."""

implementation:
if ( rets . index [ 0 ] < benchmark_rets . index [ 0 ] ) or ( rets . index [ - 1 ] > benchmark_rets . index [ - 1 ] ) :
    clipped_rets = rets [ benchmark_rets . index ]
else :
    clipped_rets = rets
return clipped_rets


signature:
def to_utc ( df ) :
    """For use in tests ; applied UTC timestamp to DataFrame ."""

implementation:
try :
    df . index = df . index . tz_localize ( 'UTC' )
except TypeError :
    df . index = df . index . tz_convert ( 'UTC' )
return df


signature:
def get_symbol_rets ( symbol , start = None , end = None ) :
    """Calls the currently registered ' returns _ func '
 Parameters
 symbol : object
 An identifier for the asset whose return
 series is desired .
 e . g . ticker symbol or database ID
 start : date , optional
 Earliest date to fetch data for .
 Defaults to earliest date available .
 end : date , optional
 Latest date to fetch data for .
 Defaults to latest date available .
 Returns
 pandas . Series
 Returned by the current ' returns _ func '"""

implementation: return SETTINGS [ 'returns_func' ] ( symbol , start = start , end = end )


signature:
def configure_legend ( ax , autofmt_xdate = True , change_colors = False , rotation = 30 , ha = 'right' ) :
    """Format legend for perf attribution plots :
 - put legend to the right of plot instead of overlapping with it
 - make legend order match up with graph lines
 - set colors according to colormap"""

implementation:
chartBox = ax . get_position ( )
ax . set_position ( [ chartBox . x0 , chartBox . y0 , chartBox . width * 0.75 , chartBox . height ] )
# make legend order match graph lines
handles , labels = ax . get_legend_handles_labels ( )
handles_and_labels_sorted = sorted ( zip ( handles , labels ) , key = lambda x : x [ 0 ] . get_ydata ( ) [ - 1 ] , reverse = True )
handles_sorted = [ h [ 0 ] for h in handles_and_labels_sorted ]
labels_sorted = [ h [ 1 ] for h in handles_and_labels_sorted ]
if change_colors :
    for handle , color in zip ( handles_sorted , cycle ( COLORS ) ) :
        handle . set_color ( color )
ax . legend ( handles = handles_sorted , labels = labels_sorted , frameon = True , framealpha = 0.5 , loc = 'upper left' , bbox_to_anchor = ( 1.05 , 1 ) , fontsize = 'large' )
# manually rotate xticklabels instead of using matplotlib ' s autofmt _ xdate
# because it disables xticklabels for all but the last plot
if autofmt_xdate :
    for label in ax . get_xticklabels ( ) :
        label . set_ha ( ha )
        label . set_rotation ( rotation )


signature:
def sample_colormap ( cmap_name , n_samples ) :
    """Sample a colormap from matplotlib"""

implementation:
colors = [ ]
colormap = cm . cmap_d [ cmap_name ]
for i in np . linspace ( 0 , 1 , n_samples ) :
    colors . append ( colormap ( i ) )
return colors


signature:
def customize ( func ) :
    """Decorator to set plotting context and axes style during function call ."""

implementation:
@ wraps ( func )
def call_w_context ( * args , ** kwargs ) :
    set_context = kwargs . pop ( 'set_context' , True )
    if set_context :
        with plotting_context ( ) , axes_style ( ) :
            return func ( * args , ** kwargs )
    else :
        return func ( * args , ** kwargs )
return call_w_context


signature:
def plotting_context ( context = 'notebook' , font_scale = 1.5 , rc = None ) :
    """Create pyfolio default plotting style context .
 Under the hood , calls and returns seaborn . plotting _ context ( ) with
 some custom settings . Usually you would use in a with - context .
 Parameters
 context : str , optional
 Name of seaborn context .
 font _ scale : float , optional
 Scale font by factor font _ scale .
 rc : dict , optional
 Config flags .
 By default , { ' lines . linewidth ' : 1.5}
 is being used and will be added to any
 rc passed in , unless explicitly overriden .
 Returns
 seaborn plotting context
 Example
 > > > with pyfolio . plotting . plotting _ context ( font _ scale = 2 ) :
 > > > pyfolio . create _ full _ tear _ sheet ( . . . , set _ context = False )
 See also
 For more information , see seaborn . plotting _ context ( ) ."""

implementation:
if rc is None :
    rc = { }
rc_default = { 'lines.linewidth' : 1.5 }
# Add defaults if they do not exist
for name , val in rc_default . items ( ) :
    rc . setdefault ( name , val )
return sns . plotting_context ( context = context , font_scale = font_scale , rc = rc )


signature:
def axes_style ( style = 'darkgrid' , rc = None ) :
    """Create pyfolio default axes style context .
 Under the hood , calls and returns seaborn . axes _ style ( ) with
 some custom settings . Usually you would use in a with - context .
 Parameters
 style : str , optional
 Name of seaborn style .
 rc : dict , optional
 Config flags .
 Returns
 seaborn plotting context
 Example
 > > > with pyfolio . plotting . axes _ style ( style = ' whitegrid ' ) :
 > > > pyfolio . create _ full _ tear _ sheet ( . . . , set _ context = False )
 See also
 For more information , see seaborn . plotting _ context ( ) ."""

implementation:
if rc is None :
    rc = { }
rc_default = { }
# Add defaults if they do not exist
for name , val in rc_default . items ( ) :
    rc . setdefault ( name , val )
return sns . axes_style ( style = style , rc = rc )


signature:
def plot_monthly_returns_heatmap ( returns , ax = None , ** kwargs ) :
    """Plots a heatmap of returns by month .
 Parameters
 returns : pd . Series
 Daily returns of the strategy , noncumulative .
 - See full explanation in tears . create _ full _ tear _ sheet .
 ax : matplotlib . Axes , optional
 Axes upon which to plot .
 * * kwargs , optional
 Passed to seaborn plotting function .
 Returns
 ax : matplotlib . Axes
 The axes that were plotted on ."""

implementation:
if ax is None :
    ax = plt . gca ( )
monthly_ret_table = ep . aggregate_returns ( returns , 'monthly' )
monthly_ret_table = monthly_ret_table . unstack ( ) . round ( 3 )
sns . heatmap ( monthly_ret_table . fillna ( 0 ) * 100.0 , annot = True , annot_kws = { "size" : 9 } , alpha = 1.0 , center = 0.0 , cbar = False , cmap = matplotlib . cm . RdYlGn , ax = ax , ** kwargs )
ax . set_ylabel ( 'Year' )
ax . set_xlabel ( 'Month' )
ax . set_title ( "Monthly returns (%)" )
return ax


signature:
def plot_annual_returns ( returns , ax = None , ** kwargs ) :
    """Plots a bar graph of returns by year .
 Parameters
 returns : pd . Series
 Daily returns of the strategy , noncumulative .
 - See full explanation in tears . create _ full _ tear _ sheet .
 ax : matplotlib . Axes , optional
 Axes upon which to plot .
 * * kwargs , optional
 Passed to plotting function .
 Returns
 ax : matplotlib . Axes
 The axes that were plotted on ."""

implementation:
if ax is None :
    ax = plt . gca ( )
x_axis_formatter = FuncFormatter ( utils . percentage )
ax . xaxis . set_major_formatter ( FuncFormatter ( x_axis_formatter ) )
ax . tick_params ( axis = 'x' , which = 'major' )
ann_ret_df = pd . DataFrame ( ep . aggregate_returns ( returns , 'yearly' ) )
ax . axvline ( 100 * ann_ret_df . values . mean ( ) , color = 'steelblue' , linestyle = '--' , lw = 4 , alpha = 0.7 )
( 100 * ann_ret_df . sort_index ( ascending = False ) ) . plot ( ax = ax , kind = 'barh' , alpha = 0.70 , ** kwargs )
ax . axvline ( 0.0 , color = 'black' , linestyle = '-' , lw = 3 )
ax . set_ylabel ( 'Year' )
ax . set_xlabel ( 'Returns' )
ax . set_title ( "Annual returns" )
ax . legend ( [ 'Mean' ] , frameon = True , framealpha = 0.5 )
return ax


signature:
def plot_monthly_returns_dist ( returns , ax = None , ** kwargs ) :
    """Plots a distribution of monthly returns .
 Parameters
 returns : pd . Series
 Daily returns of the strategy , noncumulative .
 - See full explanation in tears . create _ full _ tear _ sheet .
 ax : matplotlib . Axes , optional
 Axes upon which to plot .
 * * kwargs , optional
 Passed to plotting function .
 Returns
 ax : matplotlib . Axes
 The axes that were plotted on ."""

implementation:
if ax is None :
    ax = plt . gca ( )
x_axis_formatter = FuncFormatter ( utils . percentage )
ax . xaxis . set_major_formatter ( FuncFormatter ( x_axis_formatter ) )
ax . tick_params ( axis = 'x' , which = 'major' )
monthly_ret_table = ep . aggregate_returns ( returns , 'monthly' )
ax . hist ( 100 * monthly_ret_table , color = 'orangered' , alpha = 0.80 , bins = 20 , ** kwargs )
ax . axvline ( 100 * monthly_ret_table . mean ( ) , color = 'gold' , linestyle = '--' , lw = 4 , alpha = 1.0 )
ax . axvline ( 0.0 , color = 'black' , linestyle = '-' , lw = 3 , alpha = 0.75 )
ax . legend ( [ 'Mean' ] , frameon = True , framealpha = 0.5 )
ax . set_ylabel ( 'Number of months' )
ax . set_xlabel ( 'Returns' )
ax . set_title ( "Distribution of monthly returns" )
return ax


signature:
def plot_holdings ( returns , positions , legend_loc = 'best' , ax = None , ** kwargs ) :
    """Plots total amount of stocks with an active position , either short
 or long . Displays daily total , daily average per month , and
 all - time daily average .
 Parameters
 returns : pd . Series
 Daily returns of the strategy , noncumulative .
 - See full explanation in tears . create _ full _ tear _ sheet .
 positions : pd . DataFrame , optional
 Daily net position values .
 - See full explanation in tears . create _ full _ tear _ sheet .
 legend _ loc : matplotlib . loc , optional
 The location of the legend on the plot .
 ax : matplotlib . Axes , optional
 Axes upon which to plot .
 * * kwargs , optional
 Passed to plotting function .
 Returns
 ax : matplotlib . Axes
 The axes that were plotted on ."""

implementation:
if ax is None :
    ax = plt . gca ( )
positions = positions . copy ( ) . drop ( 'cash' , axis = 'columns' )
df_holdings = positions . replace ( 0 , np . nan ) . count ( axis = 1 )
df_holdings_by_month = df_holdings . resample ( '1M' ) . mean ( )
df_holdings . plot ( color = 'steelblue' , alpha = 0.6 , lw = 0.5 , ax = ax , ** kwargs )
df_holdings_by_month . plot ( color = 'orangered' , lw = 2 , ax = ax , ** kwargs )
ax . axhline ( df_holdings . values . mean ( ) , color = 'steelblue' , ls = '--' , lw = 3 )
ax . set_xlim ( ( returns . index [ 0 ] , returns . index [ - 1 ] ) )
leg = ax . legend ( [ 'Daily holdings' , 'Average daily holdings, by month' , 'Average daily holdings, overall' ] , loc = legend_loc , frameon = True , framealpha = 0.5 )
leg . get_frame ( ) . set_edgecolor ( 'black' )
ax . set_title ( 'Total holdings' )
ax . set_ylabel ( 'Holdings' )
ax . set_xlabel ( '' )
return ax


signature:
def plot_long_short_holdings ( returns , positions , legend_loc = 'upper left' , ax = None , ** kwargs ) :
    """Plots total amount of stocks with an active position , breaking out
 short and long into transparent filled regions .
 Parameters
 returns : pd . Series
 Daily returns of the strategy , noncumulative .
 - See full explanation in tears . create _ full _ tear _ sheet .
 positions : pd . DataFrame , optional
 Daily net position values .
 - See full explanation in tears . create _ full _ tear _ sheet .
 legend _ loc : matplotlib . loc , optional
 The location of the legend on the plot .
 ax : matplotlib . Axes , optional
 Axes upon which to plot .
 * * kwargs , optional
 Passed to plotting function .
 Returns
 ax : matplotlib . Axes
 The axes that were plotted on ."""

implementation:
if ax is None :
    ax = plt . gca ( )
positions = positions . drop ( 'cash' , axis = 'columns' )
positions = positions . replace ( 0 , np . nan )
df_longs = positions [ positions > 0 ] . count ( axis = 1 )
df_shorts = positions [ positions < 0 ] . count ( axis = 1 )
lf = ax . fill_between ( df_longs . index , 0 , df_longs . values , color = 'g' , alpha = 0.5 , lw = 2.0 )
sf = ax . fill_between ( df_shorts . index , 0 , df_shorts . values , color = 'r' , alpha = 0.5 , lw = 2.0 )
bf = patches . Rectangle ( [ 0 , 0 ] , 1 , 1 , color = 'darkgoldenrod' )
leg = ax . legend ( [ lf , sf , bf ] , [ 'Long (max: %s, min: %s)' % ( df_longs . max ( ) , df_longs . min ( ) ) , 'Short (max: %s, min: %s)' % ( df_shorts . max ( ) , df_shorts . min ( ) ) , 'Overlap' ] , loc = legend_loc , frameon = True , framealpha = 0.5 )
leg . get_frame ( ) . set_edgecolor ( 'black' )
ax . set_xlim ( ( returns . index [ 0 ] , returns . index [ - 1 ] ) )
ax . set_title ( 'Long and short holdings' )
ax . set_ylabel ( 'Holdings' )
ax . set_xlabel ( '' )
return ax


signature:
def plot_drawdown_periods ( returns , top = 10 , ax = None , ** kwargs ) :
    """Plots cumulative returns highlighting top drawdown periods .
 Parameters
 returns : pd . Series
 Daily returns of the strategy , noncumulative .
 - See full explanation in tears . create _ full _ tear _ sheet .
 top : int , optional
 Amount of top drawdowns periods to plot ( default 10 ) .
 ax : matplotlib . Axes , optional
 Axes upon which to plot .
 * * kwargs , optional
 Passed to plotting function .
 Returns
 ax : matplotlib . Axes
 The axes that were plotted on ."""

implementation:
if ax is None :
    ax = plt . gca ( )
y_axis_formatter = FuncFormatter ( utils . two_dec_places )
ax . yaxis . set_major_formatter ( FuncFormatter ( y_axis_formatter ) )
df_cum_rets = ep . cum_returns ( returns , starting_value = 1.0 )
df_drawdowns = timeseries . gen_drawdown_table ( returns , top = top )
df_cum_rets . plot ( ax = ax , ** kwargs )
lim = ax . get_ylim ( )
colors = sns . cubehelix_palette ( len ( df_drawdowns ) ) [ : : - 1 ]
for i , ( peak , recovery ) in df_drawdowns [ [ 'Peak date' , 'Recovery date' ] ] . iterrows ( ) :
    if pd . isnull ( recovery ) :
        recovery = returns . index [ - 1 ]
    ax . fill_between ( ( peak , recovery ) , lim [ 0 ] , lim [ 1 ] , alpha = .4 , color = colors [ i ] )
ax . set_ylim ( lim )
ax . set_title ( 'Top %i drawdown periods' % top )
ax . set_ylabel ( 'Cumulative returns' )
ax . legend ( [ 'Portfolio' ] , loc = 'upper left' , frameon = True , framealpha = 0.5 )
ax . set_xlabel ( '' )
return ax


signature:
def plot_drawdown_underwater ( returns , ax = None , ** kwargs ) :
    """Plots how far underwaterr returns are over time , or plots current
 drawdown vs . date .
 Parameters
 returns : pd . Series
 Daily returns of the strategy , noncumulative .
 - See full explanation in tears . create _ full _ tear _ sheet .
 ax : matplotlib . Axes , optional
 Axes upon which to plot .
 * * kwargs , optional
 Passed to plotting function .
 Returns
 ax : matplotlib . Axes
 The axes that were plotted on ."""

implementation:
if ax is None :
    ax = plt . gca ( )
y_axis_formatter = FuncFormatter ( utils . percentage )
ax . yaxis . set_major_formatter ( FuncFormatter ( y_axis_formatter ) )
df_cum_rets = ep . cum_returns ( returns , starting_value = 1.0 )
running_max = np . maximum . accumulate ( df_cum_rets )
underwater = - 100 * ( ( running_max - df_cum_rets ) / running_max )
( underwater ) . plot ( ax = ax , kind = 'area' , color = 'coral' , alpha = 0.7 , ** kwargs )
ax . set_ylabel ( 'Drawdown' )
ax . set_title ( 'Underwater plot' )
ax . set_xlabel ( '' )
return ax


signature:
def plot_perf_stats ( returns , factor_returns , ax = None ) :
    """Create box plot of some performance metrics of the strategy .
 The width of the box whiskers is determined by a bootstrap .
 Parameters
 returns : pd . Series
 Daily returns of the strategy , noncumulative .
 - See full explanation in tears . create _ full _ tear _ sheet .
 factor _ returns : pd . Series
 Daily noncumulative returns of the benchmark factor to which betas are
 computed . Usually a benchmark such as market returns .
 - This is in the same style as returns .
 ax : matplotlib . Axes , optional
 Axes upon which to plot .
 Returns
 ax : matplotlib . Axes
 The axes that were plotted on ."""

implementation:
if ax is None :
    ax = plt . gca ( )
bootstrap_values = timeseries . perf_stats_bootstrap ( returns , factor_returns , return_stats = False )
bootstrap_values = bootstrap_values . drop ( 'Kurtosis' , axis = 'columns' )
sns . boxplot ( data = bootstrap_values , orient = 'h' , ax = ax )
return ax


signature:
def show_perf_stats ( returns , factor_returns = None , positions = None , transactions = None , turnover_denom = 'AGB' , live_start_date = None , bootstrap = False , header_rows = None ) :
    """Prints some performance metrics of the strategy .
 - Shows amount of time the strategy has been run in backtest and
 out - of - sample ( in live trading ) .
 - Shows Omega ratio , max drawdown , Calmar ratio , annual return ,
 stability , Sharpe ratio , annual volatility , alpha , and beta .
 Parameters
 returns : pd . Series
 Daily returns of the strategy , noncumulative .
 - See full explanation in tears . create _ full _ tear _ sheet .
 factor _ returns : pd . Series , optional
 Daily noncumulative returns of the benchmark factor to which betas are
 computed . Usually a benchmark such as market returns .
 - This is in the same style as returns .
 positions : pd . DataFrame , optional
 Daily net position values .
 - See full explanation in create _ full _ tear _ sheet .
 transactions : pd . DataFrame , optional
 Prices and amounts of executed trades . One row per trade .
 - See full explanation in tears . create _ full _ tear _ sheet
 turnover _ denom : str , optional
 Either AGB or portfolio _ value , default AGB .
 - See full explanation in txn . get _ turnover .
 live _ start _ date : datetime , optional
 The point in time when the strategy began live trading , after
 its backtest period .
 bootstrap : boolean , optional
 Whether to perform bootstrap analysis for the performance
 metrics .
 - For more information , see timeseries . perf _ stats _ bootstrap
 header _ rows : dict or OrderedDict , optional
 Extra rows to display at the top of the displayed table ."""

implementation:
if bootstrap :
    perf_func = timeseries . perf_stats_bootstrap
else :
    perf_func = timeseries . perf_stats
perf_stats_all = perf_func ( returns , factor_returns = factor_returns , positions = positions , transactions = transactions , turnover_denom = turnover_denom )
date_rows = OrderedDict ( )
if len ( returns . index ) > 0 :
    date_rows [ 'Start date' ] = returns . index [ 0 ] . strftime ( '%Y-%m-%d' )
    date_rows [ 'End date' ] = returns . index [ - 1 ] . strftime ( '%Y-%m-%d' )
if live_start_date is not None :
    live_start_date = ep . utils . get_utc_timestamp ( live_start_date )
    returns_is = returns [ returns . index < live_start_date ]
    returns_oos = returns [ returns . index >= live_start_date ]
    positions_is = None
    positions_oos = None
    transactions_is = None
    transactions_oos = None
    if positions is not None :
        positions_is = positions [ positions . index < live_start_date ]
        positions_oos = positions [ positions . index >= live_start_date ]
        if transactions is not None :
            transactions_is = transactions [ ( transactions . index < live_start_date ) ]
            transactions_oos = transactions [ ( transactions . index > live_start_date ) ]
    perf_stats_is = perf_func ( returns_is , factor_returns = factor_returns , positions = positions_is , transactions = transactions_is , turnover_denom = turnover_denom )
    perf_stats_oos = perf_func ( returns_oos , factor_returns = factor_returns , positions = positions_oos , transactions = transactions_oos , turnover_denom = turnover_denom )
    if len ( returns . index ) > 0 :
        date_rows [ 'In-sample months' ] = int ( len ( returns_is ) / APPROX_BDAYS_PER_MONTH )
        date_rows [ 'Out-of-sample months' ] = int ( len ( returns_oos ) / APPROX_BDAYS_PER_MONTH )
    perf_stats = pd . concat ( OrderedDict ( [ ( 'In-sample' , perf_stats_is ) , ( 'Out-of-sample' , perf_stats_oos ) , ( 'All' , perf_stats_all ) , ] ) , axis = 1 )
else :
    if len ( returns . index ) > 0 :
        date_rows [ 'Total months' ] = int ( len ( returns ) / APPROX_BDAYS_PER_MONTH )
    perf_stats = pd . DataFrame ( perf_stats_all , columns = [ 'Backtest' ] )
for column in perf_stats . columns :
    for stat , value in perf_stats [ column ] . iteritems ( ) :
        if stat in STAT_FUNCS_PCT :
            perf_stats . loc [ stat , column ] = str ( np . round ( value * 100 , 1 ) ) + '%'
if header_rows is None :
    header_rows = date_rows
else :
    header_rows = OrderedDict ( header_rows )
    header_rows . update ( date_rows )
utils . print_table ( perf_stats , float_format = '{0:.2f}' . format , header_rows = header_rows , )


signature:
def plot_returns ( returns , live_start_date = None , ax = None ) :
    """Plots raw returns over time .
 Backtest returns are in green , and out - of - sample ( live trading )
 returns are in red .
 Parameters
 returns : pd . Series
 Daily returns of the strategy , noncumulative .
 - See full explanation in tears . create _ full _ tear _ sheet .
 live _ start _ date : datetime , optional
 The date when the strategy began live trading , after
 its backtest period . This date should be normalized .
 ax : matplotlib . Axes , optional
 Axes upon which to plot .
 * * kwargs , optional
 Passed to plotting function .
 Returns
 ax : matplotlib . Axes
 The axes that were plotted on ."""

implementation:
if ax is None :
    ax = plt . gca ( )
ax . set_label ( '' )
ax . set_ylabel ( 'Returns' )
if live_start_date is not None :
    live_start_date = ep . utils . get_utc_timestamp ( live_start_date )
    is_returns = returns . loc [ returns . index < live_start_date ]
    oos_returns = returns . loc [ returns . index >= live_start_date ]
    is_returns . plot ( ax = ax , color = 'g' )
    oos_returns . plot ( ax = ax , color = 'r' )
else :
    returns . plot ( ax = ax , color = 'g' )
return ax


signature:
def plot_rolling_returns ( returns , factor_returns = None , live_start_date = None , logy = False , cone_std = None , legend_loc = 'best' , volatility_match = False , cone_function = timeseries . forecast_cone_bootstrap , ax = None , ** kwargs ) :
    """Plots cumulative rolling returns versus some benchmarks ' .
 Backtest returns are in green , and out - of - sample ( live trading )
 returns are in red .
 Additionally , a non - parametric cone plot may be added to the
 out - of - sample returns region .
 Parameters
 returns : pd . Series
 Daily returns of the strategy , noncumulative .
 - See full explanation in tears . create _ full _ tear _ sheet .
 factor _ returns : pd . Series , optional
 Daily noncumulative returns of the benchmark factor to which betas are
 computed . Usually a benchmark such as market returns .
 - This is in the same style as returns .
 live _ start _ date : datetime , optional
 The date when the strategy began live trading , after
 its backtest period . This date should be normalized .
 logy : bool , optional
 Whether to log - scale the y - axis .
 cone _ std : float , or tuple , optional
 If float , The standard deviation to use for the cone plots .
 If tuple , Tuple of standard deviation values to use for the cone plots
 - See timeseries . forecast _ cone _ bounds for more details .
 legend _ loc : matplotlib . loc , optional
 The location of the legend on the plot .
 volatility _ match : bool , optional
 Whether to normalize the volatility of the returns to those of the
 benchmark returns . This helps compare strategies with different
 volatilities . Requires passing of benchmark _ rets .
 cone _ function : function , optional
 Function to use when generating forecast probability cone .
 The function signiture must follow the form :
 def cone ( in _ sample _ returns ( pd . Series ) ,
 days _ to _ project _ forward ( int ) ,
 cone _ std = ( float , or tuple ) ,
 starting _ value = ( int , or float ) )
 See timeseries . forecast _ cone _ bootstrap for an example .
 ax : matplotlib . Axes , optional
 Axes upon which to plot .
 * * kwargs , optional
 Passed to plotting function .
 Returns
 ax : matplotlib . Axes
 The axes that were plotted on ."""

implementation:
if ax is None :
    ax = plt . gca ( )
ax . set_xlabel ( '' )
ax . set_ylabel ( 'Cumulative returns' )
ax . set_yscale ( 'log' if logy else 'linear' )
if volatility_match and factor_returns is None :
    raise ValueError ( 'volatility_match requires passing of ' 'factor_returns.' )
elif volatility_match and factor_returns is not None :
    bmark_vol = factor_returns . loc [ returns . index ] . std ( )
    returns = ( returns / returns . std ( ) ) * bmark_vol
cum_rets = ep . cum_returns ( returns , 1.0 )
y_axis_formatter = FuncFormatter ( utils . two_dec_places )
ax . yaxis . set_major_formatter ( FuncFormatter ( y_axis_formatter ) )
if factor_returns is not None :
    cum_factor_returns = ep . cum_returns ( factor_returns [ cum_rets . index ] , 1.0 )
    cum_factor_returns . plot ( lw = 2 , color = 'gray' , label = factor_returns . name , alpha = 0.60 , ax = ax , ** kwargs )
if live_start_date is not None :
    live_start_date = ep . utils . get_utc_timestamp ( live_start_date )
    is_cum_returns = cum_rets . loc [ cum_rets . index < live_start_date ]
    oos_cum_returns = cum_rets . loc [ cum_rets . index >= live_start_date ]
else :
    is_cum_returns = cum_rets
    oos_cum_returns = pd . Series ( [ ] )
is_cum_returns . plot ( lw = 3 , color = 'forestgreen' , alpha = 0.6 , label = 'Backtest' , ax = ax , ** kwargs )
if len ( oos_cum_returns ) > 0 :
    oos_cum_returns . plot ( lw = 4 , color = 'red' , alpha = 0.6 , label = 'Live' , ax = ax , ** kwargs )
    if cone_std is not None :
        if isinstance ( cone_std , ( float , int ) ) :
            cone_std = [ cone_std ]
        is_returns = returns . loc [ returns . index < live_start_date ]
        cone_bounds = cone_function ( is_returns , len ( oos_cum_returns ) , cone_std = cone_std , starting_value = is_cum_returns [ - 1 ] )
        cone_bounds = cone_bounds . set_index ( oos_cum_returns . index )
        for std in cone_std :
            ax . fill_between ( cone_bounds . index , cone_bounds [ float ( std ) ] , cone_bounds [ float ( - std ) ] , color = 'steelblue' , alpha = 0.5 )
if legend_loc is not None :
    ax . legend ( loc = legend_loc , frameon = True , framealpha = 0.5 )
ax . axhline ( 1.0 , linestyle = '--' , color = 'black' , lw = 2 )
return ax


signature:
def plot_rolling_beta ( returns , factor_returns , legend_loc = 'best' , ax = None , ** kwargs ) :
    """Plots the rolling 6 - month and 12 - month beta versus date .
 Parameters
 returns : pd . Series
 Daily returns of the strategy , noncumulative .
 - See full explanation in tears . create _ full _ tear _ sheet .
 factor _ returns : pd . Series
 Daily noncumulative returns of the benchmark factor to which betas are
 computed . Usually a benchmark such as market returns .
 - This is in the same style as returns .
 legend _ loc : matplotlib . loc , optional
 The location of the legend on the plot .
 ax : matplotlib . Axes , optional
 Axes upon which to plot .
 * * kwargs , optional
 Passed to plotting function .
 Returns
 ax : matplotlib . Axes
 The axes that were plotted on ."""

implementation:
if ax is None :
    ax = plt . gca ( )
y_axis_formatter = FuncFormatter ( utils . two_dec_places )
ax . yaxis . set_major_formatter ( FuncFormatter ( y_axis_formatter ) )
ax . set_title ( "Rolling portfolio beta to " + str ( factor_returns . name ) )
ax . set_ylabel ( 'Beta' )
rb_1 = timeseries . rolling_beta ( returns , factor_returns , rolling_window = APPROX_BDAYS_PER_MONTH * 6 )
rb_1 . plot ( color = 'steelblue' , lw = 3 , alpha = 0.6 , ax = ax , ** kwargs )
rb_2 = timeseries . rolling_beta ( returns , factor_returns , rolling_window = APPROX_BDAYS_PER_MONTH * 12 )
rb_2 . plot ( color = 'grey' , lw = 3 , alpha = 0.4 , ax = ax , ** kwargs )
ax . axhline ( rb_1 . mean ( ) , color = 'steelblue' , linestyle = '--' , lw = 3 )
ax . axhline ( 0.0 , color = 'black' , linestyle = '-' , lw = 2 )
ax . set_xlabel ( '' )
ax . legend ( [ '6-mo' , '12-mo' ] , loc = legend_loc , frameon = True , framealpha = 0.5 )
ax . set_ylim ( ( - 1.0 , 1.0 ) )
return ax


signature:
def plot_rolling_volatility ( returns , factor_returns = None , rolling_window = APPROX_BDAYS_PER_MONTH * 6 , legend_loc = 'best' , ax = None , ** kwargs ) :
    """Plots the rolling volatility versus date .
 Parameters
 returns : pd . Series
 Daily returns of the strategy , noncumulative .
 - See full explanation in tears . create _ full _ tear _ sheet .
 factor _ returns : pd . Series , optional
 Daily noncumulative returns of the benchmark factor to which betas are
 computed . Usually a benchmark such as market returns .
 - This is in the same style as returns .
 rolling _ window : int , optional
 The days window over which to compute the volatility .
 legend _ loc : matplotlib . loc , optional
 The location of the legend on the plot .
 ax : matplotlib . Axes , optional
 Axes upon which to plot .
 * * kwargs , optional
 Passed to plotting function .
 Returns
 ax : matplotlib . Axes
 The axes that were plotted on ."""

implementation:
if ax is None :
    ax = plt . gca ( )
y_axis_formatter = FuncFormatter ( utils . two_dec_places )
ax . yaxis . set_major_formatter ( FuncFormatter ( y_axis_formatter ) )
rolling_vol_ts = timeseries . rolling_volatility ( returns , rolling_window )
rolling_vol_ts . plot ( alpha = .7 , lw = 3 , color = 'orangered' , ax = ax , ** kwargs )
if factor_returns is not None :
    rolling_vol_ts_factor = timeseries . rolling_volatility ( factor_returns , rolling_window )
    rolling_vol_ts_factor . plot ( alpha = .7 , lw = 3 , color = 'grey' , ax = ax , ** kwargs )
ax . set_title ( 'Rolling volatility (6-month)' )
ax . axhline ( rolling_vol_ts . mean ( ) , color = 'steelblue' , linestyle = '--' , lw = 3 )
ax . axhline ( 0.0 , color = 'black' , linestyle = '-' , lw = 2 )
ax . set_ylabel ( 'Volatility' )
ax . set_xlabel ( '' )
if factor_returns is None :
    ax . legend ( [ 'Volatility' , 'Average volatility' ] , loc = legend_loc , frameon = True , framealpha = 0.5 )
else :
    ax . legend ( [ 'Volatility' , 'Benchmark volatility' , 'Average volatility' ] , loc = legend_loc , frameon = True , framealpha = 0.5 )
return ax


signature:
def plot_rolling_sharpe ( returns , factor_returns = None , rolling_window = APPROX_BDAYS_PER_MONTH * 6 , legend_loc = 'best' , ax = None , ** kwargs ) :
    """Plots the rolling Sharpe ratio versus date .
 Parameters
 returns : pd . Series
 Daily returns of the strategy , noncumulative .
 - See full explanation in tears . create _ full _ tear _ sheet .
 factor _ returns : pd . Series , optional
 Daily noncumulative returns of the benchmark factor for
 which the benchmark rolling Sharpe is computed . Usually
 a benchmark such as market returns .
 - This is in the same style as returns .
 rolling _ window : int , optional
 The days window over which to compute the sharpe ratio .
 legend _ loc : matplotlib . loc , optional
 The location of the legend on the plot .
 ax : matplotlib . Axes , optional
 Axes upon which to plot .
 * * kwargs , optional
 Passed to plotting function .
 Returns
 ax : matplotlib . Axes
 The axes that were plotted on ."""

implementation:
if ax is None :
    ax = plt . gca ( )
y_axis_formatter = FuncFormatter ( utils . two_dec_places )
ax . yaxis . set_major_formatter ( FuncFormatter ( y_axis_formatter ) )
rolling_sharpe_ts = timeseries . rolling_sharpe ( returns , rolling_window )
rolling_sharpe_ts . plot ( alpha = .7 , lw = 3 , color = 'orangered' , ax = ax , ** kwargs )
if factor_returns is not None :
    rolling_sharpe_ts_factor = timeseries . rolling_sharpe ( factor_returns , rolling_window )
    rolling_sharpe_ts_factor . plot ( alpha = .7 , lw = 3 , color = 'grey' , ax = ax , ** kwargs )
ax . set_title ( 'Rolling Sharpe ratio (6-month)' )
ax . axhline ( rolling_sharpe_ts . mean ( ) , color = 'steelblue' , linestyle = '--' , lw = 3 )
ax . axhline ( 0.0 , color = 'black' , linestyle = '-' , lw = 3 )
ax . set_ylabel ( 'Sharpe ratio' )
ax . set_xlabel ( '' )
if factor_returns is None :
    ax . legend ( [ 'Sharpe' , 'Average' ] , loc = legend_loc , frameon = True , framealpha = 0.5 )
else :
    ax . legend ( [ 'Sharpe' , 'Benchmark Sharpe' , 'Average' ] , loc = legend_loc , frameon = True , framealpha = 0.5 )
return ax


signature:
def plot_gross_leverage ( returns , positions , ax = None , ** kwargs ) :
    """Plots gross leverage versus date .
 Gross leverage is the sum of long and short exposure per share
 divided by net asset value .
 Parameters
 returns : pd . Series
 Daily returns of the strategy , noncumulative .
 - See full explanation in tears . create _ full _ tear _ sheet .
 positions : pd . DataFrame
 Daily net position values .
 - See full explanation in create _ full _ tear _ sheet .
 ax : matplotlib . Axes , optional
 Axes upon which to plot .
 * * kwargs , optional
 Passed to plotting function .
 Returns
 ax : matplotlib . Axes
 The axes that were plotted on ."""

implementation:
if ax is None :
    ax = plt . gca ( )
gl = timeseries . gross_lev ( positions )
gl . plot ( lw = 0.5 , color = 'limegreen' , legend = False , ax = ax , ** kwargs )
ax . axhline ( gl . mean ( ) , color = 'g' , linestyle = '--' , lw = 3 )
ax . set_title ( 'Gross leverage' )
ax . set_ylabel ( 'Gross leverage' )
ax . set_xlabel ( '' )
return ax


signature:
def plot_exposures ( returns , positions , ax = None , ** kwargs ) :
    """Plots a cake chart of the long and short exposure .
 Parameters
 returns : pd . Series
 Daily returns of the strategy , noncumulative .
 - See full explanation in tears . create _ full _ tear _ sheet .
 positions _ alloc : pd . DataFrame
 Portfolio allocation of positions . See
 pos . get _ percent _ alloc .
 ax : matplotlib . Axes , optional
 Axes upon which to plot .
 * * kwargs , optional
 Passed to plotting function .
 Returns
 ax : matplotlib . Axes
 The axes that were plotted on ."""

implementation:
if ax is None :
    ax = plt . gca ( )
pos_no_cash = positions . drop ( 'cash' , axis = 1 )
l_exp = pos_no_cash [ pos_no_cash > 0 ] . sum ( axis = 1 ) / positions . sum ( axis = 1 )
s_exp = pos_no_cash [ pos_no_cash < 0 ] . sum ( axis = 1 ) / positions . sum ( axis = 1 )
net_exp = pos_no_cash . sum ( axis = 1 ) / positions . sum ( axis = 1 )
ax . fill_between ( l_exp . index , 0 , l_exp . values , label = 'Long' , color = 'green' , alpha = 0.5 )
ax . fill_between ( s_exp . index , 0 , s_exp . values , label = 'Short' , color = 'red' , alpha = 0.5 )
ax . plot ( net_exp . index , net_exp . values , label = 'Net' , color = 'black' , linestyle = 'dotted' )
ax . set_xlim ( ( returns . index [ 0 ] , returns . index [ - 1 ] ) )
ax . set_title ( "Exposure" )
ax . set_ylabel ( 'Exposure' )
ax . legend ( loc = 'lower left' , frameon = True , framealpha = 0.5 )
ax . set_xlabel ( '' )
return ax


signature:
def show_and_plot_top_positions ( returns , positions_alloc , show_and_plot = 2 , hide_positions = False , legend_loc = 'real_best' , ax = None , ** kwargs ) :
    """Prints and / or plots the exposures of the top 10 held positions of
 all time .
 Parameters
 returns : pd . Series
 Daily returns of the strategy , noncumulative .
 - See full explanation in tears . create _ full _ tear _ sheet .
 positions _ alloc : pd . DataFrame
 Portfolio allocation of positions . See pos . get _ percent _ alloc .
 show _ and _ plot : int , optional
 By default , this is 2 , and both prints and plots .
 If this is 0 , it will only plot ; if 1 , it will only print .
 hide _ positions : bool , optional
 If True , will not output any symbol names .
 legend _ loc : matplotlib . loc , optional
 The location of the legend on the plot .
 By default , the legend will display below the plot .
 ax : matplotlib . Axes , optional
 Axes upon which to plot .
 * * kwargs , optional
 Passed to plotting function .
 Returns
 ax : matplotlib . Axes , conditional
 The axes that were plotted on ."""

implementation:
positions_alloc = positions_alloc . copy ( )
positions_alloc . columns = positions_alloc . columns . map ( utils . format_asset )
df_top_long , df_top_short , df_top_abs = pos . get_top_long_short_abs ( positions_alloc )
if show_and_plot == 1 or show_and_plot == 2 :
    utils . print_table ( pd . DataFrame ( df_top_long * 100 , columns = [ 'max' ] ) , float_format = '{0:.2f}%' . format , name = 'Top 10 long positions of all time' )
    utils . print_table ( pd . DataFrame ( df_top_short * 100 , columns = [ 'max' ] ) , float_format = '{0:.2f}%' . format , name = 'Top 10 short positions of all time' )
    utils . print_table ( pd . DataFrame ( df_top_abs * 100 , columns = [ 'max' ] ) , float_format = '{0:.2f}%' . format , name = 'Top 10 positions of all time' )
if show_and_plot == 0 or show_and_plot == 2 :
    if ax is None :
        ax = plt . gca ( )
    positions_alloc [ df_top_abs . index ] . plot ( title = 'Portfolio allocation over time, only top 10 holdings' , alpha = 0.5 , ax = ax , ** kwargs )
    # Place legend below plot , shrink plot by 20%
    if legend_loc == 'real_best' :
        box = ax . get_position ( )
        ax . set_position ( [ box . x0 , box . y0 + box . height * 0.1 , box . width , box . height * 0.9 ] )
        # Put a legend below current axis
        ax . legend ( loc = 'upper center' , frameon = True , framealpha = 0.5 , bbox_to_anchor = ( 0.5 , - 0.14 ) , ncol = 5 )
    else :
        ax . legend ( loc = legend_loc )
    ax . set_xlim ( ( returns . index [ 0 ] , returns . index [ - 1 ] ) )
    ax . set_ylabel ( 'Exposure by holding' )
    if hide_positions :
        ax . legend_ . remove ( )
    return ax


signature:
def plot_max_median_position_concentration ( positions , ax = None , ** kwargs ) :
    """Plots the max and median of long and short position concentrations
 over the time .
 Parameters
 positions : pd . DataFrame
 The positions that the strategy takes over time .
 ax : matplotlib . Axes , optional
 Axes upon which to plot .
 Returns
 ax : matplotlib . Axes
 The axes that were plotted on ."""

implementation:
if ax is None :
    ax = plt . gca ( )
alloc_summary = pos . get_max_median_position_concentration ( positions )
colors = [ 'mediumblue' , 'steelblue' , 'tomato' , 'firebrick' ]
alloc_summary . plot ( linewidth = 1 , color = colors , alpha = 0.6 , ax = ax )
ax . legend ( loc = 'center left' , frameon = True , framealpha = 0.5 )
ax . set_ylabel ( 'Exposure' )
ax . set_title ( 'Long/short max and median position concentration' )
return ax


signature:
def plot_sector_allocations ( returns , sector_alloc , ax = None , ** kwargs ) :
    """Plots the sector exposures of the portfolio over time .
 Parameters
 returns : pd . Series
 Daily returns of the strategy , noncumulative .
 - See full explanation in tears . create _ full _ tear _ sheet .
 sector _ alloc : pd . DataFrame
 Portfolio allocation of positions . See pos . get _ sector _ alloc .
 ax : matplotlib . Axes , optional
 Axes upon which to plot .
 * * kwargs , optional
 Passed to plotting function .
 Returns
 ax : matplotlib . Axes
 The axes that were plotted on ."""

implementation:
if ax is None :
    ax = plt . gca ( )
sector_alloc . plot ( title = 'Sector allocation over time' , alpha = 0.5 , ax = ax , ** kwargs )
box = ax . get_position ( )
ax . set_position ( [ box . x0 , box . y0 + box . height * 0.1 , box . width , box . height * 0.9 ] )
# Put a legend below current axis
ax . legend ( loc = 'upper center' , frameon = True , framealpha = 0.5 , bbox_to_anchor = ( 0.5 , - 0.14 ) , ncol = 5 )
ax . set_xlim ( ( sector_alloc . index [ 0 ] , sector_alloc . index [ - 1 ] ) )
ax . set_ylabel ( 'Exposure by sector' )
ax . set_xlabel ( '' )
return ax


signature:
def plot_return_quantiles ( returns , live_start_date = None , ax = None , ** kwargs ) :
    """Creates a box plot of daily , weekly , and monthly return
 distributions .
 Parameters
 returns : pd . Series
 Daily returns of the strategy , noncumulative .
 - See full explanation in tears . create _ full _ tear _ sheet .
 live _ start _ date : datetime , optional
 The point in time when the strategy began live trading , after
 its backtest period .
 ax : matplotlib . Axes , optional
 Axes upon which to plot .
 * * kwargs , optional
 Passed to seaborn plotting function .
 Returns
 ax : matplotlib . Axes
 The axes that were plotted on ."""

implementation:
if ax is None :
    ax = plt . gca ( )
is_returns = returns if live_start_date is None else returns . loc [ returns . index < live_start_date ]
is_weekly = ep . aggregate_returns ( is_returns , 'weekly' )
is_monthly = ep . aggregate_returns ( is_returns , 'monthly' )
sns . boxplot ( data = [ is_returns , is_weekly , is_monthly ] , palette = [ "#4c72B0" , "#55A868" , "#CCB974" ] , ax = ax , ** kwargs )
if live_start_date is not None :
    oos_returns = returns . loc [ returns . index >= live_start_date ]
    oos_weekly = ep . aggregate_returns ( oos_returns , 'weekly' )
    oos_monthly = ep . aggregate_returns ( oos_returns , 'monthly' )
    sns . swarmplot ( data = [ oos_returns , oos_weekly , oos_monthly ] , ax = ax , color = "red" , marker = "d" , ** kwargs )
    red_dots = matplotlib . lines . Line2D ( [ ] , [ ] , color = "red" , marker = "d" , label = "Out-of-sample data" , linestyle = '' )
    ax . legend ( handles = [ red_dots ] , frameon = True , framealpha = 0.5 )
ax . set_xticklabels ( [ 'Daily' , 'Weekly' , 'Monthly' ] )
ax . set_title ( 'Return quantiles' )
return ax


signature:
def plot_turnover ( returns , transactions , positions , legend_loc = 'best' , ax = None , ** kwargs ) :
    """Plots turnover vs . date .
 Turnover is the number of shares traded for a period as a fraction
 of total shares .
 Displays daily total , daily average per month , and all - time daily
 average .
 Parameters
 returns : pd . Series
 Daily returns of the strategy , noncumulative .
 - See full explanation in tears . create _ full _ tear _ sheet .
 transactions : pd . DataFrame
 Prices and amounts of executed trades . One row per trade .
 - See full explanation in tears . create _ full _ tear _ sheet .
 positions : pd . DataFrame
 Daily net position values .
 - See full explanation in tears . create _ full _ tear _ sheet .
 legend _ loc : matplotlib . loc , optional
 The location of the legend on the plot .
 ax : matplotlib . Axes , optional
 Axes upon which to plot .
 * * kwargs , optional
 Passed to plotting function .
 Returns
 ax : matplotlib . Axes
 The axes that were plotted on ."""

implementation:
if ax is None :
    ax = plt . gca ( )
y_axis_formatter = FuncFormatter ( utils . two_dec_places )
ax . yaxis . set_major_formatter ( FuncFormatter ( y_axis_formatter ) )
df_turnover = txn . get_turnover ( positions , transactions )
df_turnover_by_month = df_turnover . resample ( "M" ) . mean ( )
df_turnover . plot ( color = 'steelblue' , alpha = 1.0 , lw = 0.5 , ax = ax , ** kwargs )
df_turnover_by_month . plot ( color = 'orangered' , alpha = 0.5 , lw = 2 , ax = ax , ** kwargs )
ax . axhline ( df_turnover . mean ( ) , color = 'steelblue' , linestyle = '--' , lw = 3 , alpha = 1.0 )
ax . legend ( [ 'Daily turnover' , 'Average daily turnover, by month' , 'Average daily turnover, net' ] , loc = legend_loc , frameon = True , framealpha = 0.5 )
ax . set_title ( 'Daily turnover' )
ax . set_xlim ( ( returns . index [ 0 ] , returns . index [ - 1 ] ) )
ax . set_ylim ( ( 0 , 2 ) )
ax . set_ylabel ( 'Turnover' )
ax . set_xlabel ( '' )
return ax


signature:
def plot_slippage_sweep ( returns , positions , transactions , slippage_params = ( 3 , 8 , 10 , 12 , 15 , 20 , 50 ) , ax = None , ** kwargs ) :
    """Plots equity curves at different per - dollar slippage assumptions .
 Parameters
 returns : pd . Series
 Timeseries of portfolio returns to be adjusted for various
 degrees of slippage .
 positions : pd . DataFrame
 Daily net position values .
 - See full explanation in tears . create _ full _ tear _ sheet .
 transactions : pd . DataFrame
 Prices and amounts of executed trades . One row per trade .
 - See full explanation in tears . create _ full _ tear _ sheet .
 slippage _ params : tuple
 Slippage pameters to apply to the return time series ( in
 basis points ) .
 ax : matplotlib . Axes , optional
 Axes upon which to plot .
 * * kwargs , optional
 Passed to seaborn plotting function .
 Returns
 ax : matplotlib . Axes
 The axes that were plotted on ."""

implementation:
if ax is None :
    ax = plt . gca ( )
slippage_sweep = pd . DataFrame ( )
for bps in slippage_params :
    adj_returns = txn . adjust_returns_for_slippage ( returns , positions , transactions , bps )
    label = str ( bps ) + " bps"
    slippage_sweep [ label ] = ep . cum_returns ( adj_returns , 1 )
slippage_sweep . plot ( alpha = 1.0 , lw = 0.5 , ax = ax )
ax . set_title ( 'Cumulative returns given additional per-dollar slippage' )
ax . set_ylabel ( '' )
ax . legend ( loc = 'center left' , frameon = True , framealpha = 0.5 )
return ax


signature:
def plot_slippage_sensitivity ( returns , positions , transactions , ax = None , ** kwargs ) :
    """Plots curve relating per - dollar slippage to average annual returns .
 Parameters
 returns : pd . Series
 Timeseries of portfolio returns to be adjusted for various
 degrees of slippage .
 positions : pd . DataFrame
 Daily net position values .
 - See full explanation in tears . create _ full _ tear _ sheet .
 transactions : pd . DataFrame
 Prices and amounts of executed trades . One row per trade .
 - See full explanation in tears . create _ full _ tear _ sheet .
 ax : matplotlib . Axes , optional
 Axes upon which to plot .
 * * kwargs , optional
 Passed to seaborn plotting function .
 Returns
 ax : matplotlib . Axes
 The axes that were plotted on ."""

implementation:
if ax is None :
    ax = plt . gca ( )
avg_returns_given_slippage = pd . Series ( )
for bps in range ( 1 , 100 ) :
    adj_returns = txn . adjust_returns_for_slippage ( returns , positions , transactions , bps )
    avg_returns = ep . annual_return ( adj_returns )
    avg_returns_given_slippage . loc [ bps ] = avg_returns
avg_returns_given_slippage . plot ( alpha = 1.0 , lw = 2 , ax = ax )
ax . set_title ( 'Average annual returns given additional per-dollar slippage' )
ax . set_xticks ( np . arange ( 0 , 100 , 10 ) )
ax . set_ylabel ( 'Average annual return' )
ax . set_xlabel ( 'Per-dollar slippage (bps)' )
return ax


signature:
def plot_daily_turnover_hist ( transactions , positions , ax = None , ** kwargs ) :
    """Plots a histogram of daily turnover rates .
 Parameters
 transactions : pd . DataFrame
 Prices and amounts of executed trades . One row per trade .
 - See full explanation in tears . create _ full _ tear _ sheet .
 positions : pd . DataFrame
 Daily net position values .
 - See full explanation in tears . create _ full _ tear _ sheet .
 ax : matplotlib . Axes , optional
 Axes upon which to plot .
 * * kwargs , optional
 Passed to seaborn plotting function .
 Returns
 ax : matplotlib . Axes
 The axes that were plotted on ."""

implementation:
if ax is None :
    ax = plt . gca ( )
turnover = txn . get_turnover ( positions , transactions )
sns . distplot ( turnover , ax = ax , ** kwargs )
ax . set_title ( 'Distribution of daily turnover rates' )
ax . set_xlabel ( 'Turnover rate' )
return ax


signature:
def plot_daily_volume ( returns , transactions , ax = None , ** kwargs ) :
    """Plots trading volume per day vs . date .
 Also displays all - time daily average .
 Parameters
 returns : pd . Series
 Daily returns of the strategy , noncumulative .
 - See full explanation in tears . create _ full _ tear _ sheet .
 transactions : pd . DataFrame
 Prices and amounts of executed trades . One row per trade .
 - See full explanation in tears . create _ full _ tear _ sheet .
 ax : matplotlib . Axes , optional
 Axes upon which to plot .
 * * kwargs , optional
 Passed to plotting function .
 Returns
 ax : matplotlib . Axes
 The axes that were plotted on ."""

implementation:
if ax is None :
    ax = plt . gca ( )
daily_txn = txn . get_txn_vol ( transactions )
daily_txn . txn_shares . plot ( alpha = 1.0 , lw = 0.5 , ax = ax , ** kwargs )
ax . axhline ( daily_txn . txn_shares . mean ( ) , color = 'steelblue' , linestyle = '--' , lw = 3 , alpha = 1.0 )
ax . set_title ( 'Daily trading volume' )
ax . set_xlim ( ( returns . index [ 0 ] , returns . index [ - 1 ] ) )
ax . set_ylabel ( 'Amount of shares traded' )
ax . set_xlabel ( '' )
return ax