Exemple #1
0
class NewHighDailyTrigger(Check):
    def __init__(self, settings):
        self.highperiod = settings.getfloat("NewHighDailyTrigger", "highperiod")
        self.minprice = settings.getfloat("NewHighDailyTrigger", "minprice")
        self.maxprice = settings.getfloat("NewHighDailyTrigger", "maxprice")
        self.high = High()
        self.highesthigh = Highest(metric=self.high, period=self.highperiod)
        self.lasthighesthigh = HistoricMetric(metric=self.highesthigh,period=1)

    def ready(self):
        if self.lasthighesthigh.ready():
            return True
        return False
    
    def check(self):
        if self.ready() and self.lastpd != None:
            if self.high.value() > self.lasthighesthigh.value() \
                and self.lasthighesthigh.value() >= self.minprice \
                and self.lasthighesthigh.value() <= self.maxprice:
                return True
        return False
    
    def handle(self, perioddata):
        self.high.handle(perioddata)
        self.highesthigh.handle(perioddata)
        self.lasthighesthigh.handle(perioddata)
        
        self.lastpd = perioddata
    
    def getLongPrice(self):
        return self.lasthighesthigh.value()

    def getShortPrice(self):
        return None
class GapDailyTrigger(PriceVolumeDailyTrigger):
    def __init__(self, settings):
        PriceVolumeDailyTrigger.__init__(self, settings)
        self.mingap = settings.getfloat("GapDailyTrigger", "mingap")
        dfilter = settings.get("GapDailyTrigger", "donchianfilter")
        if dfilter == "None":
            self.lasthighesthigh = None
            self.lastlowestlow = None
        else:
            self.high = High()
            self.highesthigh = Highest(self.high, int(dfilter))
            self.lasthighesthigh = HistoricMetric(self.highesthigh, 1)
            self.low = Low()
            self.lowestlow = Lowest(self.low, int(dfilter))
            self.lastlowestlow = HistoricMetric(self.lowestlow, 1)

    def ready(self):
        if PriceVolumeDailyTrigger.ready(self) and self.perioddata is not None and self.lastperioddata is not None:
            return True

    def check(self):
        if self.mingap >= 0.0:
            if PriceVolumeDailyTrigger.check(self) and self.perioddata is not None and \
                            ((
                                 self.perioddata.open - self.lastperioddata.close) / self.lastperioddata.close) >= self.mingap \
                    and (self.lasthighesthigh is None or (
                        self.lasthighesthigh.ready() and self.perioddata.open >= self.lasthighesthigh.value())):
                return True
        else:
            if PriceVolumeDailyTrigger.check(self) and self.perioddata is not None and \
                            ((
                                 self.perioddata.open - self.lastperioddata.close) / self.lastperioddata.close) <= self.mingap \
                    and (self.lastlowestlow is None or (
                        self.lastlowestlow.ready() and self.perioddata.open <= self.lastlowestlow.value())):
                return True
        return False

    def handle(self, perioddata):
        # store previous perioddata before we call superclass
        self.lastperioddata = self.perioddata
        if self.lasthighesthigh is not None:
            self.high.handle(perioddata)
            self.highesthigh.handle(perioddata)
            self.lasthighesthigh.handle(perioddata)
            self.low.handle(perioddata)
            self.lowestlow.handle(perioddata)
            self.lastlowestlow.handle(perioddata)
        PriceVolumeDailyTrigger.handle(self, perioddata)
Exemple #3
0
 def __init__(self, settings):
     self.highperiod = settings.getfloat("NewHighDailyTrigger", "highperiod")
     self.minprice = settings.getfloat("NewHighDailyTrigger", "minprice")
     self.maxprice = settings.getfloat("NewHighDailyTrigger", "maxprice")
     self.high = High()
     self.highesthigh = Highest(metric=self.high, period=self.highperiod)
     self.lasthighesthigh = HistoricMetric(metric=self.highesthigh,period=1)
    def __init__(self, settings):
        PriceVolumeDailyTrigger.__init__(self, settings)
        self.minatrmultiple = settings.getfloat("MomoDailyTrigger", "minatrmultiple")
        self.closepercent = settings.get("MomoDailyTrigger", "closepercent")
        self.openpercent = settings.get("MomoDailyTrigger", "openpercent")
        self.takeLongs = settings.getboolean("MomoDailyTrigger", "takeLongs")
        self.takeShorts = settings.getboolean("MomoDailyTrigger", "takeShorts")
        minaprstr = settings.get("MomoDailyTrigger", "minapr")
        self.minapr = None
        if minaprstr != "None":
            self.minapr = float(minaprstr)
        dfilter = settings.get("MomoDailyTrigger", "donchianfilter")

        self.high = High()
        self.low = Low()
        self.atr = ATR(14)
        self.lastatr = HistoricMetric(self.atr, 1)

        if dfilter == "None":
            self.lasthighesthigh = None
            self.lastlowestlow = None
        else:
            self.highesthigh = Highest(self.high, int(dfilter))
            self.lasthighesthigh = HistoricMetric(self.highesthigh, 1)
            self.lowestlow = Lowest(self.low, int(dfilter))
            self.lastlowestlow = HistoricMetric(self.lowestlow, 1)
    def __init__(self, settings):
        BasicStopManager.__init__(self, settings)

        channelPeriod = settings.getint("DonchianChannelStopManager", "channelPeriod")
        self.low = Low()
        self.high = High()
        self.lowestLow = Lowest(self.low, channelPeriod)
        self.highestHigh = Highest(self.high, channelPeriod)
        self.lastLowestLow = HistoricMetric(self.lowestLow, 1)
        self.lastHighestHigh = HistoricMetric(self.highestHigh, 1)
class DonchianChannelStopManager(BasicStopManager):
    def __init__(self, settings):
        BasicStopManager.__init__(self, settings)

        channelPeriod = settings.getint("DonchianChannelStopManager", "channelPeriod")
        self.low = Low()
        self.high = High()
        self.lowestLow = Lowest(self.low, channelPeriod)
        self.highestHigh = Highest(self.high, channelPeriod)
        self.lastLowestLow = HistoricMetric(self.lowestLow, 1)
        self.lastHighestHigh = HistoricMetric(self.highestHigh, 1)

    def handle(self, perioddata):
        BasicStopManager.handle(self, perioddata)

        self.low.handle(perioddata)
        self.high.handle(perioddata)
        self.lowestLow.handle(perioddata)
        self.highestHigh.handle(perioddata)
        self.lastLowestLow.handle(perioddata)
        self.lastHighestHigh.handle(perioddata)

    def checkTrade(self, trade):
        if trade != None and trade.entryPrice > trade.stop:
            trade.trailingstop = max(trade.stop, self.lastLowestLow.value()-0.01)
        if trade != None and trade.entryPrice < trade.stop:
            trade.trailingstop = min(trade.stop, self.lastHighestHigh.value() + 0.01)
        if trade != None and trade.exit == None \
                and trade.entryPrice > trade.stop and self.perioddata.low <= trade.trailingstop:
            trade.exit = self.perioddata.date
            trade.exitPrice = min(self.perioddata.open, trade.trailingstop)
        if trade != None and trade.exit == None \
                and trade.entryPrice < trade.stop and self.perioddata.high >= trade.trailingstop:
            trade.exit = self.perioddata.date
            trade.exitPrice = max(self.perioddata.open, trade.trailingstop)
        return trade

    def recommendedPreload(self):
        return self.lastHighestHigh.recommendedPreload()
 def __init__(self, settings):
     PriceVolumeDailyTrigger.__init__(self, settings)
     self.mingap = settings.getfloat("GapDailyTrigger", "mingap")
     dfilter = settings.get("GapDailyTrigger", "donchianfilter")
     if dfilter == "None":
         self.lasthighesthigh = None
         self.lastlowestlow = None
     else:
         self.high = High()
         self.highesthigh = Highest(self.high, int(dfilter))
         self.lasthighesthigh = HistoricMetric(self.highesthigh, 1)
         self.low = Low()
         self.lowestlow = Lowest(self.low, int(dfilter))
         self.lastlowestlow = HistoricMetric(self.lowestlow, 1)
 def __init__(self, settings, name=None):
     EntryManager.__init__(self, settings, name)
     self.mindip = settings.getfloat("R2GEntryManager", "mindip")
     self.target = self._getfloatsetting(settings, "R2GEntryManager", "target")
     self.setupLong = False
     self.setupShort = False
     self.low = Low()
     self.lod = Lowest(self.low, -1)
     self.high = High()
     self.hod = Highest(self.high, -1)
     # TODO replace trigger logic with some kind of context/info from DailyDataTrigger
     self.triggerLongPrice = None
     self.triggerShortPrice = None
     self.currentDate = None
     self.currentDayOpen = None
class R2GEntryManager(EntryManager):
    """ Enter after an open below and minimum move below the previous close, once it retakes the
    previous close and goes higher.  Opposite requirements for shorts.
    """

    def __init__(self, settings, name=None):
        EntryManager.__init__(self, settings, name)
        self.mindip = settings.getfloat("R2GEntryManager", "mindip")
        self.target = self._getfloatsetting(settings, "R2GEntryManager", "target")
        self.setupLong = False
        self.setupShort = False
        self.low = Low()
        self.lod = Lowest(self.low, -1)
        self.high = High()
        self.hod = Highest(self.high, -1)
        # TODO replace trigger logic with some kind of context/info from DailyDataTrigger
        self.triggerLongPrice = None
        self.triggerShortPrice = None
        self.currentDate = None
        self.currentDayOpen = None

    def handle(self, perioddata):
        EntryManager.handle(self, perioddata)

        current_date = perioddata.date.date
        if current_date > self.currentDate:
            self.currentDayOpen = perioddata.adjustedOpen

        self.low.handle(perioddata)
        self.lod.handle(perioddata)
        self.high.handle(perioddata)
        self.hod.handle(perioddata)

        # TODO need to rewrite this in terms of some new hinting
        # facility from the daily trigger now that I removed
        # trigger price arguments
        if self.triggerLongPrice is not None:
            if perioddata.low <= (self.triggerLongPrice - self.mindip):
                self.setupLong = True
        if self.triggerShortPrice is not None:
            if perioddata.high >= (self.triggerShortPrice + self.mindip):
                self.setupShort = True

    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 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):
        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()
class MomoDailyTrigger(PriceVolumeDailyTrigger):
    def __init__(self, settings):
        PriceVolumeDailyTrigger.__init__(self, settings)
        self.minatrmultiple = settings.getfloat("MomoDailyTrigger", "minatrmultiple")
        self.closepercent = settings.get("MomoDailyTrigger", "closepercent")
        self.openpercent = settings.get("MomoDailyTrigger", "openpercent")
        self.takeLongs = settings.getboolean("MomoDailyTrigger", "takeLongs")
        self.takeShorts = settings.getboolean("MomoDailyTrigger", "takeShorts")
        minaprstr = settings.get("MomoDailyTrigger", "minapr")
        self.minapr = None
        if minaprstr != "None":
            self.minapr = float(minaprstr)
        dfilter = settings.get("MomoDailyTrigger", "donchianfilter")

        self.high = High()
        self.low = Low()
        self.atr = ATR(14)
        self.lastatr = HistoricMetric(self.atr, 1)

        if dfilter == "None":
            self.lasthighesthigh = None
            self.lastlowestlow = None
        else:
            self.highesthigh = Highest(self.high, int(dfilter))
            self.lasthighesthigh = HistoricMetric(self.highesthigh, 1)
            self.lowestlow = Lowest(self.low, int(dfilter))
            self.lastlowestlow = HistoricMetric(self.lowestlow, 1)

    def ready(self):
        if PriceVolumeDailyTrigger.ready(self) and self.perioddata is not None and self.lastperioddata is not None:
            return True

    def check(self):
        if self.lastperioddata.close <= 0:
            return False
        if self.minapr is None or (self.lastatr.value() / self.lastperioddata.close) < self.minapr:
            return False
        if (self.lastperioddata.close - self.lastperioddata.open) < (self.lastatr.value() * self.minatrmultiple):
            return False
        if self.lastperioddata.close > self.lastperioddata.open and self.takeLongs:
            if ((self.lastperioddata.high - self.lastperioddata.close) / (
                self.lastperioddata.high - self.lastperioddata.low)) > self.closepercent:
                return False
            if ((self.lastperioddata.open - self.lastperioddata.low) / (
                self.lastperioddata.high - self.lastperioddata.low)) > self.openpercent:
                return False
            return True
        if self.lastperioddata.close < self.lastperioddata.open and self.takeShorts:
            if ((self.lastperioddata.close - self.lastperioddata.low) / (
                self.lastperioddata.high - self.lastperioddata.low)) > self.closepercent:
                return False
            if ((self.lastperioddata.high - self.lastperioddata.open) / (
                self.lastperioddata.high - self.lastperioddata.low)) > self.openpercent:
                return False
            return True

    def handle(self, perioddata):
        # store previous perioddata before we call superclass
        self.lastperioddata = self.perioddata
        self.high.handle(perioddata)
        self.low.handle(perioddata)
        self.atr.handle(perioddata)
        self.lastatr.handle(perioddata)
        if self.lasthighesthigh is not None:
            self.highesthigh.handle(perioddata)
            self.lasthighesthigh.handle(perioddata)
            self.lowestlow.handle(perioddata)
            self.lastlowestlow.handle(perioddata)
        PriceVolumeDailyTrigger.handle(self, perioddata)

    def getLongPrice(self):
        if self.lastperioddata.close > self.lastperioddata.open:
            return self.lastperioddata.close
        return None

    def getShortPrice(self):
        if self.lastperioddata.open > self.lastperioddata.close:
            return self.lastperioddata.close
        return None