def __init__(self, settings):
        DailyTrigger.__init__(self, settings)

        # this is a hack until we implement subscribing to multiple streams of data
        self.uptrendcheck = dict()

        # if True, we are filtering on uptrending SPY, if false, downtrending SPY
        # we are using the PREVIOUS bar data, hence the use of HistoricMetric.
        # we do not now if TODAY will close above/below the ma before we enter our
        # day trades.  An alternative would have been to use the open
        ticker = settings.get("TrendFilterDailyTrigger", "ticker")
        self.uptrend = settings.getboolean("TrendFilterDailyTrigger", "uptrend")
        period = settings.getint("TrendFilterDailyTrigger", "period")
        close = AdjustedClose()
        lastclose = HistoricMetric(close, 1)
        ma = SimpleMovingAverage(metric=close, period=period)
        lastma = HistoricMetric(ma, 1)
        fromdt = datetime(1900, 1, 1)
        todt = datetime.now()
        datastore = datastorefactory.get_datastore()
        for dd in datastore.getDailyData(ticker, fromdt, todt):
            close.handle(dd)
            lastclose.handle(dd)
            ma.handle(dd)
            lastma.handle(dd)
            if lastma.ready() and lastclose.ready():
                if lastclose.value() > lastma.value():
                    self.uptrendcheck[dd.date] = True
                if lastclose.value() < lastma.value():
                    self.uptrendcheck[dd.date] = False
class MovingAverageExitManager(ExitManager):
    """ Exit on a moving average as a trailing stop
    """

    def __init__(self, settings):
        ExitManager.__init__(self)
        self.period = settings.getint("MovingAverageExitManager", "period")
        self.close = AdjustedClose()
        self.ma = SimpleMovingAverage(metric=self.close, period=self.period)

    def handle(self, perioddata):
        ExitManager.handle(self, perioddata)
        self.close.handle(perioddata)
        self.ma.handle(perioddata)

    def checkTrade(self, trade):
        if trade is not None and self.ma.ready() and trade.exit is None \
                and trade.entryPrice > trade.stop \
                and self.perioddata.adjustedClose >= self.ma.value():
            trade.exit = self.perioddata.date
            trade.exitPrice = self.perioddata.adjustedClose
        if trade is not None and self.ma.ready() and trade.exit is None \
                and trade.entryPrice < trade.stop \
                and self.perioddata.adjustedClose <= self.ma.value():
            trade.exit = self.perioddata.date
            trade.exitPrice = self.perioddata.adjustedClose
        return trade

    def recommendedPreload(self):
        return self.period + 1
class RSIExitManager(ExitManager):
    """ Exit on a target RSI value.

    Handles long and short
    """

    def __init__(self, settings):
        ExitManager.__init__(self)

        self.period = settings.getint("RSIExitManager", "period")
        self.longExit = settings.getfloat("RSIExitManager", "longExit")
        self.shortExit = settings.getfloat("RSIExitManager", "shortExit")
        self.close = AdjustedClose()
        self.rsi = RSI(metric=self.close, period=self.period)

    def handle(self, perioddata):
        ExitManager.handle(self, perioddata)
        self.close.handle(perioddata)
        self.rsi.handle(perioddata)

    def checkTrade(self, trade):
        if trade is not None and self.rsi.ready() and trade.is_open() \
                and ((trade.is_long() and self.rsi.value() >= self.longExit) or
                     (trade.is_short() and self.rsi.value() <= self.shortExit)):
            trade.close(self.perioddata.date, self.perioddata.adjustedClose)
        return trade

    def recommendedPreload(self):
        return self.period + 3
class MomoPullbackDailyTrigger(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 = AdjustedClose()
        if self.dailysmatrendfilter is not None:
            self.ma = SimpleMovingAverage(metric=self.close, 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.lastpd.open >= 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:
                logger.debug("Saw minimum move in MomoPullbackDailyTrigger, indicating we have a good day")
                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())
Exemple #5
0
    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 __init__(self, settings):
        ExitManager.__init__(self)

        self.period = settings.getint("RSIExitManager", "period")
        self.longExit = settings.getfloat("RSIExitManager", "longExit")
        self.shortExit = settings.getfloat("RSIExitManager", "shortExit")
        self.close = AdjustedClose()
        self.rsi = RSI(metric=self.close, period=self.period)
Exemple #7
0
class MyTrendCheck(Check):
    def __init__(self):
        Check.__init__(self)
        # adjusted close accounts for splits and dividends
        self.close = AdjustedClose()
        self.ma = SimpleMovingAverage(metric=self.close, period=200)

    def handle(self, periodData):
        self.close.handle(periodData)
        self.ma.handle(periodData)

    def ready(self):
        return self.close.ready() and self.ma.ready()

    def check(self):
        if not self.ready():
            return False
        return self.close.value() > self.ma.value()
Exemple #8
0
    def __init__(self, settings=None, name=None):
        self.name = name
        ExitManager.__init__(self, settings)
        bb_period = self._getintsetting("BollingerBreakoutExitManager", "bbPeriod")
        bb_stdevs = self._getfloatsetting("BollingerBreakoutExitManager", "bbStdevs")
        self.close = AdjustedClose()
        self.bb = BollingerBands(metric=self.close, period=bb_period, stdev=bb_stdevs)

        self._addMetrics(self.close, self.bb)
Exemple #9
0
class MyTrendCheck(Check):
    def __init__(self):
        Check.__init__(self)
        # adjusted close accounts for splits and dividends
        self.close = AdjustedClose()
        self.ma = SimpleMovingAverage(metric=self.close, period=200)

    def handle(self, periodData):
        self.close.handle(periodData)
        self.ma.handle(periodData)
    
    def ready(self):
        return self.close.ready() and self.ma.ready()
    
    def check(self):
        if not self.ready():
            return False
        return self.close.value() > self.ma.value()
Exemple #10
0
class BollingerBreakoutExitManager(ExitManager):
    def __init__(self, settings=None, name=None):
        self.name = name
        ExitManager.__init__(self, settings)
        bb_period = self._getintsetting("BollingerBreakoutExitManager", "bbPeriod")
        bb_stdevs = self._getfloatsetting("BollingerBreakoutExitManager", "bbStdevs")
        self.close = AdjustedClose()
        self.bb = BollingerBands(metric=self.close, period=bb_period, stdev=bb_stdevs)

        self._addMetrics(self.close, self.bb)

    def checkTrade(self, trade):
        if trade is not None and trade.is_open():
            if trade.is_long():
                if self.close.value() < self.bb.lowerBand():
                    trade.close(self.perioddata.date, self.perioddata.adjustedClose)
            else:
                if self.close.value() > self.bb.upperBand():
                    trade.close(self.perioddata.date, self.perioddata.adjustedClose)
        return trade
Exemple #11
0
class MACrossoverEntryManager(EntryManager):
    """ Enter on cross higher of the fast ma over the slow ma """

    def __init__(self, settings, name=None):
        EntryManager.__init__(self, settings, name=name)

        fastma = settings.getint("MACrossoverEntryManager", "fastma")
        slowma = settings.getint("MACrossoverEntryManager", "slowma")

        # AdjustedClose is adjusted for splits and dividends
        self.close = AdjustedClose()
        self.fastma = SimpleMovingAverage(metric=self.close, period=fastma)
        self.slowma = SimpleMovingAverage(metric=self.close, period=slowma)

        # add the metrics to the entry manager, this will cause them
        # to automatically handle the stream of bar data
        self._addMetric(self.close)
        self._addMetric(self.fastma)
        self._addMetric(self.slowma)

    def checkTrade(self, trade):
        if trade is not None:
            # we don't scale in additional size, already in a trade
            return trade
        if self.fastma.ready() and self.slowma.ready() \
                and self.fastma.value() > self.slowma.value() \
                and self.close.value() > 0:
            # new trade
            entry = self.close.value()
            # no stops for this simple strategy
            stop = 0.0
            # note, self.periodData is the last bar seen, this is provided from
            # the base class EntryManager
            trade = Trade(self.periodData.stock, self.periodData.date, entry, stop)
            return trade
        return None
Exemple #12
0
    def __init__(self, settings, name=None):
        EntryManager.__init__(self, settings, name=name)

        fastma = settings.getint("MACrossoverEntryManager", "fastma")
        slowma = settings.getint("MACrossoverEntryManager", "slowma")

        # AdjustedClose is adjusted for splits and dividends
        self.close = AdjustedClose()
        self.fastma = SimpleMovingAverage(metric=self.close, period=fastma)
        self.slowma = SimpleMovingAverage(metric=self.close, period=slowma)

        # add the metrics to the entry manager, this will cause them
        # to automatically handle the stream of bar data
        self._addMetric(self.close)
        self._addMetric(self.fastma)
        self._addMetric(self.slowma)
class GapUpEntryManager:
    def __init__(self, settings):
        self.minPrice = settings.getfloat("GapAndGoSwingEntry", "minPrice")
        self.minAvgVol = settings.getint("GapAndGoSwingEntry", "minAvgVol")
        self.minPercent = settings.getfloat("GapAndGoSwingEntry", "minPercent")
        targetstr = settings.get("GapAndGoSwingEntry", "target")
        if targetstr == "None":
            self.target = None
        else:
            self.target = float(targetstr)
        self.volume = Volume()
        self.avgvol = SimpleMovingAverage(metric=self.volume, period=21)
        self.opn = AdjustedOpen()
        self.close = AdjustedClose()
        self.lastClose = HistoricMetric(metric=self.close, period=1)
        self.high = AdjustedHigh()
        self.lastHigh = HistoricMetric(metric=self.high, period=1)
        self.low = AdjustedLow()
        self.inBottomRange=0.1
        self.inTopRange=None
        
    def handle(self, perioddata):
        self.close.handle(perioddata)
        self.lastClose.handle(perioddata)
        self.high.handle(perioddata)
        self.lastHigh.handle(perioddata)
        self.opn.handle(perioddata)
        self.volume.handle(perioddata)
        self.avgvol.handle(perioddata)
        self.low.handle(perioddata)
        self.lastdd = perioddata

    def checkTrade(self):
        if self.close.ready() and self.lastClose.ready() \
                and self.opn.ready() and self.volume.ready() \
                and self.avgvol.ready():
            if self.lastdd.close >= self.minPrice and self.avgvol.value() >= self.minAvgVol \
                    and self.lastClose.value() > 0 and self.opn.value() > 0 \
                    and ((self.opn.value()-self.lastClose.value())/self.lastClose.value()) >= self.minPercent \
                    and self.low.value() >= self.lastHigh.value() \
                    and (self.inBottomRange == None or ((self.lastdd.adjustedHigh != self.lastdd.adjustedLow) and (self.close.value()-self.lastdd.adjustedLow)/(self.lastdd.adjustedHigh-self.lastdd.adjustedLow)) <= self.inBottomRange) \
                    and (self.inTopRange == None or ((self.lastdd.adjustedHigh != self.lastdd.adjustedLow) and (self.close.value()-self.lastdd.adjustedLow)/(self.lastdd.adjustedHigh-self.lastdd.adjustedLow)) >= self.inTopRange):
                stop = max(0.0, self.low.value() - 0.01)
#                 stop = max(0.0, self.lastHigh.value())
                trade = Trade(self.lastdd.stock, self.lastdd.date, self.close.value(), stop)
                if self.target != None:
                    target = self.close.value() + ((self.close.value()-stop)*self.target)
                    trade.target = target
                return trade
        return None
    
    def recommendedPreload(self):
        return 22
    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 = AdjustedClose()
        if self.dailysmatrendfilter is not None:
            self.ma = SimpleMovingAverage(metric=self.close, period=self.dailysmatrendfilter)
        else:
            self.ma = None
 def __init__(self, settings):
     self.minPrice = settings.getfloat("GapAndGoSwingEntry", "minPrice")
     self.minAvgVol = settings.getint("GapAndGoSwingEntry", "minAvgVol")
     self.minPercent = settings.getfloat("GapAndGoSwingEntry", "minPercent")
     targetstr = settings.get("GapAndGoSwingEntry", "target")
     if targetstr == "None":
         self.target = None
     else:
         self.target = float(targetstr)
     self.volume = Volume()
     self.avgvol = SimpleMovingAverage(metric=self.volume, period=21)
     self.opn = AdjustedOpen()
     self.close = AdjustedClose()
     self.lastClose = HistoricMetric(metric=self.close, period=1)
     self.high = AdjustedHigh()
     self.lastHigh = HistoricMetric(metric=self.high, period=1)
     self.low = AdjustedLow()
     self.inBottomRange=0.1
     self.inTopRange=None
Exemple #16
0
    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)
Exemple #17
0
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
Exemple #18
0
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
Exemple #19
0
 def __init__(self, settings):
     ExitManager.__init__(self)
     self.period = settings.getint("MovingAverageExitManager", "period")
     self.close = AdjustedClose()
     self.ma = SimpleMovingAverage(metric=self.close, period=self.period)
Exemple #20
0
def generate_random_perioddata(dt):
    a = random()*50+50
    b = random()*50+50
    c = random()*50+50
    d = random()*50+50
    retval = PeriodData(date=dt,period=Period.DAILY, stock="AAPL", open=a,high=max((a,b,c,d)),low=min(a,b,c,d),close=d,volume=100000,adjustedClose=d)
    return retval

def generate_random_series():
    retval = list()
    dt = datetime(year=2015,month=1,day=1)
    for i in range(1000):
        dt = dt + timedelta(days=1)
        retval.append(generate_random_perioddata(dt))
    return retval

# Here begins the example code

# Track the adjusted close and 20 period simple moving average 
close = AdjustedClose()
sma = SimpleMovingAverage(metric=close, period=20)

print "Date,SMA"

for periodData in generate_random_series():
    close.handle(periodData)
    sma.handle(periodData)
    
    if sma.ready() and close.ready():
        print "%s,%f" % (periodData.date, sma.value())
Exemple #21
0
 def __init__(self):
     Check.__init__(self)
     # adjusted close accounts for splits and dividends
     self.close = AdjustedClose()
     self.ma = SimpleMovingAverage(metric=self.close, period=200)
Exemple #22
0
 def __init__(self):
     Check.__init__(self)
     # adjusted close accounts for splits and dividends
     self.close = AdjustedClose()
     self.ma = SimpleMovingAverage(metric=self.close, period=200)