Пример #1
0
def balance_thread():
    if not os.path.isfile("mqtt_config.txt"):
        raise Exception(
            "MQTT is not configured. "
            "Create mqtt_config.txt with first line mqtt server IP address and "
            "second line with user name and"
            "third line with your password and"
            "forth line with your topic for account balance.")

    with open("mqtt_config.txt") as fp:
        ip = fp.readline().strip()
        user = fp.readline().strip()
        password = fp.readline().strip()
        topic = fp.readline().strip()

    while True:
        balance = exchange.get_balance()
        publish.single(topic,
                       payload="{0}".format(
                           sum([coin['usdtValue'] for coin in balance])),
                       qos=0,
                       retain=True,
                       hostname=ip,
                       port=1883,
                       client_id="",
                       keepalive=60,
                       will=None,
                       auth={
                           'username': user,
                           'password': password
                       },
                       tls=None)

        time.sleep(20)
Пример #2
0
def balance_thread():
    if not os.path.isfile("mqtt_config.txt"):
        raise Exception("MQTT is not configured. "
                        "Create mqtt_config.txt with first line mqtt server IP address and "
                        "second line with user name and"
                        "third line with your password and"
                        "forth line with your topic for account balance.")

    with open("mqtt_config.txt") as fp:
        ip = fp.readline().strip()
        user = fp.readline().strip()
        password = fp.readline().strip()
        topic = fp.readline().strip()

    while True:
        balance = exchange.get_balance()
        publish.single(topic,
                       payload="{0}".format(sum([coin['usdtValue'] for coin in balance])),
                       qos=0,
                       retain=True,
                       hostname=ip,
                       port=1883,
                       client_id="",
                       keepalive=60,
                       will=None,
                       auth={'username': user, 'password': password},
                       tls=None)

        time.sleep(20)
Пример #3
0
def orders_change_thread():
    orders = {}
    pushover = Pushover()
    while True:
        completed = ""
        pending = ""
        new = ""
        new_orders = exchange.get_open_orders()
        balance = exchange.get_balance()
        if orders != new_orders:
            for coin in orders:
                for o in orders[coin]:
                    if coin not in new_orders:
                        completed += "{0} {1} amount: {2}, total: {3}\n".format(o['type'].capitalize(), coin, o['amount'], o['total'])
                    else:
                        for new_o in new_orders[coin]:
                            if new_o != o:
                                completed += "{0} {1} amount: {2}, total: {3}\n".format(o['type'].capitalize(), coin, o['amount'], o['total'])

            for coin in new_orders:
                for o in new_orders[coin]:
                    if coin not in orders:
                        new += "{0} {1} amount: {2}, total: {3}\n".format(o['type'].capitalize(), coin, o['amount'], o['total'])
                    else:
                        for old_o in orders[coin]:
                            if old_o != o:
                                new += "{0} {1} amount: {2}, total: {3}\n".format(o['type'].capitalize(), coin, o['amount'], o['total'])

            for coin in new_orders:
                for o in new_orders[coin]:
                    pending += "{0} {1} amount: {2}, total: {3}\n".format(o['type'].capitalize(), coin, o['amount'], o['total'])

            message = ""
            if completed != "":
                message += "Completed or canceled orders:\n"
                message += completed
                message += "\n"

            if new != "":
                message += "New orders:\n"
                message += new
                message += "\n"

            if pending != "":
                message += "Pending orders:\n"
                message += pending
                message += "\n"

            if message != "":
                message += "Total balance: {0:.2f} USDT".format(sum([coin['usdtValue'] for coin in balance]))
                print("---------------------------")
                print(datetime.datetime.now())
                print(message)
                pushover.send(message)

            orders = new_orders

        time.sleep(10)
Пример #4
0
    def check_update(self, force=False, diff_check=True):
        now = dt.datetime.now()
        time_diff = now - self.last_update
        lower_bound = self.interval * self.leniency  #e.g. 5min*0.99=4min,57sec
        if time_diff > lower_bound or force:
            if diff_check:
                old_balances = dict(self.balances)
                old_balances_by_exchange_total = dict(
                    self.balances_by_exchange_total)
                old_balances_by_exchange_free = dict(
                    self.balances_by_exchange_free)

            for ex in exchange_objs:
                m = ex.load_markets(True)  #Force reload of markets
                self.balances_by_exchange_total[ex] = exchange.get_balance(
                    ex, 'total')
                self.balances_by_exchange_free[ex] = exchange.get_balance(
                    ex, 'free')
            #Be lazy and just call fetch_balance on every exchange again
            #TODO: be less lazy
            self.balances = exchange.get_balances(self.exchange_objs)

            # Balance diffs
            if diff_check:
                bals_diff = dict_diff(self.balances, old_balances)
                bal_total_diff = {}
                bal_free_diff = {}

                for ex in exchange_objs:
                    bal_total_diff[ex] = dict_diff(
                        self.balances_by_exchange_total[ex],
                        old_balances_by_exchange_total[ex])
                    bal_free_diff[ex] = dict_diff(
                        self.balances_by_exchange_free[ex],
                        old_balances_by_exchange_free[ex])
                print('Balance Diffs (New-Old):')
                print('\nTotals: \n----------')
                pprint(bals_diff)
                print('\nTotal by exchange: \n----------')
                pprint(bal_total_diff)
                print('\nFree bals by exchange: \n ----------')
                pprint(bal_free_diff)

            print("Balances updated")
            self.last_updated = now
Пример #5
0
def create_trade(stake_amount: float, _exchange: exchange.Exchange) -> Optional[Trade]:
    """
    Checks the implemented trading indicator(s) for a randomly picked pair,
    if one pair triggers the buy_signal a new trade record gets created
    :param stake_amount: amount of btc to spend
    :param _exchange: exchange to use
    """
    logger.info('Creating new trade with stake_amount: %f ...', stake_amount)
    whitelist = _CONF[_exchange.name.lower()]['pair_whitelist']
    # Check if btc_amount is fulfilled
    if exchange.get_balance(_CONF['stake_currency']) < stake_amount:
        raise ValueError(
            'stake amount is not fulfilled (currency={}'.format(_CONF['stake_currency'])
        )

    # Remove currently opened and latest pairs from whitelist
    trades = Trade.query.filter(Trade.is_open.is_(True)).all()
    latest_trade = Trade.query.filter(Trade.is_open.is_(False)).order_by(Trade.id.desc()).first()
    if latest_trade:
        trades.append(latest_trade)
    for trade in trades:
        if trade.pair in whitelist:
            whitelist.remove(trade.pair)
            logger.debug('Ignoring %s in pair whitelist', trade.pair)
    if not whitelist:
        raise ValueError('No pair in whitelist')

    # Pick pair based on StochRSI buy signals
    for _pair in whitelist:
        if get_buy_signal(_pair):
            pair = _pair
            break
    else:
        return None

    open_rate = exchange.get_ticker(pair)['ask']
    amount = stake_amount / open_rate
    order_id = exchange.buy(pair, open_rate, amount)

    # Create trade entity and return
    message = '*{}:* Buying [{}]({}) at rate `{:f}`'.format(
        _exchange.name,
        pair.replace('_', '/'),
        exchange.get_pair_detail_url(pair),
        open_rate
    )
    logger.info(message)
    telegram.send_msg(message)
    return Trade(pair=pair,
                 btc_amount=stake_amount,
                 open_rate=open_rate,
                 open_date=datetime.utcnow(),
                 amount=amount,
                 exchange=_exchange,
                 open_order_id=order_id,
                 is_open=True)
Пример #6
0
    def __init__(self,
                 exchange_objs,
                 coin_to_exchange,
                 start,
                 interval,
                 leniency=0.99,
                 verbose=True):
        #exchange_objs - ccxt exchange objects
        #coin_to_exchange - dict of which exchange to use for each coin {coin : exchange_obj}
        #interval - update frequency to fetch new data, typically not the same as the strat interval!
        #start - time at which the script was started (if not <10s from now, a reboot occurred)
        #leniency - float in range (0,1] that is the "wiggle room" for any time related activity
        #e.g. 0.99 leniency --> 14 minutes over 24h, 3s over 5min.
        self.exchange_objs = exchange_objs
        self.coin_to_exchange = dict(
            coin_to_exchange
        )  #make copy as we might make changes and this is a global var

        self.balances = exchange.get_balances(
            exchange_objs)  # {coin_id : val_base}
        self.balances_by_exchange_total = {
        }  # {exchange_obj : {coin_id : val_base}}
        self.balances_by_exchange_free = {}  # ditto
        for ex in exchange_objs:
            self.balances_by_exchange_total[ex] = exchange.get_balance(
                ex, 'total')
            self.balances_by_exchange_free[ex] = exchange.get_balance(
                ex, 'free')
        self.stop_loss = {}  # {coin_id : price_USD}
        self.avg_price = {}  # {coin_id : price_USD}

        self.now = dt.datetime.now()
        self.start = start
        self.interval = interval
        self.leniency = leniency
        self.last_update = dt.datetime.now()
        self.check_update(force=True)
        if self.now - start > dt.timedelta(seconds=10):
            #Start was more than 10 seconds ago, probably a reboot.
            #TODO: HANDLE REBOOTS
            raise NotImplementedError(
                'Reboots are not handled yet. Start time is more than 10s ago.'
            )
Пример #7
0
    def get_forcesell(self, trade):

        # Get current rate
        current_rate = exchange.get_ticker(trade.pair)['bid']
        # Get available balance
        currency = trade.pair.split('_')[1]
        balance = exchange.get_balance(currency)
        # Execute sell
        profit = trade.exec_sell_order(current_rate, balance)

        message = '*{}:* Selling [{}]({}) at rate `{:f} (profit: {}%)`'.format(
            trade.exchange.name, trade.pair.replace('_', '/'),
            exchange.get_pair_detail_url(trade.pair), trade.close_rate,
            round(profit, 2))

        return message
Пример #8
0
def execute_sell(trade: Trade, current_rate: float) -> None:
    """
    Executes a sell for the given trade and current rate
    :param trade: Trade instance
    :param current_rate: current rate
    :return: None
    """
    # Get available balance
    currency = trade.pair.split('_')[1]
    balance = exchange.get_balance(currency)

    profit = trade.exec_sell_order(current_rate, balance)
    message = '*{}:* Make It Rain!!!! with [{}]({}) for `{:f} (profit: {}%)`'.format(
        trade.exchange.name, trade.pair.replace('_', '/'),
        exchange.get_pair_detail_url(trade.pair), trade.close_rate,
        round(profit, 2))
    logger.info(message)
    telegram.send_msg(message)
Пример #9
0
def _forcesellall(bot: Bot, update: Update) -> None:
    """
    Handler for /forcesellall.
    Sell all trades at current price
    :param bot: telegram bot
    :param update: message update
    :return: None
    """
    if get_state() != State.RUNNING:
        send_msg('`trader is not running`', bot=bot)
        return

    try:
        trades = Trade.query.filter(Trade.is_open.is_(True)).all()

        if len(trades) == 0:
            send_msg('`open trades not found`', bot=bot)
            return

        for trade in trades:
            # Get current rate
            current_rate = exchange.get_ticker(trade.pair)['bid']
            # Get available balance
            currency = trade.pair.split('_')[1]
            balance = exchange.get_balance(currency)
            # Execute sell
            profit = trade.exec_sell_order(current_rate, balance)
            message = '*{}:* Selling [{}]({}) at rate `{:f} (profit: {}%)`'.format(
                trade.exchange.name, trade.pair.replace('_', '/'),
                exchange.get_pair_detail_url(trade.pair), trade.close_rate,
                round(profit, 2))
            logger.info(message)
            send_msg(message)
            time.sleep(25)

    except ValueError:
        send_msg('Failed to sell all trades')
        logger.warning('/forcesellall: Failed to sell all trades')
Пример #10
0
def execute_sell(trade: Trade, current_rate: float) -> None:
    """
    Executes a sell for the given trade and current rate
    :param trade: Trade instance
    :param current_rate: current rate
    :return: None
    """
    # Get available balance
    currency = trade.pair.split('_')[1]
    balance = exchange.get_balance(currency)
    whitelist = _CONF[trade.exchange.name.lower()]['pair_whitelist']

    profit = trade.exec_sell_order(current_rate, balance)
    whitelist.append(trade.pair)
    message = '*{}:* Selling [{}]({}) at rate `{:f} (profit: {}%)`'.format(
        trade.exchange.name,
        trade.pair.replace('_', '/'),
        exchange.get_pair_detail_url(trade.pair),
        trade.close_rate,
        round(profit, 2)
    )
    logger.info(message)
    telegram.send_msg(message)
Пример #11
0
def _forcesell(bot: Bot, update: Update) -> None:
    """
    Handler for /forcesell <id>.
    Sells the given trade at current price
    :param bot: telegram bot
    :param update: message update
    :return: None
    """
    if get_state() != State.RUNNING:
        send_msg('`trader is not running`', bot=bot)
        return

    try:
        trade_id = int(update.message.text.replace('/forcesell', '').strip())
        # Query for trade
        trade = Trade.query.filter(
            and_(Trade.id == trade_id, Trade.is_open.is_(True))).first()
        if not trade:
            send_msg('There is no open trade with ID: `{}`'.format(trade_id))
            return
        # Get current rate
        current_rate = exchange.get_ticker(trade.pair)['bid']
        # Get available balance
        currency = trade.pair.split('_')[1]
        balance = exchange.get_balance(currency)
        # Execute sell
        profit = trade.exec_sell_order(current_rate, balance)
        message = '*{}:* Selling [{}]({}) at rate `{:f} (profit: {}%)`'.format(
            trade.exchange.name, trade.pair.replace('_', '/'),
            exchange.get_pair_detail_url(trade.pair), trade.close_rate,
            round(profit, 2))
        logger.info(message)
        send_msg(message)

    except ValueError:
        send_msg('Invalid argument. Usage: `/forcesell <trade_id>`')
        logger.warning('/forcesell: Invalid argument received')
Пример #12
0
def orders_change_thread():
    orders = {}
    pushover = Pushover()
    while True:
        completed = ""
        pending = ""
        new = ""
        new_orders = exchange.get_open_orders()
        balance = exchange.get_balance()
        if orders != new_orders:
            for coin in orders:
                for o in orders[coin]:
                    if coin not in new_orders:
                        completed += "{0} {1} amount: {2}, total: {3}\n".format(
                            o['type'].capitalize(), coin, o['amount'],
                            o['total'])
                    else:
                        for new_o in new_orders[coin]:
                            if new_o != o:
                                completed += "{0} {1} amount: {2}, total: {3}\n".format(
                                    o['type'].capitalize(), coin, o['amount'],
                                    o['total'])

            for coin in new_orders:
                for o in new_orders[coin]:
                    if coin not in orders:
                        new += "{0} {1} amount: {2}, total: {3}\n".format(
                            o['type'].capitalize(), coin, o['amount'],
                            o['total'])
                    else:
                        for old_o in orders[coin]:
                            if old_o != o:
                                new += "{0} {1} amount: {2}, total: {3}\n".format(
                                    o['type'].capitalize(), coin, o['amount'],
                                    o['total'])

            for coin in new_orders:
                for o in new_orders[coin]:
                    pending += "{0} {1} amount: {2}, total: {3}\n".format(
                        o['type'].capitalize(), coin, o['amount'], o['total'])

            message = ""
            if completed != "":
                message += "Completed or canceled orders:\n"
                message += completed
                message += "\n"

            if new != "":
                message += "New orders:\n"
                message += new
                message += "\n"

            if pending != "":
                message += "Pending orders:\n"
                message += pending
                message += "\n"

            if message != "":
                message += "Total balance: {0:.2f} USDT".format(
                    sum([coin['usdtValue'] for coin in balance]))
                print("---------------------------")
                print(datetime.datetime.now())
                print(message)
                pushover.send(message)

            orders = new_orders

        time.sleep(10)