def run_strategy(smaPeriod): # Load the bar feed from the CSV file feed = quandlfeed.Feed() feed.addBarsFromCSV( "orcl", "D:/Develop/project/python/PycharmProjects/python3/pyalgotrade/samples/data/WIKI-ORCL-2011-quandl.csv" ) # Evaluate the strategy with the feed's bars myStratege = MyStrategy(feed, "orcl", smaPeriod) # Attach a returns analyzer to to strategy returnsAnalyzer = returns.Returns() myStratege.attachAnalyzer(returnsAnalyzer) # Attach the plotter to the strategy plt = plotter.StrategyPlotter(myStratege) # Include the SMA in the instrument's subplot to get it displayed along with the closing prices plt.getInstrumentSubplot("orcl").addDataSeries("SMA", myStratege.getSMA()) # Plot the simple returns on each bar #plt.getOrCreateSubplot("returns").addDataSeries("Simple Returns", returnsAnalyzer.getReturns()) myStratege.run() myStratege.info("Final portfolio value: $%.2f" % myStratege.getBroker().getEquity()) # Plot the strategy plt.plot()
def testDownloadAndParseDaily_UseAdjClose(self): with common.TmpDir() as tmpPath: symbol = "ORCL" instrument = "%s/%s" % (symbol, PRICE_CURRENCY) path = os.path.join(tmpPath, "quandl-daily-orcl-2010.csv") quandl.download_daily_bars("WIKI", symbol, 2010, path, authToken=QUANDL_API_KEY) bf = quandlfeed.Feed() bf.addBarsFromCSV(instrument, path) # Need to setUseAdjustedValues(True) after loading the file because we # can't tell in advance if adjusted values are there or not. bf.setUseAdjustedValues(True) bf.loadAll() ds = bf.getDataSeries(instrument) self.assertEqual(ds[-1].getDateTime(), datetime.datetime(2010, 12, 31)) self.assertEqual(ds[-1].getOpen(), 31.22) self.assertEqual(ds[-1].getHigh(), 31.33) self.assertEqual(ds[-1].getLow(), 30.93) self.assertEqual(ds[-1].getClose(), 31.3) self.assertEqual(ds[-1].getVolume(), 11716300) self.assertEqual(ds[-1].getPrice(), ds[-1].getAdjClose()) # Not checking against a specific value since this is going to change # as time passes by. self.assertNotEqual(ds[-1].getAdjClose(), None)
def testDownloadAndParseWeekly(self): with common.TmpDir() as tmpPath: instrument = "AAPL" path = os.path.join(tmpPath, "quandl-aapl-weekly-2010.csv") quandl.download_weekly_bars("WIKI", instrument, 2010, path, auth_token) bf = quandlfeed.Feed(frequency=bar.Frequency.WEEK) bf.addBarsFromCSV(instrument, path) bf.loadAll() # Quandl used to report 2010-1-3 as the first week of 2010. self.assertTrue(bf[instrument][0].getDateTime() in [ datetime.datetime(2010, 1, 3), datetime.datetime(2010, 1, 10) ]) self.assertEquals(bf[instrument][-1].getDateTime(), datetime.datetime(2010, 12, 26)) self.assertEquals(bf[instrument][-1].getOpen(), 325.0) self.assertEquals(bf[instrument][-1].getHigh(), 325.15) self.assertEquals(bf[instrument][-1].getLow(), 323.17) self.assertEquals(bf[instrument][-1].getClose(), 323.6) self.assertEquals(bf[instrument][-1].getVolume(), 7969900) self.assertEquals(bf[instrument][-1].getPrice(), 323.6) # Not checking against a specific value since this is going to change # as time passes by. self.assertNotEquals(bf[instrument][-1].getAdjClose(), None)
def testCommandLineDailyCreatingDir(self): tmpPath = tempfile.mkdtemp() shutil.rmtree(tmpPath) try: instrument = "ORCL" subprocess.call([ "python", "-m", "pyalgotrade.tools.quandl", "--source-code=WIKI", "--table-code=%s" % instrument, "--from-year=2010", "--to-year=2010", "--storage=%s" % tmpPath, "--auth-token=%s" % QUANDL_API_KEY ]) bf = quandlfeed.Feed() bf.addBarsFromCSV( instrument, os.path.join(tmpPath, "WIKI-ORCL-2010-quandl.csv")) bf.loadAll() self.assertEqual(bf[instrument][-1].getDateTime(), datetime.datetime(2010, 12, 31)) self.assertEqual(bf[instrument][-1].getOpen(), 31.22) self.assertEqual(bf[instrument][-1].getHigh(), 31.33) self.assertEqual(bf[instrument][-1].getLow(), 30.93) self.assertEqual(bf[instrument][-1].getClose(), 31.3) self.assertEqual(bf[instrument][-1].getVolume(), 11716300) self.assertEqual(bf[instrument][-1].getPrice(), 31.3) finally: shutil.rmtree(tmpPath)
def main(plot): instrument = "orcl" bBandsPeriod = 40 # Download the bars. feed = quandlfeed.Feed() feed.addBarsFromCSV("orcl", "WIKI-ORCL-2015-quandl.csv") strat = BBands(feed, instrument, bBandsPeriod) sharpeRatioAnalyzer = sharpe.SharpeRatio() strat.attachAnalyzer(sharpeRatioAnalyzer) start = strat.getBroker().getEquity() if plot: plt = plotter.StrategyPlotter(strat, True, True, True) plt.getInstrumentSubplot(instrument).addDataSeries( "upper", strat.getBollingerBands().getUpperBand()) plt.getInstrumentSubplot(instrument).addDataSeries( "middle", strat.getBollingerBands().getMiddleBand()) plt.getInstrumentSubplot(instrument).addDataSeries( "lower", strat.getBollingerBands().getLowerBand()) strat.run() print("Sharpe ratio: %.2f" % sharpeRatioAnalyzer.getSharpeRatio(0.05)) final = strat.getBroker().getEquity() print("Net: " + str(final - start)) if plot: plt.plot()
def testDownloadAndParseDailyNoAdjClose(self): with common.TmpDir() as tmpPath: instrument = "IWG" year = 2017 path = os.path.join(tmpPath, "quandl-daily-%s-%s.csv" % (instrument, year)) quandl.download_daily_bars("LSE", instrument, year, path, authToken=QUANDL_API_KEY) bf = quandlfeed.Feed() bf.setNoAdjClose() bf.setColumnName("open", "Price") bf.setColumnName("close", "Price") bf.addBarsFromCSV(instrument, path, skipMalformedBars=True) bf.loadAll() self.assertEqual(bf[instrument][0].getDateTime(), datetime.datetime(year, 1, 3)) self.assertEqual(bf[instrument][0].getOpen(), 237.80) self.assertEqual(bf[instrument][0].getHigh(), 247.00) self.assertEqual(bf[instrument][0].getLow(), 236.30) self.assertEqual(bf[instrument][0].getClose(), 237.80) self.assertEqual(bf[instrument][0].getVolume(), 3494173) self.assertEqual(bf[instrument][0].getAdjClose(), None) self.assertEqual(bf[instrument][0].getPrice(), 237.80)
def testCommandLineWeeklyCreatingDir(self): tmpPath = tempfile.mkdtemp() shutil.rmtree(tmpPath) try: symbol = "AAPL" instrument = "%s/%s" % (symbol, PRICE_CURRENCY) subprocess.call([ "python", "-m", "pyalgotrade.tools.quandl", "--source-code=WIKI", "--table-code=%s" % symbol, "--from-year=2010", "--to-year=2010", "--storage=%s" % tmpPath, "--frequency=weekly", "--auth-token=%s" % QUANDL_API_KEY ]) bf = quandlfeed.Feed() bf.addBarsFromCSV( instrument, os.path.join(tmpPath, "WIKI-AAPL-2010-quandl.csv")) bf.loadAll() ds = bf.getDataSeries(instrument) self.assertEqual(ds[-1].getDateTime(), datetime.datetime(2010, 12, 26)) self.assertEqual(ds[-1].getOpen(), 325.0) self.assertEqual(ds[-1].getHigh(), 325.15) self.assertEqual(ds[-1].getLow(), 323.17) self.assertEqual(ds[-1].getClose(), 323.6) self.assertEqual(ds[-1].getVolume(), 7969900) self.assertEqual(ds[-1].getPrice(), 323.6) finally: shutil.rmtree(tmpPath)
def testDownloadAndParseDailyNoAdjClose(self): with common.TmpDir() as tmpPath: symbol = "ADYEN" instrument = "%s/%s" % (symbol, PRICE_CURRENCY) year = 2018 path = os.path.join(tmpPath, "quandl-daily-%s-%s.csv" % (symbol, year)) quandl.download_daily_bars("EURONEXT", symbol, year, path, authToken=QUANDL_API_KEY) bf = quandlfeed.Feed() bf.setNoAdjClose() bf.setColumnName("open", "Open") bf.setColumnName("high", "High") bf.setColumnName("low", "Low") bf.setColumnName("close", "Last") bf.setColumnName("volume", "Volume") bf.addBarsFromCSV(instrument, path, skipMalformedBars=True) bf.loadAll() ds = bf.getDataSeries(instrument) self.assertEqual(ds[0].getDateTime(), datetime.datetime(year, 6, 13)) self.assertEqual(ds[0].getOpen(), 400.00) self.assertEqual(ds[0].getHigh(), 503.90) self.assertEqual(ds[0].getLow(), 400.00) self.assertEqual(ds[0].getClose(), 455.00) self.assertEqual(ds[0].getVolume(), 1529232) self.assertEqual(ds[0].getAdjClose(), None) self.assertEqual(ds[0].getPrice(), 455.00)
def run_strategy(smaPeriod): # Load the bar feed from the CSV file feed = quandlfeed.Feed() feed.addBarsFromCSV("btc", "BTCUSD_bitstamp_daily.csv") # Evaluate the strategy with the feed's bars. myStrategy = MyStrategy(feed, "btc", smaPeriod) myStrategy.run() print("Final portfolio value: $%.2f" % myStrategy.getBroker().getEquity())
def main(): # Load the bar feed from the CSV file feed = quandlfeed.Feed() feed.addBarsFromCSV("nflx", "WIKI-NFLX-2017-quandl.csv") # Evaluate the strategy with the feed's bars. myStrategy = VWMAStrategy(feed, "nflx", 10000, 70, 50) myStrategy.run() print("Final portfolio value: $%.2f" % myStrategy.getBroker().getEquity())
def run_strategy(smaPeriod): # Load the bar feed from the CSV file feed = quandlfeed.Feed() feed.addBarsFromCSV("orcl", "pyalgotrade/WIKI-ORCL-2000-quandl.csv") # Evaluate the strategy with the feed. myStrategy = MyStrategy(feed, "orcl", smaPeriod) myStrategy.run() print("Final portfolio value: $%.2f" % myStrategy.getBroker().getEquity())
def run_strategy(smaPeriod): # Load the bar feed from the CSV file feed = quandlfeed.Feed() feed.addBarsFromCSV("xom", "D:\WIKI-XOM-2018-quandl.csv") # Evaluate the strategy with the feed. myStrategy = MyStrategy(feed, "xom", smaPeriod) myStrategy.run() print("Final portfolio value: $%.2f" % myStrategy.getBroker().getEquity()) return myStrategy.getBroker().getEquity()
def build_feed(sourceCode, tableCodes, fromYear, toYear, storage, frequency=bar.Frequency.DAY, timezone=None, skipErrors=False, noAdjClose=False, authToken=None): """Build and load a :class:`pyalgotrade.barfeed.quandlfeed.Feed` using CSV files downloaded from Quandl. CSV files are downloaded if they haven't been downloaded before. :param sourceCode: The dataset source code. :type sourceCode: string. :param tableCodes: The dataset table codes. :type tableCodes: list. :param fromYear: The first year. :type fromYear: int. :param toYear: The last year. :type toYear: int. :param storage: The path were the files will be loaded from, or downloaded to. :type storage: string. :param frequency: The frequency of the bars. Only **pyalgotrade.bar.Frequency.DAY** or **pyalgotrade.bar.Frequency.WEEK** are supported. :param timezone: The default timezone to use to localize bars. Check :mod:`pyalgotrade.marketsession`. :type timezone: A pytz timezone. :param skipErrors: True to keep on loading/downloading files in case of errors. :type skipErrors: boolean. :param noAdjClose: True if the instruments don't have adjusted close values. :type noAdjClose: boolean. :param authToken: Optional. An authentication token needed if you're doing more than 50 calls per day. :type authToken: string. :rtype: :class:`pyalgotrade.barfeed.quandlfeed.Feed`. """ logger = pyalgotrade.logger.getLogger("quandl") ret = quandlfeed.Feed(frequency, timezone) if noAdjClose: ret.setNoAdjClose() if not os.path.exists(storage): logger.info("Creating %s directory" % (storage)) os.mkdir(storage) for year in range(fromYear, toYear+1): for tableCode in tableCodes: fileName = os.path.join(storage, "%s-%s-%d-quandl.csv" % (sourceCode, tableCode, year)) if not os.path.exists(fileName): logger.info("Downloading %s %d to %s" % (tableCode, year, fileName)) try: if frequency == bar.Frequency.DAY: download_daily_bars(sourceCode, tableCode, year, fileName, authToken) elif frequency == bar.Frequency.WEEK: download_weekly_bars(sourceCode, tableCode, year, fileName, authToken) else: raise Exception("Invalid frequency") except Exception, e: if skipErrors: logger.error(str(e)) continue else: raise e ret.addBarsFromCSV(tableCode, fileName)
def run_strategy(smaPeriod): instrument = "ORCL/USD" # Load the bar feed from the CSV file feed = quandlfeed.Feed() feed.addBarsFromCSV(instrument, "WIKI-ORCL-2000-quandl.csv") # Evaluate the strategy with the feed. myStrategy = MyStrategy(feed, instrument, {"USD": 1000}, smaPeriod) myStrategy.run() print("Final portfolio value: $%.2f" % myStrategy.getBroker().getEquity("USD"))
def backtest(nsim=N_SIM, history=HISTORY): """ Backtest RL Trader on whole bitstamp dataset :param nsim: Number of simulation to run :return: New entry to DB with info about simulations """ # prepare CSV to read bars from bars_df = db_to_pandas(db_name="trader", table_name="bitstamp_ohlcv", index_name="Datetime") bars_df.dropna(axis=0, inplace=True) bars_df.reset_index(inplace=True) bars_df.columns = [ "Date", "Open", "High", "Low", "Close", "Volume", "to_drop", "Adj Close" ] bars_df.drop(axis=1, columns=["to_drop"], inplace=True) bars_df['Date'] = pd.to_datetime(bars_df['Date'], format='%Y-%m-%d') final_portfolios = list() for i in range(nsim): # read bars bars = quandlfeed.Feed(bar.Frequency.DAY) bars_df.to_csv("data/btc_bars.csv", index=False) bars.addBarsFromCSV('BTC', "data/btc_bars.csv") actions = ['Buy', 'Sell', 'Hold'] budget = INITIAL_CASH # initial cash on hand ncoins = 0.0 params = [actions, budget, ncoins, history, i] RLstrat = RLTraderBacktesting(bars, *params) RLstrat.run() final_portfolios.append(RLstrat.getResult()) # print "Average return out of {} backtesting simulations: {}".format(len(final_portfolios), np.mean(final_portfolios)) # print "Standard deviation of return: {}".format(np.std(final_portfolios)) # print "Best model with saved Q values: {}".format(np.argmax(final_portfolios)) simulation_df = pd.DataFrame( { "Number of simulations": [len(final_portfolios)], "Average return": [np.mean(final_portfolios)], "Std. deviation of return": [np.std(final_portfolios)], "Best model index": [np.argmax(final_portfolios)], "Best model return": [final_portfolios[np.argmax(final_portfolios)]] }, index=[datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')]) pandas_to_db(simulation_df, db_name="trader", table_name="rl_backtesting")
def testDownloadAndParseDailyNoAdjClose(self): with common.TmpDir() as tmpPath: instrument = "ORCL" path = os.path.join(tmpPath, "quandl-daily-orcl-2013.csv") quandl.download_daily_bars("GOOG", "NASDAQ_ORCL", 2013, path, auth_token) bf = quandlfeed.Feed() bf.setNoAdjClose() bf.addBarsFromCSV(instrument, path) bf.loadAll() self.assertEquals(bf[instrument][-1].getDateTime(), datetime.datetime(2013, 12, 31)) self.assertEquals(bf[instrument][-1].getOpen(), 37.94) self.assertEquals(bf[instrument][-1].getHigh(), 38.34) self.assertEquals(bf[instrument][-1].getLow(), 37.88) self.assertEquals(bf[instrument][-1].getClose(), 38.26) self.assertEquals(bf[instrument][-1].getVolume(), 11747517) self.assertEquals(bf[instrument][-1].getAdjClose(), None) self.assertEquals(bf[instrument][-1].getPrice(), 38.26)
def testDownloadAndParseDaily(self): with common.TmpDir() as tmpPath: instrument = "ORCL" path = os.path.join(tmpPath, "quandl-daily-orcl-2010.csv") quandl.download_daily_bars("WIKI", instrument, 2010, path, auth_token) bf = quandlfeed.Feed() bf.addBarsFromCSV(instrument, path) bf.loadAll() self.assertEquals(bf[instrument][-1].getDateTime(), datetime.datetime(2010, 12, 31)) self.assertEquals(bf[instrument][-1].getOpen(), 31.22) self.assertEquals(bf[instrument][-1].getHigh(), 31.33) self.assertEquals(bf[instrument][-1].getLow(), 30.93) self.assertEquals(bf[instrument][-1].getClose(), 31.3) self.assertEquals(bf[instrument][-1].getVolume(), 11716300) self.assertEquals(bf[instrument][-1].getPrice(), 31.3) # Not checking against a specific value since this is going to change # as time passes by. self.assertNotEquals(bf[instrument][-1].getAdjClose(), None)
def testDownloadAndParseDaily(self): with common.TmpDir() as tmpPath: instrument = "ORCL" path = os.path.join(tmpPath, "quandl-daily-orcl-2010.csv") quandl.download_daily_bars("WIKI", instrument, 2010, path, auth_token) bf = quandlfeed.Feed() bf.addBarsFromCSV(instrument, path) bf.loadAll() self.assertEquals(bf[instrument][-1].getDateTime(), datetime.datetime(2010, 12, 31)) self.assertEquals(bf[instrument][-1].getOpen(), 31.22) self.assertEquals(bf[instrument][-1].getHigh(), 31.33) self.assertEquals(bf[instrument][-1].getLow(), 30.93) self.assertEquals(bf[instrument][-1].getClose(), 31.3) self.assertEquals(bf[instrument][-1].getVolume(), 11716300) self.assertEquals(bf[instrument][-1].getAdjClose(), 30.23179912467581) self.assertEquals(bf[instrument][-1].getPrice(), 31.3)
def main(plot): instrument = "AMD" #"orcl" bBandsPeriod = 40 overBoughtThreshold = 70 overSoldThreshold = 30 # Download the bars. feed = quandlfeed.Feed() feed.addBarsFromCSV("AMD", "WIKI-AMD-2016-quandl.csv") strat = BBands(feed, instrument, bBandsPeriod, overBoughtThreshold, overSoldThreshold) strat.getBroker().setCash(1000) sharpeRatioAnalyzer = sharpe.SharpeRatio() strat.attachAnalyzer(sharpeRatioAnalyzer) start = strat.getBroker().getEquity() if plot: plt = plotter.StrategyPlotter(strat, True, True, True) plt.getInstrumentSubplot(instrument).addDataSeries( "upper", strat.getBollingerBands().getUpperBand()) plt.getInstrumentSubplot(instrument).addDataSeries( "middle", strat.getBollingerBands().getMiddleBand()) plt.getInstrumentSubplot(instrument).addDataSeries( "lower", strat.getBollingerBands().getLowerBand()) plt.getOrCreateSubplot("rsi").addDataSeries("RSI", strat.getRSI()) plt.getOrCreateSubplot("rsi").addLine("Overbought", overBoughtThreshold) plt.getOrCreateSubplot("rsi").addLine("Oversold", overSoldThreshold) strat.run() print("Sharpe ratio: %.2f" % sharpeRatioAnalyzer.getSharpeRatio(0.05)) final = strat.getBroker().getEquity() print("Net: " + str(final - start)) if plot: plt.plot()
def testDownloadAndParseDaily_UseAdjClose(self): with common.TmpDir() as tmpPath: instrument = "ORCL" path = os.path.join(tmpPath, "quandl-daily-orcl-2010.csv") quandl.download_daily_bars("WIKI", instrument, 2010, path, auth_token) bf = quandlfeed.Feed() bf.addBarsFromCSV(instrument, path) # Need to setUseAdjustedValues(True) after loading the file because we # can't tell in advance if adjusted values are there or not. bf.setUseAdjustedValues(True) bf.loadAll() self.assertEquals(bf[instrument][-1].getDateTime(), datetime.datetime(2010, 12, 31)) self.assertEquals(bf[instrument][-1].getOpen(), 31.22) self.assertEquals(bf[instrument][-1].getHigh(), 31.33) self.assertEquals(bf[instrument][-1].getLow(), 30.93) self.assertEquals(bf[instrument][-1].getClose(), 31.3) self.assertEquals(bf[instrument][-1].getVolume(), 11716300) self.assertEquals(bf[instrument][-1].getAdjClose(), 30.23179912467581) self.assertEquals(bf[instrument][-1].getPrice(), 30.23179912467581)
from pyalgotrade import plotter from pyalgotrade.barfeed import quandlfeed from pyalgotrade.stratanalyzer import returns from pyalgotrade.stratanalyzer import sharpe from pyalgotrade.stratanalyzer import drawdown from pyalgotrade.stratanalyzer import trades import sma_crossover # 运行前先调整 r instrument feed | adjust params(r,instrument,feed) before running # 无风险利率 risk free rate r = 0.04 # Load the bar feed from the CSV file instrument = "moutai" feed = quandlfeed.Feed() # 调整需要的CSV路径 Adjust CSV file feed.addBarsFromCSV(instrument, 'E:\\backtest\\csv\\' + instrument + 'csv.csv') # 修改长短期均线 Adjust fast and slow MA fastMA = 5 slowMA = 20 ##line 55 调整存储图片路径 Change the root of saving image #======================================================================================== # Evaluate the strategy with the feed's bars. myStrategy = sma_crossover.SMACrossOver(feed, instrument, fastMA, slowMA) # Attach a returns analyzers to the strategy. returnsAnalyzer = returns.Returns() sharpeRatioAnalyzer = sharpe.SharpeRatio() drawdown = drawdown.DrawDown() trades = trades.Trades() myStrategy.attachAnalyzer(returnsAnalyzer)
def testInvalidFrequency(self): with self.assertRaisesRegexp(Exception, "Invalid frequency.*"): quandlfeed.Feed(frequency=bar.Frequency.MINUTE)
def run_strategy(): bBandsPeriod = 21 instrument = "399300" # 下载股票数据 MyDownload.download_csv(instrument, "2017-01-01", "2020-01-01", instrument + ".csv") # 从CSV文件加载bar feed feed = quandlfeed.Feed() feed.addBarsFromCSV(instrument, instrument + ".csv") # 创建MyStrategy实例 myStrategy = MyStrategy(feed, instrument, bBandsPeriod) plt = plotter.StrategyPlotter(myStrategy, True, True, True) # 图例添加BOLL plt.getInstrumentSubplot(instrument).addDataSeries( "upper", myStrategy.getBollingerBands().getUpperBand()) plt.getInstrumentSubplot(instrument).addDataSeries( "middle", myStrategy.getBollingerBands().getMiddleBand()) plt.getInstrumentSubplot(instrument).addDataSeries( "lower", myStrategy.getBollingerBands().getLowerBand()) # test = myStrategy.getBollingerBands().getUpperBand() - myStrategy.getBollingerBands().getLowerBand() # plt.getOrCreateSubplot("test").addDataSeries("test", test) # 图例添加MACD plt.getOrCreateSubplot("macd").addDataSeries("DIF", myStrategy.getMACD()) plt.getOrCreateSubplot("macd").addDataSeries( "DEA", myStrategy.getMACD().getSignal()) plt.getOrCreateSubplot("macd").addDataSeries( "MACD", myStrategy.getMACD().getHistogram()) # 图例添加KD plt.getOrCreateSubplot("stoch").addDataSeries("K", myStrategy.getStoch()) plt.getOrCreateSubplot("stoch").addDataSeries("D", myStrategy.getStoch().getD()) # 图例添加RSI plt.getOrCreateSubplot("rsi").addDataSeries("RSI7", myStrategy.getRSI7()) plt.getOrCreateSubplot("rsi").addDataSeries("RSI14", myStrategy.getRSI14()) plt.getOrCreateSubplot("rsi").addLine("Overbought", 70) plt.getOrCreateSubplot("rsi").addLine("Oversold", 30) # 添加回测分析 returnsAnalyzer = returns.Returns() myStrategy.attachAnalyzer(returnsAnalyzer) # 添加夏普比率分析 sharpeRatioAnalyzer = sharpe.SharpeRatio() myStrategy.attachAnalyzer(sharpeRatioAnalyzer) # 运行策略 myStrategy.run() # 输出投资组合的最终资产总值 print("最终资产总值: $%.2f" % myStrategy.getBroker().getEquity()) # 输出年度收益 print("年度收益: %.2f %%" % (returnsAnalyzer.getCumulativeReturns()[-1] * 100)) # 输出夏普比率 print("夏普比率: %.2f" % sharpeRatioAnalyzer.getSharpeRatio(0)) # 展示折线图 plt.plot()
def build_feed(sourceCode, tableCodes, fromYear, toYear, storage, frequency=bar.Frequency.DAY, timezone=None, skipErrors=False, authToken=None, columnNames={}, forceDownload=False, skipMalformedBars=False): """Build and load a :class:`pyalgotrade.barfeed.quandlfeed.Feed` using CSV files downloaded from Quandl. CSV files are downloaded if they haven't been downloaded before. :param sourceCode: The dataset source code. :type sourceCode: string. :param tableCodes: The dataset table codes. :type tableCodes: list. :param fromYear: The first year. :type fromYear: int. :param toYear: The last year. :type toYear: int. :param storage: The path were the files will be loaded from, or downloaded to. :type storage: string. :param frequency: The frequency of the bars. Only **pyalgotrade.bar.Frequency.DAY** or **pyalgotrade.bar.Frequency.WEEK** are supported. :param timezone: The default timezone to use to localize bars. Check :mod:`pyalgotrade.marketsession`. :type timezone: A pytz timezone. :param skipErrors: True to keep on loading/downloading files in case of errors. :type skipErrors: boolean. :param authToken: Optional. An authentication token needed if you're doing more than 50 calls per day. :type authToken: string. :param columnNames: Optional. A dictionary to map column names. Valid key values are: * datetime * open * high * low * close * volume * adj_close :type columnNames: dict. :param skipMalformedBars: True to skip errors while parsing bars. :type skipMalformedBars: boolean. :rtype: :class:`pyalgotrade.barfeed.quandlfeed.Feed`. """ logger = pyalgotrade.logger.getLogger("quandl") ret = quandlfeed.Feed(frequency, timezone) # Additional column names. for col, name in six.iteritems(columnNames): ret.setColumnName(col, name) if not os.path.exists(storage): logger.info("Creating %s directory" % (storage)) os.mkdir(storage) for year in range(fromYear, toYear + 1): for tableCode in tableCodes: fileName = os.path.join( storage, "%s-%s-%d-quandl.csv" % (sourceCode, tableCode, year)) if not os.path.exists(fileName) or forceDownload: logger.info("Downloading %s %d to %s" % (tableCode, year, fileName)) try: if frequency == bar.Frequency.DAY: download_daily_bars(sourceCode, tableCode, year, fileName, authToken) else: assert frequency == bar.Frequency.WEEK, "Invalid frequency" download_weekly_bars(sourceCode, tableCode, year, fileName, authToken) except Exception as e: if skipErrors: logger.error(str(e)) continue else: raise e ret.addBarsFromCSV(tableCode, fileName, skipMalformedBars=skipMalformedBars) return ret