Esempio n. 1
0
def _play(features):
    """Play an epoch with the given macd parameters"""

    time_base = features.index[0]
    now = time_base
    index = 0  # in case len(features) == 0
    for index, feature in enumerate(features.values):
        macd = feature[1]
        if np.isnan(macd):
            continue

        now += du.secToNano(index * conf.TIME_INTERVAL * 60)
        im.timeTravel(now)
        if macd < -MIN_MACD:
            lm.buyOrSell(ActionEnum.SELL, CryptoEnum.XBT)
        elif macd > MIN_MACD:
            lm.buyOrSell(ActionEnum.BUY, CryptoEnum.XBT)

        if lm.gameOver():
            # if log.VERBOSE >= 4:
            log.warning("game over:", index, "/", len(features))
            return -42

    score = lm.getGlobalBalanceInQuote()
    hodl = features["vwap"].iat[index] / features["vwap"].iat[0] * 100

    # if log.VERBOSE >= 4:
    log.debug("score:", int(score - hodl),
              "(" + str(int(score)) + "-" + str(int(hodl)) + ")")

    return score  # - hodl
Esempio n. 2
0
 def write(self, raw_data):
     """Write the given raw_data to the database, and cache it if needed"""
     if raw_data is None or raw_data.empty:
         return None
     if not fu.write(self.__class__.__name__, raw_data):
         log.warning("Couldn't write to database frame '" +
                     self.__class__.__name__ + "'")
         return False
     self.cache(fresh_data=raw_data)
     return True
Esempio n. 3
0
 def __init__(self):
     self.model = None
     self.model_file = os.path.join(conf.DATA_DIR,
                                    self.__class__.__name__ + ".model")
     try:
         self.load()
     except OSError:
         log.warning("Couldn't load", self.__class__.__name__)
     self.dependencies = []
     self._initDeps()
Esempio n. 4
0
def _tooSoon(timestamp):
    """
    Check if the previous transaction was too soon to start another one

    The delay is based on conf.TIME_INTERVAL.
    """

    last_tx = getLastTx()
    if last_tx > 0 \
       and timestamp - last_tx < du.secToNano(3 * conf.TIME_INTERVAL * 60):
        if LEDGERS[conf.QUOTE].verbose:
            log.warning("Previous transaction was too soon, waiting")
        return True
    return False
Esempio n. 5
0
def _canBuy():
    """
    Check if you can buy crypto

    This is based on your balance and your current position.
    """

    # if LAST_TX["type"] == "b":
    #     return False
    if LEDGERS[conf.QUOTE].balance < MIN_BAL:
        if LEDGERS[conf.QUOTE].verbose:
            log.warning("Not enough", conf.QUOTE.name, "to buy")
        return False
    return True
Esempio n. 6
0
def initGraph(log_lock, file_lock):
    """Launch an awesome matplotlib graph!"""

    log.setLock(log_lock)
    fu.setLock(file_lock)
    du.TIME_TRAVELER.setTime(None)
    sig.catchSignal()
    try:
        _getData()
        _initGraph()
    except Exception as e:
        log.warning("Something's bjorked in your graph :/")
        log.info("Try to run babao again with the env variable DEBUG_GRAPH set")
        # traceback.print_exc()
        raise e
    sys.exit(0)  # we exit explicitly in the subprocess, to avoid double clean
Esempio n. 7
0
def _canSell(crypto_enum):
    """
    Check if you can sell crypto

    This is based on your balance and your current position.
    """

    # if LAST_TX["type"] == "s":
    #     return False
    if getBalanceInQuote(crypto_enum) < MIN_BAL:
        # this can be quite high actually
        # support.kraken.com/ \
        # hc/en-us/articles/205893708-What-is-the-minimum-order-size-
        if LEDGERS[conf.QUOTE].verbose:
            log.warning("Not enough", crypto_enum.name, "to sell")
        return False
    return True
Esempio n. 8
0
    def fetch(self):
        if self.current_row is None:
            since = 0  # TODO: do we really need allllll the data? du.EPOCH
        else:
            since = self.current_row.name

        res = self._doRequest("Trades", {
            "pair": self.__class__.pair,
            "since": str(since)
        })
        if res is None:
            self.up_to_date = False
            return None

        fresh_data = pd.DataFrame(
            res[self.__class__.pair],
            columns=[  # as returned by kraken api
                "price", "volume", "time", "buy-sell", "market-limit", "misc"
            ],
            dtype=float)

        if not fresh_data.empty:
            fresh_data["time"] = du.secToNano(fresh_data["time"])

            if not fresh_data["time"].is_monotonic_increasing:
                log.warning("Sorting kraken data -.-")
                fresh_data.sort_values(by=['time'], inplace=True)

            fresh_data.loc[fresh_data["time"] == fresh_data["time"].iat[-1],
                           "time"] = int(res["last"])

            if since > fresh_data["time"].iat[0]:
                fresh_data.loc[fresh_data["time"] < since, "time"] = since

            fresh_data.index = fresh_data["time"]

        del fresh_data["misc"]
        del fresh_data["market-limit"]  # this could be useful
        del fresh_data["buy-sell"]  # idem
        del fresh_data["time"]

        self.up_to_date = len(fresh_data) != 1000
        return fresh_data
Esempio n. 9
0
 def updateCurrentRow(self, current_row=None, timestamp=None):
     """Update the property self.current_row, useful for time travel"""
     global LAST_WRITE
     if timestamp is not None:  # time travel
         if "Ledger" in self.__class__.__name__:
             return  # we're going to the future
         current_row = self._readFromCache(
             since=timestamp,
             till=timestamp + du.secToNano(12 * 3600)
             # assuming there is at least one row per day?
         )
         if not current_row.empty:
             current_row = current_row.iloc[0]
     if not current_row.empty:
         self.current_row = current_row
         if timestamp is not None:  # time travel
             LAST_WRITE = current_row.name
         else:
             LAST_WRITE = max(LAST_WRITE, current_row.name)
     else:  # spammy
         log.warning("Couldn't update current row for database  '" +
                     self.__class__.__name__ + "'")
Esempio n. 10
0
    def cache(self, fresh_data=None, since=None, till=None):
        """
        Save some data to cache

        If ´fresh_data´ is given, append it to cache,
        otherwise read in database from ´since´ to ´till´ and cache it
        """
        if fresh_data is not None:
            self._cache_data = self._cache_data.append(fresh_data)
            if not self._cache_data.empty:
                self._cache_data = self._cache_data.loc[
                    self._cache_data.index[-1] -
                    du.secToNano(CACHE_REAL_TIME_LOOKBACK_DAYS * 24 * 3600):]
        else:
            log.debug("Caching data from", du.toStr(since), "to",
                      du.toStr(till), "(" + self.__class__.__name__ + ")")
            self._cache_data = self._readFromFile(since, till)
        if not self._cache_data.empty:
            self.updateCurrentRow(self._cache_data.iloc[-1])
        else:
            log.warning("Database '" + self.__class__.__name__ + "' is emtpy")
            self._cache_data = pd.DataFrame(columns=self.raw_columns)
Esempio n. 11
0
def test_warning():
    log.warning("warning")
Esempio n. 12
0
def _getData():
    """
    Initialize ´DATA´ global

    Basically read ´conf.MAX_GRAPH_POINTS´ from data files
    """

    global DATA

    if not os.path.isfile(conf.DB_FILE):
        log.warning("Data files not found... Is it your first time around?")
        return False

    if INDEX is None:
        crypto = conf.CRYPTOS[0]
    else:
        crypto = conf.CRYPTOS[INDEX.ind]

    inputs = [
        lm.TRADES[crypto],
        lm.LEDGERS[conf.QUOTE],
        lm.LEDGERS[crypto]
    ]
    if conf.CURRENT_COMMAND == "backtest":
        for i in inputs:
            i._cache_data = None  # pylint: disable=W0212
        since = ib.SPLIT_DATE
    else:
        im.refreshInputs(inputs)
        since = lm.TRADES[crypto].current_row.name - du.secToNano(
            (MAX_LOOK_BACK + conf.MAX_GRAPH_POINTS) * conf.TIME_INTERVAL * 60
        )
    DATA = im.readInputs(inputs, since)

    DATA.rename(
        partial(re.sub, r'.*Trades.*-', ""),
        axis="columns", inplace=True
    )
    DATA.rename(
        partial(re.sub, r'.*Ledger' + conf.QUOTE.name + '.*-', "quote-"),
        axis="columns", inplace=True
    )
    DATA.rename(
        partial(re.sub, r'.*Ledger.*-', "crypto-"),
        axis="columns", inplace=True
    )
    DATA = DATA.loc[
        :,
        ['close', 'vwap', 'volume', 'quote-balance', 'crypto-balance']
    ]

    DATA = indic.get(DATA, INDICATORS_COLUMNS)
    DATA["macd_line"], DATA["signal_line"], DATA["macd"] = indic.macd(
        DATA["vwap"],
        46, 75, 22,
        True
    )
    if conf.CURRENT_COMMAND == "backtest":
        DATA = DATA.fillna(0)
    else:
        DATA = DATA.dropna()
    DATA["total-balance"] = DATA["quote-balance"] \
        + DATA["crypto-balance"] * DATA["close"]
    du.toDatetime(DATA)

    return True