create table if it doesnt exist and other fixes
This commit is contained in:
parent
ef4b7eed3b
commit
c9cc9faf31
@ -10,3 +10,5 @@ source .venv/bin/activate
|
|||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
./main.py
|
./main.py
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Enter your API keys and tokens in `config.json`
|
10
exchange.py
10
exchange.py
@ -46,16 +46,10 @@ class ApiWrapper(object):
|
|||||||
|
|
||||||
if use_poloniex:
|
if use_poloniex:
|
||||||
self.exchange = Exchange.POLONIEX
|
self.exchange = Exchange.POLONIEX
|
||||||
self.api = Poloniex(
|
self.api = Poloniex(key=config['poloniex']['key'], secret=config['poloniex']['secret'])
|
||||||
key=config['poloniex']['key'],
|
|
||||||
secret=config['poloniex']['secret']
|
|
||||||
)
|
|
||||||
elif use_bittrex:
|
elif use_bittrex:
|
||||||
self.exchange = Exchange.BITTREX
|
self.exchange = Exchange.BITTREX
|
||||||
self.api = Bittrex(
|
self.api = Bittrex(api_key=config['bittrex']['key'], api_secret=config['bittrex']['secret'])
|
||||||
api_key=config['bittrex']['key'],
|
|
||||||
api_secret=config['bittrex']['secret']
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
self.api = None
|
self.api = None
|
||||||
|
|
||||||
|
28
main.py
28
main.py
@ -74,19 +74,14 @@ class TradeThread(threading.Thread):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
# Check if there is already an open order for this pair
|
# Check if there is already an open order for this pair
|
||||||
open_orders = api_wrapper.get_open_orders(trade.pair)
|
orders = api_wrapper.get_open_orders(trade.pair)
|
||||||
if open_orders:
|
if orders:
|
||||||
msg = 'There is already an open order for this trade. (total: {}, remaining: {}, type: {})'\
|
msg = 'There is already an open order for this trade. (total: {}, remaining: {}, type: {})'\
|
||||||
.format(
|
.format(round(orders[0]['amount'], 8), round(orders[0]['remaining'], 8), orders[0]['type'])
|
||||||
round(open_orders[0]['amount'], 8),
|
|
||||||
round(open_orders[0]['remaining'], 8),
|
|
||||||
open_orders[0]['type']
|
|
||||||
)
|
|
||||||
logger.info(msg)
|
logger.info(msg)
|
||||||
elif close_trade_if_fulfilled(trade):
|
elif close_trade_if_fulfilled(trade):
|
||||||
logger.info('No open orders found and close values are set. Marking trade as closed ...')
|
logger.info('No open orders found and close values are set. Marking trade as closed ...')
|
||||||
else:
|
else:
|
||||||
# Maybe sell with current rate
|
|
||||||
handle_trade(trade)
|
handle_trade(trade)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
logger.exception('ValueError')
|
logger.exception('ValueError')
|
||||||
@ -135,8 +130,7 @@ def handle_trade(trade):
|
|||||||
balance = api_wrapper.get_balance(currency)
|
balance = api_wrapper.get_balance(currency)
|
||||||
|
|
||||||
for duration, threshold in sorted(conf['trade_thresholds'].items()):
|
for duration, threshold in sorted(conf['trade_thresholds'].items()):
|
||||||
duration = float(duration)
|
duration, threshold = float(duration), float(threshold)
|
||||||
threshold = float(threshold)
|
|
||||||
# Check if time matches and current rate is above threshold
|
# Check if time matches and current rate is above threshold
|
||||||
time_diff = (datetime.utcnow() - trade.open_date).total_seconds() / 60
|
time_diff = (datetime.utcnow() - trade.open_date).total_seconds() / 60
|
||||||
if time_diff > duration and current_rate > (1 + threshold) * trade.open_rate:
|
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 stake_amount: amount of btc to spend
|
||||||
:param exchange: exchange to use
|
:param exchange: exchange to use
|
||||||
"""
|
"""
|
||||||
# Whitelist sanity check
|
|
||||||
whitelist = conf[exchange.name.lower()]['pair_whitelist']
|
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
|
# Check if btc_amount is fulfilled
|
||||||
if api_wrapper.get_balance('BTC') < stake_amount:
|
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
|
# Pick random pair and execute trade
|
||||||
idx = random.randint(0, len(whitelist) - 1)
|
idx = random.randint(0, len(whitelist) - 1)
|
||||||
pair = whitelist[idx]
|
pair = whitelist[idx]
|
||||||
|
@ -8,18 +8,9 @@ from sqlalchemy.types import Enum
|
|||||||
from exchange import Exchange
|
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()
|
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):
|
class Trade(Base):
|
||||||
@ -47,3 +38,5 @@ class Trade(Base):
|
|||||||
self.open_rate,
|
self.open_rate,
|
||||||
'closed' if not self.is_open else round((datetime.utcnow() - self.open_date).total_seconds() / 60, 2)
|
'closed' if not self.is_open else round((datetime.utcnow() - self.open_date).total_seconds() / 60, 2)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Base.metadata.create_all(engine)
|
||||||
|
@ -48,7 +48,7 @@ class TelegramHandler(object):
|
|||||||
CommandHandler('stop', TelegramHandler._stop)]
|
CommandHandler('stop', TelegramHandler._stop)]
|
||||||
for handle in handles:
|
for handle in handles:
|
||||||
TelegramHandler.get_updater(conf).dispatcher.add_handler(handle)
|
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
|
@staticmethod
|
||||||
def _is_correct_scope(update):
|
def _is_correct_scope(update):
|
||||||
@ -69,8 +69,8 @@ class TelegramHandler(object):
|
|||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
if conf['telegram'].get('enabled', False):
|
if conf['telegram'].get('enabled', False):
|
||||||
|
bot = bot or TelegramHandler.get_updater(conf).bot
|
||||||
try:
|
try:
|
||||||
bot = bot or TelegramHandler.get_updater(conf).bot
|
|
||||||
bot.send_message(
|
bot.send_message(
|
||||||
chat_id=conf['telegram']['chat_id'],
|
chat_id=conf['telegram']['chat_id'],
|
||||||
text=markdown_message,
|
text=markdown_message,
|
||||||
@ -111,7 +111,7 @@ class TelegramHandler(object):
|
|||||||
*Open Rate:* `{open_rate}`
|
*Open Rate:* `{open_rate}`
|
||||||
*Close Rate:* `{close_rate}`
|
*Close Rate:* `{close_rate}`
|
||||||
*Current Rate:* `{current_rate}`
|
*Current Rate:* `{current_rate}`
|
||||||
*Close Profit:* `{close_profit}%`
|
*Close Profit:* `{close_profit}`
|
||||||
*Current Profit:* `{current_profit}%`
|
*Current Profit:* `{current_profit}%`
|
||||||
*Open Order:* `{open_order}`
|
*Open Order:* `{open_order}`
|
||||||
""".format(
|
""".format(
|
||||||
@ -121,7 +121,7 @@ class TelegramHandler(object):
|
|||||||
close_rate=trade.close_rate,
|
close_rate=trade.close_rate,
|
||||||
current_rate=current_rate,
|
current_rate=current_rate,
|
||||||
amount=round(trade.amount, 8),
|
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),
|
current_profit=round(current_profit, 2),
|
||||||
open_order='{} ({})'.format(
|
open_order='{} ({})'.format(
|
||||||
order['remaining'],
|
order['remaining'],
|
||||||
|
6
utils.py
6
utils.py
@ -55,6 +55,9 @@ def validate_conf(conf):
|
|||||||
raise ValueError('poloniex.secret must be a string')
|
raise ValueError('poloniex.secret must be a string')
|
||||||
if not isinstance(poloniex.get('pair_whitelist'), list):
|
if not isinstance(poloniex.get('pair_whitelist'), list):
|
||||||
raise ValueError('poloniex.pair_whitelist must be a 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'):
|
if conf.get('bittrex'):
|
||||||
bittrex = conf.get('bittrex')
|
bittrex = conf.get('bittrex')
|
||||||
@ -64,6 +67,9 @@ def validate_conf(conf):
|
|||||||
raise ValueError('bittrex.secret must be a string')
|
raise ValueError('bittrex.secret must be a string')
|
||||||
if not isinstance(bittrex.get('pair_whitelist'), list):
|
if not isinstance(bittrex.get('pair_whitelist'), list):
|
||||||
raise ValueError('bittrex.pair_whitelist must be a 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) \
|
if conf.get('poloniex', {}).get('enabled', False) \
|
||||||
and conf.get('bittrex', {}).get('enabled', False):
|
and conf.get('bittrex', {}).get('enabled', False):
|
||||||
|
Loading…
Reference in New Issue
Block a user