def findsetups(self, fromdt, todt): datastore = datastorefactory.get_datastore() # stocks = datastore.filterStocksByAvgVolume(fromdt, minvolume) stocks = self._getTickers(fromdt, datastore) for stock in stocks: dailydata = list() volume = Volume() avgvolume = SimpleMovingAverage(metric=volume, period=21) dailyatr = ATR(20) atrfromdt = fromdt - timedelta(days=max(self.duration, 40)) # 40 to give the atr time to normalize dailydataiter = iter(datastore.getDailyData(stock, atrfromdt, todt)) dailydataday = None try: while dailydataday == None or dailydataday.date < fromdt: dailydataday = dailydataiter.next() # have to fix it to a real object for the atr dailyatr.handle(dailydataday) dailydata.append(dailydataday) except StopIteration: pass if len(dailydata) > self.duration: dailydata = dailydata[len(dailydata) - self.duration :] # ok, we find the highest high and lowest low first high = 0 low = None for ddhighfinder in dailydata: if high < ddhighfinder.high: high = ddhighfinder.high if low == None or ddhighfinder.low < low: low = ddhighfinder.low # great, now we find how many lower highs are within the mush factor atrmush = 0 if dailyatr.value() != None: atrmush = dailyatr.value() * self.mushinessatr taps = 0 shorttaps = 0 for ddtapfinder in dailydata: delta = high - ddtapfinder.high if delta <= atrmush or delta <= self.mushinessfixed: taps = taps + 1 shortdelta = ddtapfinder.low - low if shortdelta <= atrmush or delta <= self.mushinessfixed: shorttaps = shorttaps + 1 # ok, now we can add the next dd - we go ahead and prep some things for the next loop pass # since we are no longer using them now for dailydataday in dailydataiter: saveatr = dailyatr.value() volume.handle(dailydataday) avgvolume.handle(dailydataday) dailyatr.handle(dailydataday) dailydata.append(dailydataday) dailydata = dailydata[1:] trade = None # as a hack, now we can check our peek ahead and see for free if we # ever broke the high today. If not, we are done if ( self.doLongs and taps >= self.numtaps and dailydataday.high > high and high >= self.minprice and (self.maxprice == None or high <= self.maxprice) and avgvolume.ready() and avgvolume.value() >= self.minavgvolume and ( self.minAPR == None or (dailyatr.ready() and dailyatr.value() / dailydataday.adjustedClose) >= self.minAPR ) ): # ok, we need to scan the day low = None donchlow = None if self.donchianstop != None: low = Low() donchlow = Lowest(low, self.donchianstop) intrafromdt = dailydataday.date intratodt = intrafromdt + timedelta(hours=24) intradaydata = datastore.getIntradayData(stock, self.period, intrafromdt, intratodt) if intradaydata != None and len(intradaydata) > 1: intradaybar = intradaydata[0] intralow = intradaybar.low intrahigh = intradaybar.high taps = 1 for i in range(1, len(intradaydata)): intradaybar = intradaydata[i] if trade == None and ( self.maxintradayrangeatr == None or (saveatr != None and (intrahigh - intralow) < (saveatr * self.maxintradayrangeatr)) ): intralow = min(intralow, intradaybar.low) if ( intradaybar.high <= intrahigh and (intrahigh - intradaybar.high) <= self.mushinessfixed2m ): taps = taps + 1 if intradaybar.high > intrahigh: if ( taps >= self.taps2m and intrahigh >= high and ( self.maxhour == None or intradaybar.date.hour < self.maxhour or (intradaybar.date.hour == self.maxhour and intradaybar.date.minute == 0) ) and (self.minhour == None or intradaybar.date.hour >= self.minhour) ): # trade entry if donchlow != None and donchlow.ready(): stop = donchlow.value() - 0.01 else: stop = intralow - 0.01 entryPrice = min(intradaybar.open, intrahigh + 0.01) if entryPrice > stop: trade = Trade( stock=stock, entry=intradaybar.date, entryPrice=min(intradaybar.open, intrahigh + 0.01), stop=stop, ) if self.target: trade.target = trade.entryPrice + ( self.target * (trade.entryPrice - trade.stop) ) else: # need to recalculate taps off this new high as we had no signal yet intrahigh = intradaybar.high taps = 1 for j in range(0, i - 1): if (intrahigh - intradaydata[j].high) < self.mushinessfixed2m: taps = taps + 1 if trade and trade.exit == None: if intradaybar.low < trade.trailingstop: # taken out trade.exit = intradaybar.date trade.exitPrice = min(intradaybar.open, trade.trailingstop) if trade.target != None and intradaybar.high > trade.target: trade.exit = intradaybar.date trade.exitPrice = max(intradaybar.open, trade.target) if low != None: low.handle(intradaybar) if donchlow != None: donchlow.handle(intradaybar) if trade != None and trade.exit == None: trade.exit = intradaybar.date trade.exitPrice = intradaybar.close if trade: self.tradeManager.addTrade(trade) trade = None trade = None # SHORTS # as a hack, now we can check our peek ahead and see for free if we # ever broke the low today. If not, we are done if ( self.doShorts and shorttaps >= self.numtaps and dailydataday.low < low and low >= self.minprice and avgvolume.ready() and avgvolume.value() >= self.minavgvolume and ( self.minAPR == None or (dailyatr.ready() and dailyatr.value() / dailydataday.adjustedClose) >= self.minAPR ) ): # ok, we need to scan the day high = None donchhigh = None if self.donchianstop != None: high = High() donchhigh = Highest(high, self.donchianstop) intrafromdt = dailydataday.date intratodt = intrafromdt + timedelta(hours=24) intradaydata = datastore.getIntradayData(stock, 300, intrafromdt, intratodt) if intradaydata != None and len(intradaydata) > 1: intradaybar = intradaydata[0] intralow = intradaybar.low intrahigh = intradaybar.high taps = 1 for i in range(1, len(intradaydata)): intradaybar = intradaydata[i] if trade == None and ( self.maxintradayrangeatr == None or (saveatr != None and (intrahigh - intralow) < (saveatr * self.maxintradayrangeatr)) ): intrahigh = max(intrahigh, intradaybar.high) if ( intradaybar.low >= intralow and (intradaybar.low - intralow) <= self.mushinessfixed2m ): taps = taps + 1 if intradaybar.low < intralow: if ( taps >= self.taps2m and intralow <= low and ( self.maxhour == None or intradaybar.date.hour < self.maxhour or (intradaybar.date.hour == self.maxhour and intradaybar.date.minute == 0) ) and (self.minhour == None or intradaybar.date.hour >= self.minhour) ): # trade entry if donchhigh != None and donchhigh.ready(): stop = donchhigh.value() + 0.01 else: stop = intrahigh + 0.01 entryPrice = min(intradaybar.open, intralow - 0.01) if entryPrice < stop: trade = Trade( stock=stock, entry=intradaybar.date, entryPrice=entryPrice, stop=stop ) if self.target: trade.target = trade.entryPrice - ( self.target * (trade.stop - trade.entryPrice) ) else: # need to recalculate taps off this new high as we had no signal yet intralow = intradaybar.low taps = 1 for j in range(0, i - 1): if (intralow - intradaydata[j].low) < self.mushinessfixed2m: taps = taps + 1 if trade and trade.exit == None: if intradaybar.high >= trade.trailingstop: # taken out trade.exit = intradaybar.date trade.exitPrice = max(intradaybar.open, trade.trailingstop) if trade.target != None and intradaybar.low < trade.target: trade.exit = intradaybar.date trade.exitPrice = min(intradaybar.open, trade.target) if high != None: high.handle(intradaybar) if donchhigh != None: donchhigh.handle(intradaybar) if trade != None and trade.exit == None: trade.exit = intradaybar.date trade.exitPrice = intradaybar.close if trade: self.tradeManager.addTrade(trade) trade = None trade = None # redo daily setup for the next day, already loaded in above the intraday loop # ok, we find the highest high first high = 0 low = None for ddhighfinder in dailydata: if high < ddhighfinder.high: high = ddhighfinder.high if low == None or ddhighfinder.low < low: low = ddhighfinder.low # great, now we find how many lower highs are within the mush factor atrmush = 0 if dailyatr.value() != None: atrmush = dailyatr.value() * self.mushinessatr taps = 0 shorttaps = 0 for ddtapfinder in dailydata: delta = high - ddtapfinder.high shortdelta = ddtapfinder.low - low if delta <= atrmush or delta <= self.mushinessfixed: taps = taps + 1 if shortdelta <= atrmush or shortdelta <= self.mushinessfixed: shorttaps = shorttaps + 1 return self.tradeManager.getStats()
def findsetups(self, fromdt, todt): stocks = self._getTickers(fromdt, datastore) for stock in stocks: close = Close() if self.dailysmatrendfilter != None: sma = SimpleMovingAverage(close, period=self.dailysmatrendfilter) else: sma = None # 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 = (pd.open - prevpd.close)/prevpd.close if gapsize >= self.mingap and (sma == None or sma.ready()) and (sma == None or 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 hod = intradaypd.high prevpd = intradaypd low = Low() lowestlow = Lowest(metric=low, period=self.donchianstop) low.handle(intradaypd) lowestlow.handle(intradaypd) for intradaypd in intradaydata: if trade == None \ and lowestlow.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.high > hod: entry = hod + 0.01 trade = Trade(stock, intradaypd.date, max(entry, intradaypd.open), lowestlow.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.low <= trade.trailingstop: trade.exit = intradaypd.date trade.exitPrice = min(trade.stop, intradaypd.open) if trade.exit == None and trade.target != None and intradaypd.high >= trade.target: trade.exit = intradaypd.date trade.exitPrice = max(intradaypd.open, trade.target) if intradaypd.high > hod: hod = intradaypd.high low.handle(intradaypd) lowestlow.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()