mirror of
https://github.com/wassname/catalyst.git
synced 2026-09-11 12:00:50 +08:00
ENH: Add IPython cell magic.
When zipline is imported it checks whether it runs in the IPython notebook. If it does, it registers a %%zipline magic that takes the same arguments as the CLI with the addition of a -o for specifying the output variable to store the performance frame in. The algo code in the cell is, as of yet, executed in its own environment rather than that of the IPython NB which is probably what we want. Also adds cli option to save the perf dataframe to a pickle file. Also adds an IPython notebook buyapple example.
This commit is contained in:
+53
-18
@@ -16,17 +16,16 @@
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
import ConfigParser
|
||||
from copy import copy
|
||||
|
||||
import datetime
|
||||
from six import print_
|
||||
from six.moves import configparser
|
||||
import pandas as pd
|
||||
|
||||
try:
|
||||
from pygments import highlight
|
||||
from pygments.lexers import PythonLexer
|
||||
from pygments.formatters import TerminalFormatter
|
||||
from pygments.styles import STYLE_MAP
|
||||
PYGMENTS = True
|
||||
except:
|
||||
PYGMENTS = False
|
||||
@@ -42,7 +41,8 @@ DEFAULTS = {
|
||||
'symbols': 'AAPL'
|
||||
}
|
||||
|
||||
def parse_args(argv):
|
||||
|
||||
def parse_args(argv, ipython_mode=False):
|
||||
# Parse any conf_file specification
|
||||
# We make this parser with add_help=False so that
|
||||
# it doesn't parse -h and print help.
|
||||
@@ -51,7 +51,7 @@ def parse_args(argv):
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
# Turn off help, so we print all options in response to -h
|
||||
add_help=False
|
||||
)
|
||||
)
|
||||
conf_parser.add_argument("-c", "--conf_file",
|
||||
help="Specify config file",
|
||||
metavar="FILE")
|
||||
@@ -60,7 +60,7 @@ def parse_args(argv):
|
||||
defaults = copy(DEFAULTS)
|
||||
|
||||
if args.conf_file:
|
||||
config = ConfigParser.SafeConfigParser()
|
||||
config = configparser.SafeConfigParser()
|
||||
config.read([args.conf_file])
|
||||
defaults.update(dict(config.items("Defaults")))
|
||||
|
||||
@@ -82,10 +82,34 @@ def parse_args(argv):
|
||||
parser.add_argument('--capital_base')
|
||||
parser.add_argument('--source', choices=('yahoo',))
|
||||
parser.add_argument('--symbols')
|
||||
parser.add_argument('--output', '-o')
|
||||
if ipython_mode:
|
||||
parser.add_argument('--local_namespace', action='store_true')
|
||||
|
||||
args = parser.parse_args(remaining_argv)
|
||||
|
||||
return(vars(args))
|
||||
|
||||
|
||||
def parse_cell_magic(line, cell):
|
||||
"""Parse IPython magic"""
|
||||
args_list = line.split(' ')
|
||||
args = parse_args(args_list, ipython_mode=True)
|
||||
|
||||
local_namespace = args.pop('local_namespace', False)
|
||||
# By default, execute inside IPython namespace
|
||||
if not local_namespace:
|
||||
args['namespace'] = get_ipython().user_ns # flake8: noqa
|
||||
|
||||
perf = run_algo(print_algo=False, algo_text=cell, **args)
|
||||
|
||||
# If we are running inside NB, do not output to file but create a
|
||||
# variable instead
|
||||
output_var_name = args.pop('output', None)
|
||||
if output_var_name is not None:
|
||||
get_ipython().user_ns[output_var_name] = perf # flake8: noqa
|
||||
|
||||
|
||||
def run_algo(print_algo=True, **kwargs):
|
||||
start = pd.Timestamp(kwargs['start'], tz='UTC')
|
||||
end = pd.Timestamp(kwargs['end'], tz='UTC')
|
||||
@@ -93,29 +117,40 @@ def run_algo(print_algo=True, **kwargs):
|
||||
symbols = kwargs['symbols'].split(',')
|
||||
|
||||
if kwargs['source'] == 'yahoo':
|
||||
source = zipline.data.load_bars_from_yahoo(stocks=symbols, start=start, end=end)
|
||||
source = zipline.data.load_bars_from_yahoo(
|
||||
stocks=symbols, start=start, end=end)
|
||||
else:
|
||||
raise NotImplementedError('Source %s not implemented.' % kwargs['source'])
|
||||
raise NotImplementedError(
|
||||
'Source %s not implemented.' % kwargs['source'])
|
||||
|
||||
algo_fname = kwargs['algofile']
|
||||
with open(algo_fname, 'r') as fd:
|
||||
algo_text = fd.read()
|
||||
algo_text = kwargs.get('algo_text', None)
|
||||
if algo_text is None:
|
||||
# Expect algofile to be set
|
||||
algo_fname = kwargs['algofile']
|
||||
with open(algo_fname, 'r') as fd:
|
||||
algo_text = fd.read()
|
||||
|
||||
analyze_fname = os.path.splitext(algo_fname)[0] + '_analyze.py'
|
||||
if os.path.exists(analyze_fname):
|
||||
with open(analyze_fname, 'r') as fd:
|
||||
# Simply append
|
||||
algo_text += fd.read()
|
||||
analyze_fname = os.path.splitext(algo_fname)[0] + '_analyze.py'
|
||||
if os.path.exists(analyze_fname):
|
||||
with open(analyze_fname, 'r') as fd:
|
||||
# Simply append
|
||||
algo_text += fd.read()
|
||||
|
||||
if print_algo:
|
||||
if PYGMENTS:
|
||||
highlight(algo_text, PythonLexer(), TerminalFormatter(), outfile=sys.stdout)
|
||||
highlight(algo_text, PythonLexer(), TerminalFormatter(),
|
||||
outfile=sys.stdout)
|
||||
else:
|
||||
print algo_text
|
||||
print_(algo_text)
|
||||
|
||||
algo = zipline.TradingAlgorithm(script=algo_text,
|
||||
namespace=kwargs.get('namespace', {}),
|
||||
capital_base=float(kwargs['capital_base']))
|
||||
|
||||
perf = algo.run(source)
|
||||
|
||||
output_fname = kwargs.get('output', None)
|
||||
if output_fname is not None:
|
||||
perf.to_pickle(output_fname)
|
||||
|
||||
return perf
|
||||
|
||||
Reference in New Issue
Block a user