mirror of
https://github.com/wassname/options_backtester.git
synced 2026-08-17 11:23:12 +08:00
382 KiB
382 KiB
In [1]:
import os
import sys
from pathlib import Path
BACKTESTER_DIR = Path(".").resolve().parent.parent
DATA_DIR = BACKTESTER_DIR / '../mori_opt_earnings/data/interim/optm_lz/opprcd'
print(DATA_DIR)
OPTIONS_DATA = os.path.join(DATA_DIR, 'SPX_2017.csv')
STOCKS_DATA = os.path.join(DATA_DIR, 'portfolio_data_2017.csv')
sys.path.append(BACKTESTER_DIR) # Add backtester base dir to $PYTHONPATH/media/wassname/SGIronWolf/projects5/investing/options/options_backtester/../mori_opt_earnings/data/interim/optm_lz/opprcd
In [2]:
%load_ext autoreload
%autoreload 2In [3]:
import pyfolio as pf
import matplotlib.pyplot as plt
from backtester import Backtest
from backtester.strategy import Strategy, StrategyLeg
from backtester.enums import Type, Direction, Stock
from backtester.datahandler import HistoricalOptionsData, TiingoData, Schema, OptionMetricsData
from backtester.statistics import monthly_returns_heatmap, returns_histogram, returns_chartWARNING (theano.link.c.cmodule): install mkl with `conda install mkl-service`: No module named 'mkl'
In [4]:
plt.style.use("seaborn")
plt.rcParams["figure.figsize"] = (14, 8)In [5]:
# %env TIINGO_API_KEY=your_tiingo_api_key
from dotenv import load_dotenv
import os
load_dotenv()Out [5]:
True
In [6]:
import datetime
import pandas_datareader as pdr
# restricting to 1996-01-04 00:00:00 2019-06-28 00:00:00
api_key = os.environ["TIINGO_API_KEY"]
start = datetime.datetime(1996, 1, 4)
end = datetime.datetime(2019, 6, 28)
tickers = ["MSFT", "AAPL", "XOM"] #, "TUR", "RSX", "EWY", "EWS", "VTIP", "TLT", "BWX", "PDBC", "IAU", "VNQI"]
symbols = pdr.get_data_tiingo(tickers, api_key=api_key, start=start, end=end)
symbolsOut [6]:
/home/wassname/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/pandas_datareader/tiingo.py:234: FutureWarning: In a future version of pandas all arguments of concat except for the argument 'objs' will be keyword-only return pd.concat(dfs, self._concat_axis)
| close | high | low | open | volume | adjClose | adjHigh | adjLow | adjOpen | adjVolume | divCash | splitFactor | ||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| symbol | date | ||||||||||||
| MSFT | 1996-01-04 00:00:00+00:00 | 87.37 | 87.50 | 84.87 | 87.25 | 6397100 | 3.439386 | 3.444504 | 3.340972 | 3.434662 | 102353600 | 0.0 | 1.0 |
| 1996-01-05 00:00:00+00:00 | 86.37 | 87.62 | 86.12 | 86.25 | 3880200 | 3.400020 | 3.449227 | 3.390179 | 3.395296 | 62083200 | 0.0 | 1.0 | |
| 1996-01-08 00:00:00+00:00 | 86.25 | 87.62 | 86.12 | 86.50 | 711100 | 3.395296 | 3.449227 | 3.390179 | 3.405138 | 11377600 | 0.0 | 1.0 | |
| 1996-01-09 00:00:00+00:00 | 80.19 | 86.00 | 79.87 | 86.00 | 11089000 | 3.156740 | 3.385455 | 3.144143 | 3.385455 | 177424000 | 0.0 | 1.0 | |
| 1996-01-10 00:00:00+00:00 | 82.37 | 83.25 | 80.48 | 80.50 | 11348200 | 3.242557 | 3.277199 | 3.168156 | 3.168943 | 181571200 | 0.0 | 1.0 | |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| XOM | 2019-06-24 00:00:00+00:00 | 76.95 | 77.76 | 76.81 | 77.53 | 10012236 | 64.097147 | 64.771854 | 63.980531 | 64.580270 | 10012236 | 0.0 | 1.0 |
| 2019-06-25 00:00:00+00:00 | 76.27 | 77.22 | 76.19 | 77.08 | 9739970 | 63.530727 | 64.322049 | 63.464089 | 64.205433 | 9739970 | 0.0 | 1.0 | |
| 2019-06-26 00:00:00+00:00 | 76.60 | 77.13 | 76.47 | 76.68 | 11365476 | 63.805607 | 64.247082 | 63.697321 | 63.872245 | 11365476 | 0.0 | 1.0 | |
| 2019-06-27 00:00:00+00:00 | 75.82 | 76.75 | 75.76 | 76.59 | 8147803 | 63.155889 | 63.930553 | 63.105911 | 63.797277 | 8147803 | 0.0 | 1.0 | |
| 2019-06-28 00:00:00+00:00 | 76.63 | 76.73 | 75.94 | 76.19 | 14781298 | 63.830596 | 63.913893 | 63.255846 | 63.464089 | 14781298 | 0.0 | 1.0 |
17736 rows × 12 columns
In [7]:
save_path = os.path.join(DATA_DIR, 'portfolio_data_2017.csv')
symbols.to_csv(save_path)In [ ]:
In [8]:
stock_data = TiingoData(STOCKS_DATA)
# remove tz
stock_data['date']=stock_data['date'].dt.tz_localize(None)
stock_data.start_date=stock_data.start_date.tz_localize(None)
stock_data.end_date=stock_data.end_date.tz_localize(None)
stock_data.head()Out [8]:
| symbol | date | close | high | low | open | volume | adjClose | adjHigh | adjLow | adjOpen | adjVolume | divCash | splitFactor | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | MSFT | 1996-01-04 | 87.37 | 87.50 | 84.87 | 87.25 | 6397100 | 3.439386 | 3.444504 | 3.340972 | 3.434662 | 102353600 | 0.0 | 1.0 |
| 1 | MSFT | 1996-01-05 | 86.37 | 87.62 | 86.12 | 86.25 | 3880200 | 3.400020 | 3.449227 | 3.390179 | 3.395296 | 62083200 | 0.0 | 1.0 |
| 2 | MSFT | 1996-01-08 | 86.25 | 87.62 | 86.12 | 86.50 | 711100 | 3.395296 | 3.449227 | 3.390179 | 3.405138 | 11377600 | 0.0 | 1.0 |
| 3 | MSFT | 1996-01-09 | 80.19 | 86.00 | 79.87 | 86.00 | 11089000 | 3.156740 | 3.385455 | 3.144143 | 3.385455 | 177424000 | 0.0 | 1.0 |
| 4 | MSFT | 1996-01-10 | 82.37 | 83.25 | 80.48 | 80.50 | 11348200 | 3.242557 | 3.277199 | 3.168156 | 3.168943 | 181571200 | 0.0 | 1.0 |
In [9]:
MSFT = Stock('MSFT', 0.3)
AAPL = Stock('AAPL', 0.3)
XOM = Stock('XOM', 0.4)
# EWY = Stock('EWY', 0.05)
# EWS = Stock('EWS', 0.05)
# VTIP = Stock('VTIP', 0.10)
# TLT = Stock('TLT', 0.20)
# BWX = Stock('BWX', 0.10)
# PDBC = Stock('PDBC', 0.05)
# IAU = Stock('IAU', 0.15)
# VNQI = Stock('VNQI', 0.10)In [10]:
0.10 + 0.05 + 0.05 + 0.05 + 0.05 + 0.10 + 0.20 + 0.10 + 0.05 + 0.15 + 0.10Out [10]:
1.0000000000000002
In [11]:
stocks = [
MSFT,
AAPL,
XOM,
# EWY,
# EWS,
# VTIP,
# TLT,
# BWX,
# PDBC,
# IAU,
# VNQI
]In [12]:
options_schema = Schema.options()
options_schema.update({
'underlying': 'stock',
'contract': 'optionroot',
'date': 'quotedate'})
options_schemaOut [12]:
Schema([Field(name='underlying', mapping='stock'), Field(name='underlying_last', mapping='underlying_last'), Field(name='date', mapping='quotedate'), Field(name='contract', mapping='optionroot'), Field(name='type', mapping='type'), Field(name='expiration', mapping='expiration'), Field(name='strike', mapping='strike'), Field(name='bid', mapping='bid'), Field(name='ask', mapping='ask'), Field(name='volume', mapping='volume'), Field(name='open_interest', mapping='open_interest')])
In [13]:
options_data = OptionMetricsData(["MSFT", "AAPL", "XOM"], schema=None)
schema = options_data.schema
options_data.head()Out [13]:
| date | symbol | symbol_flag | exdate | last_date | cp_flag | strike_price | best_bid | best_offer | volume | ... | am_settlement | contract_size | ss_flag | forward_price | expiry_indicator | root | suffix | secid | ticker | dte | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1996-01-04 | 09D05.1F | 0 | 1996-01-20 | NaT | P | 55000.0 | 0.000 | 0.0625 | 0.0 | ... | 0.0 | 100.0 | 0 | 87.580727 | 09D05 | 1F | 107525.0 | MSFT | 16 | |
| 1 | 1996-01-04 | 09907.E9 | 0 | 1996-02-17 | 1996-01-04 | C | 80000.0 | 9.375 | 9.7500 | 2.0 | ... | 0.0 | 100.0 | 0 | 87.960975 | 09907 | E9 | 107525.0 | MSFT | 44 | |
| 2 | 1996-01-04 | 09E5B.96 | 0 | 1996-07-20 | 1996-01-04 | C | 80000.0 | 14.250 | 14.7500 | 1.0 | ... | 0.0 | 100.0 | 0 | 89.972692 | 09E5B | 96 | 107525.0 | MSFT | 198 | |
| 3 | 1996-01-04 | 09D7E.EF | 0 | 1997-01-18 | NaT | P | 70000.0 | 3.125 | 3.5000 | 0.0 | ... | 0.0 | 100.0 | 0 | 92.275048 | 09D7E | EF | 107525.0 | MSFT | 380 | |
| 4 | 1996-01-04 | 09EF9.89 | 0 | 1996-04-20 | 1996-01-04 | C | 90000.0 | 6.500 | 6.8750 | 135.0 | ... | 0.0 | 100.0 | 0 | 88.796785 | 09EF9 | 89 | 107525.0 | MSFT | 107 |
5 rows × 28 columns
In [14]:
options_data.ticker.unique()Out [14]:
array(['MSFT', 'AAPL', 'XOM'], dtype=object)
In [15]:
# d0 = max(options_data['date'].min(), stock_data['date'].min())
# d1 = min(options_data['date'].max(), stock_data['date'].max())
# print("restricting to", d0, d1)
# stock_data = stock_data[(stock_data.date <= d1) & (stock_data.date >= d0)]
date_col = stock_data.schema['date']
stock_data.start_date = stock_data._data[date_col].min()
stock_data.end_date = stock_data._data[date_col].max()
# # remove tz
# stock_data['date']=stock_data.date.dt.tz_localize(None)
# stock_data.head()
# # options_data._data = options_data_data[(options_data.date <= d1) & (options_data.date >= d0)]In [16]:
long_straddle = Strategy(schema)In [17]:
leg1 = StrategyLeg("leg_1", schema, option_type=Type.CALL, direction=Direction.BUY)
leg2 = StrategyLeg("leg_2", schema, option_type=Type.PUT, direction=Direction.BUY)In [18]:
# options_data.head()In [19]:
leg1.entry_filter = (schema.dte >= 31) & (schema.dte <= 60) & (schema.strike >= schema.underlying_last * 0.95) & (schema.strike <= schema.underlying_last * 1.05)
leg2.entry_filter = (schema.dte >= 31) & (schema.dte <= 60) & (schema.strike >= schema.underlying_last * 0.95) & (schema.strike <= schema.underlying_last * 1.05)
leg1.exit_filter = (schema.dte <= 60)
leg2.exit_filter = (schema.dte <= 60)
long_straddle.add_legs([leg1, leg2]);In [20]:
# leg1.entry_filter = (schema.underlying == "SPX") & (schema.dte >= 31) & (schema.dte <= 60) & (schema.strike >= schema.underlying_last * 0.95) & (schema.strike <= schema.underlying_last * 1.05)
# leg2.entry_filter = (schema.underlying == "SPX") & (schema.dte >= 31) & (schema.dte <= 60) & (schema.strike >= schema.underlying_last * 0.95) & (schema.strike <= schema.underlying_last * 1.05)
# leg1.exit_filter = (schema.dte <= 60)
# leg2.exit_filter = (schema.dte <= 60)
# long_straddle.add_legs([leg1, leg2]);In [21]:
stocksOut [21]:
[Stock(symbol='MSFT', percentage=0.3), Stock(symbol='AAPL', percentage=0.3), Stock(symbol='XOM', percentage=0.4)]
In [41]:
bt = Backtest({'stocks': 0.5, 'options': 0.5, 'cash': 0})
bt.stocks = stocks
bt.options_strategy = long_straddle
bt.options_data = options_data
bt.stocks_data = stock_dataIn [42]:
options_data['date'].unique()Out [42]:
array(['1996-01-04T00:00:00.000000000', '1996-01-05T00:00:00.000000000',
'1996-01-08T00:00:00.000000000', ...,
'2019-06-26T00:00:00.000000000', '2019-06-27T00:00:00.000000000',
'2019-06-28T00:00:00.000000000'], dtype='datetime64[ns]')In [43]:
stock_data['date'].unique()
stock_data.start_dateOut [43]:
Timestamp('1996-01-04 00:00:00')In [44]:
bt.run(rebalance_freq=1)Out [44]:
0% [██████████████████████████████] 100% | ETA: 00:00:00 Total time elapsed: 00:00:31
| leg_1 | leg_2 | totals | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| contract | underlying | expiration | type | strike | cost | order | contract | underlying | expiration | type | strike | cost | order | cost | qty | date | |
In [ ]:
In [ ]:
In [45]:
bt.balanceOut [45]:
| total capital | cash | MSFT | AAPL | XOM | options qty | calls capital | puts capital | stocks qty | MSFT qty | AAPL qty | XOM qty | options capital | stocks capital | % change | accumulated return | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1996-01-03 | 1.000000e+06 | 1.000000e+06 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0.0 | 0.000000e+00 | NaN | NaN |
| 1996-01-04 | 1.000000e+06 | 5.000041e+05 | 1.499985e+05 | 1.499999e+05 | 1.999975e+05 | 0.0 | 0.0 | 0.0 | 688386.0 | 43612.0 | 622655.0 | 22119.0 | 0.0 | 4.999959e+05 | 0.000000 | 1.000000 |
| 1996-01-05 | 1.015984e+06 | 5.000041e+05 | 1.482817e+05 | 1.627850e+05 | 2.049133e+05 | 0.0 | 0.0 | 0.0 | 688386.0 | 43612.0 | 622655.0 | 22119.0 | 0.0 | 5.159800e+05 | 0.015984 | 1.015984 |
| 1996-01-08 | 1.020042e+06 | 5.000041e+05 | 1.480757e+05 | 1.645911e+05 | 2.073712e+05 | 0.0 | 0.0 | 0.0 | 688386.0 | 43612.0 | 622655.0 | 22119.0 | 0.0 | 5.200379e+05 | 0.003994 | 1.020042 |
| 1996-01-09 | 9.967210e+05 | 5.000041e+05 | 1.376717e+05 | 1.556558e+05 | 2.033894e+05 | 0.0 | 0.0 | 0.0 | 688386.0 | 43612.0 | 622655.0 | 22119.0 | 0.0 | 4.967169e+05 | -0.022863 | 0.996721 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 2019-06-21 | 8.976873e+06 | 4.235908e+06 | 1.452253e+06 | 1.457513e+06 | 1.831199e+06 | 0.0 | 0.0 | 0.0 | 69275.0 | 10928.0 | 30050.0 | 28297.0 | 0.0 | 4.740965e+06 | 0.002309 | 8.976873 |
| 2019-06-24 | 8.966552e+06 | 4.235908e+06 | 1.460841e+06 | 1.456047e+06 | 1.813757e+06 | 0.0 | 0.0 | 0.0 | 69275.0 | 10928.0 | 30050.0 | 28297.0 | 0.0 | 4.730644e+06 | -0.001150 | 8.966552 |
| 2019-06-25 | 8.882332e+06 | 4.235908e+06 | 1.414719e+06 | 1.433976e+06 | 1.797729e+06 | 0.0 | 0.0 | 0.0 | 69275.0 | 10928.0 | 30050.0 | 28297.0 | 0.0 | 4.646424e+06 | -0.009393 | 8.882332 |
| 2019-06-26 | 8.926428e+06 | 4.235908e+06 | 1.420020e+06 | 1.464992e+06 | 1.805507e+06 | 0.0 | 0.0 | 0.0 | 69275.0 | 10928.0 | 30050.0 | 28297.0 | 0.0 | 4.690520e+06 | 0.004964 | 8.926428 |
| 2019-06-27 | 8.909935e+06 | 4.235908e+06 | 1.422353e+06 | 1.464552e+06 | 1.787122e+06 | 0.0 | 0.0 | 0.0 | 69275.0 | 10928.0 | 30050.0 | 28297.0 | 0.0 | 4.674027e+06 | -0.001848 | 8.909935 |
5912 rows × 16 columns
In [46]:
bt.balance['total capital'].plot();In [47]:
bt.balance[[stock.symbol for stock in stocks]].plot();In [48]:
returns_chart(bt.balance)Out [48]:
[0;31m---------------------------------------------------------------------------[0m
[0;31mMaxRowsError[0m Traceback (most recent call last)
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/altair/vegalite/v4/api.py[0m in [0;36mto_dict[0;34m(self, *args, **kwargs)[0m
[1;32m 372[0m [0mcopy[0m [0;34m=[0m [0mself[0m[0;34m.[0m[0mcopy[0m[0;34m([0m[0mdeep[0m[0;34m=[0m[0;32mFalse[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[1;32m 373[0m [0moriginal_data[0m [0;34m=[0m [0mgetattr[0m[0;34m([0m[0mcopy[0m[0;34m,[0m [0;34m"data"[0m[0;34m,[0m [0mUndefined[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0;32m--> 374[0;31m [0mcopy[0m[0;34m.[0m[0mdata[0m [0;34m=[0m [0m_prepare_data[0m[0;34m([0m[0moriginal_data[0m[0;34m,[0m [0mcontext[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 375[0m [0;34m[0m[0m
[1;32m 376[0m [0;32mif[0m [0moriginal_data[0m [0;32mis[0m [0;32mnot[0m [0mUndefined[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/altair/vegalite/v4/api.py[0m in [0;36m_prepare_data[0;34m(data, context)[0m
[1;32m 87[0m [0;31m# convert dataframes or objects with __geo_interface__ to dict[0m[0;34m[0m[0;34m[0m[0;34m[0m[0m
[1;32m 88[0m [0;32mif[0m [0misinstance[0m[0;34m([0m[0mdata[0m[0;34m,[0m [0mpd[0m[0;34m.[0m[0mDataFrame[0m[0;34m)[0m [0;32mor[0m [0mhasattr[0m[0;34m([0m[0mdata[0m[0;34m,[0m [0;34m"__geo_interface__"[0m[0;34m)[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[0;32m---> 89[0;31m [0mdata[0m [0;34m=[0m [0m_pipe[0m[0;34m([0m[0mdata[0m[0;34m,[0m [0mdata_transformers[0m[0;34m.[0m[0mget[0m[0;34m([0m[0;34m)[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 90[0m [0;34m[0m[0m
[1;32m 91[0m [0;31m# convert string input to a URLData[0m[0;34m[0m[0;34m[0m[0;34m[0m[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/toolz/functoolz.py[0m in [0;36mpipe[0;34m(data, *funcs)[0m
[1;32m 628[0m """
[1;32m 629[0m [0;32mfor[0m [0mfunc[0m [0;32min[0m [0mfuncs[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[0;32m--> 630[0;31m [0mdata[0m [0;34m=[0m [0mfunc[0m[0;34m([0m[0mdata[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 631[0m [0;32mreturn[0m [0mdata[0m[0;34m[0m[0;34m[0m[0m
[1;32m 632[0m [0;34m[0m[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/toolz/functoolz.py[0m in [0;36m__call__[0;34m(self, *args, **kwargs)[0m
[1;32m 304[0m [0;32mdef[0m [0m__call__[0m[0;34m([0m[0mself[0m[0;34m,[0m [0;34m*[0m[0margs[0m[0;34m,[0m [0;34m**[0m[0mkwargs[0m[0;34m)[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[1;32m 305[0m [0;32mtry[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[0;32m--> 306[0;31m [0;32mreturn[0m [0mself[0m[0;34m.[0m[0m_partial[0m[0;34m([0m[0;34m*[0m[0margs[0m[0;34m,[0m [0;34m**[0m[0mkwargs[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 307[0m [0;32mexcept[0m [0mTypeError[0m [0;32mas[0m [0mexc[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[1;32m 308[0m [0;32mif[0m [0mself[0m[0;34m.[0m[0m_should_curry[0m[0;34m([0m[0margs[0m[0;34m,[0m [0mkwargs[0m[0;34m,[0m [0mexc[0m[0;34m)[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/altair/vegalite/data.py[0m in [0;36mdefault_data_transformer[0;34m(data, max_rows)[0m
[1;32m 17[0m [0;34m@[0m[0mcurried[0m[0;34m.[0m[0mcurry[0m[0;34m[0m[0;34m[0m[0m
[1;32m 18[0m [0;32mdef[0m [0mdefault_data_transformer[0m[0;34m([0m[0mdata[0m[0;34m,[0m [0mmax_rows[0m[0;34m=[0m[0;36m5000[0m[0;34m)[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[0;32m---> 19[0;31m [0;32mreturn[0m [0mcurried[0m[0;34m.[0m[0mpipe[0m[0;34m([0m[0mdata[0m[0;34m,[0m [0mlimit_rows[0m[0;34m([0m[0mmax_rows[0m[0;34m=[0m[0mmax_rows[0m[0;34m)[0m[0;34m,[0m [0mto_values[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 20[0m [0;34m[0m[0m
[1;32m 21[0m [0;34m[0m[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/toolz/functoolz.py[0m in [0;36mpipe[0;34m(data, *funcs)[0m
[1;32m 628[0m """
[1;32m 629[0m [0;32mfor[0m [0mfunc[0m [0;32min[0m [0mfuncs[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[0;32m--> 630[0;31m [0mdata[0m [0;34m=[0m [0mfunc[0m[0;34m([0m[0mdata[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 631[0m [0;32mreturn[0m [0mdata[0m[0;34m[0m[0;34m[0m[0m
[1;32m 632[0m [0;34m[0m[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/toolz/functoolz.py[0m in [0;36m__call__[0;34m(self, *args, **kwargs)[0m
[1;32m 304[0m [0;32mdef[0m [0m__call__[0m[0;34m([0m[0mself[0m[0;34m,[0m [0;34m*[0m[0margs[0m[0;34m,[0m [0;34m**[0m[0mkwargs[0m[0;34m)[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[1;32m 305[0m [0;32mtry[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[0;32m--> 306[0;31m [0;32mreturn[0m [0mself[0m[0;34m.[0m[0m_partial[0m[0;34m([0m[0;34m*[0m[0margs[0m[0;34m,[0m [0;34m**[0m[0mkwargs[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 307[0m [0;32mexcept[0m [0mTypeError[0m [0;32mas[0m [0mexc[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[1;32m 308[0m [0;32mif[0m [0mself[0m[0;34m.[0m[0m_should_curry[0m[0;34m([0m[0margs[0m[0;34m,[0m [0mkwargs[0m[0;34m,[0m [0mexc[0m[0;34m)[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/altair/utils/data.py[0m in [0;36mlimit_rows[0;34m(data, max_rows)[0m
[1;32m 82[0m [0;34m"than the maximum allowed ({}). "[0m[0;34m[0m[0;34m[0m[0m
[1;32m 83[0m [0;34m"For information on how to plot larger datasets "[0m[0;34m[0m[0;34m[0m[0m
[0;32m---> 84[0;31m [0;34m"in Altair, see the documentation"[0m[0;34m.[0m[0mformat[0m[0;34m([0m[0mmax_rows[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 85[0m )
[1;32m 86[0m [0;32mreturn[0m [0mdata[0m[0;34m[0m[0;34m[0m[0m
[0;31mMaxRowsError[0m: The number of rows in your dataset is greater than the maximum allowed (5000). For information on how to plot larger datasets in Altair, see the documentationalt.VConcatChart(...)
In [49]:
monthly_returns_heatmap(bt.balance)Out [49]:
In [50]:
returns_histogram(bt.balance)Out [50]:
[0;31m---------------------------------------------------------------------------[0m
[0;31mMaxRowsError[0m Traceback (most recent call last)
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/altair/vegalite/v4/api.py[0m in [0;36mto_dict[0;34m(self, *args, **kwargs)[0m
[1;32m 2018[0m [0mcopy[0m[0;34m.[0m[0mdata[0m [0;34m=[0m [0mcore[0m[0;34m.[0m[0mInlineData[0m[0;34m([0m[0mvalues[0m[0;34m=[0m[0;34m[[0m[0;34m{[0m[0;34m}[0m[0;34m][0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[1;32m 2019[0m [0;32mreturn[0m [0msuper[0m[0;34m([0m[0mChart[0m[0;34m,[0m [0mcopy[0m[0;34m)[0m[0;34m.[0m[0mto_dict[0m[0;34m([0m[0;34m*[0m[0margs[0m[0;34m,[0m [0;34m**[0m[0mkwargs[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0;32m-> 2020[0;31m [0;32mreturn[0m [0msuper[0m[0;34m([0m[0;34m)[0m[0;34m.[0m[0mto_dict[0m[0;34m([0m[0;34m*[0m[0margs[0m[0;34m,[0m [0;34m**[0m[0mkwargs[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 2021[0m [0;34m[0m[0m
[1;32m 2022[0m [0;32mdef[0m [0madd_selection[0m[0;34m([0m[0mself[0m[0;34m,[0m [0;34m*[0m[0mselections[0m[0;34m)[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/altair/vegalite/v4/api.py[0m in [0;36mto_dict[0;34m(self, *args, **kwargs)[0m
[1;32m 372[0m [0mcopy[0m [0;34m=[0m [0mself[0m[0;34m.[0m[0mcopy[0m[0;34m([0m[0mdeep[0m[0;34m=[0m[0;32mFalse[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[1;32m 373[0m [0moriginal_data[0m [0;34m=[0m [0mgetattr[0m[0;34m([0m[0mcopy[0m[0;34m,[0m [0;34m"data"[0m[0;34m,[0m [0mUndefined[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0;32m--> 374[0;31m [0mcopy[0m[0;34m.[0m[0mdata[0m [0;34m=[0m [0m_prepare_data[0m[0;34m([0m[0moriginal_data[0m[0;34m,[0m [0mcontext[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 375[0m [0;34m[0m[0m
[1;32m 376[0m [0;32mif[0m [0moriginal_data[0m [0;32mis[0m [0;32mnot[0m [0mUndefined[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/altair/vegalite/v4/api.py[0m in [0;36m_prepare_data[0;34m(data, context)[0m
[1;32m 87[0m [0;31m# convert dataframes or objects with __geo_interface__ to dict[0m[0;34m[0m[0;34m[0m[0;34m[0m[0m
[1;32m 88[0m [0;32mif[0m [0misinstance[0m[0;34m([0m[0mdata[0m[0;34m,[0m [0mpd[0m[0;34m.[0m[0mDataFrame[0m[0;34m)[0m [0;32mor[0m [0mhasattr[0m[0;34m([0m[0mdata[0m[0;34m,[0m [0;34m"__geo_interface__"[0m[0;34m)[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[0;32m---> 89[0;31m [0mdata[0m [0;34m=[0m [0m_pipe[0m[0;34m([0m[0mdata[0m[0;34m,[0m [0mdata_transformers[0m[0;34m.[0m[0mget[0m[0;34m([0m[0;34m)[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 90[0m [0;34m[0m[0m
[1;32m 91[0m [0;31m# convert string input to a URLData[0m[0;34m[0m[0;34m[0m[0;34m[0m[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/toolz/functoolz.py[0m in [0;36mpipe[0;34m(data, *funcs)[0m
[1;32m 628[0m """
[1;32m 629[0m [0;32mfor[0m [0mfunc[0m [0;32min[0m [0mfuncs[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[0;32m--> 630[0;31m [0mdata[0m [0;34m=[0m [0mfunc[0m[0;34m([0m[0mdata[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 631[0m [0;32mreturn[0m [0mdata[0m[0;34m[0m[0;34m[0m[0m
[1;32m 632[0m [0;34m[0m[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/toolz/functoolz.py[0m in [0;36m__call__[0;34m(self, *args, **kwargs)[0m
[1;32m 304[0m [0;32mdef[0m [0m__call__[0m[0;34m([0m[0mself[0m[0;34m,[0m [0;34m*[0m[0margs[0m[0;34m,[0m [0;34m**[0m[0mkwargs[0m[0;34m)[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[1;32m 305[0m [0;32mtry[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[0;32m--> 306[0;31m [0;32mreturn[0m [0mself[0m[0;34m.[0m[0m_partial[0m[0;34m([0m[0;34m*[0m[0margs[0m[0;34m,[0m [0;34m**[0m[0mkwargs[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 307[0m [0;32mexcept[0m [0mTypeError[0m [0;32mas[0m [0mexc[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[1;32m 308[0m [0;32mif[0m [0mself[0m[0;34m.[0m[0m_should_curry[0m[0;34m([0m[0margs[0m[0;34m,[0m [0mkwargs[0m[0;34m,[0m [0mexc[0m[0;34m)[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/altair/vegalite/data.py[0m in [0;36mdefault_data_transformer[0;34m(data, max_rows)[0m
[1;32m 17[0m [0;34m@[0m[0mcurried[0m[0;34m.[0m[0mcurry[0m[0;34m[0m[0;34m[0m[0m
[1;32m 18[0m [0;32mdef[0m [0mdefault_data_transformer[0m[0;34m([0m[0mdata[0m[0;34m,[0m [0mmax_rows[0m[0;34m=[0m[0;36m5000[0m[0;34m)[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[0;32m---> 19[0;31m [0;32mreturn[0m [0mcurried[0m[0;34m.[0m[0mpipe[0m[0;34m([0m[0mdata[0m[0;34m,[0m [0mlimit_rows[0m[0;34m([0m[0mmax_rows[0m[0;34m=[0m[0mmax_rows[0m[0;34m)[0m[0;34m,[0m [0mto_values[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 20[0m [0;34m[0m[0m
[1;32m 21[0m [0;34m[0m[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/toolz/functoolz.py[0m in [0;36mpipe[0;34m(data, *funcs)[0m
[1;32m 628[0m """
[1;32m 629[0m [0;32mfor[0m [0mfunc[0m [0;32min[0m [0mfuncs[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[0;32m--> 630[0;31m [0mdata[0m [0;34m=[0m [0mfunc[0m[0;34m([0m[0mdata[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 631[0m [0;32mreturn[0m [0mdata[0m[0;34m[0m[0;34m[0m[0m
[1;32m 632[0m [0;34m[0m[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/toolz/functoolz.py[0m in [0;36m__call__[0;34m(self, *args, **kwargs)[0m
[1;32m 304[0m [0;32mdef[0m [0m__call__[0m[0;34m([0m[0mself[0m[0;34m,[0m [0;34m*[0m[0margs[0m[0;34m,[0m [0;34m**[0m[0mkwargs[0m[0;34m)[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[1;32m 305[0m [0;32mtry[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[0;32m--> 306[0;31m [0;32mreturn[0m [0mself[0m[0;34m.[0m[0m_partial[0m[0;34m([0m[0;34m*[0m[0margs[0m[0;34m,[0m [0;34m**[0m[0mkwargs[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 307[0m [0;32mexcept[0m [0mTypeError[0m [0;32mas[0m [0mexc[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[1;32m 308[0m [0;32mif[0m [0mself[0m[0;34m.[0m[0m_should_curry[0m[0;34m([0m[0margs[0m[0;34m,[0m [0mkwargs[0m[0;34m,[0m [0mexc[0m[0;34m)[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/altair/utils/data.py[0m in [0;36mlimit_rows[0;34m(data, max_rows)[0m
[1;32m 82[0m [0;34m"than the maximum allowed ({}). "[0m[0;34m[0m[0;34m[0m[0m
[1;32m 83[0m [0;34m"For information on how to plot larger datasets "[0m[0;34m[0m[0;34m[0m[0m
[0;32m---> 84[0;31m [0;34m"in Altair, see the documentation"[0m[0;34m.[0m[0mformat[0m[0;34m([0m[0mmax_rows[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 85[0m )
[1;32m 86[0m [0;32mreturn[0m [0mdata[0m[0;34m[0m[0;34m[0m[0m
[0;31mMaxRowsError[0m: The number of rows in your dataset is greater than the maximum allowed (5000). For information on how to plot larger datasets in Altair, see the documentationalt.Chart(...)
In [51]:
bt.run(rebalance_freq=1, sma_days=30);0% [██████████████████████████████] 100% | ETA: 00:00:00 Total time elapsed: 00:00:29
In [52]:
bt.balance[[stock.symbol for stock in stocks]].plot();In [53]:
pf.create_returns_tear_sheet(returns = bt.balance['% change'].dropna())/home/wassname/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/empyrical/utils.py:442: UserWarning: Yahoo Finance read failed: 'date', falling back to Google UserWarning)
[0;31m---------------------------------------------------------------------------[0m
[0;31mKeyError[0m Traceback (most recent call last)
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/pandas/core/indexes/base.py[0m in [0;36mget_loc[0;34m(self, key, method, tolerance)[0m
[1;32m 3360[0m [0;32mtry[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[0;32m-> 3361[0;31m [0;32mreturn[0m [0mself[0m[0;34m.[0m[0m_engine[0m[0;34m.[0m[0mget_loc[0m[0;34m([0m[0mcasted_key[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 3362[0m [0;32mexcept[0m [0mKeyError[0m [0;32mas[0m [0merr[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/pandas/_libs/index.pyx[0m in [0;36mpandas._libs.index.IndexEngine.get_loc[0;34m()[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/pandas/_libs/index.pyx[0m in [0;36mpandas._libs.index.IndexEngine.get_loc[0;34m()[0m
[0;32mpandas/_libs/hashtable_class_helper.pxi[0m in [0;36mpandas._libs.hashtable.PyObjectHashTable.get_item[0;34m()[0m
[0;32mpandas/_libs/hashtable_class_helper.pxi[0m in [0;36mpandas._libs.hashtable.PyObjectHashTable.get_item[0;34m()[0m
[0;31mKeyError[0m: 'date'
The above exception was the direct cause of the following exception:
[0;31mKeyError[0m Traceback (most recent call last)
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/empyrical/utils.py[0m in [0;36mget_symbol_returns_from_yahoo[0;34m(symbol, start, end)[0m
[1;32m 435[0m [0mpx[0m [0;34m=[0m [0mweb[0m[0;34m.[0m[0mget_data_yahoo[0m[0;34m([0m[0msymbol[0m[0;34m,[0m [0mstart[0m[0;34m=[0m[0mstart[0m[0;34m,[0m [0mend[0m[0;34m=[0m[0mend[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0;32m--> 436[0;31m [0mpx[0m[0;34m[[0m[0;34m'date'[0m[0;34m][0m [0;34m=[0m [0mpd[0m[0;34m.[0m[0mto_datetime[0m[0;34m([0m[0mpx[0m[0;34m[[0m[0;34m'date'[0m[0;34m][0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 437[0m [0mpx[0m[0;34m.[0m[0mset_index[0m[0;34m([0m[0;34m'date'[0m[0;34m,[0m [0mdrop[0m[0;34m=[0m[0;32mFalse[0m[0;34m,[0m [0minplace[0m[0;34m=[0m[0;32mTrue[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/pandas/core/frame.py[0m in [0;36m__getitem__[0;34m(self, key)[0m
[1;32m 3457[0m [0;32mreturn[0m [0mself[0m[0;34m.[0m[0m_getitem_multilevel[0m[0;34m([0m[0mkey[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0;32m-> 3458[0;31m [0mindexer[0m [0;34m=[0m [0mself[0m[0;34m.[0m[0mcolumns[0m[0;34m.[0m[0mget_loc[0m[0;34m([0m[0mkey[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 3459[0m [0;32mif[0m [0mis_integer[0m[0;34m([0m[0mindexer[0m[0;34m)[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/pandas/core/indexes/base.py[0m in [0;36mget_loc[0;34m(self, key, method, tolerance)[0m
[1;32m 3362[0m [0;32mexcept[0m [0mKeyError[0m [0;32mas[0m [0merr[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[0;32m-> 3363[0;31m [0;32mraise[0m [0mKeyError[0m[0;34m([0m[0mkey[0m[0;34m)[0m [0;32mfrom[0m [0merr[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 3364[0m [0;34m[0m[0m
[0;31mKeyError[0m: 'date'
During handling of the above exception, another exception occurred:
[0;31mAttributeError[0m Traceback (most recent call last)
[0;32m/tmp/ipykernel_1862594/2665695955.py[0m in [0;36m<module>[0;34m[0m
[0;32m----> 1[0;31m [0mpf[0m[0;34m.[0m[0mcreate_returns_tear_sheet[0m[0;34m([0m[0mreturns[0m [0;34m=[0m [0mbt[0m[0;34m.[0m[0mbalance[0m[0;34m[[0m[0;34m'% change'[0m[0;34m][0m[0;34m.[0m[0mdropna[0m[0;34m([0m[0;34m)[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/pyfolio/plotting.py[0m in [0;36mcall_w_context[0;34m(*args, **kwargs)[0m
[1;32m 50[0m [0;32mif[0m [0mset_context[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[1;32m 51[0m [0;32mwith[0m [0mplotting_context[0m[0;34m([0m[0;34m)[0m[0;34m,[0m [0maxes_style[0m[0;34m([0m[0;34m)[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[0;32m---> 52[0;31m [0;32mreturn[0m [0mfunc[0m[0;34m([0m[0;34m*[0m[0margs[0m[0;34m,[0m [0;34m**[0m[0mkwargs[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 53[0m [0;32melse[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[1;32m 54[0m [0;32mreturn[0m [0mfunc[0m[0;34m([0m[0;34m*[0m[0margs[0m[0;34m,[0m [0;34m**[0m[0mkwargs[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/pyfolio/tears.py[0m in [0;36mcreate_returns_tear_sheet[0;34m(returns, positions, transactions, live_start_date, cone_std, benchmark_rets, bootstrap, return_fig)[0m
[1;32m 442[0m [0;34m[0m[0m
[1;32m 443[0m [0;32mif[0m [0mbenchmark_rets[0m [0;32mis[0m [0;32mNone[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[0;32m--> 444[0;31m [0mbenchmark_rets[0m [0;34m=[0m [0mutils[0m[0;34m.[0m[0mget_symbol_rets[0m[0;34m([0m[0;34m'SPY'[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 445[0m [0;34m[0m[0m
[1;32m 446[0m [0mreturns[0m [0;34m=[0m [0mreturns[0m[0;34m[[0m[0mreturns[0m[0;34m.[0m[0mindex[0m [0;34m>[0m [0mbenchmark_rets[0m[0;34m.[0m[0mindex[0m[0;34m[[0m[0;36m0[0m[0;34m][0m[0;34m][0m[0;34m[0m[0;34m[0m[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/pyfolio/utils.py[0m in [0;36mget_symbol_rets[0;34m(symbol, start, end)[0m
[1;32m 598[0m return SETTINGS['returns_func'](symbol,
[1;32m 599[0m [0mstart[0m[0;34m=[0m[0mstart[0m[0;34m,[0m[0;34m[0m[0;34m[0m[0m
[0;32m--> 600[0;31m end=end)
[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/pyfolio/deprecate.py[0m in [0;36mwrapper[0;34m(*args, **kwargs)[0m
[1;32m 41[0m [0mstacklevel[0m[0;34m=[0m[0mstacklevel[0m[0;34m[0m[0;34m[0m[0m
[1;32m 42[0m )
[0;32m---> 43[0;31m [0;32mreturn[0m [0mfn[0m[0;34m([0m[0;34m*[0m[0margs[0m[0;34m,[0m [0;34m**[0m[0mkwargs[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 44[0m [0;32mreturn[0m [0mwrapper[0m[0;34m[0m[0;34m[0m[0m
[1;32m 45[0m [0;32mreturn[0m [0mdeprecated_dec[0m[0;34m[0m[0;34m[0m[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/pyfolio/utils.py[0m in [0;36mdefault_returns_func[0;34m(symbol, start, end)[0m
[1;32m 399[0m [0;34m-[0m [0mSee[0m [0mfull[0m [0mexplanation[0m [0;32min[0m [0mtears[0m[0;34m.[0m[0mcreate_full_tear_sheet[0m [0;34m([0m[0mreturns[0m[0;34m)[0m[0;34m.[0m[0;34m[0m[0;34m[0m[0m
[1;32m 400[0m """
[0;32m--> 401[0;31m [0;32mreturn[0m [0mempyrical[0m[0;34m.[0m[0mutils[0m[0;34m.[0m[0mdefault_returns_func[0m[0;34m([0m[0msymbol[0m[0;34m,[0m [0mstart[0m[0;34m=[0m[0;32mNone[0m[0;34m,[0m [0mend[0m[0;34m=[0m[0;32mNone[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 402[0m [0;34m[0m[0m
[1;32m 403[0m [0;34m[0m[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/empyrical/deprecate.py[0m in [0;36mwrapper[0;34m(*args, **kwargs)[0m
[1;32m 41[0m [0mstacklevel[0m[0;34m=[0m[0mstacklevel[0m[0;34m[0m[0;34m[0m[0m
[1;32m 42[0m )
[0;32m---> 43[0;31m [0;32mreturn[0m [0mfn[0m[0;34m([0m[0;34m*[0m[0margs[0m[0;34m,[0m [0;34m**[0m[0mkwargs[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 44[0m [0;32mreturn[0m [0mwrapper[0m[0;34m[0m[0;34m[0m[0m
[1;32m 45[0m [0;32mreturn[0m [0mdeprecated_dec[0m[0;34m[0m[0;34m[0m[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/empyrical/utils.py[0m in [0;36mdefault_returns_func[0;34m(symbol, start, end)[0m
[1;32m 488[0m [0msymbol[0m[0;34m=[0m[0;34m'SPY'[0m[0;34m,[0m[0;34m[0m[0;34m[0m[0m
[1;32m 489[0m [0mstart[0m[0;34m=[0m[0;34m'1/1/1970'[0m[0;34m,[0m[0;34m[0m[0;34m[0m[0m
[0;32m--> 490[0;31m end=datetime.now())
[0m[1;32m 491[0m [0mrets[0m [0;34m=[0m [0mrets[0m[0;34m[[0m[0mstart[0m[0;34m:[0m[0mend[0m[0;34m][0m[0;34m[0m[0;34m[0m[0m
[1;32m 492[0m [0;32melse[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/empyrical/deprecate.py[0m in [0;36mwrapper[0;34m(*args, **kwargs)[0m
[1;32m 41[0m [0mstacklevel[0m[0;34m=[0m[0mstacklevel[0m[0;34m[0m[0;34m[0m[0m
[1;32m 42[0m )
[0;32m---> 43[0;31m [0;32mreturn[0m [0mfn[0m[0;34m([0m[0;34m*[0m[0margs[0m[0;34m,[0m [0;34m**[0m[0mkwargs[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 44[0m [0;32mreturn[0m [0mwrapper[0m[0;34m[0m[0;34m[0m[0m
[1;32m 45[0m [0;32mreturn[0m [0mdeprecated_dec[0m[0;34m[0m[0;34m[0m[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/empyrical/utils.py[0m in [0;36mget_returns_cached[0;34m(filepath, update_func, latest_dt, **kwargs)[0m
[1;32m 322[0m [0;34m[0m[0m
[1;32m 323[0m [0;32mif[0m [0mupdate_cache[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[0;32m--> 324[0;31m [0mreturns[0m [0;34m=[0m [0mupdate_func[0m[0;34m([0m[0;34m**[0m[0mkwargs[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 325[0m [0;32mtry[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m
[1;32m 326[0m [0mensure_directory[0m[0;34m([0m[0mcache_dir[0m[0;34m([0m[0;34m)[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/empyrical/deprecate.py[0m in [0;36mwrapper[0;34m(*args, **kwargs)[0m
[1;32m 41[0m [0mstacklevel[0m[0;34m=[0m[0mstacklevel[0m[0;34m[0m[0;34m[0m[0m
[1;32m 42[0m )
[0;32m---> 43[0;31m [0;32mreturn[0m [0mfn[0m[0;34m([0m[0;34m*[0m[0margs[0m[0;34m,[0m [0;34m**[0m[0mkwargs[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 44[0m [0;32mreturn[0m [0mwrapper[0m[0;34m[0m[0;34m[0m[0m
[1;32m 45[0m [0;32mreturn[0m [0mdeprecated_dec[0m[0;34m[0m[0;34m[0m[0m
[0;32m~/miniforge3/envs/mori_opt_earnings/lib/python3.7/site-packages/empyrical/utils.py[0m in [0;36mget_symbol_returns_from_yahoo[0;34m(symbol, start, end)[0m
[1;32m 441[0m [0;34m'Yahoo Finance read failed: {}, falling back to Google'[0m[0;34m.[0m[0mformat[0m[0;34m([0m[0me[0m[0;34m)[0m[0;34m,[0m[0;34m[0m[0;34m[0m[0m
[1;32m 442[0m UserWarning)
[0;32m--> 443[0;31m [0mpx[0m [0;34m=[0m [0mweb[0m[0;34m.[0m[0mget_data_google[0m[0;34m([0m[0msymbol[0m[0;34m,[0m [0mstart[0m[0;34m=[0m[0mstart[0m[0;34m,[0m [0mend[0m[0;34m=[0m[0mend[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[1;32m 444[0m [0mrets[0m [0;34m=[0m [0mpx[0m[0;34m[[0m[0;34m[[0m[0;34m'Close'[0m[0;34m][0m[0;34m][0m[0;34m.[0m[0mpct_change[0m[0;34m([0m[0;34m)[0m[0;34m.[0m[0mdropna[0m[0;34m([0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[1;32m 445[0m [0;34m[0m[0m
[0;31mAttributeError[0m: module 'pandas_datareader.data' has no attribute 'get_data_google'In [ ]: