def testTwoBarReturns_CloseClose(self): initialCash = 15.90 bar_feed = yahoofeed.Feed() bar_feed.set_bar_filter( csvfeed.DateRangeFilter( strategy_test.datetime_from_date(2001, 12, 06), strategy_test.datetime_from_date(2001, 12, 07))) bar_feed.add_bars_from_csv( ReturnsTestCase.TestInstrument, common.get_data_file_path("orcl-2001-yahoofinance.csv")) strat = strategy_test.TestStrategy(bar_feed, initialCash) # 2001-12-06,15.61,16.03,15.50,15.90,66944900,15.55 # 2001-12-07,15.74,15.95,15.55,15.91,42463200,15.56 # Manually place the entry order, to get it filled on the first bar. order = strat.get_broker().create_market_order( broker.Order.Action.BUY, ReturnsTestCase.TestInstrument, 1, True) # Close: 15.90 strat.get_broker().place_order(order) strat.addOrder(strategy_test.datetime_from_date(2001, 12, 06), strat.get_broker().create_market_order, broker.Order.Action.SELL, ReturnsTestCase.TestInstrument, 1, True) # Close: 15.91 stratAnalyzer = returns.Returns() strat.attach_analyzer(stratAnalyzer) strat.run() self.assertTrue(strat.get_broker().get_cash() == initialCash + (15.91 - 15.90)) # First day returns: 0 self.assertTrue(stratAnalyzer.get_returns()[0] == 0) # Second day returns: Open vs Prev. day's close self.assertTrue(stratAnalyzer.get_returns()[1] == (15.91 - 15.90) / 15.90)
def testIGE_BrokerWithCommission(self): commision = 0.5 initialCash = 42.09 + commision # This testcase is based on an example from Ernie Chan's book: # 'Quantitative Trading: How to Build Your Own Algorithmic Trading Business' bar_feed = yahoofeed.Feed() bar_feed.add_bars_from_csv( "ige", common.get_data_file_path("sharpe-ratio-test-ige.csv")) brk = backtesting.Broker(initialCash, bar_feed, backtesting.FixedCommission(commision)) strat = strategy_test.TestStrategy(bar_feed, initialCash, brk) strat.get_broker().set_use_adj_values(True) strat.setBrokerOrdersGTC(True) stratAnalyzer = sharpe.SharpeRatio() strat.attach_analyzer(stratAnalyzer) # Manually place the order to get it filled on the first bar. order = strat.get_broker().create_market_order( broker.Order.Action.BUY, "ige", 1, True) # Adj. Close: 42.09 order.set_good_until_canceled(True) strat.get_broker().place_order(order) strat.addOrder(strategy_test.datetime_from_date(2007, 11, 13), strat.get_broker().create_market_order, broker.Order.Action.SELL, "ige", 1, True) # Adj. Close: 127.64 strat.run() self.assertTrue( round(strat.get_broker().get_cash(), 2) == initialCash + (127.64 - 42.09 - commision * 2)) self.assertTrue(strat.get_order_updated_events() == 2) # The results are slightly different only because I'm taking into account the first bar as well, # and I'm also adding commissions. self.assertEqual( round(stratAnalyzer.get_sharpe_ratio(0.04, 252, annualized=True), 6), 0.776443)
def testOneBarReturn(self): initialCash = 1000 bar_feed = yahoofeed.Feed() bar_feed.set_bar_filter( csvfeed.DateRangeFilter( strategy_test.datetime_from_date(2001, 12, 07), strategy_test.datetime_from_date(2001, 12, 07))) bar_feed.add_bars_from_csv( ReturnsTestCase.TestInstrument, common.get_data_file_path("orcl-2001-yahoofinance.csv")) strat = strategy_test.TestStrategy(bar_feed, initialCash) # 2001-12-07,15.74,15.95,15.55,15.91,42463200,15.56 # Manually place the orders to get them filled on the first (and only) bar. order = strat.get_broker().create_market_order( broker.Order.Action.BUY, ReturnsTestCase.TestInstrument, 1, False) # Open: 15.74 strat.get_broker().place_order(order) order = strat.get_broker().create_market_order( broker.Order.Action.SELL, ReturnsTestCase.TestInstrument, 1, True) # Close: 15.91 strat.get_broker().place_order(order) stratAnalyzer = returns.Returns() strat.attach_analyzer(stratAnalyzer) strat.run() self.assertTrue(strat.get_broker().get_cash() == initialCash + (15.91 - 15.74)) finalValue = 1000 - 15.74 + 15.91 rets = (finalValue - initialCash) / float(initialCash) self.assertEqual(stratAnalyzer.get_returns()[-1], rets)
def run_strategy(smaPeriod): # Load the yahoo feed from the CSV file feed = yahoofeed.Feed() feed.add_bars_from_csv("orcl", "orcl-2000.csv") # Evaluate the strategy with the feed's bars. myStrategy = MyStrategy(feed, smaPeriod) myStrategy.run()
def __test(self, strategy_class, finalValue): feed = yahoofeed.Feed() feed.add_bars_from_csv( "orcl", common.get_data_file_path("orcl-2001-yahoofinance.csv")) myStrategy = strategy_class(feed, 10, 25) myStrategy.run() myStrategy.printDebug("Final result:", round(myStrategy.getFinalValue(), 2)) self.assertTrue(round(myStrategy.getFinalValue(), 2) == finalValue)
def testWithPerFileTimezone(self): bar_feed = yahoofeed.Feed() bar_feed.add_bars_from_csv(YahooTestCase.TestInstrument, common.get_data_file_path("orcl-2000-yahoofinance.csv"), marketsession.USEquities.getTimezone()) bar_feed.add_bars_from_csv(YahooTestCase.TestInstrument, common.get_data_file_path("orcl-2001-yahoofinance.csv"), marketsession.USEquities.getTimezone()) bar_feed.start() for bars in bar_feed: bar = bars.get_bar(YahooTestCase.TestInstrument) self.assertFalse(dt.datetime_is_naive(bar.get_date_time())) bar_feed.stop() bar_feed.join()
def testMapTypeOperations(self): bar_feed = yahoofeed.Feed() bar_feed.add_bars_from_csv(YahooTestCase.TestInstrument, common.get_data_file_path("orcl-2000-yahoofinance.csv"), marketsession.USEquities.getTimezone()) bar_feed.start() for bars in bar_feed: self.assertTrue(YahooTestCase.TestInstrument in bars) self.assertFalse(YahooTestCase.TestInstrument not in bars) bars[YahooTestCase.TestInstrument] with self.assertRaises(KeyError): bars["pirulo"] bar_feed.stop() bar_feed.join()
def testNoTrades(self): bar_feed = yahoofeed.Feed() bar_feed.add_bars_from_csv("ige", common.get_data_file_path("sharpe-ratio-test-ige.csv")) bar_feed.add_bars_from_csv("spy", common.get_data_file_path("sharpe-ratio-test-spy.csv")) strat = strategy_test.TestStrategy(bar_feed, 1000) strat.setBrokerOrdersGTC(True) strat.get_broker().set_use_adj_values(True) stratAnalyzer = drawdown.DrawDown() strat.attach_analyzer(stratAnalyzer) strat.run() self.assertTrue(strat.get_broker().get_cash() == 1000) self.assertTrue(strat.get_order_updated_events() == 0) self.assertTrue(stratAnalyzer.get_max_draw_down() == 0) self.assertTrue(stratAnalyzer.get_longest_draw_down_duration()== 0)
def testNoTrades(self): bar_feed = yahoofeed.Feed() bar_feed.add_bars_from_csv( "ige", common.get_data_file_path("sharpe-ratio-test-ige.csv")) strat = strategy_test.TestStrategy(bar_feed, 1000) stratAnalyzer = sharpe.SharpeRatio() strat.attach_analyzer(stratAnalyzer) strat.run() self.assertTrue(strat.get_broker().get_cash() == 1000) self.assertTrue( stratAnalyzer.get_sharpe_ratio(0.04, 252, annualized=True) == 0) self.assertTrue(stratAnalyzer.get_sharpe_ratio(0, 252) == 0) self.assertTrue( stratAnalyzer.get_sharpe_ratio(0, 252, annualized=True) == 0)
def testDifferentTimezones(self): # Market times in UTC: # - TSE: 0hs ~ 6hs # - US: 14:30hs ~ 21hs feed = yahoofeed.Feed() for year in [2010, 2011]: feed.add_bars_from_csv( "^n225", common.get_data_file_path("nikkei-%d-yahoofinance.csv" % year), marketsession.TSE.getTimezone()) feed.add_bars_from_csv( "spy", common.get_data_file_path("spy-%d-yahoofinance.csv" % year), marketsession.USEquities.getTimezone()) self.__testDifferentTimezonesImpl(feed)
def testLoadDailyBars(self): tmpFeed = TemporarySQLiteFeed(SQLiteFeedTestCase.dbName, bar.Frequency.DAY) with tmpFeed: # Load bars using a Yahoo! feed. yahooFeed = yahoofeed.Feed() yahooFeed.add_bars_from_csv( "orcl", common.get_data_file_path("orcl-2000-yahoofinance.csv"), marketsession.USEquities.timezone) yahooFeed.add_bars_from_csv( "orcl", common.get_data_file_path("orcl-2001-yahoofinance.csv"), marketsession.USEquities.timezone) # Fill the database using the bars from the Yahoo! feed. sqliteFeed = tmpFeed.get_feed() sqliteFeed.get_database().add_bars_from_feed(yahooFeed) # Load the SQLite feed and process all bars. sqliteFeed.load_bars("orcl") sqliteFeed.start() for bars in sqliteFeed: pass sqliteFeed.stop() sqliteFeed.join() # Check that both dataseries have the same bars. yahooDS = yahooFeed["orcl"] sqliteDS = sqliteFeed["orcl"] self.assertEqual(len(yahooDS), len(sqliteDS)) for i in xrange(len(yahooDS)): self.assertEqual(yahooDS[i].get_date_time(), sqliteDS[i].get_date_time()) self.assertEqual(yahooDS[i].get_open(), sqliteDS[i].get_open()) self.assertEqual(yahooDS[i].get_high(), sqliteDS[i].get_high()) self.assertEqual(yahooDS[i].get_low(), sqliteDS[i].get_low()) self.assertEqual(yahooDS[i].get_close(), sqliteDS[i].get_close()) self.assertEqual(yahooDS[i].get_adj_close(), sqliteDS[i].get_adj_close()) self.assertEqual(yahooDS[i].get_bars_until_session_close(), sqliteDS[i].get_bars_until_session_close()) self.assertEqual(yahooDS[i].get_session_close(), sqliteDS[i].get_session_close())
def main(): # Load the orders file. ordersFile = OrdersFile("orders.csv") print "First date", ordersFile.getFirstDate() print "Last date", ordersFile.getLastDate() print "Symbols", ordersFile.get_symbols() # Load the data from QSTK storage. QS environment variable has to be defined. feed = yahoofeed.Feed() feed.set_bar_filter( csvfeed.DateRangeFilter(ordersFile.getFirstDate(), ordersFile.getLastDate())) feed.set_daily_bar_time( datetime.time(0, 0, 0) ) # This is to match the dates loaded with the ones in the orders file. for symbol in ordersFile.get_symbols(): feed.add_bars_from_csv( symbol, os.path.join(os.getenv("QS"), "QSData", "Yahoo", symbol + ".csv")) # Run the strategy. cash = 1000000 use_adjustedClose = True myStrategy = MyStrategy(feed, cash, ordersFile, use_adjustedClose) # Attach returns and sharpe ratio analyzers. retAnalyzer = returns.Returns() myStrategy.attach_analyzer(retAnalyzer) sharpeRatioAnalyzer = sharpe.SharpeRatio() myStrategy.attach_analyzer(sharpeRatioAnalyzer) myStrategy.run() # Print the results. print "Final portfolio value: $%.2f" % myStrategy.get_result() print "Anual return: %.2f %%" % (retAnalyzer.get_cumulative_returns()[-1] * 100) print "Average daily return: %.2f %%" % ( stats.mean(retAnalyzer.get_returns()) * 100) print "Std. dev. daily return: %.4f" % (stats.stddev( retAnalyzer.get_returns())) print "Sharpe ratio: %.2f" % (sharpeRatioAnalyzer.get_sharpe_ratio(0, 252))
def testSharpeRatioIGE_SPY_Broker(self): initialCash = 42.09 # This testcase is based on an example from Ernie Chan's book: # 'Quantitative Trading: How to Build Your Own Algorithmic Trading Business' bar_feed = yahoofeed.Feed() bar_feed.add_bars_from_csv( "ige", common.get_data_file_path("sharpe-ratio-test-ige.csv")) bar_feed.add_bars_from_csv( "spy", common.get_data_file_path("sharpe-ratio-test-spy.csv")) strat = strategy_test.TestStrategy(bar_feed, initialCash) strat.get_broker().set_use_adj_values(True) strat.setBrokerOrdersGTC(True) stratAnalyzer = sharpe.SharpeRatio() strat.attach_analyzer(stratAnalyzer) # Manually place IGE order to get it filled on the first bar. order = strat.get_broker().create_market_order( broker.Order.Action.BUY, "ige", 1, True) # Adj. Close: 42.09 order.set_good_until_canceled(True) strat.get_broker().place_order(order) # Manually place SPY order to get it filled on the first bar. order = strat.get_broker().create_market_order( broker.Order.Action.SELL_SHORT, "spy", 1, True) # Adj. Close: 105.52 order.set_good_until_canceled(True) strat.get_broker().place_order(order) strat.addOrder(strategy_test.datetime_from_date(2007, 11, 13), strat.get_broker().create_market_order, broker.Order.Action.SELL, "ige", 1, True) # Adj. Close: 127.64 strat.addOrder(strategy_test.datetime_from_date(2007, 11, 13), strat.get_broker().create_market_order, broker.Order.Action.BUY_TO_COVER, "spy", 1, True) # Adj. Close: 147.67 strat.run() self.assertTrue(strat.get_order_updated_events() == 4) self.assertTrue( round(strat.get_broker().get_cash(), 2) == round( initialCash + (127.64 - 42.09) + (105.52 - 147.67), 2))
def testGoogle2011(self): initial_value = 1000000 bar_feed = yahoofeed.Feed() bar_feed.add_bars_from_csv( ReturnsTestCase.TestInstrument, common.get_data_file_path("goog-2011-yahoofinance.csv")) strat = strategy_test.TestStrategy(bar_feed, initial_value) order = strat.get_broker().create_market_order( broker.Order.Action.BUY, ReturnsTestCase.TestInstrument, 1654, True) # 2011-01-03 close: 604.35 strat.get_broker().place_order(order) stratAnalyzer = returns.Returns() strat.attach_analyzer(stratAnalyzer) strat.run() finalValue = strat.get_broker().get_value( strat.get_feed().get_last_bars()) self.assertEqual( round(stratAnalyzer.get_cumulative_returns()[-1], 4), round((finalValue - initial_value) / float(initial_value), 4))
def __testIGE_BrokerImpl(self, quantity): initialCash = 42.09*quantity # This testcase is based on an example from Ernie Chan's book: # 'Quantitative Trading: How to Build Your Own Algorithmic Trading Business' bar_feed = yahoofeed.Feed() bar_feed.add_bars_from_csv("ige", common.get_data_file_path("sharpe-ratio-test-ige.csv")) strat = strategy_test.TestStrategy(bar_feed, initialCash) strat.get_broker().set_use_adj_values(True) strat.setBrokerOrdersGTC(True) stratAnalyzer = drawdown.DrawDown() strat.attach_analyzer(stratAnalyzer) # Manually place the order to get it filled on the first bar. order = strat.get_broker().create_market_order(broker.Order.Action.BUY, "ige", quantity, True) # Adj. Close: 42.09 order.set_good_until_canceled(True) strat.get_broker().place_order(order) strat.addOrder(strategy_test.datetime_from_date(2007, 11, 13), strat.get_broker().create_market_order, broker.Order.Action.SELL, "ige", quantity, True) # Adj. Close: 127.64 strat.run() self.assertTrue(round(strat.get_broker().get_cash(), 2) == initialCash + (127.64 - 42.09) * quantity) self.assertTrue(strat.get_order_updated_events() == 2) self.assertTrue(round(stratAnalyzer.get_max_draw_down(), 5) == 0.31178) self.assertTrue(stratAnalyzer.get_longest_draw_down_duration()== 432)
def testCumulativeReturn(self): initialCash = 33.06 bar_feed = yahoofeed.Feed() bar_feed.add_bars_from_csv( ReturnsTestCase.TestInstrument, common.get_data_file_path("orcl-2001-yahoofinance.csv")) strat = strategy_test.TestStrategy(bar_feed, initialCash) strat.addPosEntry(strategy_test.datetime_from_date(2001, 1, 12), strat.enter_long, ReturnsTestCase.TestInstrument, 1) # 33.06 strat.addPosExit(strategy_test.datetime_from_date(2001, 11, 27), strat.exit_position) # 14.32 stratAnalyzer = returns.Returns() strat.attach_analyzer(stratAnalyzer) strat.run() self.assertTrue( round(strat.get_broker().get_cash(), 2) == round( initialCash + (14.32 - 33.06), 2)) self.assertTrue( round(33.06 * (1 + stratAnalyzer.get_cumulative_returns()[-1]), 2) == 14.32)
def loadDailyBarFeed(self): bar_feed = yahoofeed.Feed() bar_feed.add_bars_from_csv( StrategyTestCase.TestInstrument, common.get_data_file_path("orcl-2000-yahoofinance.csv")) return bar_feed
from pytradelib.barfeed import yahoofeed from pytradelib.stratanalyzer import returns from pytradelib.stratanalyzer import sharpe from pytradelib.stratanalyzer import drawdown from pytradelib.stratanalyzer import trades import smacross_strategy # Load the yahoo feed from the CSV file feed = yahoofeed.Feed() feed.add_bars_from_csv("orcl", "orcl-2000.csv") # Evaluate the strategy with the feed's bars. myStrategy = smacross_strategy.Strategy(feed, 20) # Attach different analyzers to a strategy before executing it. retAnalyzer = returns.Returns() myStrategy.attach_analyzer(retAnalyzer) sharpeRatioAnalyzer = sharpe.SharpeRatio() myStrategy.attach_analyzer(sharpeRatioAnalyzer) drawDownAnalyzer = drawdown.DrawDown() myStrategy.attach_analyzer(drawDownAnalyzer) tradesAnalyzer = trades.Trades() myStrategy.attach_analyzer(tradesAnalyzer) # Run the strategy. myStrategy.run() print "Final portfolio value: $%.2f" % myStrategy.get_result() print "Cumulative returns: %.2f %%" % ( retAnalyzer.get_cumulative_returns()[-1] * 100) print "Sharpe ratio: %.2f" % (sharpeRatioAnalyzer.get_sharpe_ratio(0.05, 252))
class YahooTestCase(unittest.TestCase): TestInstrument = "orcl" def __parse_date(self, date): parser = csvfeed.YahooRowParser(datetime.time(23, 59)) row = {"Date":date, "Close":0, "Open":0 , "High":0 , "Low":0 , "Volume":0 , "Adj Close":0} return parser.parse_bar(row).get_date_time() def testParseDate_1(self): date = self.__parse_date("1950-1-1") self.assertTrue(date.day == 1) self.assertTrue(date.month == 1) self.assertTrue(date.year == 1950) def testParseDate_2(self): date = self.__parse_date("2000-1-1") self.assertTrue(date.day == 1) self.assertTrue(date.month == 1) self.assertTrue(date.year == 2000) def testDateCompare(self): self.assertTrue(self.__parse_date("2000-1-1") == self.__parse_date("2000-1-1")) self.assertTrue(self.__parse_date("2000-1-1") != self.__parse_date("2001-1-1")) self.assertTrue(self.__parse_date("1999-1-1") < self.__parse_date("2001-1-1")) self.assertTrue(self.__parse_date("2011-1-1") > self.__parse_date("2001-2-2")) def testCSVFeedLoadOrder(self): bar_feed = csvfeed.YahooFeed() bar_feed.add_bars_from_csv(YahooTestCase.TestInstrument, common.get_data_file_path("orcl-2000-yahoofinance.csv")) bar_feed.add_bars_from_csv(YahooTestCase.TestInstrument, common.get_data_file_path("orcl-2001-yahoofinance.csv")) # Dispatch and handle events. handler = BarFeedEventHandler_TestLoadOrder(self, bar_feed, YahooTestCase.TestInstrument) bar_feed.get_new_bars_event().subscribe(handler.on_bars) while not bar_feed.stop_dispatching(): bar_feed.dispatch() self.assertTrue(handler.get_eventCount() > 0) def __testFilteredRangeImpl(self, from_date, toDate): bar_feed = csvfeed.YahooFeed() bar_feed.set_bar_filter(csvfeed.DateRangeFilter(from_date, toDate)) bar_feed.add_bars_from_csv(YahooTestCase.TestInstrument, common.get_data_file_path("orcl-2000-yahoofinance.csv")) bar_feed.add_bars_from_csv(YahooTestCase.TestInstrument, common.get_data_file_path("orcl-2001-yahoofinance.csv")) # Dispatch and handle events. handler = BarFeedEventHandler_TestFilterRange(self, YahooTestCase.TestInstrument, from_date, toDate) bar_feed.get_new_bars_event().subscribe(handler.on_bars) while not bar_feed.stop_dispatching(): bar_feed.dispatch() self.assertTrue(handler.get_eventCount() > 0) def testFilteredRangeFrom(self): # Only load bars from year 2001. self.__testFilteredRangeImpl(datetime.datetime(2001, 1, 1, 00, 00), None) def testFilteredRangeTo(self): # Only load bars up to year 2000. self.__testFilteredRangeImpl(None, datetime.datetime(2000, 12, 31, 23, 55)) def testFilteredRangeFromTo(self): # Only load bars in year 2000. self.__testFilteredRangeImpl(datetime.datetime(2000, 1, 1, 00, 00), datetime.datetime(2000, 12, 31, 23, 55)) def testWithoutTimezone(self): bar_feed = yahoofeed.Feed() bar_feed.add_bars_from_csv(YahooTestCase.TestInstrument, common.get_data_file_path("orcl-2000-yahoofinance.csv")) bar_feed.add_bars_from_csv(YahooTestCase.TestInstrument, common.get_data_file_path("orcl-2001-yahoofinance.csv")) bar_feed.start() for bars in bar_feed: bar = bars.get_bar(YahooTestCase.TestInstrument) self.assertTrue(dt.datetime_is_naive(bar.get_date_time())) bar_feed.stop() bar_feed.join() def testWithDefaultTimezone(self): bar_feed = yahoofeed.Feed(marketsession.USEquities.getTimezone()) bar_feed.add_bars_from_csv(YahooTestCase.TestInstrument, common.get_data_file_path("orcl-2000-yahoofinance.csv")) bar_feed.add_bars_from_csv(YahooTestCase.TestInstrument, common.get_data_file_path("orcl-2001-yahoofinance.csv")) bar_feed.start() for bars in bar_feed: bar = bars.get_bar(YahooTestCase.TestInstrument) self.assertFalse(dt.datetime_is_naive(bar.get_date_time())) bar_feed.stop() bar_feed.join() def testWithPerFileTimezone(self): bar_feed = yahoofeed.Feed() bar_feed.add_bars_from_csv(YahooTestCase.TestInstrument, common.get_data_file_path("orcl-2000-yahoofinance.csv"), marketsession.USEquities.getTimezone()) bar_feed.add_bars_from_csv(YahooTestCase.TestInstrument, common.get_data_file_path("orcl-2001-yahoofinance.csv"), marketsession.USEquities.getTimezone()) bar_feed.start() for bars in bar_feed: bar = bars.get_bar(YahooTestCase.TestInstrument) self.assertFalse(dt.datetime_is_naive(bar.get_date_time())) bar_feed.stop() bar_feed.join() def testWithIntegerTimezone(self): try: bar_feed = yahoofeed.Feed(-5) self.assertTrue(False, "Exception expected") except Exception, e: self.assertTrue(str(e).find("timezone as an int parameter is not supported anymore") == 0) try: bar_feed = yahoofeed.Feed() bar_feed.add_bars_from_csv(YahooTestCase.TestInstrument, common.get_data_file_path("orcl-2000-yahoofinance.csv"), -3) self.assertTrue(False, "Exception expected") except Exception, e: self.assertTrue(str(e).find("timezone as an int parameter is not supported anymore") == 0)
def testWithIntegerTimezone(self): try: bar_feed = yahoofeed.Feed(-5) self.assertTrue(False, "Exception expected") except Exception, e: self.assertTrue(str(e).find("timezone as an int parameter is not supported anymore") == 0)