From c9cc9faf31491bad811f7d0a5d8d61ce9cdb8dd3 Mon Sep 17 00:00:00 2001 From: gcarq Date: Sat, 13 May 2017 00:30:08 +0200 Subject: [PATCH] create table if it doesnt exist and other fixes --- README.md | 2 ++ exchange.py | 10 ++-------- main.py | 28 ++++++++++++++-------------- persistence.py | 15 ++++----------- rpc/telegram.py | 8 ++++---- utils.py | 6 ++++++ 6 files changed, 32 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 50a774029..4fc330881 100644 --- a/README.md +++ b/README.md @@ -10,3 +10,5 @@ source .venv/bin/activate pip install -r requirements.txt ./main.py ``` + +Enter your API keys and tokens in `config.json` \ No newline at end of file diff --git a/exchange.py b/exchange.py index c86e8ec05..258123b22 100644 --- a/exchange.py +++ b/exchange.py @@ -46,16 +46,10 @@ class ApiWrapper(object): if use_poloniex: self.exchange = Exchange.POLONIEX - self.api = Poloniex( - key=config['poloniex']['key'], - secret=config['poloniex']['secret'] - ) + self.api = Poloniex(key=config['poloniex']['key'], secret=config['poloniex']['secret']) elif use_bittrex: self.exchange = Exchange.BITTREX - self.api = Bittrex( - api_key=config['bittrex']['key'], - api_secret=config['bittrex']['secret'] - ) + self.api = Bittrex(api_key=config['bittrex']['key'], api_secret=config['bittrex']['secret']) else: self.api = None diff --git a/main.py b/main.py index ff1a09fb8..36ee5dee1 100755 --- a/main.py +++ b/main.py @@ -74,19 +74,14 @@ class TradeThread(threading.Thread): continue # Check if there is already an open order for this pair - open_orders = api_wrapper.get_open_orders(trade.pair) - if open_orders: + orders = api_wrapper.get_open_orders(trade.pair) + if orders: msg = 'There is already an open order for this trade. (total: {}, remaining: {}, type: {})'\ - .format( - round(open_orders[0]['amount'], 8), - round(open_orders[0]['remaining'], 8), - open_orders[0]['type'] - ) + .format(round(orders[0]['amount'], 8), round(orders[0]['remaining'], 8), orders[0]['type']) logger.info(msg) elif close_trade_if_fulfilled(trade): logger.info('No open orders found and close values are set. Marking trade as closed ...') else: - # Maybe sell with current rate handle_trade(trade) except ValueError: logger.exception('ValueError') @@ -135,8 +130,7 @@ def handle_trade(trade): balance = api_wrapper.get_balance(currency) for duration, threshold in sorted(conf['trade_thresholds'].items()): - duration = float(duration) - threshold = float(threshold) + duration, threshold = float(duration), float(threshold) # Check if time matches and current rate is above threshold time_diff = (datetime.utcnow() - trade.open_date).total_seconds() / 60 if time_diff > duration and current_rate > (1 + threshold) * trade.open_rate: @@ -168,13 +162,19 @@ def create_trade(stake_amount: float, exchange): :param stake_amount: amount of btc to spend :param exchange: exchange to use """ - # Whitelist sanity check whitelist = conf[exchange.name.lower()]['pair_whitelist'] - if not whitelist or not isinstance(whitelist, list): - raise ValueError('No usable pair in whitelist.') # Check if btc_amount is fulfilled if api_wrapper.get_balance('BTC') < stake_amount: - raise ValueError('BTC amount is not fulfilled.') + raise ValueError('BTC amount is not fulfilled') + + # Remove latest trade pair from whitelist + latest_trade = Trade.order_by(Trade.id.desc()).first() + if latest_trade and latest_trade.pair in whitelist: + whitelist.remove(latest_trade.pair) + logger.debug('Ignoring {} in pair whitelist') + if not whitelist: + raise ValueError('No pair in whitelist') + # Pick random pair and execute trade idx = random.randint(0, len(whitelist) - 1) pair = whitelist[idx] diff --git a/persistence.py b/persistence.py index 6f53f8014..efb5fec46 100644 --- a/persistence.py +++ b/persistence.py @@ -8,18 +8,9 @@ from sqlalchemy.types import Enum from exchange import Exchange -def create_session(base, filename): - """ - Creates sqlite database and setup tables. - :return: sqlalchemy Session - """ - engine = create_engine(filename, echo=False) - base.metadata.create_all(engine) - return scoped_session(sessionmaker(bind=engine, autoflush=True, autocommit=True)) - - Base = declarative_base() -Session = create_session(Base, filename='sqlite:///tradesv2.sqlite') +engine = create_engine('sqlite:///tradesv2.sqlite', echo=False) +Session = scoped_session(sessionmaker(bind=engine, autoflush=True, autocommit=True)) class Trade(Base): @@ -47,3 +38,5 @@ class Trade(Base): self.open_rate, 'closed' if not self.is_open else round((datetime.utcnow() - self.open_date).total_seconds() / 60, 2) ) + +Base.metadata.create_all(engine) diff --git a/rpc/telegram.py b/rpc/telegram.py index 3fb3655fb..96b85e338 100644 --- a/rpc/telegram.py +++ b/rpc/telegram.py @@ -48,7 +48,7 @@ class TelegramHandler(object): CommandHandler('stop', TelegramHandler._stop)] for handle in handles: TelegramHandler.get_updater(conf).dispatcher.add_handler(handle) - TelegramHandler.get_updater(conf).start_polling() + TelegramHandler.get_updater(conf).start_polling(clean=True, bootstrap_retries=3) @staticmethod def _is_correct_scope(update): @@ -69,8 +69,8 @@ class TelegramHandler(object): :return: None """ if conf['telegram'].get('enabled', False): + bot = bot or TelegramHandler.get_updater(conf).bot try: - bot = bot or TelegramHandler.get_updater(conf).bot bot.send_message( chat_id=conf['telegram']['chat_id'], text=markdown_message, @@ -111,7 +111,7 @@ class TelegramHandler(object): *Open Rate:* `{open_rate}` *Close Rate:* `{close_rate}` *Current Rate:* `{current_rate}` -*Close Profit:* `{close_profit}%` +*Close Profit:* `{close_profit}` *Current Profit:* `{current_profit}%` *Open Order:* `{open_order}` """.format( @@ -121,7 +121,7 @@ class TelegramHandler(object): close_rate=trade.close_rate, current_rate=current_rate, amount=round(trade.amount, 8), - close_profit=round(trade.close_profit, 2) if trade.close_profit else 'None', + close_profit='{}%'.format(round(trade.close_profit, 2)) if trade.close_profit else None, current_profit=round(current_profit, 2), open_order='{} ({})'.format( order['remaining'], diff --git a/utils.py b/utils.py index f9a9cad27..c229c22b8 100644 --- a/utils.py +++ b/utils.py @@ -55,6 +55,9 @@ def validate_conf(conf): raise ValueError('poloniex.secret must be a string') if not isinstance(poloniex.get('pair_whitelist'), list): raise ValueError('poloniex.pair_whitelist must be a list') + if poloniex.get('enabled', False): + if not poloniex.get('pair_whitelist'): + raise ValueError('poloniex.pair_whitelist must contain some pairs') if conf.get('bittrex'): bittrex = conf.get('bittrex') @@ -64,6 +67,9 @@ def validate_conf(conf): raise ValueError('bittrex.secret must be a string') if not isinstance(bittrex.get('pair_whitelist'), list): raise ValueError('bittrex.pair_whitelist must be a list') + if bittrex.get('enabled', False): + if not bittrex.get('pair_whitelist'): + raise ValueError('bittrex.pair_whitelist must contain some pairs') if conf.get('poloniex', {}).get('enabled', False) \ and conf.get('bittrex', {}).get('enabled', False):