Skip to content

Commit 03568e0

Browse files
authored
Merge pull request #618 from huaiweicheng/master
add turnover_denom in create_txn_tear_sheet and fix some small issues
2 parents 852e761 + ef516e9 commit 03568e0

File tree

2 files changed

+37
-24
lines changed

2 files changed

+37
-24
lines changed

pyfolio/plotting.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,7 +1323,7 @@ def plot_return_quantiles(returns, live_start_date=None, ax=None, **kwargs):
13231323
return ax
13241324

13251325

1326-
def plot_turnover(returns, transactions, positions,
1326+
def plot_turnover(returns, transactions, positions, turnover_denom='AGB',
13271327
legend_loc='best', ax=None, **kwargs):
13281328
"""
13291329
Plots turnover vs. date.
@@ -1345,6 +1345,9 @@ def plot_turnover(returns, transactions, positions,
13451345
positions : pd.DataFrame
13461346
Daily net position values.
13471347
- See full explanation in tears.create_full_tear_sheet.
1348+
turnover_denom : str, optional
1349+
Either AGB or portfolio_value, default AGB.
1350+
- See full explanation in txn.get_turnover.
13481351
legend_loc : matplotlib.loc, optional
13491352
The location of the legend on the plot.
13501353
ax : matplotlib.Axes, optional
@@ -1364,7 +1367,7 @@ def plot_turnover(returns, transactions, positions,
13641367
y_axis_formatter = FuncFormatter(utils.two_dec_places)
13651368
ax.yaxis.set_major_formatter(FuncFormatter(y_axis_formatter))
13661369

1367-
df_turnover = txn.get_turnover(positions, transactions)
1370+
df_turnover = txn.get_turnover(positions, transactions, turnover_denom)
13681371
df_turnover_by_month = df_turnover.resample("M").mean()
13691372
df_turnover.plot(color='steelblue', alpha=1.0, lw=0.5, ax=ax, **kwargs)
13701373
df_turnover_by_month.plot(
@@ -1517,7 +1520,7 @@ def plot_capacity_sweep(returns, transactions, market_data,
15171520
return ax
15181521

15191522

1520-
def plot_daily_turnover_hist(transactions, positions,
1523+
def plot_daily_turnover_hist(transactions, positions, turnover_denom='AGB',
15211524
ax=None, **kwargs):
15221525
"""
15231526
Plots a histogram of daily turnover rates.
@@ -1530,6 +1533,9 @@ def plot_daily_turnover_hist(transactions, positions,
15301533
positions : pd.DataFrame
15311534
Daily net position values.
15321535
- See full explanation in tears.create_full_tear_sheet.
1536+
turnover_denom : str, optional
1537+
Either AGB or portfolio_value, default AGB.
1538+
- See full explanation in txn.get_turnover.
15331539
ax : matplotlib.Axes, optional
15341540
Axes upon which to plot.
15351541
**kwargs, optional
@@ -1543,7 +1549,7 @@ def plot_daily_turnover_hist(transactions, positions,
15431549

15441550
if ax is None:
15451551
ax = plt.gca()
1546-
turnover = txn.get_turnover(positions, transactions)
1552+
turnover = txn.get_turnover(positions, transactions, turnover_denom)
15471553
sns.distplot(turnover, ax=ax, **kwargs)
15481554
ax.set_title('Distribution of daily turnover rates')
15491555
ax.set_xlabel('Turnover rate')

pyfolio/tears.py

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,6 @@ def create_full_tear_sheet(returns,
6666
cone_std=(1.0, 1.5, 2.0),
6767
bootstrap=False,
6868
unadjusted_returns=None,
69-
style_factors=None,
70-
sectors=None,
71-
caps=None,
72-
shares_held=None,
73-
volumes=None,
74-
percentile=None,
7569
turnover_denom='AGB',
7670
set_context=True,
7771
factor_returns=None,
@@ -402,6 +396,7 @@ def create_simple_tear_sheet(returns,
402396
plotting.plot_turnover(returns,
403397
transactions,
404398
positions,
399+
turnover_denom=turnover_denom,
405400
ax=ax_turnover)
406401

407402
plotting.plot_txn_time_hist(transactions, ax=ax_txn_timings)
@@ -603,8 +598,8 @@ def create_returns_tear_sheet(returns, positions=None,
603598
@plotting.customize
604599
def create_position_tear_sheet(returns, positions,
605600
show_and_plot_top_pos=2, hide_positions=False,
606-
return_fig=False, sector_mappings=None,
607-
transactions=None, estimate_intraday='infer'):
601+
sector_mappings=None, transactions=None,
602+
estimate_intraday='infer', return_fig=False):
608603
"""
609604
Generate a number of plots for analyzing a
610605
strategy's positions and holdings.
@@ -627,8 +622,6 @@ def create_position_tear_sheet(returns, positions,
627622
hide_positions : bool, optional
628623
If True, will not output any symbol names.
629624
Overrides show_and_plot_top_pos to 0 to suppress text output.
630-
return_fig : boolean, optional
631-
If True, returns the figure that was plotted on.
632625
sector_mappings : dict or pd.Series, optional
633626
Security identifier to sector mapping.
634627
Security ids as keys, sectors as values.
@@ -638,6 +631,8 @@ def create_position_tear_sheet(returns, positions,
638631
estimate_intraday: boolean or str, optional
639632
Approximate returns for intraday strategies.
640633
See description in create_full_tear_sheet.
634+
return_fig : boolean, optional
635+
If True, returns the figure that was plotted on.
641636
"""
642637

643638
positions = utils.check_intraday(estimate_intraday, returns,
@@ -697,8 +692,8 @@ def create_position_tear_sheet(returns, positions,
697692

698693
@plotting.customize
699694
def create_txn_tear_sheet(returns, positions, transactions,
700-
unadjusted_returns=None, estimate_intraday='infer',
701-
return_fig=False):
695+
turnover_denom='AGB', unadjusted_returns=None,
696+
estimate_intraday='infer', return_fig=False):
702697
"""
703698
Generate a number of plots for analyzing a strategy's transactions.
704699
@@ -715,6 +710,9 @@ def create_txn_tear_sheet(returns, positions, transactions,
715710
transactions : pd.DataFrame
716711
Prices and amounts of executed trades. One row per trade.
717712
- See full explanation in create_full_tear_sheet.
713+
turnover_denom : str, optional
714+
Either AGB or portfolio_value, default AGB.
715+
- See full explanation in txn.get_turnover.
718716
unadjusted_returns : pd.Series, optional
719717
Daily unadjusted returns of the strategy, noncumulative.
720718
Will plot additional swippage sweep analysis.
@@ -743,12 +741,15 @@ def create_txn_tear_sheet(returns, positions, transactions,
743741
returns,
744742
transactions,
745743
positions,
744+
turnover_denom=turnover_denom,
746745
ax=ax_turnover)
747746

748747
plotting.plot_daily_volume(returns, transactions, ax=ax_daily_volume)
749748

750749
try:
751-
plotting.plot_daily_turnover_hist(transactions, positions,
750+
plotting.plot_daily_turnover_hist(transactions,
751+
positions,
752+
turnover_denom=turnover_denom,
752753
ax=ax_turnover_hist)
753754
except ValueError:
754755
warnings.warn('Unable to generate turnover plot.', UserWarning)
@@ -956,7 +957,8 @@ def create_capacity_tear_sheet(returns, positions, transactions,
956957
trade_daily_vol_limit=0.05,
957958
last_n_days=utils.APPROX_BDAYS_PER_MONTH * 6,
958959
days_to_liquidate_limit=1,
959-
estimate_intraday='infer'):
960+
estimate_intraday='infer',
961+
return_fig=False):
960962
"""
961963
Generates a report detailing portfolio size constraints set by
962964
least liquid tickers. Plots a "capacity sweep," a curve describing
@@ -993,6 +995,8 @@ def create_capacity_tear_sheet(returns, positions, transactions,
993995
estimate_intraday: boolean or str, optional
994996
Approximate returns for intraday strategies.
995997
See description in create_full_tear_sheet.
998+
return_fig : boolean, optional
999+
If True, returns the figure that was plotted on.
9961000
"""
9971001

9981002
positions = utils.check_intraday(estimate_intraday, returns,
@@ -1046,14 +1050,17 @@ def create_capacity_tear_sheet(returns, positions, transactions,
10461050
llt[llt['max_pct_bar_consumed'] > trade_daily_vol_limit * 100])
10471051

10481052
bt_starting_capital = positions.iloc[0].sum() / (1 + returns.iloc[0])
1049-
_, ax_capacity_sweep = plt.subplots(figsize=(14, 6))
1053+
fig, ax_capacity_sweep = plt.subplots(figsize=(14, 6))
10501054
plotting.plot_capacity_sweep(returns, transactions, market_data,
10511055
bt_starting_capital,
10521056
min_pv=100000,
10531057
max_pv=300000000,
10541058
step_size=1000000,
10551059
ax=ax_capacity_sweep)
10561060

1061+
if return_fig:
1062+
return fig
1063+
10571064

10581065
@plotting.customize
10591066
def create_perf_attrib_tear_sheet(returns,
@@ -1062,8 +1069,8 @@ def create_perf_attrib_tear_sheet(returns,
10621069
factor_loadings,
10631070
transactions=None,
10641071
pos_in_dollars=True,
1065-
return_fig=False,
1066-
factor_partitions=FACTOR_PARTITIONS):
1072+
factor_partitions=FACTOR_PARTITIONS,
1073+
return_fig=False):
10671074
"""
10681075
Generate plots and tables for analyzing a strategy's performance.
10691076
@@ -1093,15 +1100,15 @@ def create_perf_attrib_tear_sheet(returns,
10931100
Flag indicating whether `positions` are in dollars or percentages
10941101
If True, positions are in dollars.
10951102
1096-
return_fig : boolean, optional
1097-
If True, returns the figure that was plotted on.
1098-
10991103
factor_partitions : dict
11001104
dict specifying how factors should be separated in factor returns
11011105
and risk exposures plots
11021106
- Example:
11031107
{'style': ['momentum', 'size', 'value', ...],
11041108
'sector': ['technology', 'materials', ... ]}
1109+
1110+
return_fig : boolean, optional
1111+
If True, returns the figure that was plotted on.
11051112
"""
11061113
portfolio_exposures, perf_attrib_data = perf_attrib.perf_attrib(
11071114
returns, positions, factor_returns, factor_loadings, transactions,

0 commit comments

Comments
 (0)