I want to create a reproducible example where the traded series and the benchmark are manually provided. This would make the life of people that are approaching to zipline incredibly easier. In fact, given the recent shut down of Yahoo!Finance API, even introductory examples with zipline are not going to work anymore since an HTTP error will be returned when trying to import the ^GSPC benchmark from Yahoo behind the scenes. As a consequence, nowadays there is not a single code snippet from the official tutorial that works AFAIK.
import pytz
from pandas_datareader import DataReader
from collections import OrderedDict
from zipline.algorithm import TradingAlgorithm
from zipline.api import order, record, symbol, set_benchmark
# Import data from yahoo
data = OrderedDict()
start_date = '01/01/2014'
end_date = '01/01/2017'
data['AAPL'] = DataReader('AAPL',
data_source='google',
start=start_date,
end=end_date)
data['SPY'] = DataReader('SPY',
data_source='google',
start=start_date,
end=end_date)
# panel.minor_axis is ['Open', 'High', 'Low', 'Close', 'Volume'].
panel = pd.Panel(data)
panel.major_axis = panel.major_axis.tz_localize(pytz.utc)
def initialize(context):
set_benchmark(data['SPY'])
def handle_data(context, data):
order(data['AAPL'], 10)
record(AAPL=data.current(data['AAPL'], 'Close'))
algo_obj = TradingAlgorithm(initialize=initialize,
handle_data=handle_data,
capital_base=100000)
perf_manual = algo_obj.run(panel)
Returns: HTTPError: HTTP Error 404: Not Found
Question: how to make the strategy to work using AAPL as traded asset and SPY as benchmark?
Constraint: AAPL and SPY must be manually provided as in the example.
Disclaimer: I'm a maintainer of Zipline.
You can use the csvdir bundle to ingest csv files (tutorial here) and then make a call to set_benchmark() in your initialize() function. I'm also working a branch that allows zipline algorithms to run without a benchmark so even if you're not able to get benchmark data, your algorithm shouldn't crash.
Replace zipline in your requirements.txt with this:
git+https://github.com/quantopian/zipline
Then run pip install -r requirements.txt
Related
I'm trying to learn backtesting.py, when I run the following sample code, it pops up these errors, anyone could help? I tried to uninstall the Bokeh package and reinstall an older version, but it doen't work.
BokehDeprecationWarning: Passing lists of formats for DatetimeTickFormatter scales was deprecated in Bokeh 3.0. Configure a single string format for each scale
C:\Users\paul_\AppData\Local\Programs\Python\Python310\lib\site-packages\bokeh\models\formatters.py:399: UserWarning: DatetimeFormatter scales now only accept a single format. Using the first prodvided: '%d %b'
warnings.warn(f"DatetimeFormatter scales now only accept a single format. Using the first prodvided: {fmt[0]!r} ")
BokehDeprecationWarning: Passing lists of formats for DatetimeTickFormatter scales was deprecated in Bokeh 3.0. Configure a single string format for each scale
C:\Users\paul_\AppData\Local\Programs\Python\Python310\lib\site-packages\bokeh\models\formatters.py:399: UserWarning: DatetimeFormatter scales now only accept a single format. Using the first prodvided: '%m/%Y'
warnings.warn(f"DatetimeFormatter scales now only accept a single format. Using the first prodvided: {fmt[0]!r} ")
GridPlot(id='p11925', ...)
import bokeh
import datetime
import pandas_ta as ta
import pandas as pd
from backtesting import Backtest
from backtesting import Strategy
from backtesting.lib import crossover
from backtesting.test import GOOG
class RsiOscillator(Strategy):
upper_bound = 70
lower_bound = 30
rsi_window = 14
# Do as much initial computation as possible
def init(self):
self.rsi = self.I(ta.rsi, pd.Series(self.data.Close), self.rsi_window)
# Step through bars one by one
# Note that multiple buys are a thing here
def next(self):
if crossover(self.rsi, self.upper_bound):
self.position.close()
elif crossover(self.lower_bound, self.rsi):
self.buy()
bt = Backtest(GOOG, RsiOscillator, cash=10_000, commission=.002)
stats = bt.run()
bt.plot()
An issue was opened for this in the GitHub repo:
https://github.com/kernc/backtesting.py/issues/803
A comment in the issue suggests to downgrade bokeh to 2.4.3:
python3 -m pip install bokeh==2.4.3
This worked for me.
I had a similar issue, using Spyder IDE.
Found out I need to call the below for the plot to show for Spyder.
backtesting.set_bokeh_output(notebook=False)
I have update Python to version 3.11 & downgrade bokeh to 2.4.3
This worked for me.
Downgrading Bokeh didn't work for me.
But, after importing backtesting in Jupyter, I needed to do:
backtesting.set_bokeh_output(notebook=False)
The expected plot was then generated in a new interactive browser tab.
This is the code I have as of now and I have tried multiple different ways to get the correct code but to no avail.
I am using the Biopython module for this.
from Bio.Entrez import efetch
def print_abstract(pmid):
handle = efetch(db='pubmed', id=pmid, retmode='text', rettype='abstract')
print handle.read()
I tried the code as listed above along with a few tweaks here and there but nothing seems to be working for a simple query.
Step 1: When using python3, use print() as such:
from Bio.Entrez import efetch
def print_abstract(pmid):
handle = efetch(db='pubmed', id=pmid, retmode='text', rettype='abstract')
print(handle.read())
Step 2: To make use of NCBI's E-utilities, NCBI requires you to specify your email address with each request. So, specify any email (it doesn't have to be real) as follows:
from Bio import Entrez
Entrez.email = 'some#example.com'
Step 3: Now you can retrieve an abstract programmatically, for example by running
print_abstract(35312860)
This gives me:
1. Acta Diabetol. 2022 Mar 21. doi: 10.1007/s00592-022-01878-z. [Epub ahead of
print]
Significant and persistent improvements in time in range and positive emotions in
children and adolescents with type 1 diabetes using a closed-loop control system
after attending a virtual educational camp.
...
OBJECTIVE: To evaluate the six-month impact of the advanced automated functions...
I try to retrieve historical financial Data from iex or morningstar. For this I use the Following Code.
import pandas as pd
pd.core.common.is_list_like = pd.api.types.is_list_like
import pandas_datareader.data as web
import datetime
start = datetime.datetime(2019, 1, 1)
end = datetime.datetime(2019, 1, 10)
facebook = web.DataReader("FB", 'morningstar', start, end)
print(facebook.head())
Unfortunatly I get the error message:
NotImplementedError: data_source='morningstar' is not implemented
or
ValueError: The IEX Cloud API key must be provided either through the
api_key variable or through the environment variable IEX_API_KEY
depending on which of both sources I use.
I tried to
pip uninstall pandas-datareader
pip install pandas-datareader
several times and also restarted the kernel but nothing changes. Was there any change to this APIs or am I doing anything wrong?
From the documentation:
You need to obtain the IEX_API_KEY from IEX and pass it to os.environ["IEX_API_KEY"]. (https://pandas-datareader.readthedocs.io/en/latest/remote_data.html#remote-data-iex)
I don't know if the IEX API still works.
The morningstar is not implemented. The following data sources (at the time of writing) are:
Tiingo
IEX
Alpha Vantage
Enigma
Quandl
St.Louis FED (FRED)
Kenneth French’s data library
World Bank
OECD
Eurostat
Thrift Savings Plan
Nasdaq Trader symbol definitions
Stooq
MOEX
You must provide an API Key when using IEX. You can do this using
os.environ["IEX_API_KEY"] = "pk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
or by exporting the key before starting the IPython session.
You can visit iexcloud.io, after creating a student account you will get an API key for free.
I am importing the data set set and getting the above warning and not able to understand which function is causing this warning.
DeprecationWarning: You are using the post() function from 'ibm_botocore.vendored.requests'. This is not a public API in ibm_botocore and will be removed in the future. Additionally, this version of requests is out of date. We recommend you install the requests package, 'import requests' directly, and use the requests.post() function instead.
Code
import types
import pandas as pd
from botocore.client import Config
import ibm_boto3
def __iter__(self): return 0
client_cbe8a2731f0140ccb1120588edd17f92 = ibm_boto3.client(service_name='s3',
ibm_api_key_id='xxx',
ibm_auth_endpoint="https://yy",
config=Config(signature_version='oauth'),
endpoint_url='https://zz.com')
body = `enter code here`client_cbe8a2731f0140ccb1120588edd17f92.get_object(Bucket='abc',Key='data.csv')['Body']
# add missing __iter__ method, so pandas accepts body as file-like object
if not hasattr(body, "__iter__"): body.__iter__ = types.MethodType( __iter__, body )
data = pd.read_csv(body)
Try shutting down and restarting your Kernel. I was running in a Jupyter Notebook with the identical issue. Shutdown/Restart seemed to resolve!
Update... I must have been lucky. I am still seeing this message randomly. I can not discern any pattern.
I am trying to get a price of a stock from google by using pandas-datareader.data but when I try to call Amazon(amazons price right now is over 1,000) it gives me a value error. I assume it is because of the comma in the price. It automatically attempts to turn it into a float so I have no opportunity to use a .replace function.
ValueError: could not convert string to float: '1,001.30'
I seemingly cannot seem to find a workaround to this issue so any help would be very appreciated, thanks.
import pandas_datareader.data as web
def money(stock):
#df = web.DataReader(stock, "google", start=start, end=end)
df2 = web.get_quote_google(stock)
I think there seems to be currently a compatibility issue with panads and pandas_datareader. However, this might solve your problem using yahoo-finance:
use pip install yahoo-finance to install the module and then run
import yahoo_finance
import pandas as pd
symbol = yahoo_finance.Share("AMZN")
google_df = symbol.get_price()
This gives me no error on the price of Amazon