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
def _checkTradeNoScale(self): if self.hod is not None \ and self.periodData.high > self.hod \ and self.prevLowestLow.ready() \ and (self.hoddate.hour < 12 or (self.hoddate.hour == 12 and self.hoddate.minute == 0)) \ 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.hod - self.open) / self.open) >= self.minmove: # new trade entry = max(self.periodData.open, self.hod + 0.01) if self.maxprice is None or entry <= self.maxprice: stop = self.prevLowestLow.value() - 0.01 trade = Trade(self.periodData.stock, self.periodData.date, entry, stop) if self.target is not None: target = entry + ((entry - stop) * 2) trade.target = target if self.periodData.low < stop: trade.exit = self.periodData.date trade.exitPrice = stop return trade return None
def checkTrade(self): if self.lasthigh.ready() and self.donchStop.ready() \ and self.taps >= self.numTaps and self.lastdd.high > self.lasthigh.value() \ and (self.minhour is None or self.lastdd.date.hour >= self.minhour) \ and (self.maxhour is None or self.lastdd.date.hour < self.maxhour): entryPrice = max(self.lastdd.open, self.lasthigh.value() + 0.01) stop = max(0.0, self.donchStop.value() - 0.01) trade = Trade(self.lastdd.stock, self.lastdd.date, entryPrice, stop) if self.target is not None: trade.target = trade.entryPrice + (trade.entryPrice - trade.stop) * self.target return trade return None
def checkTrade(self): # TODO logic needs to be updated with some sort of hinting mechanism from the # daily trigger, if key price levels are desired if self.triggerLongPrice is not None and self.periodData.high >= (self.triggerLongPrice + 0.01): entry_price = max(self.periodData.open, self.triggerLongPrice + 0.01) stop = 0 trade = Trade(self.periodData.stock, self.periodData.date, entry_price, stop) if self.target is not None: trade.target = trade.entryPrice + (trade.entryPrice - trade.stop) * self.target return trade if self.triggerShortPrice is not None and self.periodData.low <= (self.triggerShortPrice - 0.01): entry_price = min(self.periodData.open, self.triggerShortPrice - 0.01) stop = entry_price * 2 trade = Trade(self.periodData.stock, self.periodData.date, entry_price, stop) if self.target is not None: trade.target = trade.entryPrice - (trade.stop - trade.entryPrice) * self.target return trade return None
def checkTrade(self): if self.setupLong and self.periodData.high >= (self.triggerLongPrice + 0.01) \ and self.currentDayOpen is not None and self.currentDayOpen < self.triggerLongPrice: entry_price = max(self.periodData.open, self.triggerLongPrice + 0.01) stop = self.lod.value() - 0.01 trade = Trade(self.periodData.stock, self.periodData.date, entry_price, stop) if self.target is not None: trade.target = trade.entryPrice + (trade.entryPrice - trade.stop) * self.target return trade if self.setupShort and self.periodData.low <= (self.triggerShortPrice - 0.01) \ and self.currentDayOpen is not None and self.currentDayOpen > self.triggerShortPrice: entry_price = min(self.periodData.open, self.triggerShortPrice - 0.01) stop = self.hod.value() + 0.01 trade = Trade(self.periodData.stock, self.periodData.date, entry_price, stop) if self.target is not None: trade.target = trade.entryPrice - (trade.stop - trade.entryPrice) * self.target return trade return None
def checkTrade(self): if self.lastma.ready() and ((self.high - self.opn) / self.opn) >= self.minmove: if self.periodData.low <= self.lastma.value(): entry_price = min(self.periodData.open, self.lastma.value()) stop = self.low - 0.01 trade = Trade(self.lastdd.stock, self.lastdd.date, entry_price, stop) if self.target is not None: trade.target = trade.entryPrice + (trade.entryPrice - trade.stop) * self.target return trade if self.lastma.ready() and ((self.opn - self.low) / self.opn) >= self.minmove: if self.periodData.high >= self.lastma.value(): entry_price = max(self.periodData.open, self.lastma.value()) stop = self.high + 0.01 trade = Trade(self.lastdd.stock, self.lastdd.date, entry_price, stop) if self.target is not None: trade.target = trade.entryPrice + (trade.entryPrice - trade.stop) * self.target return trade return None
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 checkTrade(self, trade): if trade is not None: # no scale ins return trade if self.enterEarly is not None: if self.doLong and self.bar > self.numBars and not self.low_violated: entry_price = self.low + ((self.high - self.low) * self.enterEarly) if self.periodData.low <= entry_price: ep = min(self.periodData.open, entry_price) stop = self.low - 0.01 trade = Trade(self.periodData.stock, self.periodData.date, ep, stop) if self.target is not None: trade.target = trade.entryPrice + (trade.entryPrice - trade.stop) * self.target if self.periodData.low <= trade.stop: trade.exit = self.periodData.Date trade.exitPrice = trade.stop return trade if self.periodData.low < self.low or self.periodData.high > self.high: # disable even if high violated, we don't chase it self.low_violated = True if self.doShort and self.bar > self.numBars and self.high_violated == False: entry_price = self.high - ((self.high - self.low) * self.enterEarly) if self.periodData.high >= entry_price: ep = max(self.periodData.open, entry_price) stop = self.high + 0.01 trade = Trade(self.periodData.stock, self.periodData.date, ep, stop) if self.target is not None: trade.target = trade.entryPrice + (trade.entryPrice - trade.stop) * self.target if self.periodData.high >= trade.stop: trade.exit = self.periodData.Date trade.exitPrice = trade.stop return trade if self.periodData.low < self.low or self.periodData.high > self.high: # disable even if high violated, we don't chase it self.high_violated = True else: if self.doLong and self.bar > self.numBars and self.low_violated == False and self.periodData.high >= ( self.high + 0.01): entry_price = max(self.periodData.open, self.high + 0.01) stop = self.low - 0.01 trade = Trade(self.periodData.stock, self.periodData.date, entry_price, stop) if self.target is not None: trade.target = trade.entryPrice + (trade.entryPrice - trade.stop) * self.target return trade if self.doShort and self.bar > self.numBars and self.high_violated == False and self.periodData.low <= ( self.low - 0.01): entry_price = min(self.periodData.open, self.low - 0.01) stop = self.high + 0.01 trade = Trade(self.periodData.stock, self.periodData.date, entry_price, stop) if self.target is not None: trade.target = trade.entryPrice + (trade.entryPrice - trade.stop) * self.target return trade return None
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()