示例#1
0
    def get_dividend_summary(update, context):
        ticker = update.message.text
        user = update.effective_user
        log().info("User %s entered ticker value %s.", user.first_name, ticker)

        years = 5

        share = Share(ticker)

        if not share.is_valid:
            update.message.reply_text(
                "Invalid ticker. Please use /start to go back to the main menu"
            )
            log().info("User %s entered an invalid ticker value %s.",
                       user.first_name, ticker)
            return ConversationHandler.END

        a = share.get_dividend_summary(datetime.datetime.now().year,
                                       datetime.datetime.now().year - years)
        s = '<b>' + share.name + '</b>\n\n'

        for item in a:
            s += '<b>' + str(item.year) + ' (' + str(
                item.total) + ')</b>' + '\n'
            i = 1
            for pay_date, pay_amount in zip(item.pay_date, item.amount):
                if pay_date == '-':
                    continue
                s += pd.to_datetime(pay_date).strftime('%d %B') + ': ' + str(
                    pay_amount).replace('SGD', 'SGD ') + '\n'
                i += 1
            s += '\n'

        update.message.reply_text(s, parse_mode='HTML')
        return ConversationHandler.END
示例#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()
示例#3
0
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')
示例#4
0
 def get_ticker_shares(update, context):
     user = update.effective_user
     log().info("User %s wants to calculate using shares.", user.first_name)
     query = update.callback_query
     query.answer()
     query.edit_message_text(
         text="Enter ticker symbol (e.g D05)")
     return DIVIDENDCALCSHARESSTATE
示例#5
0
 def __end_chat(update, context):
     user = update.effective_user
     query = update.callback_query
     query.answer()
     log().info("User %s ended the conversation.", user.first_name)
     query.edit_message_text(
         'Chat ended. Use /start to show the menu again.')
     return ConversationHandler.END
示例#6
0
 def get_ticker(update, context):
     user = update.effective_user
     log().info("User %s pressed the dividend summary button.",
                user.first_name)
     query = update.callback_query
     query.answer()
     query.edit_message_text(text="Enter ticker symbol (e.g D05)")
     return GETSUMMARY
示例#7
0
文件: db.py 项目: santhoshraje/kubera
 def __init__(self, dbname):
     self.dbname = dbname
     try:
         self.conn = sqlite3.connect(dbname)
         self.cursor = self.conn.cursor()
         self.create_table('watchlist', 'id integer, ticker text')
     except sqlite3.Error as e:
         log().critical('local database initialisation error: "%s"', e)
         self.conn = None
示例#8
0
    def calculate_by_shares_second(self, update, context):
        self.amount = update.message.text
        user = update.effective_user
        log().info("User %s entered amount %s", user.first_name, self.amount)
        share = Share(self.stock_name)

        dividends = float(share.get_dividend_summary(2019).total.replace('SGD', '')) * int(self.amount)

        update.message.reply_text("Expected dividends based on last year's data: SGD " + str(
            dividends) + "\n\n Use /start to go back to main menu")

        return ConversationHandler.END
示例#9
0
    def calculate_by_amt_second(self, update, context):
        self.amount = update.message.text
        user = update.effective_user
        log().info("User %s entered amount %s", user.first_name, self.amount)

        share = Share(self.stock_name)
        # get 2019 dividends
        dividends = float(share.get_dividend_summary(2019).total.replace('SGD', ''))
        # get number of shares from amount
        tmp = int(int(self.amount) / float(share.price) / 100)
        no_of_shares = tmp * 100
        # calculate returns
        returns = no_of_shares * dividends

        update.message.reply_text("Expected dividends based on last year's data: SGD " + str(
            returns) + "\n\n Use /start to go back to main menu")

        return ConversationHandler.END
示例#10
0
    def calculate_by_amt_first(self, update, context):
        self.stock_name = update.message.text
        user = update.effective_user
        log().info("User %s entered ticker value %s", user.first_name, self.stock_name)
        share = Share(self.stock_name)
        if not share.is_valid:
            update.message.reply_text("Invalid ticker. Please use /start to go back to the main menu")
            return ConversationHandler.END

        dividend_check = share.get_dividend_summary(2019)

        if dividend_check is None:
            update.message.reply_text("Sorry, dividend data is unavailable for this company. Please use /start to go "
                                      "back to the main menu")
            return ConversationHandler.END

        update.message.reply_text("Enter purchase amount in SGD")

        return DIVIDENDCALCAMTSTATEFINAL
示例#11
0
 def show_options(update, context):
     user = update.effective_user
     log().info("User %s pressed the dividend calculator button.", user.first_name)
     # answer query
     query = update.callback_query
     query.answer()
     # new keyboard
     keyboard = [
         [InlineKeyboardButton("🔸 Calculate by amount",
                               callback_data=str(DIVIDENDCALCAMT))],
         [InlineKeyboardButton("🔸 Calculate by shares",
                               callback_data=str(DIVIDENDCALCSHARES))]
     ]
     reply_markup = InlineKeyboardMarkup(keyboard)
     query.edit_message_text(
         text="You can calculate expected dividends by entering either the number of shares bought or the amount "
              "paid for the shares",
         reply_markup=reply_markup
     )
     return DIVIDENDCALCFIRST
示例#12
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
示例#13
0
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')
示例#14
0
 def error(update, context):
     log().warning('"%s"', context.error)
示例#15
0
    def get_upcoming_dividends(update, context):
        user = update.effective_user
        log().info("User %s pressed the upcoming dividends button.",
                   user.first_name)
        query = update.callback_query
        query.answer()
        # query.edit_message_text(text='Fetching data...')

        f = open("Logs/upcoming1.pickle", "rb")
        array_1 = pickle.load(f)
        f.close()

        f = open("Logs/upcoming2.pickle", "rb")
        array_2 = pickle.load(f)
        f.close()

        f = open("Logs/upcoming3.pickle", "rb")
        array_3 = pickle.load(f)
        f.close()

        f = open("Logs/upcoming4.pickle", "rb")
        array_4 = pickle.load(f)
        f.close()

        f = open("Logs/upcoming5.pickle", "rb")
        array_5 = pickle.load(f)
        f.close()

        tmp = ''
        for a in array_1:
            tmp += '<b>' + a.name.lstrip() + ' (' + a.ticker + ')</b>\n‣ Market Cap: ' + str(a.market_cap) \
                    + '\n‣ BVPS (MRQ): ' + str(a.book_value) + '\n‣ Price: ' + str(a.price) + \
                    '\n‣ Amount: ' + str(a.payout_amount) + '\n‣ Yield: ' + a.yield_data + '\n‣ Date: ' + a.payout_date + '\n\n'
        context.bot.send_message(chat_id=update.callback_query.message.chat.id,
                                 text=tmp,
                                 parse_mode='html',
                                 silent=True)
        time.sleep(0.5)

        tmp = ''
        for b in array_2:
            tmp += '<b>' + b.name.lstrip() + ' (' + str(b.ticker) + ')</b>\n‣ Market cap: ' + str(b.market_cap) \
                    + '\n‣ Book value: ' + str(b.book_value) + '\n‣ Price: ' + str(b.price) + \
                    '\n‣ Amount: ' + str(b.payout_amount) + '\n‣ Yield: ' + b.yield_data + '\n‣ Date: ' + b.payout_date + '\n\n'
        context.bot.send_message(chat_id=update.callback_query.message.chat.id,
                                 text=tmp,
                                 parse_mode='html',
                                 silent=True)
        time.sleep(0.5)

        tmp = ''
        for c in array_3:
            tmp += '<b>' + c.name.lstrip() + ' (' + str(c.ticker) + ')</b>\n‣ Market cap: ' + str(c.market_cap) \
                    + '\n‣ Book value: ' + str(c.book_value) + '\n‣ Price:' + str(c.price) + \
                    '\n‣ Amount: ' + str(c.payout_amount) + '\n‣ Yield: ' + c.yield_data + '\n‣ Date: ' + c.payout_date + '\n\n'
        context.bot.send_message(chat_id=update.callback_query.message.chat.id,
                                 text=tmp,
                                 parse_mode='html',
                                 silent=True)
        time.sleep(0.5)

        tmp = ''
        for d in array_4:
            tmp += '<b>' + d.name.lstrip() + ' (' + str(d.ticker) + ')</b>\n‣ Market cap: ' + str(d.market_cap) \
                    + '\n‣ Book value: ' + str(d.book_value) + '\n‣ Price: ' + str(d.price) + \
                    '\n‣ Amount: ' + str(d.payout_amount) + '\n‣ Yield: ' + d.yield_data + '\n‣ Date: ' + d.payout_date + '\n\n'
        context.bot.send_message(chat_id=update.callback_query.message.chat.id,
                                 text=tmp,
                                 parse_mode='html',
                                 silent=True)
        time.sleep(0.5)

        tmp = ''
        for e in array_5:
            tmp += '<b>' + e.name.lstrip() + ' (' + str(e.ticker) + ')</b>\n‣ Market cap: ' + str(e.market_cap) \
                    + '\n‣ Book value: ' + str(e.book_value) + '\n‣ Price: ' + str(e.price) + \
                    '\n‣ Amount: ' + str(e.payout_amount) + '\n‣ Yield: ' + e.yield_data + '\n‣ Date: ' + e.payout_date + '\n\n'
        context.bot.send_message(chat_id=update.callback_query.message.chat.id,
                                 text=tmp,
                                 parse_mode='html',
                                 silent=True)

        return ConversationHandler.END