예제 #1
0
    def checkMarketStatus(self, currency, data=None):
        if data is None:
            data = self.datastore[currency]

        market = CoinCalc.getInstance().get_market(currency)
        if market:
            traderTA = Trader(market)
            self.cs = traderTA.get_candlesticks(self.timeframe, self.framesize)

            ath = 0
            for v in self.cs["high"]:
                if v > ath:
                    ath = v

            atl = 9999999
            for v in self.cs["low"]:
                if v < atl:
                    atl = v

            ret = {
                "price": {
                    "count": 0,
                    "last": self.cs["closed"][-1],
                    "open": self.cs["open"][-1],
                    "HIGH": ath,
                    "LOW": atl,
                    "time": self.cs["time"][-1],
                }
            }
            for indicator in self.indicators:
                if indicator == "macd":
                    macd = MACD(self.cs)
                    ret["macd"] = macd.get_analysis(data)
                elif indicator == "bbands":
                    bb = BBands(self.cs, timeperiod=20, nbdevup=2, nbdevdn=2)
                    ret["bbands"] = bb.get_analysis(data)

            return ret
예제 #2
0
def market_tadata(worker_id):
    global influxDb

    while True:
        try:
            res = ExchangeDataHandler().getInstance().getRedisDb().blpop(
                "ta_markets")
            market = res[1].decode("utf-8")
            received_ts = time.strftime("%c")
            for framesize in frame_sizes.split(" "):
                starttime = time.time()
                traderTA = Trader(market)
                cs = traderTA.get_candlesticks("24h", framesize)
                traderTA.get_indicators()
                endtime = time.time()
                diftime = endtime - starttime
                #print("TA on {} with {} framesize completed in {}".format(market,framesize,diftime))
                for i in range(0, traderTA.get_indicator_size()):
                    res = traderTA.get_indicator_index(i)
                    influxDb.bulkAddTA("bittrex", traderTA.market, framesize,
                                       res, diftime)

        except Exception as ex:
            print("market_tadata exception thrown: {}".format(ex))
예제 #3
0
class TradeBot(object):

    OVERBOUGHT = 100
    OVERSOLD = 200

    #def __init__(self, market,budget, tradelimit, candlestick = "5m",timeframe = "24h",  name = None, config = {} ):
    def __init__(self, name, config):

        self.cycles = 0
        self.config = config
        self.name = name
        self.budget = config.get("budget", 0)
        self.initial_budget = self.budget
        self.tradelimit = config.get("tradelimit", 0)

        self.market = config.get("market", None)
        self.candlesize = config.get("candlesize", "1h")
        self.timeframe = config.get("timeframe", "1d")
        self.basesize = config.get("basesize", "1m")

        if not self.market:
            raise Exception(
                "missing required fields market: {}, budget: {}, tradelimit: {}"
                .format(self.market, self.budget, self.tradelimit))

        if "usdt" in self.market.lower():
            self.scale = config.get("scale", "2")
        else:
            self.scale = config.get("scale", "8")

        self.tcpsock = None

        # move this functionality to wallet class
        self.growth_target = config.get("growthtarget", 2)
        self.stop_loss = config.get("stoploss", 3)
        self.signal = None
        self.results = {}

        #dataprovider for candlestick data
        self.trader = Trader(market=self.market)

        #candlestick data
        self.csdata = None

        #manage indicators
        self.analyzer = None

        #manage orders
        self.ordermanager = None

        #keep track of latest indicator and bot signals
        self.signal_history = {}
        self.all_signals = []

        self.log = logging.getLogger('crypto')

        # debug messages passed to bot client
        self.debug = []

        #aggregate bot data for bot client
        self.data_provider = BotDataProvider(self)

        #enable backtesting...
        self.backtest = config.get("backtest", False)
        if "backtest_start_time" in config:
            ts = config["backtest_start_time"]
        else:
            ofs = config.get("backtest_start_ofs", 259200)
            ts = time.time() - ofs
            ts = ts - (ts % 3600) - config.get("run_offset", 0)

        self.backtest_tick = ts
        self.backtest_startprice = None
        self.backtest_endprice = 0

        self.run_interval = config.get("run_interval", 300)

        if self.backtest:
            random.seed()
            rid = random.randint(100, 70000)
            self.name = "{}-{}".format(name, rid)

    def createSocket(self, ip="127.0.0.1", port):
        self.tcpsock = TcpSock(ip, port, self)
        self.tcpsock.start()

    def stopBackTest(self):
        self.backtest = False
        self.log.info("backtest completed")

    def marketRate(self, index=1):
        return self.analyzer.last("closed", index)

    def getOrderManager(self):
        return self.ordermanager

    def setOrderManager(self, om):
        self.ordermanager = om
        self.ordermanager.setBot(self)
        self.log.info("initializing order manager")
        self.ordermanager.startOrderMonitor(self.config.get(
            "orderrefresh", 60))

    def getSignal(self):
        return self.signal

    def checkSignal(self, name, signal, timepassed):
        checktime = time.time() - timepassed
        if name in self.signal_history and self.signal_history[name][
                "time"] > checktime:
            self.debug.append("checksignal {} triggered".format(name))
            return self.signal_history[name]["strength"]

        return None

    def pushSignal(self, name, signal, strength, minor=False):

        if strength is not None:
            sig = {
                "name": self.getName(),
                "signal": signal,
                "rate": self.marketRate(),
                "cstime": self.analyzer.last("time"),
                "time": time.time(),
                "strength": strength,
                "count": 1
            }

            if not minor:
                if self.signal and self.signal["name"] == sig[
                        "name"] and self.signal["cstime"] == sig["cstime"]:
                    self.signal["count"] += 1
                else:
                    self.signal = sig

            if name in self.signal_history and self.signal_history[name][
                    "cstime"] == sig["cstime"]:
                self.signal_history[name]["count"] += 1
            else:
                self.signal_history[name] = sig
                if not minor:
                    self.all_signals.append(sig)

    def debug_reset(self):
        self.debug = []

    def append_debug_message(self, msg):
        self.debug.append(msg)

    def get_debug_messages(self):
        return self.debug

    def process(self):
        res = None

        if self.getSignal():
            res = self.getOrderManager().processSignal()

        self.getOrderManager().checkStops()

        self.cycles += 1
        return res

    def candleColor(self, idx):
        if self.csdata['closed'][idx] >= self.csdata['open'][idx]:
            return 'green'
        else:
            return 'red'

    def candle(self, idx):
        return {
            "date": self.csdata["time"][idx],
            "open": self.csdata["open"][idx],
            "high": self.csdata["high"][idx],
            "low": self.csdata["low"][idx],
            "close": self.csdata["closed"][idx],
            "volume": self.csdata["volume"][idx],
            "basevolume": self.csdata["basevolume"][idx]
        }

    def refreshCandlesticks(self, csdata=None):
        # redo backtest logic....
        if self.backtest:
            bt_time = "{}s".format(int(self.backtest_tick))
            self.csdata = self.trader.get_candlesticks(self.timeframe,
                                                       self.candlesize,
                                                       dateOffset=bt_time,
                                                       base_size=self.basesize)
            self.backtest_endprice = self.csdata["closed"][-1]
            if self.backtest_startprice is None:
                self.backtest_startprice = self.csdata["closed"][-1]
            self.backtest_tick += self.run_interval
            if self.backtest_tick > time.time():
                self.log.info("backtest complete")
                self.backtest_tick = time.time()
        else:
            if csdata == None:
                self.csdata = self.trader.get_candlesticks(
                    self.timeframe,
                    size=self.candlesize,
                    base_size=self.basesize)
            else:
                self.csdata = csdata

        self.analyzer = Analyzer(self.csdata)
        self.signal = None
        return self.analyzer

    def getAnalyzer():
        return self.analyzer

    def getMarket(self):
        return self.market

    def getName(self):
        return self.name

    def getIndicators(self):
        return self.indicators

    def dataProvider(self):
        return self.data_provider

    def info(self):
        return {
            "name": self.name,
            "cycle": self.cycles,
            "signal": self.signal,
            "last": self.marketRate(),
            "time": self.analyzer.last("time"),
            "servertime": time.strftime("%c"),
            "config": self.config
        }
예제 #4
0
파일: bot.py 프로젝트: meetri/cryptobot
class Bot(object):
    def __init__(self, name, config, settings=None):

        self.log = logging.getLogger('crypto')

        self.config = config
        self.name = name
        # self.budget = config.get("budget",0)
        # self.initial_budget = self.budget
        # self.tradelimit = config.get("tradelimit",0)

        self.market = config.get("market", None)
        self.exchange = config.get("exchange", "bittrex")
        self.candlesize = config.get("candlesize", "5m")
        self.timeframe = config.get("timeframe", "3d")
        self.basesize = config.get("basesize", "1m")
        self.stopped = False

        if not self.market:
            raise Exception("missing required fields market: {}".format(
                self.market))

        if "usdt" in self.market.lower():
            self.scale = config.get("scale", 2)
        else:
            self.scale = config.get("scale", 8)

        # sync wallet with database ?
        self.syncWallet = config.get("syncWallet", False)

        #candlestick data
        self.csdata = None
        self.market_summary = None
        self.last = None
        self.scrapeDate = None
        self.startDate = None

        #dataprovider for candlestick data
        self.trader = Trader(market=self.market, exchange=self.exchange)

        #manage indicators
        self.analyzer = None

        #tcp socket
        self.tcpsock = None

        # signal details
        self.history = []

        # bot signals
        self.signals = None

        #cached api results
        self.apiInfo = {}

        #bot settings
        self.defaults = None
        self.setDefaults()
        self.settings = self.updateSettings(settings)

        #threadHandler
        self.thread = None
        self.botSleep = 15
        self.ticks = 0
        self.eticks = 0
        self.rticks = 0
        self.refresh_high = None
        self.refresh_low = None
        self.candle_remaining = None

        wname = "sim:{}:{}".format(self.name, self.market)
        self.simwallet = TradeWallet({
            'market': self.market,
            'name': wname,
            'sync': False,
            'scale': self.scale
        })

        wname = "{}:{}".format(self.name, self.market)
        self.wallet = TradeWallet({
            'market': self.market,
            'name': wname,
            'mode': 'live',
            'sync': self.syncWallet,
            'scale': self.scale
        })

        if self.syncWallet:
            self.wallet.load()
            self.wallet.notify("Traderbot {}: {} started".format(
                self.name, self.market))

    def configure(self, config):
        self.config = {
            "market": "",
            "candlesize": "5m",
            "budget": 0.01,
            "maxtrades": 5,
            "target": 0.05,
            "stop": 0.025,
            "notify": ""
        }

        self.config = {**self.config, **config}

    def setDefaults(self):
        self.defaults = {
            "rsi.buy": 35,
            "rsi.sell": 65,
            "baseMinDistance": 0.04,
            "baseMultiplier": 10,
            "short.sma.period": 50,
            "long.sma.period": 200,
            "sma.bear.score": -25,
            "sma.bull.score": 5,
            "death.cross": -100,
            "golden.cross": 20,
            "dband.top": -15,
            "dband.bottom": 15,
            "bband.below": 5,
            "bband.above": -15,
            "bband.enter.bottom": 10,
        }

    def updateSettings(self, override=None):
        if override != None:
            self.settings = {**self.defaults, **override}
        else:
            self.settings = self.defaults

        return self.settings

    def score(self, score, csdataIndex, message):
        self.history.append({
            'candle': self.csdata['time'][csdataIndex],
            "score": score,
            "message": message
        })
        return score

    def getInfo(self, query=None):
        if query in self.apiInfo:
            return self.apiInfo[query]
        elif query == "stop":
            self.stopped = True
            return json.dumps({"message": "bot stopped"})

    def getSignals(self, idx):
        return {'signal': None, 'score': 0, 'messages': self.history}

    def buildOutput(self):
        self.apiInfo["help"] = json.dumps({"message": "no help here buddy"})

    def processRunner(self):
        while not self.stopped:
            try:
                self.process()
                self.ticks += 1
            except Exception as ex:
                print("Error: {}".format(ex))
                self.eticks += 1
                #raise ex

            # print(".",end=" ")
            time.sleep(self.botSleep)

    def start(self):
        self.startDate = datetime.datetime.utcnow().strftime(
            '%Y-%m-%dT%H:%M:%S')
        self.thread = Thread(target=self.processRunner)
        self.thread.start()

    def stop(self):
        self.thread.join()

    def isStopped(self):
        return self.stopped

    def process(self, options={}):
        return None

    def refresh(self, scrape=False):

        # print("market={},exchange={}".format(self.market, self.exchange))
        scraper = Scraper({'market': self.market, 'exchange': self.exchange})

        self.candle_remaining = self.trader.getCandleRemaining()
        if self.candle_remaining is None:
            csdata = None
            if scrape:
                try:
                    if self.candlesize == "1d" or self.candlesize == "1h":
                        cs = self.candlesize
                    else:
                        cs = "1m"

                    # print('scraping:{}'.format(cs))
                    csdata = scraper.cc_scrapeCandle(cs)
                    self.scrapeDate = datetime.datetime.utcnow().strftime(
                        '%Y-%m-%dT%H:%M:%S')
                    self.rticks += 1
                except Exception as ex:
                    print(ex)

                if self.candlesize not in ("1m", "1d", "1h"):
                    csdata = None

            self.loadCandlesticks(csdata)

        try:
            if self.exchange == "bittrex":
                self.market_summary = Bittrex().public_get_market_summary(
                    self.market).data["result"][0]
            else:
                last = scraper.cc_lastprice()
                self.market_summary = {"Last": last, "Ask": 0, "Bid": 0}
        except Exception as ex:
            self.market_summary = {
                "Last": self.csdata["closed"][-1],
                "Ask": 0,
                "Bid": 0
            }

        self.last = self.market_summary['Last']
        self.csdata['closed'][-1] = self.last

        if self.candle_remaining is not None:
            if self.last > self.refresh_high:
                self.refresh_high == self.last
            if self.last < self.refresh_low:
                self.refresh_low = self.last
        else:
            self.refresh_high = self.csdata["high"][-1]
            self.refresh_low = self.csdata["low"][-1]

        #self.candle_remaining = self.trader.candle_remaining

        self.csdata["high"][-1] = self.refresh_high
        self.csdata["low"][-1] = self.refresh_low

        self.calculate_ta()

    def lastidx(self):
        return len(self.csdata['closed']) - 1

    def calculate_ta(self):
        self.tadata = {}

    def createSocket(self, ip="127.0.0.1", port=9500):
        self.tcpsock = TcpSock(ip, port, self)
        self.tcpsock.start()

    def closeSocket(self):
        self.tcpsock.close()

    def candleColor(self, idx):
        if self.csdata['closed'][idx] >= self.csdata['open'][idx]:
            return 'green'
        else:
            return 'red'

    def candle(self, idx, ta=None):
        candle = {
            "date": self.csdata["time"][idx],
            "open": self.csdata["open"][idx],
            "high": self.csdata["high"][idx],
            "low": self.csdata["low"][idx],
            "close": self.csdata["closed"][idx],
            "volume": self.csdata["volume"][idx],
            "basevolume": self.csdata["basevolume"][idx]
        }

        if ta is not None:
            for name in self.tadata:
                if not numpy.isnan(self.tadata[name][idx]):
                    candle.update({name: self.tadata[name][idx]})

        return candle

    def getAnalyzer():
        return self.analyzer

    def getMarket(self):
        return self.market

    def getName(self):
        return self.name

    def getIndicators(self):
        return self.indicators

    def loadCandlesticks(self, csdata=None):
        if csdata == None:
            self.csdata = self.trader.get_candlesticks(self.timeframe,
                                                       size=self.candlesize,
                                                       base_size=self.basesize)
        else:
            self.csdata = csdata

        self.analyzer = Analyzer(self.csdata)