def testInvalidDateTimes(self): b1 = bar.BasicBar(datetime.datetime.now(), 2, 3, 1, 2.1, 10, 5, bar.Frequency.DAY) b2 = bar.BasicBar(datetime.datetime.now() + datetime.timedelta(days=1), 2, 3, 1, 2.1, 10, 5, bar.Frequency.DAY) with self.assertRaises(Exception): bar.Bars({"a": b1, "b": b2})
def testResample(self): barDs = bards.BarDataSeries() resampledDS = resampled_ds.ResampledDataSeries(barDs.getCloseDataSeries(), bar.Frequency.MINUTE, sum) resampledBarDS = resampled_ds.ResampledBarDataSeries(barDs, bar.Frequency.MINUTE) barDs.append(bar.BasicBar(datetime.datetime(2011, 1, 1, 1, 1, 1), 2.1, 3, 1, 2, 10, 1, bar.Frequency.SECOND)) barDs.append(bar.BasicBar(datetime.datetime(2011, 1, 1, 1, 1, 2), 2, 3, 1, 2.3, 10, 2, bar.Frequency.SECOND)) barDs.append(bar.BasicBar(datetime.datetime(2011, 1, 1, 1, 2, 1), 2, 3, 1, 2, 10, 2, bar.Frequency.SECOND)) self.assertEqual(len(resampledBarDS), 1) self.assertEqual(resampledBarDS[0].getDateTime(), datetime.datetime(2011, 1, 1, 1, 1)) self.assertEqual(resampledBarDS[0].getOpen(), 2.1) self.assertEqual(resampledBarDS[0].getHigh(), 3) self.assertEqual(resampledBarDS[0].getLow(), 1) self.assertEqual(resampledBarDS[0].getClose(), 2.3) self.assertEqual(resampledBarDS[0].getVolume(), 20) self.assertEqual(resampledBarDS[0].getAdjClose(), 2) self.assertEqual(resampledDS[-1], 2 + 2.3) resampledBarDS.pushLast() self.assertEqual(len(resampledBarDS), 2) self.assertEqual(resampledBarDS[1].getDateTime(), datetime.datetime(2011, 1, 1, 1, 2)) self.assertEqual(resampledBarDS[1].getOpen(), 2) self.assertEqual(resampledBarDS[1].getHigh(), 3) self.assertEqual(resampledBarDS[1].getLow(), 1) self.assertEqual(resampledBarDS[1].getClose(), 2) self.assertEqual(resampledBarDS[1].getVolume(), 10) self.assertEqual(resampledBarDS[1].getAdjClose(), 2) resampledDS.pushLast() self.assertEqual(resampledDS[1], 2)
def testBasic(self): dt = datetime.datetime.now() b1 = bar.BasicBar(dt, 1, 1, 1, 1, 10, 1, bar.Frequency.DAY) b2 = bar.BasicBar(dt, 2, 2, 2, 2, 10, 2, bar.Frequency.DAY) bars = bar.Bars({"a": b1, "b": b2}) self.assertEqual(bars["a"].getClose(), 1) self.assertEqual(bars["b"].getClose(), 2) self.assertTrue("a" in bars) self.assertEqual(bars.items(), [("a", b1), ("b", b2)]) self.assertEqual(bars.keys(), ["a", "b"]) self.assertEqual(bars.getInstruments(), ["a", "b"]) self.assertEqual(bars.getDateTime(), dt) self.assertEqual(bars.getBar("a").getClose(), 1)
def testBlackWhiteReversal(self): bds = bards.BarDataSeries() lb = linebreak.LineBreak(bds, 2) bds.append(bar.BasicBar(datetime.datetime(2008, 3, 5), 10, 12, 8, 9, 1, None, bar.Frequency.DAY)) self.assertEqual(len(lb), 1) bds.append(bar.BasicBar(datetime.datetime(2008, 3, 6), 9, 12, 9, 12, 1, None, bar.Frequency.DAY)) self.assertEqual(len(lb), 1) self.assertEqual(lb[-1].isBlack(), True) self.assertEqual(lb[-1].getDateTime(), datetime.datetime(2008, 3, 5)) bds.append(bar.BasicBar(datetime.datetime(2008, 3, 7), 9, 13, 5, 13, 1, None, bar.Frequency.DAY)) self.assertEqual(len(lb), 2) self.assertEqual(lb[-1].isWhite(), True) self.assertEqual(lb[-1].getDateTime(), datetime.datetime(2008, 3, 7))
def testAppendInvalidDatetime(self): ds = bards.BarDataSeries() for i in xrange(10): now = datetime.datetime.now() + datetime.timedelta(seconds=i) ds.append(bar.BasicBar(now, 0, 0, 0, 0, 0, 0, bar.Frequency.SECOND)) # Adding the same datetime twice should fail with self.assertRaises(Exception): ds.append( bar.BasicBar(now, 0, 0, 0, 0, 0, 0, bar.Frequency.SECOND)) # Adding a previous datetime should fail with self.assertRaises(Exception): ds.append( bar.BasicBar(now - datetime.timedelta(seconds=i), 0, 0, 0, 0, 0, 0, bar.Frequency.SECOND))
def testBaseBarFeedNoAdjClose(self): bars = [ bar.Bars({ "orcl": bar.BasicBar(datetime.datetime(2001, 1, 1), 1, 1, 1, 1, 1, None, bar.Frequency.DAY) }), bar.Bars({ "orcl": bar.BasicBar(datetime.datetime(2001, 1, 2), 1, 1, 1, 1, 1, None, bar.Frequency.DAY) }), ] barFeed = barfeed.OptimizerBarFeed(bar.Frequency.DAY, ["orcl"], bars) check_base_barfeed(self, barFeed, False)
def __buildBar(self, openPrice, highPrice, lowPrice, closePrice): dateTime = datetime.datetime.now() + datetime.timedelta( seconds=self.__currSeconds) self.__currSeconds += 1 return bar.BasicBar(dateTime, openPrice, highPrice, lowPrice, closePrice, closePrice * 10, closePrice, bar.Frequency.DAY)
def getBars(self, instrument, frequency, timezone=None, fromDateTime=None, toDateTime=None): instrument = normalize_instrument(instrument) sql = "select bar.timestamp, bar.open, bar.high, bar.low, bar.close, bar.volume, bar.adj_close, bar.frequency" \ " from bar join instrument on (bar.instrument_id = instrument.instrument_id)" \ " where instrument.name = ? and bar.frequency = ?" args = [instrument, frequency] if fromDateTime is not None: sql += " and bar.timestamp >= ?" args.append(dt.datetime_to_timestamp(fromDateTime)) if toDateTime is not None: sql += " and bar.timestamp <= ?" args.append(dt.datetime_to_timestamp(toDateTime)) sql += " order by bar.timestamp asc" cursor = self.__connection.cursor() cursor.execute(sql, args) ret = [] for row in cursor: dateTime = dt.timestamp_to_datetime(row[0]) if timezone: dateTime = dt.localize(dateTime, timezone) ret.append( bar.BasicBar(dateTime, row[1], row[2], row[3], row[4], row[5], row[6], row[7])) cursor.close() return ret
def testInvalidConstruction(self): with self.assertRaises(Exception): bar.BasicBar(datetime.datetime.now(), 2, 1, 1, 1, 1, 1, bar.Frequency.DAY) with self.assertRaises(Exception): bar.BasicBar(datetime.datetime.now(), 1, 1, 1, 2, 1, 1, bar.Frequency.DAY) with self.assertRaises(Exception): bar.BasicBar(datetime.datetime.now(), 1, 2, 1.5, 1, 1, 1, bar.Frequency.DAY) with self.assertRaises(Exception): bar.BasicBar(datetime.datetime.now(), 2, 2, 1.5, 1, 1, 1, bar.Frequency.DAY) with self.assertRaises(Exception): bar.BasicBar(datetime.datetime.now(), 1, 1, 1.5, 1, 1, 1, bar.Frequency.DAY)
def parseBar(self, csvRowDict): dateTime = self.__parseDateTime(csvRowDict["Date Time"]) close = float(csvRowDict["Close"]) open_ = float(csvRowDict["Open"]) high = float(csvRowDict["High"]) low = float(csvRowDict["Low"]) volume = float(csvRowDict["Volume"]) return bar.BasicBar(dateTime, open_, high, low, close, volume, None, self.__frequency)
def testDateTimesNotInOrder(self): bars = [ bar.Bars({ "orcl": bar.BasicBar(datetime.datetime(2001, 1, 2), 1, 1, 1, 1, 1, 1, bar.Frequency.DAY) }), bar.Bars({ "orcl": bar.BasicBar(datetime.datetime(2001, 1, 1), 1, 1, 1, 1, 1, 1, bar.Frequency.DAY) }), ] f = barfeed.OptimizerBarFeed(bar.Frequency.DAY, ["orcl"], bars) with self.assertRaisesRegex(Exception, "Bar date times are not in order.*"): for dt, b in f: pass
def addBarsFromListofDicts(self, instrument, list_of_dicts, timezone=None): """Loads bars for a given instrument from a list of dictionaries. The instrument gets registered in the bar feed. :param instrument: Instrument identifier. :type instrument: string. :param list_of_dicts: A list of dicts. First item should contain columns. :type list_of_dicts: list :param timezone: The timezone to use to localize bars. Check :mod:`quantworks.marketsession`. :type timezone: A pytz timezone. """ if timezone is None: timezone = self.__timezone if not isinstance(list_of_dicts, (list, tuple)): raise ValueError( 'This function only supports types: {list, tuple}') if not isinstance(list_of_dicts[0], dict): raise ValueError('List should only contain dicts') dicts_have_adj_close = self.__columnNames[ 'adj_close'] in list_of_dicts[0].keys() missing_columns = [ col for col in self.__columnNames.values() if col not in list_of_dicts[0].keys() ] if missing_columns: raise ValueError('Missing required columns: {}'.format( repr(missing_columns))) # Convert dicts to Bar(s) loadedBars = map( lambda row: bar.BasicBar( self.__localize_dt(row[self.__columnNames['datetime']]), row[self.__columnNames['open']], row[self.__columnNames['high']], row[self.__columnNames['low']], row[self.__columnNames['close']], row[self.__columnNames['volume']], row[self.__columnNames['adj_close']], self.getFrequency(), extra={ key: row[key] for key in set(row.keys()).difference(self.__columnNames. values()) }), list_of_dicts) super(Feed, self)._addBars(instrument, loadedBars) if dicts_have_adj_close: self.__haveAdjClose = True elif self.__haveAdjClose: raise Exception( "Previous bars had adjusted close and these ones don't have.")
def run_test(cls): bf = MockBarFeed(bar.Frequency.DAY) bars = [ bar.BasicBar(datetime.datetime(2000, 1, 1), 10, 10, 10, 10, 10, 10, bar.Frequency.DAY), ] bf.addBarsFromSequence("orcl", bars) strat = MockStrategy(bf, 1000) strat.run()
def build_bars_from_closing_prices(closingPrices): ret = [] nextDateTime = datetime.datetime.now() for closePrice in closingPrices: bar_ = bar.BasicBar(nextDateTime, closePrice, closePrice, closePrice, closePrice, closePrice, closePrice, bar.Frequency.DAY) ret.append(bar_) nextDateTime = nextDateTime + datetime.timedelta(days=1) return ret
def testNonEmpty(self): ds = bards.BarDataSeries() for i in xrange(10): ds.append( bar.BasicBar( datetime.datetime.now() + datetime.timedelta(seconds=i), 0, 0, 0, 0, 0, 0, bar.Frequency.SECOND)) for i in xrange(0, 10): self.assertTrue(ds[i].getOpen() == 0)
def testDateTimes(self): ds = bards.BarDataSeries() firstDt = datetime.datetime.now() for i in xrange(10): ds.append( bar.BasicBar(firstDt + datetime.timedelta(seconds=i), 2, 4, 1, 3, 10, 3, bar.Frequency.SECOND)) for i in xrange(10): self.assertEqual(ds[i].getDateTime(), ds.getDateTimes()[i]) self.assertEqual(ds.getDateTimes()[i], firstDt + datetime.timedelta(seconds=i))
def __loadSarTestBarDs(self): seconds = 0 ret = bards.BarDataSeries() for i in xrange(len(SAR_HIGH)): dateTime = datetime.datetime.now() + datetime.timedelta( seconds=seconds) ret.append( bar.BasicBar(dateTime, SAR_LOW[i], SAR_HIGH[i], SAR_LOW[i], SAR_HIGH[i], 0, SAR_LOW[i], bar.Frequency.DAY)) seconds += 1 return ret
def __loadBarDS(self): seconds = 0 ret = bards.BarDataSeries() for i in xrange(len(OPEN_VALUES)): dateTime = datetime.datetime.now() + datetime.timedelta( seconds=seconds) ret.append( bar.BasicBar(dateTime, OPEN_VALUES[i], HIGH_VALUES[i], LOW_VALUES[i], CLOSE_VALUES[i], VOLUME_VALUES[i], CLOSE_VALUES[i], bar.Frequency.DAY)) seconds += 1 return ret
def testNoAdjClose(self): b = bar.BasicBar(datetime.datetime.now(), 2, 3, 1, 2.1, 10, None, bar.Frequency.DAY) with self.assertRaises(Exception): b.setUseAdjustedValue(True) with self.assertRaises(Exception): b.getOpen(True) with self.assertRaises(Exception): b.getHigh(True) with self.assertRaises(Exception): b.getLow(True) with self.assertRaises(Exception): b.getClose(True)
def testSeqLikeOps(self): seq = [] ds = bards.BarDataSeries() for i in xrange(10): bar_ = bar.BasicBar( datetime.datetime.now() + datetime.timedelta(seconds=i), 2, 4, 1, 3, 10, 3, bar.Frequency.SECOND) ds.append(bar_) seq.append(bar_) self.assertEqual(ds[-1], seq[-1]) self.assertEqual(ds[-2], seq[-2]) self.assertEqual(ds[0], seq[0]) self.assertEqual(ds[1], seq[1]) self.assertEqual(ds[-2:][-1], seq[-2:][-1])
def testNestedDataSeries(self): ds = bards.BarDataSeries() for i in xrange(10): ds.append( bar.BasicBar( datetime.datetime.now() + datetime.timedelta(seconds=i), 2, 4, 1, 3, 10, 3, bar.Frequency.SECOND)) self.__testGetValue(ds.getOpenDataSeries(), 10, 2) self.__testGetValue(ds.getCloseDataSeries(), 10, 3) self.__testGetValue(ds.getHighDataSeries(), 10, 4) self.__testGetValue(ds.getLowDataSeries(), 10, 1) self.__testGetValue(ds.getVolumeDataSeries(), 10, 10) self.__testGetValue(ds.getAdjCloseDataSeries(), 10, 3) self.__testGetValue(ds.getPriceDataSeries(), 10, 3)
def parseBar(self, csvRowDict): dateTime = self.__parseDate(csvRowDict["Date"]) close = float(csvRowDict["Close"]) open_ = float(csvRowDict["Open"]) high = float(csvRowDict["High"]) low = float(csvRowDict["Low"]) volume = float(csvRowDict["Volume"]) adjClose = None if self.__sanitize: open_, high, low, close = common.sanitizeOhlc( open_, high, low, close) return bar.BasicBar(dateTime, open_, high, low, close, volume, adjClose, self.__frequency)
def addBarsFromDataFrame(self, instrument, df, timezone=None): """Loads bars for a given instrument from a Pandas DataFrame. The instrument gets registered in the bar feed. :param instrument: Instrument identifier. :type instrument: string. :param df: The pandas DataFrame :type df: pd.DataFrame :param timezone: The timezone to use to localize bars. Check :mod:`quantworks.marketsession`. :type timezone: A pytz timezone. """ if timezone is None: timezone = self.__timezone df_has_adj_close = self.__columnNames['adj_close'] in df.columns missing_columns = [ col for col in self.__columnNames.values() if col not in df.columns ] if missing_columns: raise ValueError('Missing required columns: {}'.format( repr(missing_columns))) # Convert DataFrame row(s) to Bar(s) loadedBars = map( lambda row: bar.BasicBar( self.__localize_dt(row[self.__columnNames['datetime']]), row[self.__columnNames['open']], row[self.__columnNames['high']], row[self.__columnNames['low']], row[self.__columnNames['close']], row[self.__columnNames['volume']], row[self.__columnNames['adj_close']], self.getFrequency(), extra={ key: row[key] for key in set(row.keys()).difference(self.__columnNames. values()) }), df.to_dict(orient='record')) self._addBars(instrument, loadedBars) if df_has_adj_close: self.__haveAdjClose = True elif self.__haveAdjClose: raise Exception( "Previous bars had adjusted close and these ones don't have.")
def testCheckNow(self): barDs = bards.BarDataSeries() resampledBarDS = resampled_ds.ResampledBarDataSeries(barDs, bar.Frequency.MINUTE) barDateTime = datetime.datetime(2014, 7, 7, 22, 46, 28, 10000) barDs.append(bar.BasicBar(barDateTime, 2.1, 3, 1, 2, 10, 1, bar.Frequency.MINUTE)) self.assertEqual(len(resampledBarDS), 0) resampledBarDS.checkNow(barDateTime + datetime.timedelta(minutes=1)) self.assertEqual(len(resampledBarDS), 1) self.assertEqual(barDs[0].getOpen(), resampledBarDS[0].getOpen()) self.assertEqual(barDs[0].getHigh(), resampledBarDS[0].getHigh()) self.assertEqual(barDs[0].getLow(), resampledBarDS[0].getLow()) self.assertEqual(barDs[0].getClose(), resampledBarDS[0].getClose()) self.assertEqual(barDs[0].getVolume(), resampledBarDS[0].getVolume()) self.assertEqual(barDs[0].getAdjClose(), resampledBarDS[0].getAdjClose()) self.assertEqual(resampledBarDS[0].getDateTime(), datetime.datetime(2014, 7, 7, 22, 46))
def testPickle(self): b1 = bar.BasicBar(datetime.datetime.now(), 2, 3, 1, 2.1, 10, 5, bar.Frequency.DAY) b2 = cPickle.loads(cPickle.dumps(b1)) self.assertEqual(b1.getDateTime(), b2.getDateTime()) self.assertEqual(b1.getOpen(), b2.getOpen()) self.assertEqual(b1.getHigh(), b2.getHigh()) self.assertEqual(b1.getLow(), b2.getLow()) self.assertEqual(b1.getClose(), b2.getClose()) self.assertEqual(b1.getVolume(), b2.getVolume()) self.assertEqual(b1.getAdjClose(), b2.getAdjClose()) self.assertEqual(b1.getFrequency(), b2.getFrequency()) self.assertEqual(b1.getPrice(), b2.getPrice()) self.assertEqual(b1.getOpen(True), b2.getOpen(True)) self.assertEqual(b1.getHigh(True), b2.getHigh(True)) self.assertEqual(b1.getLow(True), b2.getLow(True)) self.assertEqual(b1.getClose(True), b2.getClose(True))
def testStockChartsATRAdjusted(self): # Test data from http://stockcharts.com/help/doku.php?id=chart_school:technical_indicators:average_true_range_a high = [ 48.70, 48.72, 48.90, 48.87, 48.82, 49.05, 49.20, 49.35, 49.92, 50.19, 50.12, 49.66, 49.88, 50.19, 50.36, 50.57, 50.65, 50.43, 49.63, 50.33, 50.29, 50.17, 49.32, 48.50, 48.32, 46.80, 47.80, 48.39, 48.66, 48.79 ] low = [ 47.790, 48.140, 48.390, 48.370, 48.240, 48.635, 48.940, 48.860, 49.500, 49.870, 49.200, 48.900, 49.430, 49.725, 49.260, 50.090, 50.300, 49.210, 48.980, 49.610, 49.200, 49.430, 48.080, 47.640, 41.550, 44.283, 47.310, 47.200, 47.900, 47.730 ] close = [ 48.160, 48.610, 48.750, 48.630, 48.740, 49.030, 49.070, 49.320, 49.910, 50.130, 49.530, 49.500, 49.750, 50.030, 50.310, 50.520, 50.410, 49.340, 49.370, 50.230, 49.238, 49.930, 48.430, 48.180, 46.570, 45.410, 47.770, 47.720, 48.620, 47.850 ] expected = [ None, None, None, None, None, None, None, None, None, None, None, None, None, 0.555000, 0.593929, 0.585791, 0.568949, 0.615452, 0.617920, 0.642354, 0.674329, 0.692770, 0.775429, 0.781470, 1.209229, 1.302620, 1.380290, 1.366698, 1.336219, 1.316482 ] # Build a bar dataseries using the test data. barDataSeries = bards.BarDataSeries() atrDS = atr.ATR(barDataSeries, 14, True) now = datetime.datetime(2000, 1, 1) for i in xrange(len(high)): b = bar.BasicBar(now + datetime.timedelta(days=i), close[i], high[i], low[i], close[i], 100, close[i] / 2, bar.Frequency.DAY) barDataSeries.append(b) if expected[i] is None: self.assertEqual(atrDS[-1], None) else: self.assertEqual(common.safe_round(atrDS[-1], 2), round(expected[i] / 2, 2))
def testGetPrice(self): b = bar.BasicBar(datetime.datetime.now(), 2, 3, 1, 2.1, 10, 5, bar.Frequency.DAY) self.assertEqual(b.getPrice(), b.getClose()) b.setUseAdjustedValue(True) self.assertEqual(b.getPrice(), b.getAdjClose())
def testTypicalPrice(self): b = bar.BasicBar(datetime.datetime.now(), 2, 3, 1, 2.1, 10, 5, bar.Frequency.DAY) self.assertEqual(b.getTypicalPrice(), (3 + 1 + 2.1) / 3)