From 93ad1ff3093d586326a4462aed81291c8bbc449e Mon Sep 17 00:00:00 2001 From: Derek Wong Date: Wed, 4 Dec 2019 04:29:31 +0000 Subject: [PATCH 1/5] change to capacity.py changed the indexer market_data[price] to the .xs of multilevel indexing using .xs(price, level = market_data. also replaced deprecated pd.timeGrouper with pd.Grouper(freq=D) --- pyfolio/capacity.py | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/pyfolio/capacity.py b/pyfolio/capacity.py index 00864741..5191c479 100644 --- a/pyfolio/capacity.py +++ b/pyfolio/capacity.py @@ -18,10 +18,9 @@ def daily_txns_with_bar_data(transactions, market_data): transactions : pd.DataFrame Prices and amounts of executed trades. One row per trade. - See full explanation in tears.create_full_tear_sheet - market_data : pd.DataFrame - Daily market_data - - DataFrame has a multi-index index, one level is dates and another is - market_data contains volume & price, equities as columns + market_data : pd.Panel + Contains "volume" and "price" DataFrames for the tickers + in the passed positions DataFrames Returns ------- @@ -35,8 +34,9 @@ def daily_txns_with_bar_data(transactions, market_data): txn_daily = pd.DataFrame(transactions.assign( amount=abs(transactions.amount)).groupby( ['symbol', pd.Grouper(freq='D')]).sum()['amount']) - txn_daily['price'] = market_data.xs('price', level=1).unstack() - txn_daily['volume'] = market_data.xs('volume', level=1).unstack() + # ['symbol', pd.TimeGrouper('D')]).sum()['amount']) + txn_daily['price'] = market_data.xs('price', level='market_data').unstack() + txn_daily['volume'] = market_data.xs('volume', level='market_data').unstack() txn_daily = txn_daily.reset_index().set_index('date') @@ -64,10 +64,10 @@ def days_to_liquidate_positions(positions, market_data, positions: pd.DataFrame Contains daily position values including cash - See full explanation in tears.create_full_tear_sheet - market_data : pd.DataFrame - Daily market_data - - DataFrame has a multi-index index, one level is dates and another is - market_data contains volume & price, equities as columns + 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. @@ -84,7 +84,8 @@ def days_to_liquidate_positions(positions, market_data, Datetime index, symbols as columns. """ - DV = market_data.xs('volume', level=1) * market_data.xs('price', level=1) + # DV = market_data['volume'] * market_data['price'] + DV = market_data.xs('volume', level='market_data') * market_data.xs('price', level='market_data') roll_mean_dv = DV.rolling(window=mean_volume_window, center=False).mean().shift() roll_mean_dv = roll_mean_dv.replace(0, np.nan) @@ -112,10 +113,10 @@ def get_max_days_to_liquidate_by_ticker(positions, market_data, positions: pd.DataFrame Contains daily position values including cash - See full explanation in tears.create_full_tear_sheet - market_data : pd.DataFrame - Daily market_data - - DataFrame has a multi-index index, one level is dates and another is - market_data contains volume & price, equities as columns + 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. @@ -169,10 +170,10 @@ def get_low_liquidity_transactions(transactions, market_data, transactions : pd.DataFrame Prices and amounts of executed trades. One row per trade. - See full explanation in create_full_tear_sheet. - market_data : pd.DataFrame - Daily market_data - - DataFrame has a multi-index index, one level is dates and another is - market_data contains volume & price, equities as columns + 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. """ From 8042bed796ff3cb0b09ddd2cb771acfe3778777a Mon Sep 17 00:00:00 2001 From: Derek Wong Date: Wed, 4 Dec 2019 04:40:49 +0000 Subject: [PATCH 2/5] removedsome comments / formatting --- pyfolio/capacity.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pyfolio/capacity.py b/pyfolio/capacity.py index 5191c479..9742de12 100644 --- a/pyfolio/capacity.py +++ b/pyfolio/capacity.py @@ -34,7 +34,6 @@ def daily_txns_with_bar_data(transactions, market_data): txn_daily = pd.DataFrame(transactions.assign( amount=abs(transactions.amount)).groupby( ['symbol', pd.Grouper(freq='D')]).sum()['amount']) - # ['symbol', pd.TimeGrouper('D')]).sum()['amount']) txn_daily['price'] = market_data.xs('price', level='market_data').unstack() txn_daily['volume'] = market_data.xs('volume', level='market_data').unstack() From 97f95ff1d31dbfd2fd46a1cdb0b310f9b86de7a0 Mon Sep 17 00:00:00 2001 From: Derek Wong Date: Thu, 5 Dec 2019 02:24:38 +0000 Subject: [PATCH 3/5] updated PEP 8 errors based on TRAVIS CI fail --- .idea/.gitignore | 2 ++ .idea/inspectionProfiles/profiles_settings.xml | 6 ++++++ .idea/misc.xml | 4 ++++ .idea/modules.xml | 8 ++++++++ .idea/pyfolio.iml | 15 +++++++++++++++ .idea/vcs.xml | 6 ++++++ pyfolio/capacity.py | 9 ++++----- 7 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/pyfolio.iml create mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..e7e9d11d --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,2 @@ +# Default ignored files +/workspace.xml diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 00000000..105ce2da --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 00000000..939579a1 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..fd51b2a1 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/pyfolio.iml b/.idea/pyfolio.iml new file mode 100644 index 00000000..fee24300 --- /dev/null +++ b/.idea/pyfolio.iml @@ -0,0 +1,15 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..94a25f7f --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/pyfolio/capacity.py b/pyfolio/capacity.py index 9742de12..0330a88a 100644 --- a/pyfolio/capacity.py +++ b/pyfolio/capacity.py @@ -83,7 +83,6 @@ def days_to_liquidate_positions(positions, market_data, Datetime index, symbols as columns. """ - # DV = market_data['volume'] * market_data['price'] DV = market_data.xs('volume', level='market_data') * market_data.xs('price', level='market_data') roll_mean_dv = DV.rolling(window=mean_volume_window, center=False).mean().shift() @@ -93,7 +92,7 @@ def days_to_liquidate_positions(positions, market_data, positions_alloc = positions_alloc.drop('cash', axis=1) days_to_liquidate = (positions_alloc * capital_base) / \ - (max_bar_consumption * roll_mean_dv) + (max_bar_consumption * roll_mean_dv) return days_to_liquidate.iloc[mean_volume_window:] @@ -187,7 +186,7 @@ def get_low_liquidity_transactions(transactions, market_data, bar_consumption = txn_daily_w_bar.assign( max_pct_bar_consumed=( - txn_daily_w_bar.amount/txn_daily_w_bar.volume)*100 + 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() @@ -228,8 +227,8 @@ def apply_slippage_penalty(returns, txn_daily, simulate_starting_capital, 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 + 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) From 8992fd1f3c5f3e26d4ce72c821e3106296082a89 Mon Sep 17 00:00:00 2001 From: Derek Wong Date: Thu, 5 Dec 2019 02:37:44 +0000 Subject: [PATCH 4/5] line wrap at 79 --- .idea/.gitignore | 2 -- .idea/inspectionProfiles/profiles_settings.xml | 6 ------ .idea/misc.xml | 4 ---- .idea/modules.xml | 8 -------- .idea/pyfolio.iml | 15 --------------- .idea/vcs.xml | 6 ------ pyfolio/capacity.py | 10 ++++++---- 7 files changed, 6 insertions(+), 45 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/inspectionProfiles/profiles_settings.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/pyfolio.iml delete mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index e7e9d11d..00000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# Default ignored files -/workspace.xml diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 105ce2da..00000000 --- a/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 939579a1..00000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index fd51b2a1..00000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/pyfolio.iml b/.idea/pyfolio.iml deleted file mode 100644 index fee24300..00000000 --- a/.idea/pyfolio.iml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7f..00000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/pyfolio/capacity.py b/pyfolio/capacity.py index 0330a88a..9c167cd8 100644 --- a/pyfolio/capacity.py +++ b/pyfolio/capacity.py @@ -35,7 +35,8 @@ def daily_txns_with_bar_data(transactions, market_data): amount=abs(transactions.amount)).groupby( ['symbol', pd.Grouper(freq='D')]).sum()['amount']) txn_daily['price'] = market_data.xs('price', level='market_data').unstack() - txn_daily['volume'] = market_data.xs('volume', level='market_data').unstack() + txn_daily['volume'] = market_data.xs('volume', + level='market_data').unstack() txn_daily = txn_daily.reset_index().set_index('date') @@ -83,7 +84,8 @@ def days_to_liquidate_positions(positions, market_data, Datetime index, symbols as columns. """ - DV = market_data.xs('volume', level='market_data') * market_data.xs('price', level='market_data') + DV = market_data.xs('volume', level='market_data') * \ + market_data.xs('price', level='market_data') roll_mean_dv = DV.rolling(window=mean_volume_window, center=False).mean().shift() roll_mean_dv = roll_mean_dv.replace(0, np.nan) @@ -185,8 +187,8 @@ def get_low_liquidity_transactions(transactions, market_data, 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 + 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() From 37fce06e30c5a076f3fc210b73512d2ff4e7f1b0 Mon Sep 17 00:00:00 2001 From: Derek Wong Date: Thu, 5 Dec 2019 02:46:46 +0000 Subject: [PATCH 5/5] over indenting --- pyfolio/capacity.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pyfolio/capacity.py b/pyfolio/capacity.py index 9c167cd8..bce1ba2e 100644 --- a/pyfolio/capacity.py +++ b/pyfolio/capacity.py @@ -84,9 +84,10 @@ def days_to_liquidate_positions(positions, market_data, Datetime index, symbols as columns. """ - DV = market_data.xs('volume', level='market_data') * \ + dv = market_data.xs('volume', level='market_data') * \ market_data.xs('price', level='market_data') - roll_mean_dv = DV.rolling(window=mean_volume_window, + + roll_mean_dv = dv.rolling(window=mean_volume_window, center=False).mean().shift() roll_mean_dv = roll_mean_dv.replace(0, np.nan) @@ -229,8 +230,8 @@ def apply_slippage_penalty(returns, txn_daily, simulate_starting_capital, 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 + 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)