def start(ctx, market, resolution, start, end, automatic, backtest, papertrade, strategy, btc, coins): """Start a new bot on the given market and the given amount of BTC""" try: market = ctx.exchange.get_market(market, backtest, papertrade) except ValueError as ex: click.echo(ex.message) sys.exit(1) strategy = STRATEGIES[strategy]() if start: start = datetime.datetime.strptime(start, "%Y-%m-%d %H:%M:%S") if end: end = datetime.datetime.strptime(end, "%Y-%m-%d %H:%M:%S") if backtest: if start is None or end is None: click.echo( "Error! For backtests you must provide a timeframe by setting start and end!" ) sys.exit(1) bot = get_bot(market, strategy, resolution, start, end, btc, coins) bot.start(backtest, automatic) if backtest: click.echo(render_bot_tradelog(bot.trades)) click.echo(render_bot_statistic(bot.stat(backtest))) db.delete(bot) db.commit()
def load_bot(market, strategy, resolution, start, end): """Will load an existing bot from the database. While loading the bot will replay its trades from the trade log to set the available btc and coins for further trading. Beside the btc and amount of coins all other aspects of the coin like the time frame and strategy are defined by the user. They are not loaded from the database.""" try: bot = db.query(Cointrader).filter( Cointrader.market == market._name).one() log.info("Loading bot {} {}".format(bot.market, bot.id)) bot._market = market bot._strategy = strategy bot._resolution = resolution bot._start = start bot._end = end bot.strategy = str(strategy) btc, amount = replay_tradelog(bot.trades) log.info("Loaded state from trade log: {} BTC {} COINS".format( btc, amount)) bot.btc = btc bot.amount = amount db.commit() return bot except sa.orm.exc.NoResultFound: return None
def _sell(self): result = self._market.sell(self.amount) # {u'orderNumber': u'101984509454', # u'resultingTrades': [{u'tradeID': u'10337105', # u'rate': u'0.01458758', # u'amount': u'0.01263972', # u'date': u'2017-08-28 19:57:51', # u'total': u'0.00018438', # u'type': u'sell'}]} order_id = result["orderNumber"] order_type = "SELL" total_btc = 0 for t in result["resultingTrades"]: trade_id = t["tradeID"] date = t["date"] amount = t["amount"] rate = t["rate"] btc = t["total"] total_btc += float(btc) trade = Trade(date, order_type, order_id, trade_id, self._market._name, rate, self.amount, amount, 0, btc) self.trades.append(trade) # Finally set the internal state of the bot. Amount will be 0 after # selling but we now have some BTC. self.state = 0 self.amount = 0 self.btc = total_btc db.commit()
def _buy(self): result = self._market.buy(self.btc) # {u'orderNumber': u'101983568396', # u'resultingTrades': [{u'tradeID': u'10337029', # u'rate': u'0.01459299', # u'amount': u'0.01263972', # u'date': u'2017-08-28 19:51:50', # u'total': u'0.00018445', u'type': u'buy'}]} order_id = result["orderNumber"] order_type = "BUY" total_amount = 0 for t in result["resultingTrades"]: trade_id = t["tradeID"] date = t["date"] amount = t["amount"] total_amount += float(amount) rate = t["rate"] btc = t["total"] trade = Trade(date, order_type, order_id, trade_id, self._market._name, rate, 0, amount, self.btc, btc) self.trades.append(trade) # Finally set the internal state of the bot. BTC will be 0 after # buying but we now have some amount of coins. self.amount = total_amount self.btc = 0 self.state = 1 db.commit()
def start(ctx, market, resolution, start, end, automatic, backtest, papertrade, strategy, btc, coins): """Start a new bot on the given market and the given amount of BTC""" # Check start and end date try: if start: start = datetime.datetime.strptime(start, "%Y-%m-%d %H:%M:%S") if end: end = datetime.datetime.strptime(end, "%Y-%m-%d %H:%M:%S") except ValueError: click.echo( "Date is not valid. Must be in format 'YYYY-mm-dd HH:MM:SS'") sys.exit(1) # Build the market on which the bot will operate # First check if the given market is a valid market. If not exit # here with a error message. # If the market is valid create a real market instance of and # instance for backtests depending on the user input. if ctx.exchange.is_valid_market(market): if backtest: if start is None or end is None: click.echo( "Error! For backtests you must provide a timeframe by setting start and end!" ) sys.exit(1) market = BacktestMarket(ctx.exchange, market) else: market = Market(ctx.exchange, market) else: click.echo("Market {} is not available".format(market)) sys.exit(1) # Check if the given resolution is supported if not ctx.exchange.is_valid_resolution(resolution): valid_resolutions = ", ".join(ctx.exchange.resolutions.keys()) click.echo("Resolution {} is not supported.\n" "Please choose one of the following: {}".format( resolution, valid_resolutions)) sys.exit(1) # Initialise a strategy. strategy = STRATEGIES[strategy]() bot = get_bot(market, strategy, resolution, start, end, btc, coins) bot.start(backtest, automatic) if backtest: click.echo(render_bot_tradelog(bot.trades)) click.echo(render_bot_statistic(bot.stat(backtest))) db.delete(bot) db.commit()
def get_bot(market, strategy, resolution, start, end, btc, amount): try: bot = db.query(Cointrader).filter( Cointrader.market == market._name).one() log.info("Loading bot {} {}".format(bot.market, bot.id)) bot._market = market bot.strategy = str(strategy) bot._strategy = strategy bot._resolution = resolution bot._start = start bot._end = end db.commit() btc, amount = replay_tradelog(bot.trades) log.info("Loaded state from trade log: {} BTC {} COINS".format( btc, amount)) bot.btc = btc bot.amount = amount except sa.orm.exc.NoResultFound: bot = Cointrader(market, strategy, resolution, start, end) log.info("Creating new bot {}".format(bot.market)) if btc is None: balances = market._exchange.get_balance() btc = balances["BTC"]["quantity"] if amount is None: balances = market._exchange.get_balance() amount = balances[market.currency]["quantity"] bot.btc = btc bot.amount = amount chart = market.get_chart(resolution, start, end) rate = chart.get_first_point()["close"] date = datetime.datetime.utcfromtimestamp( chart.get_first_point()["date"]) trade = Trade(date, "INIT", 0, 0, market._name, rate, amount, 0, btc, 0) bot.trades.append(trade) db.add(bot) db.commit() strategy.set_bot(bot) return bot
def _buy(self): result = self._market.buy(self.btc) order_id = result["orderNumber"] order_type = "BUY" total_amount = 0 for t in result["resultingTrades"]: trade_id = t["tradeID"] date = t["date"] amount = t["amount"] total_amount += float(amount) rate = t["rate"] btc = t["total"] trade = Trade(date, order_type, order_id, trade_id, self._market._name, rate, 0, amount, self.btc, btc) self.trades.append(trade) # Finally set the internal state of the bot. BTC will be 0 after # buying but we now have some amount of coins. self.amount = total_amount self.btc = 0 self.state = 1 db.commit()
def _sell(self): result = self._market.sell(self.amount) order_id = result["orderNumber"] order_type = "SELL" total_btc = 0 for t in result["resultingTrades"]: trade_id = t["tradeID"] date = t["date"] amount = t["amount"] rate = t["rate"] btc = t["total"] total_btc += float(btc) trade = Trade(date, order_type, order_id, trade_id, self._market._name, rate, self.amount, amount, 0, btc) self.trades.append(trade) # Finally set the internal state of the bot. Amount will be 0 after # selling but we now have some BTC. self.state = 0 self.amount = 0 self.btc = total_btc db.commit()
def create_bot(market, strategy, resolution, start, end, btc, amount): """Will create a new bot instance.""" bot = Cointrader(market, strategy, resolution, start, end) log.info("Creating new bot {}".format(bot.market)) # Setup the bot with coins and BTC. if btc is None: balances = market._exchange.get_balance() btc = balances["BTC"]["quantity"] if amount is None: balances = market._exchange.get_balance() amount = balances[market.currency]["quantity"] bot.btc = btc bot.amount = amount chart = market.get_chart(resolution, start, end) rate = chart.get_first_point()["close"] date = datetime.datetime.utcfromtimestamp(chart.get_first_point()["date"]) trade = Trade(date, "INIT", 0, 0, market._name, rate, amount, 0, btc, 0) bot.trades.append(trade) db.add(bot) db.commit() return bot
def stat(self, delete_trades=False): """Returns a dictionary with some statistic of the performance of the bot. Performance means how good cointrader performs in comparison to the market movement. Market movement is measured by looking at the start- and end rate of the chart. The performance of cointrader is measured by looking at the start and end value of the trade. These values are also multiplied with the start and end rate. So if cointrader does some good decisions and increases eater btc or amount of coins of the bot the performance should be better.""" chart = self._market.get_chart(self._resolution, self._start, self._end) first = chart.get_first_point() market_start_rate = first["close"] start_date = datetime.datetime.utcfromtimestamp(first["date"]) last = chart.get_last_point() market_end_rate = last["close"] end_date = datetime.datetime.utcfromtimestamp(last["date"]) # Set start value for trade in self.trades: if trade.order_type == "INIT": trader_start_btc = trade.btc trader_start_amount = trade.amount market_start_btc = trade.btc market_start_amount = trade.amount trader_end_btc = trader_start_btc trader_end_amount = trader_start_amount for trade in self.trades: if trade.order_type == "BUY": trader_end_amount += trade.amount_taxed trader_end_btc -= trade.btc elif trade.order_type == "SELL": trader_end_btc += trade.btc_taxed trader_end_amount -= trade.amount trader_start_value = trader_start_btc + trader_start_amount * market_start_rate market_start_value = trader_start_value trader_end_value = trader_end_btc + trader_end_amount * market_end_rate market_end_value = market_start_btc + market_start_amount * market_end_rate trader_profit = trader_end_value - trader_start_value market_profit = market_end_value - market_start_value stat = { "start": start_date, "end": end_date, "market_start_value": market_start_value, "market_end_value": market_end_value, "profit_chart": market_profit / market_end_value * 100, "trader_start_value": trader_start_value, "trader_end_value": trader_end_value, "profit_cointrader": trader_profit / trader_end_value * 100, } if delete_trades: for trade in self.trades: db.delete(trade) db.commit() return stat