class MomoAfternoonBreakoutDailyTrigger(DailyTrigger): def __init__(self, settings): DailyTrigger.__init__(self, settings) self.minprice = settings.getfloat("Strategy", "minprice") self.minvolume = settings.getint("Strategy", "minvolume") self.minmove = settings.getfloat("Strategy", "minmove") smatrend = settings.get("Strategy", "dailysmatrendfilter") if smatrend == "None": self.dailysmatrendfilter = None else: self.dailysmatrendfilter = int(smatrend) self.volume = Volume() self.avgvol = SimpleMovingAverage(self.volume, 21) self.close = Close() if self.dailysmatrendfilter is not None: self.ma = SimpleMovingAverage(period=self.dailysmatrendfilter) else: self.ma = None def ready(self): return (self.ma is None or self.ma.ready()) and self.avgvol.ready() and self.close.ready() def check(self): if self.ready() and self.lastpd is not None: # todo would be a lot faster if I could implement a peek at today to check the move is big enough if self.close.value() >= self.minprice \ and (self.ma is None or self.close.value() > self.ma.value()) \ and self.avgvol.value() >= self.minvolume \ and ((self.peekpd.high - self.peekpd.open) / self.peekpd.open) >= self.minmove: return True return False def handle(self, perioddata): if self.ma is not None: self.ma.handle(perioddata) self.volume.handle(perioddata) self.avgvol.handle(perioddata) self.close.handle(perioddata) self.lastpd = perioddata def recommendedPreload(self): mapreload = 0 if self.ma is not None: mapreload = self.ma.recommendedPreload() return max(mapreload, self.avgvol.recommendedPreload())
def __init__(self, settings, name=None): NoScaleInEntryManager.__init__(self, settings, name) self.minPrice = settings.getfloat("JBMarwoodSupernovaShortEntry", "minPrice") self.maxPrice = settings.getfloat("JBMarwoodSupernovaShortEntry", "maxPrice") self.minVol = settings.getint("JBMarwoodSupernovaShortEntry", "minVol") self.minPctChange = settings.getfloat("JBMarwoodSupernovaShortEntry", "minPctChange") self.numdays = settings.getint("JBMarwoodSupernovaShortEntry", "numBars") self.onOpen = settings.getboolean("JBMarwoodSupernovaShortEntry", "enterNextOpen") self.onDownClose = settings.getboolean("JBMarwoodSupernovaShortEntry", "enterNextDayDownClose") targetstr = settings.get("JBMarwoodSupernovaShortEntry", "target") if targetstr == "None": self.target = None else: self.target = float(targetstr) self.stopPercent = settings.getfloat("JBMarwoodSupernovaShortEntry", "stopPercent") self.setupYesterday = True self.rawclose = Close() self.close = AdjustedClose() self.oldClose = HistoricMetric(self.close, period=self.numdays) self.change = Subtract(self.close, self.oldClose) self.pctChange = Divide(self.change, self.oldClose) self.volume = Volume() self._addMetric(self.rawclose) self._addMetric(self.close) self._addMetric(self.oldClose) self._addMetric(self.change) self._addMetric(self.pctChange) self._addMetric(self.volume)
class BollingerBreakoutEntryManager(NoScaleInEntryManager): def __init__(self, settings=None, name=None): NoScaleInEntryManager.__init__(self, settings, name) self.min_price = self._getfloatsetting("BollingerBreakoutEntryManager", "minPrice") self.min_vol = self._getintsetting("BollingerBreakoutEntryManager", "minVolume") bb_period = self._getintsetting("BollingerBreakoutEntryManager", "bbPeriod") bb_stdevs = self._getfloatsetting("BollingerBreakoutEntryManager", "bbStdevs") self.do_long = self._getboolsetting("BollingerBreakoutEntryManager", "doLong") self.do_short = self._getboolsetting("BollingerBreakoutEntryManager", "doShort") sma_period = self._getintsetting("BollingerBreakoutEntryManager", "smaPeriod") if sma_period is not None: self.sma = SimpleMovingAverage(period=sma_period) else: self.sma = None self.raw_close = Close() self.close = AdjustedClose() self.vol = AverageVolume() self.bb = BollingerBands(metric=self.close, period=bb_period, stdev=bb_stdevs) self._addMetrics(self.sma, self.raw_close, self.close, self.vol, self.bb) def _checkTradeNoScale(self): trade = None if self.raw_close.value() >= self.min_price and self.vol.value() >= self.min_vol \ and self.close.value() > self.bb.upperBand() and self.do_long \ and (self.sma is None or self.close.value() > self.sma.value()): entry_price = self.close.value() stop = 0 trade = Trade(stock=self.periodData.stock, entry=self.periodData.date, entryPrice=entry_price, stop=stop) if self.raw_close.value() >= self.min_price and self.vol.value() >= self.min_vol \ and self.close.value() < self.bb.upperBand() and self.do_short \ and (self.sma is None or self.close.value() < self.sma.value()): entry_price = self.close.value() stop = entry_price * 10 trade = Trade(stock=self.periodData.stock, entry=self.periodData.date, entryPrice=entry_price, stop=stop) return trade
def __init__(self, settings): DailyTrigger.__init__(self, settings) self.minprice = settings.getfloat("Strategy", "minprice") self.minvolume = settings.getint("Strategy", "minvolume") self.minmove = settings.getfloat("Strategy", "minmove") smatrend = settings.get("Strategy", "dailysmatrendfilter") if smatrend == "None": self.dailysmatrendfilter = None else: self.dailysmatrendfilter = int(smatrend) self.volume = Volume() self.avgvol = SimpleMovingAverage(self.volume, 21) self.close = Close() if self.dailysmatrendfilter is not None: self.ma = SimpleMovingAverage(period=self.dailysmatrendfilter) else: self.ma = None
def __init__(self, settings=None, name=None): NoScaleInEntryManager.__init__(self, settings, name) self.min_price = self._getfloatsetting("BollingerBreakoutEntryManager", "minPrice") self.min_vol = self._getintsetting("BollingerBreakoutEntryManager", "minVolume") bb_period = self._getintsetting("BollingerBreakoutEntryManager", "bbPeriod") bb_stdevs = self._getfloatsetting("BollingerBreakoutEntryManager", "bbStdevs") self.do_long = self._getboolsetting("BollingerBreakoutEntryManager", "doLong") self.do_short = self._getboolsetting("BollingerBreakoutEntryManager", "doShort") sma_period = self._getintsetting("BollingerBreakoutEntryManager", "smaPeriod") if sma_period is not None: self.sma = SimpleMovingAverage(period=sma_period) else: self.sma = None self.raw_close = Close() self.close = AdjustedClose() self.vol = AverageVolume() self.bb = BollingerBands(metric=self.close, period=bb_period, stdev=bb_stdevs) self._addMetrics(self.sma, self.raw_close, self.close, self.vol, self.bb)
def __init__(self, settings, name=None): EntryManager.__init__(self, settings, name) self.minhour = settings.getint("Strategy", "minhour") self.maxhour = settings.getint("Strategy", "maxhour") self.target = self._getintsetting("Strategy", "target") self.minmove = settings.getfloat("Strategy", "minmove") self.maxprice = self._getfloatsetting("Strategy", "maxprice") self.maperiod = self._getintsetting("Strategy", "ma") self.stopPercentToLow = self._getfloatsetting("Strategy", "stopPercentToLow") self.hod = None self.open = None self.hoddate = None self.low = None self.close = Close() self.ma = ExponentialMovingAverage(metric=self.close, period=self.maperiod) self.mademove = False self.lastpd = None
class MomoPullbackEntryManager(EntryManager): """ Enter at a moving average after a minimum move. Stop is set at a percentage between the moving average and the low of day. """ def __init__(self, settings, name=None): EntryManager.__init__(self, settings, name) self.minhour = settings.getint("Strategy", "minhour") self.maxhour = settings.getint("Strategy", "maxhour") self.target = self._getintsetting("Strategy", "target") self.minmove = settings.getfloat("Strategy", "minmove") self.maxprice = self._getfloatsetting("Strategy", "maxprice") self.maperiod = self._getintsetting("Strategy", "ma") self.stopPercentToLow = self._getfloatsetting("Strategy", "stopPercentToLow") self.hod = None self.open = None self.hoddate = None self.low = None self.close = Close() self.ma = ExponentialMovingAverage(metric=self.close, period=self.maperiod) self.mademove = False self.lastpd = None def handle(self, perioddata): self.close.handle(perioddata) self.ma.handle(perioddata) if self.lastpd is not None and self.lastpd.date.day != perioddata.date.day: self.low = None self.hod = None self.hoddate = None self.mademove = False if self.open is None: self.open = perioddata.open if self.lastpd is not None and (self.low is None or self.lastpd.low < self.low): self.low = self.lastpd.low if self.periodData is not None: # quick, use previous value to update hod if self.hod is None or self.periodData.high >= self.hod: self.hod = self.periodData.high self.hoddate = self.periodData.date if not self.mademove and self.low is not None and self.hod is not None and self.open is not None and ( self.hod - self.open) / self.open >= self.minmove: logger.debug("saw minimum desired move in MomoPullbackManager, waiting for pullback") self.mademove = True EntryManager.handle(self, perioddata) self.lastpd = perioddata def checkTrade(self, trade): if trade is not None: # no scale ins return trade if self.mademove \ and self.periodData.date.hour >= self.minhour \ and (self.periodData.date.hour < self.maxhour or (self.periodData.date.hour == self.maxhour and self.periodData.date.minute == 0)) \ and self.periodData.low <= self.ma.value(): # we have an entry entry = min(self.periodData.open, self.ma.value()) if self.maxprice is None or entry <= self.maxprice: stop = self.low - 0.01 if self.stopPercentToLow is not None: stop = entry - (self.stopPercentToLow * (entry - self.low)) # at least 10c if stop >= entry - 0.1: stop = entry - 0.1 trade = Trade(self.periodData.stock, self.periodData.date, entry, stop) if self.target is not None: target = entry + ((entry - stop) * self.target) trade.target = target if self.periodData.low < stop: trade.exit = self.periodData.date trade.exitPrice = stop return trade return None
class JBMarwoodSupernovaShortEntryManager(NoScaleInEntryManager): def __init__(self, settings, name=None): NoScaleInEntryManager.__init__(self, settings, name) self.minPrice = settings.getfloat("JBMarwoodSupernovaShortEntry", "minPrice") self.maxPrice = settings.getfloat("JBMarwoodSupernovaShortEntry", "maxPrice") self.minVol = settings.getint("JBMarwoodSupernovaShortEntry", "minVol") self.minPctChange = settings.getfloat("JBMarwoodSupernovaShortEntry", "minPctChange") self.numdays = settings.getint("JBMarwoodSupernovaShortEntry", "numBars") self.onOpen = settings.getboolean("JBMarwoodSupernovaShortEntry", "enterNextOpen") self.onDownClose = settings.getboolean("JBMarwoodSupernovaShortEntry", "enterNextDayDownClose") targetstr = settings.get("JBMarwoodSupernovaShortEntry", "target") if targetstr == "None": self.target = None else: self.target = float(targetstr) self.stopPercent = settings.getfloat("JBMarwoodSupernovaShortEntry", "stopPercent") self.setupYesterday = True self.rawclose = Close() self.close = AdjustedClose() self.oldClose = HistoricMetric(self.close, period=self.numdays) self.change = Subtract(self.close, self.oldClose) self.pctChange = Divide(self.change, self.oldClose) self.volume = Volume() self._addMetric(self.rawclose) self._addMetric(self.close) self._addMetric(self.oldClose) self._addMetric(self.change) self._addMetric(self.pctChange) self._addMetric(self.volume) def _checkTradeNoScale(self): trade = None if self.setupYesterday: if self.onOpen: entry = self.periodData.adjustedOpen stop = entry * (1 + self.stopPercent) if entry != stop: trade = Trade(self.periodData.stock, self.periodData.date, entry, stop) if self.target != None: target = self.close.value() * (1.0 - self.target) trade.target = target elif self.onDownClose and self.periodData.adjustedClose < self.periodData.adjustedOpen: stop = self.periodData.adjustedHigh + 0.01 # stop = self.close.value()*(1+self.stopPercent) if stop != self.close.value(): trade = Trade(self.periodData.stock, self.periodData.date, self.close.value(), stop) if self.target != None: target = self.close.value() * (1.0 - self.target) trade.target = target if ( self.pctChange.ready() and self.rawclose.value() >= self.minPrice and self.rawclose.value() <= self.maxPrice and self.volume.value() >= self.minVol and self.pctChange.value() >= self.minPctChange ): if not self.onDownClose and not self.onOpen: # enter immediately stop = self.close.value() * (1 + self.stopPercent) if stop != self.close.value(): trade = Trade(self.periodData.stock, self.periodData.date, self.close.value(), stop) if self.target != None: target = self.close.value() * (1.0 - self.target) trade.target = target self.setupYesterday = True else: self.setupYesterday = False if trade is not None and (trade.entryPrice == 0 or trade.entryPrice == trade.stop): return None return trade
def findsetups(self, fromdt, todt): stocks = self._getTickers(fromdt, datastore) for stock in stocks: close = Close() sma = None if self.dailysmatrendfilter != None: sma = SimpleMovingAverage(close, period=self.dailysmatrendfilter) # padded extra to make sure 50 day sma has enough trading days to work with before our window dailydata = datastore.getDailyData(stock, fromdt - timedelta(days=100), todt) prevpd = None for pd in dailydata: if prevpd != None and pd.date >= fromdt: trade = None if pd.open == prevpd.close or prevpd.close == 0: gapsize=0 else: gapsize = (prevpd.close - pd.open)/prevpd.close if gapsize >= self.mingap and (sma == None or (sma.ready() and pd.open < sma.value())) and pd.open >= self.minprice: intrafromdt = pd.date intratodt = pd.date + timedelta(hours=24) intradaydata = iter(datastore.getIntradayData(stock, 300, intrafromdt, intratodt)) try: intradaypd = intradaydata.next() entry = None lod = intradaypd.low prevpd = intradaypd high = High() highesthigh = Highest(metric=high, period=self.donchianstop) high.handle(intradaypd) highesthigh.handle(intradaypd) for intradaypd in intradaydata: if trade == None \ and highesthigh.ready() \ and intradaypd.date.hour >= self.minhour \ and (intradaypd.date.hour < self.maxhour \ or (intradaypd.date.hour == self.maxhour and intradaypd.date.minute==0)) \ and intradaypd.low < lod: entry = lod - 0.01 trade = Trade(stock, intradaypd.date, min(entry, intradaypd.open), highesthigh.value()+0.01) if self.target != None: trade.target = trade.entryPrice + (self.target * (trade.entryPrice-trade.stop)) if trade != None and trade.exit == None: if intradaypd.high >= trade.trailingstop: trade.exit = intradaypd.date trade.exitPrice = max(trade.stop, intradaypd.open) if trade.exit == None and trade.target != None and intradaypd.low <= trade.target: trade.exit = intradaypd.date trade.exitPrice = min(intradaypd.open, trade.target) if intradaypd.low < lod: lod = intradaypd.low high.handle(intradaypd) highesthigh.handle(intradaypd) except StopIteration: pass # eod, close it if it is still open if trade != None and trade.exit == None: trade.exit = intradaypd.date trade.exitPrice = intradaypd.close if trade != None: self.tradeManager.addTrade(trade) # now we can update the indicators - since we finished trading the day close.handle(pd) if sma != None: sma.handle(pd) prevpd = pd return self.tradeManager.getStats()
def findsetups(self, fromdt, todt): numstopouts = 0 stocks = self._getTickers(fromdt, datastore) for stock in stocks: # padded extra to make sure 200 day sma has enough trading days to work with before our window dailydata = datastore.getDailyData(stock, fromdt - timedelta(days=(self.slowma*2)), todt) close = Close() fastma = SimpleMovingAverage(period=self.fastma) slowma = SimpleMovingAverage(period=self.slowma) lastfastma = HistoricMetric(metric=fastma, period=1) lastslowma = HistoricMetric(metric=slowma, period=1) atr = ATR(period=14) lastdd = None trade = None for pd in dailydata: close.handle(pd) fastma.handle(pd) slowma.handle(pd) lastfastma.handle(pd) lastslowma.handle(pd) atr.handle(pd) # check for long stopout if trade != None and pd.low < trade.trailingstop: trade.exit = pd.date trade.exitPrice = min(pd.open, trade.trailingstop) self.tradeManager.addTrade(trade) numstopouts = numstopouts + 1 trade = None # check for long exit if trade != None and fastma.value() < slowma.value(): trade.exit = pd.date trade.exitPrice = pd.close self.tradeManager.addTrade(trade) trade = None if fastma.ready() and slowma.ready() and lastfastma.ready() and lastslowma.ready() and atr.ready(): pass # check for new long if trade == None and fastma.ready() and slowma.ready() \ and lastfastma.ready() and lastslowma.ready() \ and (self.atrStop == None or atr.ready()) \ and pd.date >= fromdt \ and fastma.value() > slowma.value() \ and lastfastma.value() <= lastslowma.value() \ and pd.close >= self.minprice: stop = 0 if self.atrStop != None: stop = max(0,pd.close - (float(self.atrStop) * atr.value())) if self.percentStop != None: stop = max(0, pd.close * (1.0 - self.percentStop)) trade = Trade(stock=stock, entry=pd.date, entryPrice=pd.close, stop=stop) if trade != None and trade.entry == None: trade.exit = lastdd.date trade.exitPrice = lastdd.close self.tradeManager.addTrade(trade) trade = None print "num stopouts was %d" % numstopouts return self.tradeManager.getStats()