def __init__(self): self.startep = lib.str2epoch("2019-11-27T17:45:00") self.endep = lib.str2epoch("2019-11-28T00:25:00") name = "TestHistIndex" subc = SubChart(name, "USD_JPY", "M5", startep=self.startep, endep=self.endep) super(TestHistIndex, self).__init__("TestHistIndex", subc) super(HistIndex, self).__init__(name, subc) subc.onTick(TickEvent(self.endep,0,0,0)) (t,_,_,_,_,_) = subc.getPrices(self.startep, self.endep) self.subc = subc for epoch in t: self.calcHist(epoch)
def testNormal(self): env.run_mode = env.MODE_SIMULATE st = lib.str2epoch("2019/04/02 09:00", "%Y/%m/%d %H:%M") ed = lib.str2epoch("2019/04/02 12:00", "%Y/%m/%d %H:%M") s = SubChart("testNormal", "USD_JPY", "M5", st, ed, 5, 48) u = s.unitsecs (t,_,_,_,_,_) = s.getPrices() self.assertEqual(len(t), len(s.prices[0])) # 1 i, now = s.getTime(st + 100) self.assertEqual(i,5) self.assertEqual(now,1554195600) # 2 i, now = s.getTime(st + 400) self.assertEqual(i,6) self.assertEqual(now,1554195900) # 3 i, now = s.getTime(ed + 400) self.assertEqual(i,42) self.assertEqual(now,1554206700) # 4 i, now = s.getTime(ed - 500) self.assertEqual(i,39) self.assertEqual(now,1554205800) from event.tick import TickEvent tickEvent = TickEvent(1554196200+100, 1, 1) s.onTick(tickEvent) (t,o,h,l,c,v) = s.getPrices() self.assertEqual(t[-1], 1554196200) self.assertEqual(o[-1], 111.372) self.assertEqual(v[-1], 22) (t,o,h,l,c,v) = s.getPrices(5) self.assertEqual(t[0], 1554195600) self.assertEqual(t[-1], 1554196200) (t,o,h,l,c,v) = s.getPrices(5,6) self.assertEqual(t[-1], 1554195900) ep = ed + u*(48-len(s.prices[0])+48*0.5+1) tickEvent = TickEvent(ep, 1, 1) s.onTick(tickEvent) self.assertEqual(len(s.prices[0]), 48+48*0.5) (t,_,_,_,_,_) = s.getPrices() self.assertEqual(t[-1],ep) ep = t[-1] + u tickEvent = TickEvent(ep+100, 1, 1) s.onTick(tickEvent) self.assertEqual(len(s.prices[0]), 48) (t,_,_,_,_,_) = s.getPrices() self.assertEqual(t[-1],ep)
class EmaIndex(TechnicalIndex): def __init__(self, instrument, granularity, startep, endep, ema_span=20): super(EmaIndex, self).__init__("EmaIndex", instrument, granularity) self.subc = SubChart("EmaIndex", instrument, granularity, startep, endep) (t, _, _, _, cl, _) = self.subc.getPrices() self.epochs = t[ema_span:] self.alpha = 2.0 / (ema_span + 1) self.ema_span = ema_span self.now = 0 first_ema = sum(cl[:ema_span]) / ema_span self.ema = [] self._calcEma(t[ema_span - 1:], cl[ema_span - 1:], first_ema) def _calcEma(self, t, cl, last_ema): ema = self.ema for i in range(1, len(cl)): if t[i] - t[i - 1] > self.unitsecs: preema = cl[i] else: preema = last_ema last_ema = preema + self.alpha * (cl[i] - preema) ema.append(last_ema) self.ema = ema def onTick(self, tickEvent): epoch = tickEvent.time i, epoch = self.subc.getTime(epoch) if epoch == self.now: return i, epoch, self.ema[i - self.ema_span] if i < 0: self.updateEma() self.now = epoch i = i - self.ema_span if i >= 0: return i, epoch, self.ema[i - self.ema_span] else: return i, epoch, -1 def updateEma(self): (t1, _, _, _, cl1, _) = self.subc.getLatestChart(self.epochs[-1]) self._calcEma(t1, cl1, self.ema[-1]) def getPlotElement(self, color="k"): return PlotEleLineChart(self.epochs, self.ema)
class PowerIndex(TechnicalIndex): def __init__(self, instrument, granularity, startep, endep, sumspan=20): super(PowerIndex, self).__init__(instrument, granularity) self.subc = SubChart("PowerIndex", instrument, granularity, startep, endep) self.sumspan = sumspan self.bull = [] self.bear = [] self.bull_totals = [] self.bear_totals = [] self.epochs = [] (tl, _, hl, ll, cl, _) = self.subc.getPrices() self._calcPower(tl, hl, ll, cl) def _calcPower(self, tl, hl, ll, cl): bull = [] bear = [] for i in range(1, len(tl)): j = i - 1 u = hl[i] - ll[i] e = u c1 = cl[j] c2 = cl[i] d = c2 - c1 if d >= 0: e -= d if e < 0: e = 0 else: u += d if u < 0: u = 0 bull.append(u) bear.append(e) for i in range(self.sumspan, len(bull)): self.bull_totals.append(sum(bull[i - self.sumspan:i])) self.bear_totals.append(sum(bear[i - self.sumspan:i])) self.bull.extend(bull[self.sumspan:]) self.bear.extend(bear[self.sumspan:]) self.epochs.extend(tl[self.sumspan + 1:])
class CheckIndex(TechnicalIndex): def __init__(self, instrument, granularity, startep=-1, endep=-1): super(CheckIndex, self).__init__(instrument, granularity) self.subc = SubChart(self.__class__.__name__, instrument, granularity, startep, endep) self.cntForNext = 0 self.nowidx = -1 self.now = -1 def onTick(self, tickEvent): i, epoch = self.subc.onTick(tickEvent) if i == -1: return False if self.now == epoch: return if self.cntForNext > 0: self.cntForNext -= (epoch - self.now) / self.unitsecs if self.cntForNext < 0: self.cntForNext = 0 self.nowidx = i self.now = epoch return True def isNextOK(self): if self.cntForNext == 0: return True else: return False def addForNext(self, cnt): self.cntForNext += cnt def getPriceAt(self, j=0): i = self.nowidx (t, ol, hl, ll, cl, vl) = self.subc.getPrices() k = i - j return (t[k], ol[k], hl[k], ll[k], cl[k], vl[k]) #direction=1: up dow #direction=-1: down dow def isDowCandle(self, direction=1): try: i = self.nowidx (_, _, hl, ll, _, _) = self.subc.getPrices() if direction == 1: if hl[i] > hl[i - 1] and ll[i] > ll[i - 1]: return True else: return False elif direction == -1: if hl[i] < hl[i - 1] and ll[i] < ll[i - 1]: return True else: return False else: return False except IndexError: lib.printError( self.now, "index error: i=%d len(hl)=%d len(ll)=%d" % (i, len(hl), len(ll))) raise IndexError def isWindowOpen(self, wsize=0): i = self.nowidx (_, _, hl, ll, _, _) = self.subc.getPrices() if hl[i] + wsize < ll[i - 1] or ll[i] - wsize > hl[i - 1]: return True return False def isHourRange(self, startHour, endHour): eh = (self.now % (3600 * 24)) / 3600 if eh >= startHour and eh <= endHour: return True return False def isNHoursBeforeWeekend(self, n): if self.isWeekend(): return False if math.floor((self.now / (3600 * 24) + 4) % 7) == 5: #Friday if self.isHourRange(20 - n, 21): return False return True def isNHoursAfterWeekend(self, n): if self.isWeekend(): return False dn = math.floor((self.now / (3600 * 24) + 4) % 7) if dn == 0: #Sunday if self.isHourRange(22, 22 + n): return False elif dn == 1 and n >= 2: # Monday if self.isHourRange(22, 24) or self.isHourRange(0, n - 2): return False return True # considering summer time, at this funtion # weekend starts 1 hour earlier on winter # and ends 1 hour later on summer, to make always the same result # New York time def isWeekend(self): dn = math.floor((self.now / (3600 * 24) + 4) % 7) if dn == 6: # Saturday return True elif dn == 0: # Sunday if self.isHourRange(0, 22): return True elif dn == 5: # Friday if self.isHourRange(20, 24): return True return False