def run_algorithm( security='AAPL', start_date='20100101', end_date='20150101', initial_cash=100000, rsi_window=15, low_RSI=30, high_RSI=70): logging.debug('run_algorithm begin') # dates start = dateutil.parser.parse(start_date) end = dateutil.parser.parse(end_date) # get data from yahoo data = load_from_yahoo(stocks=[security], indexes={}, start=start, end=end) logging.debug('done loading from yahoo. {} {} {}'.format( security, start_date, end_date)) # create and run algorithm algo = TradingAlgorithm( initialize=initialize, handle_data=handle_data, capital_base=initial_cash) algo.security = security initialize.low_RSI = low_RSI initialize.high_RSI = high_RSI initialize.rsi_window = rsi_window logging.debug('starting to run algo...') results = algo.run(data).dropna() logging.debug('done running algo') return results
def test_schedule_funtion_rule_creation(self, mode): nop = lambda *args, **kwargs: None self.sim_params.data_frequency = mode algo = TradingAlgorithm( initialize=nop, handle_data=nop, sim_params=self.sim_params, ) # Schedule something for NOT Always. algo.schedule_function(nop, time_rule=zipline.utils.events.Never()) event_rule = algo.event_manager._events[1].rule self.assertIsInstance(event_rule, zipline.utils.events.OncePerDay) inner_rule = event_rule.rule self.assertIsInstance(inner_rule, zipline.utils.events.ComposedRule) first = inner_rule.first second = inner_rule.second composer = inner_rule.composer self.assertIsInstance(first, zipline.utils.events.Always) if mode == 'daily': self.assertIsInstance(second, zipline.utils.events.Always) else: self.assertIsInstance(second, zipline.utils.events.Never) self.assertIs(composer, zipline.utils.events.ComposedRule.lazy_and)
def test_pipeline_output_after_initialize(self): """ Assert that calling pipeline_output after initialize raises correctly. """ def initialize(context): attach_pipeline(Pipeline('test')) pipeline_output('test') raise AssertionError("Shouldn't make it past pipeline_output()") def handle_data(context, data): raise AssertionError("Shouldn't make it past initialize!") def before_trading_start(context, data): raise AssertionError("Shouldn't make it past initialize!") algo = TradingAlgorithm( initialize=initialize, handle_data=handle_data, before_trading_start=before_trading_start, data_frequency='daily', pipeline_loader=self.pipeline_loader, start=self.first_asset_start - trading_day, end=self.last_asset_end + trading_day, env=self.env, ) with self.assertRaises(PipelineOutputDuringInitialize): algo.run(source=self.closes)
def test_pipeline_output_after_initialize(self): """ Assert that calling pipeline_output after initialize raises correctly. """ def initialize(context): attach_pipeline(Pipeline(), "test") pipeline_output("test") raise AssertionError("Shouldn't make it past pipeline_output()") def handle_data(context, data): raise AssertionError("Shouldn't make it past initialize!") def before_trading_start(context, data): raise AssertionError("Shouldn't make it past initialize!") algo = TradingAlgorithm( initialize=initialize, handle_data=handle_data, before_trading_start=before_trading_start, data_frequency="daily", get_pipeline_loader=lambda column: self.pipeline_loader, start=self.first_asset_start - self.trading_day, end=self.last_asset_end + self.trading_day, env=self.env, ) with self.assertRaises(PipelineOutputDuringInitialize): algo.run(self.data_portal)
def test_get_output_nonexistent_pipeline(self): """ Assert that calling add_pipeline after initialize raises appropriately. """ def initialize(context): attach_pipeline(Pipeline(), "test") def handle_data(context, data): raise AssertionError("Shouldn't make it past before_trading_start") def before_trading_start(context, data): pipeline_output("not_test") raise AssertionError("Shouldn't make it past pipeline_output!") algo = TradingAlgorithm( initialize=initialize, handle_data=handle_data, before_trading_start=before_trading_start, data_frequency="daily", get_pipeline_loader=lambda column: self.pipeline_loader, start=self.first_asset_start - self.trading_day, end=self.last_asset_end + self.trading_day, env=self.env, ) with self.assertRaises(NoSuchPipeline): algo.run(self.data_portal)
def test_api_get_environment(self): platform = 'zipline' metadata = {0: {'symbol': 'TEST', 'asset_type': 'equity'}} algo = TradingAlgorithm(script=api_get_environment_algo, asset_metadata=metadata, platform=platform) algo.run(self.df) self.assertEqual(algo.environment, platform)
def wrapper(self, data_frequency, days=None): sim_params, source = self.sim_and_source[data_frequency] algo = TradingAlgorithm( initialize=initialize_with(self, tfm_name, days), handle_data=handle_data_wrapper(f), sim_params=sim_params, ) algo.run(source)
def test_assets_appear_on_correct_days(self, test_name, chunks): """ Assert that assets appear at correct times during a backtest, with correctly-adjusted close price values. """ if chunks == 'all_but_one_day': chunks = ( self.dates.get_loc(self.last_asset_end) - self.dates.get_loc(self.first_asset_start) ) - 1 elif chunks == 'custom_iter': chunks = [] st = np.random.RandomState(12345) remaining = ( self.dates.get_loc(self.last_asset_end) - self.dates.get_loc(self.first_asset_start) ) while remaining > 0: chunk = st.randint(3) chunks.append(chunk) remaining -= chunk def initialize(context): p = attach_pipeline(Pipeline(), 'test', chunks=chunks) p.add(USEquityPricing.close.latest, 'close') def handle_data(context, data): results = pipeline_output('test') date = get_datetime().normalize() for asset in self.assets: # Assets should appear iff they exist today and yesterday. exists_today = self.exists(date, asset) existed_yesterday = self.exists(date - self.trading_day, asset) if exists_today and existed_yesterday: latest = results.loc[asset, 'close'] self.assertEqual(latest, self.expected_close(date, asset)) else: self.assertNotIn(asset, results.index) before_trading_start = handle_data algo = TradingAlgorithm( initialize=initialize, handle_data=handle_data, before_trading_start=before_trading_start, data_frequency='daily', get_pipeline_loader=lambda column: self.pipeline_loader, start=self.first_asset_start, end=self.last_asset_end, env=self.env, ) # Run for a week in the middle of our data. algo.run(self.data_portal)
def test_algo_record_allow_mock(self): """ Test that values from "MagicMock"ed methods can be passed to record. Relevant for our basic/validation and methods like history, which will end up returning a MagicMock instead of a DataFrame. """ test_algo = TradingAlgorithm(script=record_variables, sim_params=self.sim_params) set_algo_instance(test_algo) test_algo.record(foo=MagicMock())
def algoRunNext(self): if(self.hasNext()): currentSeriesValue = self.timeDF.iloc[self.index]; self.index += 1; start, end = self._getStartEndTimeFromCurrentSeries(currentSeriesValue); algo = TradingAlgorithm(initialize=self.initialize, handle_data=self.handle_data, identifiers=self.stockName) data = loader.load_bars_from_yahoo(stocks=self.stockName, start=start, end=end); return algo.run(data); else: raise ValueError;
def test_order_in_init(self): """ Test that calling order in initialize will raise an error. """ with self.assertRaises(OrderDuringInitialize): test_algo = TradingAlgorithm( script=call_order_in_init, sim_params=self.sim_params, ) set_algo_instance(test_algo) test_algo.run(self.source)
def runMaster(): """ Loads backtest data, and runs the backtest.""" global TRAINING_STOCK, BACKTEST_STOCK TRAINING_STOCK = 'SPY' SELECT_STOCKS = ['AAPL', 'DIS', 'XOM', 'UNH', 'WMT'] algo_obj = TradingAlgorithm(initialize=initialize, handle_data=handle_data) perf_manual = [] for stock in SELECT_STOCKS: BACKTEST_STOCK = stock backtestData = loadData(2002, 2002+BACKTEST_TIME, stock_list=[stock, 'SPY']) #, startM=1, endM=2, print "Create algorithm..." perf_manual.append(algo_obj.run(backtestData)) analyze(perf_manual)
def test_add_history_in_handle_data(self): def handle_data(algo, data): algo.add_history(1, '1m', 'price') algo = TradingAlgorithm( initialize=lambda _: None, handle_data=handle_data, sim_params=self.sim_params, ) algo.run(self.source) self.assertIsNotNone(algo.history_container) self.assertEqual(algo.history_container.buffer_panel.window_length, 1)
def test_get_open_orders(self): def initialize(algo): algo.minute = 0 def handle_data(algo, data): if algo.minute == 0: # Should be filled by the next minute algo.order(1, 1) # Won't be filled because the price is too low. algo.order(2, 1, style=LimitOrder(0.01)) algo.order(2, 1, style=LimitOrder(0.01)) algo.order(2, 1, style=LimitOrder(0.01)) all_orders = algo.get_open_orders() self.assertEqual(list(all_orders.keys()), [1, 2]) self.assertEqual(all_orders[1], algo.get_open_orders(1)) self.assertEqual(len(all_orders[1]), 1) self.assertEqual(all_orders[2], algo.get_open_orders(2)) self.assertEqual(len(all_orders[2]), 3) if algo.minute == 1: # First order should have filled. # Second order should still be open. all_orders = algo.get_open_orders() self.assertEqual(list(all_orders.keys()), [2]) self.assertEqual([], algo.get_open_orders(1)) orders_2 = algo.get_open_orders(2) self.assertEqual(all_orders[2], orders_2) self.assertEqual(len(all_orders[2]), 3) for order in orders_2: algo.cancel_order(order) all_orders = algo.get_open_orders() self.assertEqual(all_orders, {}) algo.minute += 1 algo = TradingAlgorithm(initialize=initialize, handle_data=handle_data, sim_params=self.sim_params) algo.run(self.source)
def test_multiple_pipelines(self): """ Test that we can attach multiple pipelines and access the correct output based on the pipeline name. """ def initialize(context): pipeline_close = attach_pipeline(Pipeline(), 'test_close') pipeline_volume = attach_pipeline(Pipeline(), 'test_volume') pipeline_close.add(USEquityPricing.close.latest, 'close') pipeline_volume.add(USEquityPricing.volume.latest, 'volume') def handle_data(context, data): closes = pipeline_output('test_close') volumes = pipeline_output('test_volume') date = get_datetime().normalize() for asset in self.assets: # Assets should appear iff they exist today and yesterday. exists_today = self.exists(date, asset) existed_yesterday = self.exists(date - self.trading_day, asset) if exists_today and existed_yesterday: self.assertEqual( closes.loc[asset, 'close'], self.expected_close(date, asset) ) self.assertEqual( volumes.loc[asset, 'volume'], self.expected_volume(date, asset) ) else: self.assertNotIn(asset, closes.index) self.assertNotIn(asset, volumes.index) column_to_loader = { USEquityPricing.close: self.pipeline_close_loader, USEquityPricing.volume: self.pipeline_volume_loader, } algo = TradingAlgorithm( initialize=initialize, handle_data=handle_data, data_frequency='daily', get_pipeline_loader=lambda column: column_to_loader[column], start=self.first_asset_start, end=self.last_asset_end, env=self.env, ) algo.run(self.data_portal)
def _create_generator(self, sim_params): # Call the simulation trading algorithm for side-effects: # it creates the perf tracker TradingAlgorithm._create_generator(self, sim_params) self.trading_client = LiveAlgorithmExecutor( self, sim_params, self.data_portal, self._create_clock(), self._create_benchmark_source(), self.restrictions, universe_func=self._calculate_universe ) return self.trading_client.transform()
def run_clusters(strategy_class, clustering_tickers, cluster_num, epochs_num, training_start, training_end, backtest_start, backtest_end, is_graph, is_elbow): """ Run the test given command-line args. Cluster. For each cluster, train a strategy on that cluster. For each stock in that cluster, run a backtest. Graph results. """ print "\nGathering data..." ticker_list, raw_stock_data_list = Manager.getRawStockDataList(clustering_tickers, training_start, training_end, 252) normalized_stock_data_list = [Manager.preprocessData(x) for x in raw_stock_data_list] print "\nClustering..." tickers, clusters = createClusters(ticker_list, normalized_stock_data_list, cluster_num) print "# of stocks: " + str(len(normalized_stock_data_list)) print "# of clusters: " + str(len(clusters)) print "" for t, c in itertools.izip(tickers, clusters): print "\tCluster: " + str(len(c)), "stocks: ", for symbol in t: print symbol, print "" if is_graph: graphClusters(clusters) if is_elbow: graphElbowMethod(normalized_stock_data_list) for t, cluster in itertools.izip(tickers, clusters): settings.STRATEGY_OBJECT = trainStrategy(strategy_class, cluster, epochs_num) for ticker in t: print "Cluster:", t print "Stock:", ticker tmp_ticks, tmp_data = Manager.getRawStockDataList([ticker], training_start, training_end, 252) settings.BACKTEST_STOCK = ticker settings.PRE_BACKTEST_DATA = tmp_data[0] print "Create Algorithm..." algo_obj = TradingAlgorithm(initialize=initialize, handle_data=handle_data) try: backtest_data = load_bars_from_yahoo(stocks=[ticker, 'SPY'], start=backtest_start, end=backtest_end) try: perf = algo_obj.run(backtest_data) analyze([ticker], [perf]) except ValueError, e: print str(e) except IOError, e: print "Stock Error: could not load", ticker, "from Yahoo." print "Only testing one cluster for now - Done!" return
def test_pipeline_beyond_daily_bars(self): """ Ensure that we can run an algo with pipeline beyond the max date of the daily bars. """ # For ensuring we call before_trading_start. count = [0] current_day = self.trading_calendar.next_session_label( self.pipeline_loader.raw_price_loader.last_available_dt, ) def initialize(context): pipeline = attach_pipeline(Pipeline(), 'test') vwap = VWAP(window_length=10) pipeline.add(vwap, 'vwap') # Nothing should have prices less than 0. pipeline.set_screen(vwap < 0) def handle_data(context, data): pass def before_trading_start(context, data): context.results = pipeline_output('test') self.assertTrue(context.results.empty) count[0] += 1 algo = TradingAlgorithm( initialize=initialize, handle_data=handle_data, before_trading_start=before_trading_start, data_frequency='daily', get_pipeline_loader=lambda column: self.pipeline_loader, start=self.dates[0], end=current_day, env=self.env, ) algo.run( FakeDataPortal(), overwrite_sim_params=False, ) self.assertTrue(count[0] > 0)
def test_history(self): history_algo = """ from zipline.api import history, add_history def initialize(context): add_history(10, '1d', 'price') def handle_data(context, data): df = history(10, '1d', 'price') """ algo = TradingAlgorithm( script=history_algo, sim_params=self.sim_params, ) output = algo.run(self.source) self.assertIsNot(output, None)
def test_history(self): history_algo = """ from zipline.api import history, add_history def initialize(context): add_history(10, '1d', 'price') def handle_data(context, data): df = history(10, '1d', 'price') """ start = pd.Timestamp('1991-01-01', tz='UTC') end = pd.Timestamp('1991-01-15', tz='UTC') source = RandomWalkSource(start=start, end=end) algo = TradingAlgorithm(script=history_algo, data_frequency='minute') output = algo.run(source) self.assertIsNot(output, None)
def handle_data(self, data): # overload handle_data() method #print self.day_count date = TradingAlgorithm.get_datetime(self) self.dates.append(date) #print self.portfolio #print str(date)[0:10] # Get price and trend data for sym in sym_list: #print self.portfolio # Price sym_price = data[sym].price sym_high = data[sym].high sym_low = data[sym].low sym_volume = data[sym].volume self.prices[sym] = np.append(self.prices[sym],sym_price) self.lows[sym] = np.append(self.prices[sym],sym_low) self.highs[sym] = np.append(self.prices[sym],sym_high) # Volume self.volume[sym] = np.append(self.volume[sym],sym_volume) # RSI, MACD, Chaikin, MFI mfi = self.get_mfi(sym) cmf = self.get_chaikin(sym) self.chaikin_plot[sym] = np.append(self.chaikin_plot[sym],cmf) rsi = self.get_rsi(sym)[-1] self.rsi_plot[sym] = np.append(self.rsi_plot[sym],rsi) macd, macdsignal, macdhist = self.get_macd(sym) # Trend trend = self.trend_dfs[sym]['sum'][self.dates[-1]] self.trends[sym].append(float(trend)) # Get gains gain = self.trade_gain(sym) self.gains[sym] = np.append(self.gains[sym],gain) # Get RS and zscore if self.day_count >= window_long: rs = self.get_rs zscore = self.trend_zscore(sym,date,window_long) zscore_s = self.trend_zscore(sym,date,window_short) self.zscores[sym].append(zscore) self.zscores_s[sym].append(zscore_s) # Execute trades if self.portfolio.positions[sym].amount == 0 and self.zscores[sym][-1] >= 2 and mfi > 40: # cmf > -0.1 and :# and rsi <= 30: # and cmf > -0.05: #if self.zscores_s[sym][-1] > self.zscores[sym][-1] and self.zscores_s[sym][-2] < self.zscores[sym][-2]: if 1 == 1: self.long(data,sym) print str(date)[0:10],'LONG:',sym elif self.portfolio.positions[sym].amount != 0: if sym_price >= self.atr_plot[sym]['profit'][-1] or sym_price <= self.atr_plot[sym]['loss'][-1]: q = self.portfolio.positions[sym].amount self.order(sym,-q) print str(date)[0:10],'Exit:',sym else: self.zscores[sym].append(0) self.zscores_s[sym].append(0) atr = self.get_atr(sym)[-1] self.atr_plot[sym]['profit'].append((atr*3)+sym_price) self.atr_plot[sym]['loss'].append(-(atr*3)+sym_price) self.day_count += 1
def test_zipline_api_resolves_dynamically(self): # Make a dummy algo. algo = TradingAlgorithm( initialize=lambda context: None, handle_data=lambda context, data: None, sim_params=self.sim_params, ) # Verify that api methods get resolved dynamically by patching them out # and then calling them for method in algo.all_api_methods(): name = method.__name__ sentinel = object() def fake_method(*args, **kwargs): return sentinel setattr(algo, name, fake_method) with ZiplineAPI(algo): self.assertIs(sentinel, getattr(zipline.api, name)())
def test_register_post_init(self): def initialize(algo): algo.initialized = True def handle_data(algo, data): with self.assertRaises(RegisterTradingControlPostInit): algo.set_max_position_size(self.sid, 1, 1) with self.assertRaises(RegisterTradingControlPostInit): algo.set_max_order_size(self.sid, 1, 1) with self.assertRaises(RegisterTradingControlPostInit): algo.set_max_order_count(1) with self.assertRaises(RegisterTradingControlPostInit): algo.set_long_only() algo = TradingAlgorithm(initialize=initialize, handle_data=handle_data) algo.run(self.source) self.source.rewind()
def test_duplicate_pipeline_names(self): """ Test that we raise an error when we try to attach a pipeline with a name that already exists for another attached pipeline. """ def initialize(context): attach_pipeline(Pipeline(), 'test') attach_pipeline(Pipeline(), 'test') algo = TradingAlgorithm( initialize=initialize, data_frequency='daily', get_pipeline_loader=lambda column: self.pipeline_close_loader, start=self.first_asset_start, end=self.last_asset_end, env=self.env, ) with self.assertRaises(DuplicatePipelineName): algo.run(self.data_portal)
def test_assets_appear_on_correct_days(self, test_name, chunksize): """ Assert that assets appear at correct times during a backtest, with correctly-adjusted close price values. """ if chunksize == "all_but_one_day": chunksize = (self.dates.get_loc(self.last_asset_end) - self.dates.get_loc(self.first_asset_start)) - 1 def initialize(context): p = attach_pipeline(Pipeline(), "test", chunksize=chunksize) p.add(USEquityPricing.close.latest, "close") def handle_data(context, data): results = pipeline_output("test") date = get_datetime().normalize() for asset in self.assets: # Assets should appear iff they exist today and yesterday. exists_today = self.exists(date, asset) existed_yesterday = self.exists(date - self.trading_day, asset) if exists_today and existed_yesterday: latest = results.loc[asset, "close"] self.assertEqual(latest, self.expected_close(date, asset)) else: self.assertNotIn(asset, results.index) before_trading_start = handle_data algo = TradingAlgorithm( initialize=initialize, handle_data=handle_data, before_trading_start=before_trading_start, data_frequency="daily", get_pipeline_loader=lambda column: self.pipeline_loader, start=self.first_asset_start, end=self.last_asset_end, env=self.env, ) # Run for a week in the middle of our data. algo.run(self.data_portal)
def test_get_environment(self): expected_env = { 'arena': 'backtest', 'data_frequency': 'minute', 'start': pd.Timestamp('2006-01-03 14:31:00+0000', tz='UTC'), 'end': pd.Timestamp('2006-01-04 21:00:00+0000', tz='UTC'), 'capital_base': 100000.0, 'platform': 'zipline' } def initialize(algo): self.assertEqual('zipline', algo.get_environment()) self.assertEqual(expected_env, algo.get_environment('*')) def handle_data(algo, data): pass algo = TradingAlgorithm(initialize=initialize, handle_data=handle_data, sim_params=self.sim_params) algo.run(self.source)
def test_get_datetime(self, name, tz): algo = dedent( """ import pandas as pd from zipline.api import get_datetime def initialize(context): context.tz = {tz} or 'UTC' context.first_bar = True def handle_data(context, data): if context.first_bar: dt = get_datetime({tz}) if dt.tz.zone != context.tz: raise ValueError("Mismatched Zone") elif dt.tz_convert("US/Eastern").hour != 9: raise ValueError("Mismatched Hour") elif dt.tz_convert("US/Eastern").minute != 31: raise ValueError("Mismatched Minute") context.first_bar = False """.format(tz=repr(tz)) ) start = to_utc('2014-01-02 9:31') end = to_utc('2014-01-03 9:31') source = RandomWalkSource( start=start, end=end, ) sim_params = factory.create_simulation_parameters( data_frequency='minute' ) algo = TradingAlgorithm( script=algo, sim_params=sim_params, identifiers=[1] ) algo.run(source) self.assertFalse(algo.first_bar)
def handle_data(self, data): # overload handle_data() method day = TradingAlgorithm.get_datetime(self) self.dates.append(day) #print self.day_count #print self.portfolio # Get price data for sym in sym_list: sym_price = data[sym].price sym_high = data[sym].high sym_low = data[sym].low self.prices[sym] = np.append(self.prices[sym],sym_price) self.lows[sym] = np.append(self.prices[sym],sym_low) self.highs[sym] = np.append(self.prices[sym],sym_high) # Execute trades for sym in sym_list: if self.day_count >= 0: atr = self.get_atr(sym)[-1] rsi = self.get_rsi(sym)[-1] macd, macdsignal, macdhist = self.get_macd(sym) slowk, slowd = self.get_stoch(sym) # if self.portfolio.positions[sym].amount == 0: if macd[-1] > 0 and rsi > 70 and 50 <= slowk[-1] <= 80: print day,' Long ',sym self.long(data,sym) self.buy_plot[sym].append(self.day_count) take = (atr*5)+sym_price stop = -(atr*2)+sym_price self.stops[sym] = [take,stop] elif macd[-1] < 0 and rsi < 30 and 20 <= slowk[-1] <= 50: print day,' Short ',sym self.short(data,sym) self.sell_plot[sym].append(self.day_count) take = -(atr*5)+sym_price stop = (atr*2)+sym_price self.stops[sym] = [take,stop] else: pass elif self.portfolio.positions[sym].amount > 0: if sym_price >= self.stops[sym][0] or sym_price <= self.stops[sym][1]: print day,' Exit Long ',sym q = self.portfolio.positions[sym].amount self.order(sym,-q) self.sell_plot[sym].append(self.day_count) elif self.portfolio.positions[sym].amount < 0: if sym_price <= self.stops[sym][0] or sym_price >= self.stops[sym][1]: print day,' Exit Short ',sym q = self.portfolio.positions[sym].amount self.order(sym,-q) self.buy_plot[sym].append(self.day_count) self.day_count += 1
def test_assets_appear_on_correct_days(self): """ Assert that assets appear at correct times during a backtest, with correctly-adjusted close price values. """ def initialize(context): p = Pipeline('test') p.add(USEquityPricing.close.latest, 'close') attach_pipeline(p) def handle_data(context, data): results = pipeline_output('test') date = get_datetime().normalize() for asset in self.assets: # Assets should appear iff they exist today and yesterday. exists_today = self.exists(date, asset) existed_yesterday = self.exists(date - trading_day, asset) if exists_today and existed_yesterday: latest = results.loc[asset, 'close'] self.assertEqual(latest, self.expected_close(date, asset)) else: self.assertNotIn(asset, results.index) before_trading_start = handle_data algo = TradingAlgorithm( initialize=initialize, handle_data=handle_data, before_trading_start=before_trading_start, data_frequency='daily', pipeline_loader=self.pipeline_loader, start=self.first_asset_start - trading_day, end=self.last_asset_end + trading_day, env=self.env, ) # Run for a week in the middle of our data. algo.run(source=self.closes.iloc[10:17])
def test_empty_pipeline(self): # For ensuring we call before_trading_start. count = [0] def initialize(context): pipeline = attach_pipeline(Pipeline(), 'test') vwap = VWAP(window_length=10) pipeline.add(vwap, 'vwap') # Nothing should have prices less than 0. pipeline.set_screen(vwap < 0) def handle_data(context, data): pass def before_trading_start(context, data): context.results = pipeline_output('test') self.assertTrue(context.results.empty) count[0] += 1 algo = TradingAlgorithm( initialize=initialize, handle_data=handle_data, before_trading_start=before_trading_start, data_frequency='daily', get_pipeline_loader=lambda column: self.pipeline_loader, start=self.dates[0], end=self.dates[-1], env=self.env, ) algo.run( source=self.make_source(), overwrite_sim_params=False, ) self.assertTrue(count[0] > 0)
def test_api_symbol(self): algo = TradingAlgorithm(script=api_symbol_algo) algo.run(self.df)
def test_volshare_slippage(self): # verify order -> transaction -> portfolio position. # -------------- test_algo = TradingAlgorithm( script=""" from zipline.api import * def initialize(context): model = slippage.VolumeShareSlippage( volume_limit=.3, price_impact=0.05 ) set_slippage(model) set_commission(commission.PerShare(0.02)) context.count = 2 context.incr = 0 def handle_data(context, data): if context.incr < context.count: # order small lots to be sure the # order will fill in a single transaction order(0, 5000) record(price=data[0].price) record(volume=data[0].volume) record(incr=context.incr) context.incr += 1 """, sim_params=self.sim_params, ) set_algo_instance(test_algo) self.zipline_test_config['algorithm'] = test_algo self.zipline_test_config['trade_count'] = 100 # 67 will be used inside assert_single_position # to confirm we have as many transactions as expected. # The algo places 2 trades of 5000 shares each. The trade # events have volume ranging from 100 to 950. The volume cap # of 0.3 limits the trade volume to a range of 30 - 316 shares. # The spreadsheet linked below calculates the total position # size over each bar, and predicts 67 txns will be required # to fill the two orders. The number of bars and transactions # differ because some bars result in multiple txns. See # spreadsheet for details: # https://www.dropbox.com/s/ulrk2qt0nrtrigb/Volume%20Share%20Worksheet.xlsx self.zipline_test_config['expected_transactions'] = 67 # self.zipline_test_config['transforms'] = \ # test_algo.transform_visitor.transforms.values() zipline = simfactory.create_test_zipline(**self.zipline_test_config) output, _ = assert_single_position(self, zipline) # confirm the slippage and commission on a sample # transaction per_share_commish = 0.02 perf = output[1] transaction = perf['daily_perf']['transactions'][0] commish = transaction['amount'] * per_share_commish self.assertEqual(commish, transaction['commission']) self.assertEqual(2.029, transaction['price'])
import pandas_datareader.data as reader import datetime import matplotlib.pyplot as plt from zipline.api import order, symbol from zipline.algorithm import TradingAlgorithm start_time = datetime.datetime(2016, 2, 19) end_time = datetime.datetime(2019, 10, 4) dat = reader.DataReader("078930.KS", "yahoo", start_time, end_time) dat = dat[dat["Volume"] != 0] dat = dat[["Adj Close"]] dat.columns = ["078930.KS"] dat = dat.tz_localize("UTC") def initialize(context): pass def handle_data(context, dat): order(symbol("078930.KS"), 1) algo = TradingAlgorithm( initialize=initialize, handle_data=handle_data ) # zipline api bug. reference -> https://github.com/quantopian/zipline/issues/2480
log.info('Has open orders, not rebalancing.') else: context.rebalance_date = exchange_time context.next_rebalance_date = context.rebalance_date + timedelta( days=context.rebalance_days) rebalance(context, data, exchange_time) def rebalance(context, data, exchange_time): for sid in context.sids: if sid in data: order_target_percent(sid, context.sids[sid]) # handle_data functions algo_obj = TradingAlgorithm(initialize=initialize, handle_data=handle_data) # Run algorithm data = load_data() start_time = time.time() #cProfile.run('algo_obj.run(data)', 'restats') algo_obj.run(data) #p = pstats.Stats('restats') #p.strip_dirs().sort_stats(-1).print_stats() #p.sort_stats('cumulative').print_stats(20) #p.sort_stats('time').print_stats(10) #perf_manual = algo_obj.run(data) #RiskMetricsCumulative print "Risk Metrics" print type(algo_obj.perf_tracker.cumulative_risk_metrics)
def _run( handle_data, initialize, before_trading_start, analyze, algofile, algotext, defines, data_frequency, capital_base, bundle, bundle_timestamp, start, end, output, trading_calendar, print_algo, metrics_set, local_namespace, environ, blotter, custom_loader, benchmark_spec, ): """Run a backtest for the given algorithm. This is shared between the cli and :func:`zipline.run_algo`. """ bundle_data = bundles.load( bundle, environ, bundle_timestamp, ) if trading_calendar is None: trading_calendar = get_calendar("XNYS") # date parameter validation if trading_calendar.session_distance(start, end) < 1: raise _RunAlgoError( "There are no trading days between %s and %s" % ( start.date(), end.date(), ), ) benchmark_sid, benchmark_returns = benchmark_spec.resolve( asset_finder=bundle_data.asset_finder, start_date=start, end_date=end, ) if algotext is not None: if local_namespace: ip = get_ipython() # noqa namespace = ip.user_ns else: namespace = {} for assign in defines: try: name, value = assign.split("=", 2) except ValueError: raise ValueError( "invalid define %r, should be of the form name=value" % assign, ) try: # evaluate in the same namespace so names may refer to # eachother namespace[name] = eval(value, namespace) except Exception as e: raise ValueError( "failed to execute definition for name %r: %s" % (name, e), ) elif defines: raise _RunAlgoError( "cannot pass define without `algotext`", "cannot pass '-D' / '--define' without '-t' / '--algotext'", ) else: namespace = {} if algofile is not None: algotext = algofile.read() if print_algo: if PYGMENTS: highlight( algotext, PythonLexer(), TerminalFormatter(), outfile=sys.stdout, ) else: click.echo(algotext) first_trading_day = bundle_data.equity_minute_bar_reader.first_trading_day data = DataPortal( bundle_data.asset_finder, trading_calendar=trading_calendar, first_trading_day=first_trading_day, equity_minute_reader=bundle_data.equity_minute_bar_reader, equity_daily_reader=bundle_data.equity_daily_bar_reader, adjustment_reader=bundle_data.adjustment_reader, ) pipeline_loader = USEquityPricingLoader.without_fx( bundle_data.equity_daily_bar_reader, bundle_data.adjustment_reader, ) def choose_loader(column): if column in USEquityPricing.columns: return pipeline_loader try: return custom_loader.get(column) except KeyError: raise ValueError("No PipelineLoader registered for column %s." % column) if isinstance(metrics_set, str): try: metrics_set = metrics.load(metrics_set) except ValueError as e: raise _RunAlgoError(str(e)) if isinstance(blotter, str): try: blotter = load(Blotter, blotter) except ValueError as e: raise _RunAlgoError(str(e)) try: perf = TradingAlgorithm( namespace=namespace, data_portal=data, get_pipeline_loader=choose_loader, trading_calendar=trading_calendar, sim_params=SimulationParameters( start_session=start, end_session=end, trading_calendar=trading_calendar, capital_base=capital_base, data_frequency=data_frequency, ), metrics_set=metrics_set, blotter=blotter, benchmark_returns=benchmark_returns, benchmark_sid=benchmark_sid, **{ "initialize": initialize, "handle_data": handle_data, "before_trading_start": before_trading_start, "analyze": analyze, } if algotext is None else { "algo_filename": getattr(algofile, "name", "<algorithm>"), "script": algotext, }).run() except NoBenchmark: raise _RunAlgoError( ("No ``benchmark_spec`` was provided, and" " ``zipline.api.set_benchmark`` was not called in" " ``initialize``."), ("Neither '--benchmark-symbol' nor '--benchmark-sid' was" " provided, and ``zipline.api.set_benchmark`` was not called" " in ``initialize``. Did you mean to pass '--no-benchmark'?"), ) if output == "-": click.echo(str(perf)) elif output != os.devnull: # make the zipline magic not write any data perf.to_pickle(output) return perf
plt.legend(loc=0) plt.gcf().set_size_inches(18, 8) else: msg = 'AAPL, short_ema and long_ema data not captured using record().' ax2.annotate(msg, xy=(0.1, 0.5)) log.info(msg) plt.show() # Note: this if-block should be removed if running # this algorithm on quantopian.com if __name__ == '__main__': from datetime import datetime import pytz from zipline.algorithm import TradingAlgorithm from zipline.utils.factory import load_from_yahoo # Set the simulation start and end dates. dl = DownLoad() data = dl.load_data('603600') data['yygf'] = data['close'] transform = DataFrame(data, columns=['yygf']) transform.index = data['date'] transform.index = transform.index.tz_localize('UTC') #这一步比较重要 # Create and run the algorithm. algo = TradingAlgorithm(initialize=initialize, handle_data=handle_data)#identifiers=['yygf'] 这个必须不要,不然总去下个数据 results = algo.run(transform).dropna() # Plot the portfolio and asset data. analyze(results=results)
def test_noop_string(self): algo = TradingAlgorithm(script=noop_algo) algo.run(self.df)
def test_api_get_environment(self): environment = 'zipline' algo = TradingAlgorithm(script=api_get_environment_algo, environment=environment) algo.run(self.df) self.assertEqual(algo.environment, environment)
from zipline.algorithm import TradingAlgorithm # data start = datetime.datetime(2010, 1, 1) end = datetime.datetime(2016, 3, 19) data = web.DataReader("AAPL", "yahoo", start, end) # 애플에 대한 데이터 # 백테스팅에는 수정 종가만 사용되므로 DataFrame 객체에서 해당 칼럼만 가져오고 칼럼의 이름도 'AAPL'로 변경 data = data[['Adj Close']] data.columns = ['AAPL'] data = data.tz_localize('UTC') # Zipline 백테스팅 시뮬레이터는 시뮬레이션을 수행하기 전에 항상 initialize 함수를 호출 def initialize(context): """ 시뮬레이션에 사용할 초기 투자 금액이나 거래 수수료와 같은 값들을 설정 """ pass # Zipline 시뮬레이터는 시뮬레이션을 수행하는 동안 거래일마다 handle_data를 호출 def handle_data(context, data): """ 실제 거래 알고리즘 구현 """ order(symbol('AAPL'), 1) algo = TradingAlgorithm(initialize=initialize, handle_data=handle_data) result = algo.run(data) # 일별 매수 알고리즘 시뮬레이션 결과 바인딩 plt.plot(result.index, result.portfolio_value) # portfolio_value: 보유 현금과 주식 평가 금액을 합산한 금액 plt.show()
import matplotlib matplotlib.use('Qt5Agg') import matplotlib.pyplot as plt def initialize(context): pass def handle_data(context, data): order(symbol('AAPL'), 1) start = datetime.datetime(2013, 1, 1) end = datetime.datetime.now() - datetime.timedelta(3) data = web.DataReader("AAPL", "yahoo", start, end) data = data[['Adj Close']] data.columns = ["AAPL"] data = data.tz_localize("UTC") algo = TradingAlgorithm(initialize=initialize, handle_data=handle_data) results = algo.run(data) plt.plot(data.index, results.ending_cash, label='ending_cash') plt.plot(data.index, results.ending_value, label='ending_value') plt.plot(data.index, results.portfolio_value, label='portfolio_value') plt.legend(loc='best') plt.grid() plt.show()
def test_api_calls_string(self): algo = TradingAlgorithm(script=api_algo) algo.run(self.df)
results.AAPL.plot(ax=ax2) ax2.set_ylabel('AAPL price (USD)') # Show the plot. plt.gcf().set_size_inches(18, 8) plt.show() # Note: this if-block should be removed if running # this algorithm on quantopian.com if __name__ == '__main__': from datetime import datetime import pytz from zipline.algorithm import TradingAlgorithm from zipline.utils.factory import load_from_yahoo # Set the simulation start and end dates start = datetime(2014, 1, 1, 0, 0, 0, 0, pytz.utc) end = datetime(2014, 11, 1, 0, 0, 0, 0, pytz.utc) # Load price data from yahoo. data = load_from_yahoo(stocks=['AAPL'], indexes={}, start=start, end=end) # Create and run the algorithm. algo = TradingAlgorithm(initialize=initialize, handle_data=handle_data, identifiers=['AAPL']) results = algo.run(data) analyze(results=results)
def test_api_get_environment(self): platform = 'zipline' algo = TradingAlgorithm(script=api_get_environment_algo, platform=platform) algo.run(self.df) self.assertEqual(algo.environment, platform)
pass def before_trading_start(context, data): context.pipeline_data = pipeline_output('my_pipeline') #print("pipeline_data",type(context.pipeline_data)) #print(context.portfolio) pass ################################################################################################################################################# for i in range(0,len(g_models)): #for i in range(0,4): g_idx = i algor_obj = TradingAlgorithm(initialize=initialize, handle_data=handle_data,before_trading_start = before_trading_start, sim_params=sim_params, env=trading_environment, data_frequency = 'daily', get_pipeline_loader = choose_loader, ) result = algor_obj.run(data) #result.to_csv("result.csv", encoding="utf-8") #print(result) # for index,values in result.iterrows(): # print index # for t in values['transactions']: # print t # print "++++++++++++++++++++++++++++++++++++++++++++" # for x in result.columns:
def test_noop(self): algo = TradingAlgorithm(initialize=initialize_noop, handle_data=handle_data_noop) algo.run(self.df)
def test_handle_adjustment(self, set_screen): AAPL, MSFT, BRK_A = assets = self.AAPL, self.MSFT, self.BRK_A window_lengths = [1, 2, 5, 10] vwaps = self.compute_expected_vwaps(window_lengths) def vwap_key(length): return "vwap_%d" % length def initialize(context): pipeline = Pipeline() context.vwaps = [] for length in vwaps: name = vwap_key(length) factor = VWAP(window_length=length) context.vwaps.append(factor) pipeline.add(factor, name=name) filter_ = (USEquityPricing.close.latest > 300) pipeline.add(filter_, 'filter') if set_screen: pipeline.set_screen(filter_) attach_pipeline(pipeline, 'test') def handle_data(context, data): today = get_datetime() results = pipeline_output('test') expect_over_300 = { AAPL: today < self.AAPL_split_date, MSFT: False, BRK_A: True, } for asset in assets: should_pass_filter = expect_over_300[asset] if set_screen and not should_pass_filter: self.assertNotIn(asset, results.index) continue asset_results = results.loc[asset] self.assertEqual(asset_results['filter'], should_pass_filter) for length in vwaps: computed = results.loc[asset, vwap_key(length)] expected = vwaps[length][asset].loc[today] # Only having two places of precision here is a bit # unfortunate. assert_almost_equal(computed, expected, decimal=2) # Do the same checks in before_trading_start before_trading_start = handle_data algo = TradingAlgorithm( initialize=initialize, handle_data=handle_data, before_trading_start=before_trading_start, data_frequency='daily', get_pipeline_loader=lambda column: self.pipeline_loader, start=self.dates[max(window_lengths)], end=self.dates[-1], env=self.env, ) algo.run( source=self.make_source(), # Yes, I really do want to use the start and end dates I passed to # TradingAlgorithm. overwrite_sim_params=False, )
def _run(handle_data, initialize, before_trading_start, analyze, algofile, algotext, defines, data_frequency, capital_base, data, bundle, bundle_timestamp, start, end, output, trading_calendar, print_algo, metrics_set, local_namespace, environ, blotter, additional_loaders): """Run a backtest for the given algorithm. This is shared between the cli and :func:`zipline.run_algo`. """ if algotext is not None: if local_namespace: ip = get_ipython() # noqa namespace = ip.user_ns else: namespace = {} for assign in defines: try: name, value = assign.split('=', 2) except ValueError: raise ValueError( 'invalid define %r, should be of the form name=value' % assign, ) try: # evaluate in the same namespace so names may refer to # eachother namespace[name] = eval(value, namespace) except Exception as e: raise ValueError( 'failed to execute definition for name %r: %s' % (name, e), ) elif defines: raise _RunAlgoError( 'cannot pass define without `algotext`', "cannot pass '-D' / '--define' without '-t' / '--algotext'", ) else: namespace = {} if algofile is not None: algotext = algofile.read() if print_algo: if PYGMENTS: highlight( algotext, PythonLexer(), TerminalFormatter(), outfile=sys.stdout, ) else: click.echo(algotext) if trading_calendar is None: trading_calendar = get_calendar('NYSE') # date parameter validation if trading_calendar.session_distance(start, end) < 1: raise _RunAlgoError( 'There are no trading days between %s and %s' % ( start.date(), end.date(), ), ) if bundle is not None: bundle_data = bundles.load( bundle, environ, bundle_timestamp, ) prefix, connstr = re.split( r'sqlite:///', str(bundle_data.asset_finder.engine.url), maxsplit=1, ) if prefix: raise ValueError( "invalid url %r, must begin with 'sqlite:///'" % str(bundle_data.asset_finder.engine.url), ) env = TradingEnvironment( asset_db_path=connstr, environ=environ, trading_calendar=trading_calendar, trading_day=trading_calendar.day, trading_days=trading_calendar.schedule[start:end].index, ) first_trading_day =\ bundle_data.equity_minute_bar_reader.first_trading_day data = DataPortal( env.asset_finder, trading_calendar=trading_calendar, first_trading_day=first_trading_day, equity_minute_reader=bundle_data.equity_minute_bar_reader, equity_daily_reader=bundle_data.equity_daily_bar_reader, adjustment_reader=bundle_data.adjustment_reader, ) pipeline_loader = USEquityPricingLoader( bundle_data.equity_daily_bar_reader, bundle_data.adjustment_reader, ) def choose_loader(column): if column in USEquityPricing.columns: return pipeline_loader if additional_loaders is not None: loader = additional_loaders.get(column) if loader is not None: return loader raise ValueError("No PipelineLoader registered for column %s." % column) else: env = TradingEnvironment( environ=environ, trading_calendar=trading_calendar, trading_day=trading_calendar.day, trading_days=trading_calendar.schedule[start:end].index, ) choose_loader = None if isinstance(metrics_set, six.string_types): try: metrics_set = metrics.load(metrics_set) except ValueError as e: raise _RunAlgoError(str(e)) if isinstance(blotter, six.string_types): try: blotter = load(Blotter, blotter) except ValueError as e: raise _RunAlgoError(str(e)) perf = TradingAlgorithm( namespace=namespace, env=env, get_pipeline_loader=choose_loader, trading_calendar=trading_calendar, sim_params=create_simulation_parameters( start=start, end=end, capital_base=capital_base, data_frequency=data_frequency, trading_calendar=trading_calendar, ), metrics_set=metrics_set, blotter=blotter, **{ 'initialize': initialize, 'handle_data': handle_data, 'before_trading_start': before_trading_start, 'analyze': analyze, } if algotext is None else { 'algo_filename': getattr(algofile, 'name', '<algorithm>'), 'script': algotext, }).run( data, overwrite_sim_params=False, ) if output == '-': click.echo(str(perf)) elif output != os.devnull: # make the zipline magic not write any data perf.to_pickle(output) return perf
trading.environment = TradingEnvironment(load=load_t, bm_symbol='^HSI', exchange_tz='Asia/Shanghai') # 回测参数设置 sim_params = create_simulation_parameters( year=2014, start=pd.to_datetime("2001-01-01 00:00:00").tz_localize("Asia/Shanghai"), end=pd.to_datetime("2001-09-21 00:00:00").tz_localize("Asia/Shanghai"), data_frequency="daily", emission_rate="daily") # 原始版本是上面这样的,代码里面是交易日历,然而,如何产生交易日历呢? # setting the algo parameters algor_obj = TradingAlgorithm(initialize=initialize, handle_data=handle_data, sim_params=sim_params, env=trading.environment, analyze=analyze) parse = lambda x: datetime.date(datetime.strptime(x, '%Y/%m/%d')) # data generator data_s = pd.read_csv('AAPL.csv', parse_dates=['Date'], index_col=0, date_parser=parse) print(data_s) data_c = pd.Panel({'AAPL': data_s}) perf_manual = algor_obj.run(data_c) # Print perf_manual.to_csv('myoutput.csv')
buy=buy, sell=sell) #============================================================================== # sym = symbol('HMD') # # order_target(sym,1) #============================================================================== data = data[['Adj Close']] data.columns = ['HMD'] algo = TradingAlgorithm(capital_base=10000000, initialize=initialize, handle_data=handle_data, identifiers=['HMD']) results = algo.run(data) print(results.info()) print(results.buy) ax = results[['ma5', 'ma20']].plot(figsize=(16, 4)) ax.plot(results.ix[results.buy == True].index, results.ma5[results.buy == True], '^') ax.plot(results.ix[results.sell == True].index, results.ma5[results.sell == True], '^') results['ending_cash'].plot(figsize=(16, 4), secondary_y=True) results['portfolio_value'].plot()
import pytz from datetime import datetime from zipline.algorithm import TradingAlgorithm from zipline.utils.factory import load_bars_from_yahoo # Load data manually from Yahoo! finance stocks = ['AAPL'] start = datetime(2000, 1, 1, 0, 0, 0, 0, pytz.utc) end = datetime(2012, 1, 1, 0, 0, 0, 0, pytz.utc) data = load_bars_from_yahoo(stocks=stocks, start=start, end=end) algo_obj = TradingAlgorithm(initialize=initialize, handle_data=handle_data) perf_manual = algo_obj.run(data)
cash=cash, value=value) elif (MA1 < MA2) and current_positions != 0: order_target(context.security, 0) record(date=date, MA1=MA1, MA2=MA2, Price=current_price, status="sell", shares="--", PnL=current_pnl, cash=cash, value=value) else: record(date=date, MA1=MA1, MA2=MA2, Price=current_price, status="--", shares="--", PnL=current_pnl, cash=cash, value=value) algo_obj = TradingAlgorithm(initialize=initialize, handle_data=strategy) #run algo perf_manual = algo_obj.run(panel)
def test_api_calls(self): algo = TradingAlgorithm(initialize=initialize_api, handle_data=handle_data_api) algo.run(self.df)