def __init__(self, dataSeries, period, numStdDev, maxLen=None): self.__sma = ma.SMA(dataSeries, period, maxLen=maxLen) self.__stdDev = stats.StdDev(dataSeries, period, maxLen=maxLen) self.__upperBand = dataseries.SequenceDataSeries(maxLen) self.__lowerBand = dataseries.SequenceDataSeries(maxLen) self.__numStdDev = numStdDev # It is important to subscribe after sma and stddev since we'll use those values. dataSeries.getNewValueEvent().subscribe(self.__onNewValue)
def __init__(self, feed, instrument1, instrument2, windowSize): super(StatArb, self).__init__(feed) self.setUseAdjustedValues(True) self.__statArbHelper = StatArbHelper( feed[instrument1].getAdjCloseDataSeries(), feed[instrument2].getAdjCloseDataSeries(), windowSize) self.__i1 = instrument1 self.__i2 = instrument2 # These are used only for plotting purposes. self.__spread = dataseries.SequenceDataSeries() self.__hedgeRatio = dataseries.SequenceDataSeries()
def testIncremental(self): size = 20 ds1 = dataseries.SequenceDataSeries() ds2 = dataseries.SequenceDataSeries() ads1, ads2 = aligned.datetime_aligned(ds1, ds2) now = datetime.datetime.now() for i in range(size): ds1.appendWithDateTime(now + datetime.timedelta(seconds=i), i) ds2.appendWithDateTime(now + datetime.timedelta(seconds=i), i) self.assertEqual(len(ads1), len(ads2)) self.assertEqual(ads1[:], ads2[:]) self.assertEqual(ads1.getDateTimes()[:], ads2.getDateTimes()[:])
def testBoundedSources(self): ds1 = dataseries.SequenceDataSeries(1) ds2 = dataseries.SequenceDataSeries(1) ads1, ads2 = aligned.datetime_aligned(ds1, ds2) now = datetime.datetime.now() ds1.appendWithDateTime(now + datetime.timedelta(seconds=1), 1) ds1.appendWithDateTime(now + datetime.timedelta(seconds=2), 2) ds1.appendWithDateTime(now + datetime.timedelta(seconds=3), 3) ds2.appendWithDateTime(now + datetime.timedelta(seconds=2), 2) ds2.appendWithDateTime(now + datetime.timedelta(seconds=3), 3) ds2.appendWithDateTime(now + datetime.timedelta(seconds=4), 4) self.assertEqual(ads1[:], [2, 3]) self.assertEqual(ads2[:], [2, 3])
def __loadMedPriceDS(self): ret = dataseries.SequenceDataSeries() for i in range(len(OPEN_VALUES)): ret.append(LOW_VALUES[i] + (HIGH_VALUES[i] - LOW_VALUES[i]) / 2.0) return ret
def testStraightLine(self): seqDS = dataseries.SequenceDataSeries() lsReg = linreg.LeastSquaresRegression(seqDS, 3) nextDateTime = datetime.datetime(2012, 1, 1) seqDS.appendWithDateTime(nextDateTime, 1) self.assertEqual(lsReg[-1], None) nextDateTime = nextDateTime + datetime.timedelta(hours=1) seqDS.appendWithDateTime(nextDateTime, 2) self.assertEqual(lsReg[-1], None) # Check current value. nextDateTime = nextDateTime + datetime.timedelta(hours=1) seqDS.appendWithDateTime(nextDateTime, 3) self.assertEqual(round(lsReg[-1], 2), 3) # Check future values. futureDateTime = nextDateTime + datetime.timedelta(hours=1) self.assertEqual(round(lsReg.getValueAt(futureDateTime), 2), 4) futureDateTime = futureDateTime + datetime.timedelta(minutes=30) self.assertEqual(round(lsReg.getValueAt(futureDateTime), 2), 4.5) futureDateTime = futureDateTime + datetime.timedelta(minutes=30) self.assertEqual(round(lsReg.getValueAt(futureDateTime), 2), 5) # Move forward in sub-second increments. nextDateTime = nextDateTime + datetime.timedelta(milliseconds=50) seqDS.appendWithDateTime(nextDateTime, 4) nextDateTime = nextDateTime + datetime.timedelta(milliseconds=50) seqDS.appendWithDateTime(nextDateTime, 5) self.assertEqual(round(lsReg[-1], 2), 5)
def __buildSeqDS(self, values): ret = dataseries.SequenceDataSeries() for value in values: ret.append(value) return ret
def testSeqLikeOps(self): seq = list(range(10)) ds = dataseries.SequenceDataSeries() for value in seq: ds.append(value) # Test length and every item. self.assertEqual(len(ds), len(seq)) for i in range(len(seq)): self.assertEqual(ds[i], seq[i]) # Test negative indices self.assertEqual(ds[-1], seq[-1]) self.assertEqual(ds[-2], seq[-2]) self.assertEqual(ds[-9], seq[-9]) # Test slices sl = slice(0, 1, 2) self.assertEqual(ds[sl], seq[sl]) sl = slice(0, 9, 2) self.assertEqual(ds[sl], seq[sl]) sl = slice(0, -1, 1) self.assertEqual(ds[sl], seq[sl]) for i in range(-100, 100): self.assertEqual(ds[i:], seq[i:]) for step in range(1, 10): for i in range(-100, 100): self.assertEqual(ds[i::step], seq[i::step])
def build_hurst(values, period, minLags, maxLags): ds = dataseries.SequenceDataSeries() ret = hurst.HurstExponent(ds, period, minLags, maxLags) for value in values: ds.append(value) return ret
def __getOrCreateExtraDS(self, name): ret = self.__extraDS.get(name) if ret is None: ret = dataseries.SequenceDataSeries(self.getMaxLen()) self.__extraDS[name] = ret return ret
def __buildWMA(self, weights, values, seqMaxLen=None, wmaMaxLen=None): seqDS = dataseries.SequenceDataSeries(maxLen=seqMaxLen) ret = ma.WMA(seqDS, weights, wmaMaxLen) for value in values: seqDS.append(value) return ret
def __buildROC(self, values, period, rocMaxLen=None): seqDS = dataseries.SequenceDataSeries() ret = roc.RateOfChange(seqDS, period, rocMaxLen) for value in values: seqDS.append(value) return ret
def __buildSlope(self, values, period, slopeMaxLen=None): seqDS = dataseries.SequenceDataSeries() ret = linreg.Slope(seqDS, period, slopeMaxLen) for value in values: seqDS.append(value) return ret
def __buildTrend(self, values, trendDays, positiveThreshold, negativeThreshold, trendMaxLen=None): seqDS = dataseries.SequenceDataSeries() ret = linreg.Trend(seqDS, trendDays, positiveThreshold, negativeThreshold, trendMaxLen) for value in values: seqDS.append(value) return ret
def testCrossAboveWithSMA(self): ds1 = dataseries.SequenceDataSeries() ds2 = dataseries.SequenceDataSeries() sma1 = ma.SMA(ds1, 15) sma2 = ma.SMA(ds2, 25) for i in range(100): ds1.append(i) ds2.append(50) if i == 58: self.assertEqual(cross.cross_above(sma1[:], sma2[:], -2, None), 1) else: self.assertEqual(cross.cross_above(sma1[:], sma2[:], -2, None), 0)
def __buildRSI(self, values, period, rsiMaxLen=None): seqDS = dataseries.SequenceDataSeries() ret = rsi.RSI(seqDS, period, rsiMaxLen) for value in values: seqDS.append(value) return ret
def __buildRatio(self, values, ratioMaxLen=None): seqDS = dataseries.SequenceDataSeries() ret = ratio.Ratio(seqDS, ratioMaxLen) for value in values: seqDS.append(value) return ret
def __buildSMA(self, period, values, smaMaxLen=None): seqDs = dataseries.SequenceDataSeries() ret = ma.SMA(seqDs, period, smaMaxLen) for value in values: seqDs.append(value) return ret
def testMaxLen(self): ds = dataseries.SequenceDataSeries() for i in range(3000): ds.append(i) self.assertEqual(len(ds), 2048) self.assertEqual(ds[0], 952) self.assertEqual(ds[-1], 2999)
def testStdDev_1(self): values = [1, 1, 2, 3, 5] seqDS = dataseries.SequenceDataSeries() stdDev = stats.StdDev(seqDS, 1) for value in values: seqDS.append(value) for i in stdDev: self.assertEqual(i, 0)
def testHighLow(self): values = dataseries.SequenceDataSeries() high = highlow.High(values, 5) low = highlow.Low(values, 3) for value in [1, 2, 3, 4, 5]: values.append(value) self.assertEqual(high[-1], 5) self.assertEqual(low[-1], 3)
def testStdDev_Bounded(self): values = [1, 1, 2, 3, 5] seqDS = dataseries.SequenceDataSeries() stdDev = stats.StdDev(seqDS, 2, maxLen=2) for value in values: seqDS.append(value) self.assertEqual(stdDev[0], numpy.array([2, 3]).std()) self.assertEqual(stdDev[1], numpy.array([3, 5]).std())
def __init__(self, dataSeries, fastEMA, slowEMA, signalEMA, maxLen=None): assert (fastEMA > 0) assert (slowEMA > 0) assert (fastEMA < slowEMA) assert (signalEMA > 0) super().__init__(maxLen) # We need to skip some values when calculating the fast EMA in order for both EMA # to calculate their first values at the same time. # I'M FORCING THIS BEHAVIOUR ONLY TO MAKE THIS FITLER MATCH TA-Lib MACD VALUES. self.__fastEMASkip = slowEMA - fastEMA self.__fastEMAWindow = ma.EMAEventWindow(fastEMA) self.__slowEMAWindow = ma.EMAEventWindow(slowEMA) self.__signalEMAWindow = ma.EMAEventWindow(signalEMA) self.__signal = dataseries.SequenceDataSeries(maxLen) self.__histogram = dataseries.SequenceDataSeries(maxLen) dataSeries.getNewValueEvent().subscribe(self.__onNewValue)
def testNotAligned(self): size = 20 ds1 = dataseries.SequenceDataSeries() ds2 = dataseries.SequenceDataSeries() ads1, ads2 = aligned.datetime_aligned(ds1, ds2) now = datetime.datetime.now() for i in range(size): if i % 2 == 0: ds1.appendWithDateTime(now + datetime.timedelta(seconds=i), i) else: ds2.appendWithDateTime(now + datetime.timedelta(seconds=i), i) self.assertEqual(len(ds1), len(ds2)) for ads in [ads1, ads2]: self.assertEqual(len(ads), 0) self.assertEqual(ads.getValueAbsolute(0), None) self.assertEqual(ads.getDateTimes(), [])
def testFullyAligned(self): size = 20 ds1 = dataseries.SequenceDataSeries() ds2 = dataseries.SequenceDataSeries() ads1, ads2 = aligned.datetime_aligned(ds1, ds2) now = datetime.datetime.now() for i in range(size): ds1.appendWithDateTime(now + datetime.timedelta(seconds=i), i) ds2.appendWithDateTime(now + datetime.timedelta(seconds=i), i) self.assertEqual(len(ds1), len(ds2)) for ads in [ads1, ads2]: self.assertEqual(len(ads), size) for i in range(size): self.assertEqual(ads.getValueAbsolute(i), i) self.assertEqual(ads.getDateTimes()[i], now + datetime.timedelta(seconds=i))
def testEventWindow(self): ds = dataseries.SequenceDataSeries() smaEW = ma.SMAEventWindow(10) sma = ma.SMA(ds, 10) smaEW.onNewValue(None, None) # This value should get skipped for i in range(100): ds.append(i) smaEW.onNewValue(None, i) self.assertEqual(sma[-1], smaEW.getValue()) smaEW.onNewValue(None, None) # This value should get skipped
def testBounded(self): ds = dataseries.SequenceDataSeries(maxLen=2) for i in range(100): ds.append(i) if i > 0: self.assertEqual(ds[0], i - 1) self.assertEqual(ds[1], i) self.assertEqual(len(ds), 2)
def testStdDev(self): values = [1, 1, 2, 3, 5] seqDS = dataseries.SequenceDataSeries() stdDev = stats.StdDev(seqDS, 2) for value in values: seqDS.append(value) self.assertEqual(stdDev[0], None) self.assertEqual(stdDev[1], numpy.array([1, 1]).std()) self.assertEqual(stdDev[2], numpy.array([1, 2]).std()) self.assertEqual(stdDev[3], numpy.array([2, 3]).std()) self.assertEqual(stdDev[4], numpy.array([3, 5]).std())
def testPartiallyAligned(self): size = 20 commonDateTimes = [] ds1 = dataseries.SequenceDataSeries() ds2 = dataseries.SequenceDataSeries() ads1, ads2 = aligned.datetime_aligned(ds1, ds2) now = datetime.datetime.now() for i in range(size): if i % 3 == 0: commonDateTimes.append(now + datetime.timedelta(seconds=i)) ds1.appendWithDateTime(now + datetime.timedelta(seconds=i), i) ds2.appendWithDateTime(now + datetime.timedelta(seconds=i), i) elif i % 2 == 0: ds1.appendWithDateTime(now + datetime.timedelta(seconds=i), i) else: ds2.appendWithDateTime(now + datetime.timedelta(seconds=i), i) self.assertEqual(len(ads1), len(ads2)) self.assertEqual(ads1[:], ads2[:]) self.assertEqual(ads1.getDateTimes(), commonDateTimes) self.assertEqual(ads2.getDateTimes(), commonDateTimes)
def testZScore(self): values = [1.10, 2.20, 4.00, 5.10, 6.00, 7.10, 8.20, 9.00, 10.10, 3.00, 4.10, 5.20, 7.00, 8.10, 9.20, 16.00, 17.10, 18.20, 19.30, 20.40] expected = [None, None, None, None, 1.283041407, 1.317884611, 1.440611043, 1.355748299, 1.4123457, -1.831763202, -0.990484842, -0.388358578, 0.449889908, 1.408195169, 1.332948099, 1.867732104, 1.334258333, 1.063608066, 0.939656572, 1.414213562] seqDS = dataseries.SequenceDataSeries() zscore = stats.ZScore(seqDS, 5) i = 0 for value in values: seqDS.append(value) if i >= 4: self.assertEqual(round(zscore[-1], 4), round(expected[i], 4)) i += 1