Skip to content

Commit a87d9d1

Browse files
committed
ran autopep8, no aggression this time. closes #1.
1 parent d01e016 commit a87d9d1

File tree

5 files changed

+137
-78
lines changed

5 files changed

+137
-78
lines changed

quantrisk/plotting.py

+100-59
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import timeseries
1313
import positions
1414

15+
1516
def set_plot_defaults():
1617
# the below just sets some nice default plotting/charting colors/styles
1718
matplotlib.style.use('fivethirtyeight')
@@ -27,7 +28,7 @@ def plot_rolling_risk_factors(
2728
df_cum_rets,
2829
df_rets,
2930
risk_factors,
30-
rolling_beta_window=63*2,
31+
rolling_beta_window=63 * 2,
3132
legend_loc='best'):
3233
from matplotlib.ticker import FuncFormatter
3334
y_axis_formatter = FuncFormatter(utils.one_dec_places)
@@ -95,7 +96,7 @@ def plot_rolling_risk_factors(
9596
plt.axhline(0.0, color='black')
9697

9798
plt.ylabel('alpha', fontsize=14)
98-
plt.xlim( (df_rets.index[0], df_rets.index[-1]) )
99+
plt.xlim((df_rets.index[0], df_rets.index[-1]))
99100
plt.ylim((-.40, .40))
100101
plt.title(
101102
'Multi-factor Alpha (vs. Factors: Small-Cap, High-Growth, Momentum)',
@@ -233,22 +234,22 @@ def plot_holdings(df_pos, end_date=None, legend_loc='best'):
233234
alpha=1.0)
234235
if end_date is not None:
235236
plt.xlim((df_holdings.index[0], end_date))
236-
237+
237238
plt.legend(['Daily holdings',
238239
'Average daily holdings, by month',
239240
'Average daily holdings, net'],
240241
loc=legend_loc)
241242
plt.title('# of Holdings Per Day')
242-
243+
243244

244245
def plot_drawdowns(df_rets, df_cum_rets=None, top=10):
245246
df_drawdowns = timeseries.gen_drawdown_table(df_rets)
246-
247+
247248
# df_cum_rets - 1 = cum_returns when startingvalue=None
248-
249+
249250
if df_cum_rets is None:
250251
df_cum_rets = timeseries.cum_returns(df_rets, starting_value=1)
251-
252+
252253
running_max = np.maximum.accumulate(df_cum_rets - 1)
253254
underwater = running_max - (df_cum_rets - 1)
254255
fig, (ax1, ax2) = plt.subplots(nrows=2, figsize=(13, 6))
@@ -273,26 +274,32 @@ def plot_drawdowns(df_rets, df_cum_rets=None, top=10):
273274

274275

275276
def show_perf_stats(df_rets, algo_create_date, benchmark_rets):
276-
df_rets_backtest = df_rets[ df_rets.index < algo_create_date]
277-
df_rets_live = df_rets[ df_rets.index > algo_create_date]
277+
df_rets_backtest = df_rets[df_rets.index < algo_create_date]
278+
df_rets_live = df_rets[df_rets.index > algo_create_date]
278279

279-
print 'Out-of-Sample Months: ' + str( int( len(df_rets_live) / 21) )
280-
print 'Backtest Months: ' + str( int( len(df_rets_backtest) / 21) )
280+
print 'Out-of-Sample Months: ' + str(int(len(df_rets_live) / 21))
281+
print 'Backtest Months: ' + str(int(len(df_rets_backtest) / 21))
281282

282-
perf_stats_backtest = np.round(timeseries.perf_stats(df_rets_backtest, inputIsNAV=False, returns_style='arithmetic'), 2)
283-
perf_stats_backtest_ab = np.round(timeseries.calc_alpha_beta(df_rets_backtest, benchmark_rets), 2)
283+
perf_stats_backtest = np.round(timeseries.perf_stats(
284+
df_rets_backtest, inputIsNAV=False, returns_style='arithmetic'), 2)
285+
perf_stats_backtest_ab = np.round(
286+
timeseries.calc_alpha_beta(df_rets_backtest, benchmark_rets), 2)
284287
perf_stats_backtest.loc['alpha'] = perf_stats_backtest_ab[0]
285288
perf_stats_backtest.loc['beta'] = perf_stats_backtest_ab[1]
286289
perf_stats_backtest.columns = ['Backtest']
287290

288-
perf_stats_live = np.round(timeseries.perf_stats(df_rets_live, inputIsNAV=False, returns_style='arithmetic'), 2)
289-
perf_stats_live_ab = np.round(timeseries.calc_alpha_beta(df_rets_live, benchmark_rets), 2)
291+
perf_stats_live = np.round(timeseries.perf_stats(
292+
df_rets_live, inputIsNAV=False, returns_style='arithmetic'), 2)
293+
perf_stats_live_ab = np.round(
294+
timeseries.calc_alpha_beta(df_rets_live, benchmark_rets), 2)
290295
perf_stats_live.loc['alpha'] = perf_stats_live_ab[0]
291296
perf_stats_live.loc['beta'] = perf_stats_live_ab[1]
292297
perf_stats_live.columns = ['Out_of_Sample']
293298

294-
perf_stats_all = np.round(timeseries.perf_stats(df_rets, inputIsNAV=False, returns_style='arithmetic'), 2)
295-
perf_stats_all_ab = np.round(timeseries.calc_alpha_beta(df_rets, benchmark_rets), 2)
299+
perf_stats_all = np.round(timeseries.perf_stats(
300+
df_rets, inputIsNAV=False, returns_style='arithmetic'), 2)
301+
perf_stats_all_ab = np.round(
302+
timeseries.calc_alpha_beta(df_rets, benchmark_rets), 2)
296303
perf_stats_all.loc['alpha'] = perf_stats_all_ab[0]
297304
perf_stats_all.loc['beta'] = perf_stats_all_ab[1]
298305
perf_stats_all.columns = ['All_History']
@@ -302,15 +309,18 @@ def show_perf_stats(df_rets, algo_create_date, benchmark_rets):
302309

303310
print perf_stats_both
304311

312+
305313
def plot_rolling_returns(df_cum_rets, df_rets, benchmark_rets, benchmark2_rets, algo_create_date, timeseries_input_only=True, legend_loc='best'):
306314
#future_cone_stdev = 1.5
307315

308316
y_axis_formatter = FuncFormatter(utils.one_dec_places)
309-
fig = plt.figure(figsize=(13,8))
317+
fig = plt.figure(figsize=(13, 8))
310318
ax = fig.add_subplot(111)
311319
ax.yaxis.set_major_formatter(FuncFormatter(y_axis_formatter))
312-
timeseries.cum_returns(benchmark_rets[df_cum_rets.index], 1.0).plot(ax=ax, lw=2, color='gray', label='', alpha=0.60)
313-
timeseries.cum_returns(benchmark2_rets[df_cum_rets.index], 1.0).plot(ax=ax, lw=2, color='gray', label='', alpha=0.35)
320+
timeseries.cum_returns(benchmark_rets[df_cum_rets.index], 1.0).plot(
321+
ax=ax, lw=2, color='gray', label='', alpha=0.60)
322+
timeseries.cum_returns(benchmark2_rets[df_cum_rets.index], 1.0).plot(
323+
ax=ax, lw=2, color='gray', label='', alpha=0.35)
314324

315325
if not timeseries_input_only and df_cum_rets.index[-1] <= algo_create_date:
316326
df_cum_rets.plot(lw=3, color='forestgreen', label='', alpha=0.6)
@@ -319,8 +329,10 @@ def plot_rolling_returns(df_cum_rets, df_rets, benchmark_rets, benchmark2_rets,
319329
'Algo backtest'],
320330
loc=legend_loc)
321331
else:
322-
df_cum_rets[:algo_create_date].plot(lw=3, color='forestgreen', label='', alpha=0.6)
323-
df_cum_rets[algo_create_date:].plot(lw=4, color='red', label='', alpha=0.6)
332+
df_cum_rets[:algo_create_date].plot(
333+
lw=3, color='forestgreen', label='', alpha=0.6)
334+
df_cum_rets[algo_create_date:].plot(
335+
lw=4, color='red', label='', alpha=0.6)
324336

325337
#cone_df = timeseries.cone_rolling(df_rets, num_stdev=future_cone_stdev, cone_fit_end_date=algo_create_date)
326338

@@ -333,17 +345,17 @@ def plot_rolling_returns(df_cum_rets, df_rets, benchmark_rets, benchmark2_rets,
333345
#cone_df_live['line'].plot(ls='--', lw=2, color='coral', alpha=0.7)
334346
#cone_df_future['line'].plot(ls='--', lw=2, color='navy', alpha=0.7)
335347

336-
#ax.fill_between(cone_df_live.index,
348+
# ax.fill_between(cone_df_live.index,
337349
# cone_df_live.sd_down,
338350
# cone_df_live.sd_up,
339351
# color='coral', alpha=0.20)
340352

341-
#ax.fill_between(cone_df_future.index,
353+
# ax.fill_between(cone_df_future.index,
342354
# cone_df_future.sd_down,
343355
# cone_df_future.sd_up,
344356
# color='navy', alpha=0.15)
345357

346-
plt.axhline(1.0 , linestyle='--', color='black', lw=2)
358+
plt.axhline(1.0, linestyle='--', color='black', lw=2)
347359
plt.ylabel('Cumulative returns', fontsize=14)
348360
plt.xlim((df_cum_rets.index[0], df_cum_rets.index[-1]))
349361

@@ -359,24 +371,27 @@ def plot_rolling_returns(df_cum_rets, df_rets, benchmark_rets, benchmark2_rets,
359371
'Algo LIVE'],
360372
loc=legend_loc)
361373

374+
362375
def plot_rolling_beta(df_cum_rets, df_rets, benchmark_rets, rolling_beta_window=63, legend_loc='best'):
363376
y_axis_formatter = FuncFormatter(utils.one_dec_places)
364-
fig = plt.figure(figsize=(13,3))
377+
fig = plt.figure(figsize=(13, 3))
365378
ax = fig.add_subplot(111)
366379
ax.yaxis.set_major_formatter(FuncFormatter(y_axis_formatter))
367380

368-
plt.title("Rolling Portfolio Beta to SP500",fontsize=16)
381+
plt.title("Rolling Portfolio Beta to SP500", fontsize=16)
369382
plt.ylabel('beta', fontsize=14)
370-
rb_1 = timeseries.rolling_beta(df_rets, benchmark_rets, rolling_window=rolling_beta_window*2)
383+
rb_1 = timeseries.rolling_beta(
384+
df_rets, benchmark_rets, rolling_window=rolling_beta_window * 2)
371385
rb_1.plot(color='steelblue', lw=3, alpha=0.6, ax=ax)
372-
rb_2 = timeseries.rolling_beta(df_rets, benchmark_rets, rolling_window=rolling_beta_window*3)
386+
rb_2 = timeseries.rolling_beta(
387+
df_rets, benchmark_rets, rolling_window=rolling_beta_window * 3)
373388
rb_2.plot(color='grey', lw=3, alpha=0.4, ax=ax)
374-
plt.xlim( (df_cum_rets.index[0], df_cum_rets.index[-1]) )
389+
plt.xlim((df_cum_rets.index[0], df_cum_rets.index[-1]))
375390
plt.ylim((-2.5, 2.5))
376391
plt.axhline(rb_1.mean(), color='steelblue', linestyle='--', lw=3)
377392
plt.axhline(0.0, color='black', linestyle='-', lw=2)
378393

379-
#plt.fill_between(cone_df_future.index,
394+
# plt.fill_between(cone_df_future.index,
380395
# rb_1.mean() + future_cone_stdev*np.std(rb_1),
381396
# rb_1.mean() - future_cone_stdev*np.std(rb_1),
382397
# color='steelblue', alpha=0.2)
@@ -385,20 +400,23 @@ def plot_rolling_beta(df_cum_rets, df_rets, benchmark_rets, rolling_beta_window=
385400
'12-mo'],
386401
loc=legend_loc)
387402

388-
def plot_rolling_sharp(df_cum_rets, df_rets, rolling_sharpe_window=63*2):
403+
404+
def plot_rolling_sharp(df_cum_rets, df_rets, rolling_sharpe_window=63 * 2):
389405
y_axis_formatter = FuncFormatter(utils.one_dec_places)
390406
fig = plt.figure(figsize=(13, 3))
391407
ax = fig.add_subplot(111)
392408
ax.yaxis.set_major_formatter(FuncFormatter(y_axis_formatter))
393409

394-
rolling_sharpe_ts = timeseries.rolling_sharpe(df_rets, rolling_sharpe_window)
410+
rolling_sharpe_ts = timeseries.rolling_sharpe(
411+
df_rets, rolling_sharpe_window)
395412
rolling_sharpe_ts.plot(alpha=.7, lw=3, color='orangered')
396413
ax.yaxis.set_major_formatter(FuncFormatter(y_axis_formatter))
397414
plt.title('Rolling Sharpe ratio (6-month)', fontsize=16)
398-
plt.axhline(rolling_sharpe_ts.mean(), color='orangered', linestyle='--', lw=3)
415+
plt.axhline(
416+
rolling_sharpe_ts.mean(), color='orangered', linestyle='--', lw=3)
399417
plt.axhline(0.0, color='black', linestyle='-', lw=3)
400418

401-
#plt.fill_between(cone_df_future.index,
419+
# plt.fill_between(cone_df_future.index,
402420
# rolling_sharpe_ts.mean() + future_cone_stdev*np.std(rolling_sharpe_ts),
403421
# rolling_sharpe_ts.mean() - future_cone_stdev*np.std(rolling_sharpe_ts),
404422
# color='orangered', alpha=0.15)
@@ -407,26 +425,33 @@ def plot_rolling_sharp(df_cum_rets, df_rets, rolling_sharpe_window=63*2):
407425
plt.ylim((-3.0, 6.0))
408426
plt.ylabel('Sharpe ratio', fontsize=14)
409427

428+
410429
def plot_gross_leverage(df_cum_rets, gross_lev):
411430
fig = plt.figure(figsize=(13, 3))
412431
gross_lev.plot(alpha=0.8, lw=0.5, color='g', legend=False)
413432
#plt.axhline(0.0, color='black', lw=2)
414-
plt.axhline(np.mean(gross_lev.iloc[:,0]), color='g', linestyle='--', lw=3, alpha=1.0)
415-
plt.xlim( (df_cum_rets.index[0], df_cum_rets.index[-1]) )
433+
plt.axhline(
434+
np.mean(gross_lev.iloc[:, 0]), color='g', linestyle='--', lw=3, alpha=1.0)
435+
plt.xlim((df_cum_rets.index[0], df_cum_rets.index[-1]))
416436
plt.title('Gross Leverage')
417437
plt.ylabel('Gross Leverage', fontsize=14)
418438

439+
419440
def plot_exposures(df_cum_rets, df_pos_alloc):
420441
fig = plt.figure(figsize=(13, 3))
421442
df_long_short = positions.get_long_short_pos(df_pos_alloc)
422-
df_long_short.plot(kind='area', color=['lightblue','green','coral'], alpha=1.0)
423-
plt.xlim( (df_cum_rets.index[0], df_cum_rets.index[-1]) )
443+
df_long_short.plot(
444+
kind='area', color=['lightblue', 'green', 'coral'], alpha=1.0)
445+
plt.xlim((df_cum_rets.index[0], df_cum_rets.index[-1]))
424446
plt.title("Long/Short/Cash Exposure")
425447
plt.ylabel('Exposure', fontsize=14)
426448

449+
427450
def show_and_plot_top_positions(df_cum_rets, df_pos_alloc, show_and_plot=2):
428-
# show_and_plot allows for both showing info and plot, or doing only one. plot:0, show:1, both:2 (default 2).
429-
df_top_long, df_top_short, df_top_abs = positions.get_top_long_short_abs(df_pos_alloc)
451+
# show_and_plot allows for both showing info and plot, or doing only one.
452+
# plot:0, show:1, both:2 (default 2).
453+
df_top_long, df_top_short, df_top_abs = positions.get_top_long_short_abs(
454+
df_pos_alloc)
430455

431456
if show_and_plot == 0 or show_and_plot == 2:
432457
print"\n"
@@ -445,78 +470,94 @@ def show_and_plot_top_positions(df_cum_rets, df_pos_alloc, show_and_plot=2):
445470
print np.round(pd.DataFrame(df_top_abs)[0].values, 3)
446471
print"\n"
447472

448-
_, _, df_top_abs_all = positions.get_top_long_short_abs(df_pos_alloc, top=1000)
473+
_, _, df_top_abs_all = positions.get_top_long_short_abs(
474+
df_pos_alloc, top=1000)
449475
print 'All positions ever held'
450476
print pd.DataFrame(df_top_abs_all).index.values
451477
print np.round(pd.DataFrame(df_top_abs_all)[0].values, 3)
452478
print"\n"
453479

454480
if show_and_plot == 1 or show_and_plot == 2:
455481
fig = plt.figure(figsize=(13, 3))
456-
df_pos_alloc[df_top_abs.index].plot(title='Portfolio allocation over time, only top 10 holdings', alpha=0.4)#kind='area')
482+
df_pos_alloc[df_top_abs.index].plot(
483+
title='Portfolio allocation over time, only top 10 holdings', alpha=0.4) # kind='area')
457484
plt.ylabel('Exposure by Stock', fontsize=14)
458485
# plt.figure(figsize=(13, 6))
459-
plt.xlim( (df_cum_rets.index[0], df_cum_rets.index[-1]) )
486+
plt.xlim((df_cum_rets.index[0], df_cum_rets.index[-1]))
487+
460488

461489
def plot_return_quantiles(df_rets, df_weekly, df_monthly):
462490
fig = plt.figure(figsize=(13, 6))
463-
sns.boxplot([df_rets, df_weekly, df_monthly], names=['daily', 'weekly', 'monthly'])
491+
sns.boxplot([df_rets, df_weekly, df_monthly],
492+
names=['daily', 'weekly', 'monthly'])
464493
plt.title('Return quantiles')
465494

495+
466496
def show_return_range(df_rets, df_weekly):
467-
var_daily = timeseries.var_cov_var_normal(1e7, .05, df_rets.mean(), df_rets.std())
468-
var_weekly = timeseries.var_cov_var_normal(1e7, .05, df_weekly.mean(), df_weekly.std())
469-
two_sigma_daily = df_rets.mean() - 2*df_rets.std()
470-
two_sigma_weekly = df_weekly.mean() - 2*df_weekly.std()
497+
var_daily = timeseries.var_cov_var_normal(
498+
1e7, .05, df_rets.mean(), df_rets.std())
499+
var_weekly = timeseries.var_cov_var_normal(
500+
1e7, .05, df_weekly.mean(), df_weekly.std())
501+
two_sigma_daily = df_rets.mean() - 2 * df_rets.std()
502+
two_sigma_weekly = df_weekly.mean() - 2 * df_weekly.std()
471503

472504
var_sigma = pd.Series([two_sigma_daily, two_sigma_weekly],
473505
index=['2-sigma returns daily', '2-sigma returns weekly'])
474506

475507
print np.round(var_sigma, 3)
476508

509+
477510
def plot_interesting_times(df_rets, benchmark_rets, legend_loc='best'):
478511
rets_interesting = timeseries.extract_interesting_date_ranges(df_rets)
479512
print '\nStress Events'
480-
print np.round(pd.DataFrame(rets_interesting).describe().transpose().loc[:,['mean','min','max']], 3)
513+
print np.round(pd.DataFrame(rets_interesting).describe().transpose().loc[:, ['mean', 'min', 'max']], 3)
481514

482-
bmark_interesting = timeseries.extract_interesting_date_ranges(benchmark_rets)
515+
bmark_interesting = timeseries.extract_interesting_date_ranges(
516+
benchmark_rets)
483517

484-
fig = plt.figure(figsize=(31,19))
518+
fig = plt.figure(figsize=(31, 19))
485519
for i, (name, rets_period) in enumerate(rets_interesting.iteritems()):
486-
ax = fig.add_subplot(6, 3, i+1)
487-
timeseries.cum_returns(rets_period).plot(ax=ax, color='forestgreen', label='algo', alpha=0.7, lw=2)
488-
timeseries.cum_returns(bmark_interesting[name]).plot(ax=ax, color='gray', label='SPY', alpha=0.6)
520+
ax = fig.add_subplot(6, 3, i + 1)
521+
timeseries.cum_returns(rets_period).plot(
522+
ax=ax, color='forestgreen', label='algo', alpha=0.7, lw=2)
523+
timeseries.cum_returns(bmark_interesting[name]).plot(
524+
ax=ax, color='gray', label='SPY', alpha=0.6)
489525
plt.legend(['algo',
490526
'SPY'],
491527
loc=legend_loc)
492528
ax.set_title(name, size=14)
493529
ax.set_ylabel('', size=12)
494530
ax.legend()
495531

532+
496533
def plot_turnover(df_cum_rets, df_txn, df_pos_val, legend_loc='best'):
497534
fig = plt.figure(figsize=(13, 4))
498535
df_turnover = df_txn.txn_volume / df_pos_val.abs().sum(axis='columns')
499536
df_turnover_by_month = df_turnover.resample('1M', how='mean')
500537
df_turnover.plot(color='steelblue', alpha=1.0, lw=0.5)
501538
df_turnover_by_month.plot(color='orangered', alpha=0.5, lw=2)
502-
plt.axhline(df_turnover.mean(), color='steelblue', linestyle='--', lw=3, alpha=1.0)
539+
plt.axhline(
540+
df_turnover.mean(), color='steelblue', linestyle='--', lw=3, alpha=1.0)
503541
plt.legend(['Daily turnover',
504542
'Average daily turnover, by month',
505543
'Average daily turnover, net'],
506544
loc=legend_loc)
507545
plt.title('Daily turnover')
508-
plt.xlim( (df_cum_rets.index[0], df_cum_rets.index[-1]) )
546+
plt.xlim((df_cum_rets.index[0], df_cum_rets.index[-1]))
509547
plt.ylim((0, 1))
510548
plt.ylabel('% turn-over')
511549

550+
512551
def plot_daily_volume(df_cum_rets, df_txn):
513552
fig = plt.figure(figsize=(13, 4))
514553
df_txn.txn_shares.plot(alpha=1.0, lw=0.5)
515-
plt.axhline(df_txn.txn_shares.mean(), color='steelblue', linestyle='--', lw=3, alpha=1.0)
554+
plt.axhline(df_txn.txn_shares.mean(), color='steelblue',
555+
linestyle='--', lw=3, alpha=1.0)
516556
plt.title('Daily volume traded')
517-
plt.xlim( (df_cum_rets.index[0], df_cum_rets.index[-1]) )
557+
plt.xlim((df_cum_rets.index[0], df_cum_rets.index[-1]))
518558
plt.ylabel('# shares traded')
519559

560+
520561
def plot_volume_per_day_hist(df_txn):
521562
fig = plt.figure(figsize=(13, 4))
522563
sns.distplot(df_txn.txn_volume)

0 commit comments

Comments
 (0)