def post_market_data(context: telegram.ext.CallbackContext):
    # connect to database
    log().info('post market data job started')
    total_users = 0
    tickers = []
    user_id = 0
    db = DBEngine()
    row = db.custom_command('SELECT DISTINCT id FROM watchlist')
    # for each id
    for r in row:
        s = 'Here is your watchlist update for today:\n\n'
        user_id = r[0]

        rowx = db.custom_command('SELECT ticker FROM watchlist WHERE id=' + str(user_id))
        # for each ticker that belongs to the user
        for x in rowx:
            tickers.append(x[0])
        # print(tickers)
        for ticker in tickers:
            share = Share(ticker)
            s += '<b>' + share.name + ' (' + share.ticker + ')</b>\nOpen: ' + str(share.open) + \
                 '\nLow: ' + str(share.low) + '\nHigh: ' + str(share.high) + \
                 '\nClose: ' + str(share.price) + '\nPrev Close: ' + \
                 str(share.previous_close) + '\n50MA: ' + str(share.fifty_day_ma) + \
                 '\nVolume: ' + str(share.volume)+'\n\n'
        try:
            context.bot.send_message(chat_id=user_id, text=s, parse_mode='HTML')
            total_users += 1
            tickers.clear()
            time.sleep(1)
        except TelegramError:
            tickers.clear()
            continue

    log().info('market data sent to ' + str(total_users) + ' users')
Beispiel #2
0
    def __init__(self):
        self.config = BotConfig(dev=False)
        log().info('kubera version' + self.config.version + ' started')
        # db engine
        DBEngine()
        # loaded from config
        self.token = self.config.token
        # telegram api
        self.updater = Updater(self.token, use_context=True)
        # job queue
        self.job_queue = self.updater.job_queue
        # Get the dispatcher to register handlers
        self.dp = self.updater.dispatcher
        # error handling
        self.dp.add_error_handler(self.error)
        # controllers
        MainMenu(self.dp)
        DividendSummary(self.dp)
        UpdateWatchlist(self.dp)
        About(self.dp)
        # jobs
        # 5:15 PM singapore time (after market close)
        self.job_queue.run_daily(post_market_data, datetime.time(hour=9, minute=15), (0, 1, 2, 3, 4))

        # start bot
        self.updater.start_polling()
        self.updater.idle()
Beispiel #3
0
 def __remove_share_final(self, update, context):
     tickers = {}
     user = update.effective_user
     query = update.callback_query
     query.answer()
     # print(query.data)
     DBEngine().delete_item('watchlist', 'ticker', query.data)
     result = DBEngine().custom_command("SELECT ticker FROM watchlist WHERE id=" + str(user.id))
     for result in result:
         my_share = Share(result[0])
         tickers[my_share.ticker] = my_share.name
     s = ""
     for key, value in tickers.items():
         s += value + " (" + key + ")" + "\n"
     update.callback_query.message.edit_text("Your watchlist has been updated.\n\n<b>Current watchlist:</b>\n" + s,
                                             parse_mode='HTML')
     return ConversationHandler.END
Beispiel #4
0
def main():
    db = DBEngine('test.sqlite')

    # # setup table
    # db.setup()
    # # add single item to database
    # db.add_item('watchlist', ['id', 'ticker'], ['1234', 'v03'])
    # db.add_item('watchlist', ['id', 'ticker'], ['1234', 'u11'])
    # db.add_item('watchlist', ['id', 'ticker'], ['1234', 'c6l'])
    row = db.custom_command('SELECT DISTINCT id FROM watchlist ')
    # for each id
    for r in row:
        print(r[0])
        rowx = db.custom_command('SELECT ticker FROM watchlist WHERE id=' +
                                 str(r[0]))
        # for each ticker that belongs to the user
        for x in rowx:
            print(x[0])
Beispiel #5
0
 def __remove_share(self, update, context):
     query = update.callback_query
     query.answer()
     keyboard = []
     user = update.effective_user
     result = DBEngine().custom_command("SELECT ticker FROM watchlist WHERE id=" + str(user.id))
     for result in result:
         my_share = Share(result[0])
         keyboard.append([InlineKeyboardButton(my_share.name + " (" + my_share.ticker + ")",
                                               callback_data=my_share.ticker)])
     reply_markup = InlineKeyboardMarkup(keyboard)
     update.callback_query.message.edit_text("What would you like to remove?", reply_markup=reply_markup,
                                             parse_mode='HTML')
     return REMOVESHARE
Beispiel #6
0
    def __add_share_final(self, update, context):
        tickers = {}
        user = update.effective_user
        # print(user.id)
        ticker = update.message.text
        share = Share(ticker)
        count = DBEngine().count("SELECT COUNT (*) FROM watchlist WHERE id=" + str(user.id))
        result = DBEngine().custom_command("SELECT ticker FROM watchlist WHERE id=" + str(user.id))
        # check for valid ticker
        if not share.is_valid:
            update.message.reply_text("Invalid ticker. Please use /start to go back to the main menu")
            return ConversationHandler.END
        # check if the user has hit watchlist limit
        if count >= 3:
            update.message.reply_text("You have reached your watchlist limit")
            return ConversationHandler.END
        # create dictionary of existing watchlist
        for result in result:
            my_share = Share(result[0])
            tickers[my_share.ticker] = my_share.name
        # add the incoming entry
        before = len(tickers)
        tickers[share.ticker] = share.name
        after = len(tickers)
        if before == after:
            update.message.reply_text("This stock is already on your watchlist")
            return ConversationHandler.END

        DBEngine().add_item('watchlist', ['id', 'ticker'], [user.id, share.ticker])

        s = ""
        for key, value in tickers.items():
            s += value + " (" + key + ")" + "\n"

        update.message.reply_text("Your watchlist has been updated.\n\n<b>Current watchlist:</b>\n" + s,
                                  parse_mode='HTML')
        return ConversationHandler.END
Beispiel #7
0
    def __yes(self, update, context):
        # send to users
        for user in DBEngine().get_items('users', 'id'):
            try:
                context.bot.send_message(chat_id=user[0],
                                         text=self.__message,
                                         parse_mode='HTML')
                log().info('Message has been sent to %s', user[0])
                time.sleep(1)
            except TelegramError as e:
                log().warning(e)
                log().warning('User %s has blocked the bot', user[0])
                # DBEngine().delete_item('users', 'id', user[0])
                # log().info('User %s has been removed from the database', user[0])
                continue

        # send message
        update.message.reply_text('Update sent to all users')
        return ConversationHandler.END
Beispiel #8
0
    def __show_menu(self, update, context):
        tickers = {}
        first_name = update.effective_user.first_name
        user_id = update.effective_user.id
        s = "Hi " + first_name + ", what would you like to do?\n\n<b>Your watchlist:</b>\n"
        result = DBEngine().custom_command(
            "SELECT ticker FROM watchlist WHERE id=" + str(user_id))
        for result in result:
            my_share = Share(result[0])
            tickers[my_share.ticker] = my_share.name

        for key, value in tickers.items():
            s += value + " (" + key + ")" + "\n"

        if len(tickers) == 0:
            s += "Empty! Update your watchlist to receive automatic alerts about your favourite stocks."

        keyboard = [
            [
                InlineKeyboardButton("Update my watchlist",
                                     callback_data=str(states.UPDATEWATCHLIST))
            ],
            [
                InlineKeyboardButton("Dividend history",
                                     callback_data=str(states.DIVIDENDINFO))
            ],
            # [InlineKeyboardButton("Bot settings",
            #                       callback_data=str(states.SETTINGS))],
            [
                InlineKeyboardButton("About this bot",
                                     callback_data=str(states.ABOUT))
            ]
            # [InlineKeyboardButton("Cancel",
            #                       callback_data=str(states.MENUCANCEL))]
        ]
        reply_markup = InlineKeyboardMarkup(keyboard)
        # Send message with text and appended InlineKeyboard
        update.message.reply_text(s,
                                  reply_markup=reply_markup,
                                  parse_mode='HTML')
def post_market_analysis(context: telegram.ext.CallbackContext):
    # connect to database
    db = DBEngine()
    # fetch tickers
    tickers = db.get_items('stocks', 'ticker')
    # update values
    for ticker in tickers:
        share = Share(ticker[0])
        # ignore tickers with missing volume information
        if share.volume == 'unavailable':
            continue
        # add volume to database
        db.update_item('stocks', 'volume', share.volume, 'ticker', ticker[0])
        # add company name to database
        db.update_item('stocks', 'name', share.name, 'ticker', ticker[0])
        # add change % to database
        db.update_item('stocks', 'change', share.change, 'ticker', ticker[0])
        time.sleep(1)

    # get top 5 results from database sorted
    volume = db.custom_command('select name, volume from stocks order by volume desc limit 5')
    gainers = db.custom_command('select name, change from stocks order by change desc limit 5')
    losers = db.custom_command('select name, change from stocks order by change asc limit 5')

    # STI change
    sti_change_raw = Share('^STI').percent_changed
    # append '%'
    sti_change = str(sti_change_raw) + '%'
    # prepend '+' if the value is positive
    if sti_change_raw > 0:
        sti_change = '+' + sti_change

    # create string
    s = '<b>Market Statistics (' + datetime.today().strftime('%d %B %Y') + ')</b>\n\n'
    s += '<b>STI overall change: </b>' + sti_change + '\n\n'
    s += '<b>Highest volumes:</b>\n'

    for idx, row in enumerate(volume):
        s += '‣ ' + row[0] + ' [' + str(millify(row[1])) + ']\n'

    s += '\n'
    s += '<b>Top gainers:</b>\n'

    for idx, row in enumerate(gainers):
        s += '‣ ' + row[0] + ' [+' + str(row[1]) + ']' + '\n'

    s += '\n'
    s += '<b>Top losers:</b>\n'

    for idx, row in enumerate(losers):
        s += '‣ ' + row[0] + ' [' + str(row[1]) + ']' + '\n'

    total_users = 0
    # send message to all users
    for user in DBEngine().get_items('users', 'id'):
        try:
            context.bot.send_message(chat_id=user[0], text=s, parse_mode='HTML')
            total_users += 1
            time.sleep(1)
        except TelegramError:
            DBEngine().delete_item('users', 'id', user[0])
            continue

    log().info('market statistics sent to ' + str(total_users) + ' users')