Path: blob/master/ invest-robot-contest_trading_bot-master/bot/handlers/buy_handlers.py
5935 views
from main import bot1from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton2from trading.get_account_info import get_currency_sing3from main import dp4from aiogram.types import Message, ReplyKeyboardMarkup5from bot.keyboards.start_menu_keyboard import get_start_menu6from aiogram.dispatcher import FSMContext7from aiogram.dispatcher.filters.state import State, StatesGroup8from aiogram import types9from trading.trade_help import in_lot_figi, get_price_figi, quotation_to_float10from trading.place_order import buy_order11from trading.check_av import check_time12from config.personal_data import get_account_type, get_account_access, get_account13from trading.get_securities import get_security_list14from trading.get_securities import security_name_by_figi15"""1617Тут представлены все хэндлеры, которые отвечают за продажу бумаг1819"""2021"""22Создаём три состояния FSM23"""242526class SearchSecurityBuy(StatesGroup):27wait_sfb_buy = State()282930class BuyOrder(StatesGroup):31b_wait_figi = State()32b_wait_quantity = State()33b_wait_price = State()343536"""37Начало поиска бумаг38"""394041@dp.message_handler(text="Купить")42async def start_buy(message):43if get_account_access(message.from_user.id) == 1:44await bot.send_message(chat_id=message.from_user.id, text="Введите название бумаги или FIGI:")45await SearchSecurityBuy.wait_sfb_buy.set()46else:47await bot.send_message(chat_id=message.from_user.id, text=f"<b>У Вас используется токен только для чтения!</b>")484950"""51Поиск бумаг на покупку52"""535455@dp.message_handler(state=SearchSecurityBuy.wait_sfb_buy)56async def search_security_buy(message: Message, state: FSMContext):57security_list = get_security_list(user_id=message.from_user.id, name=message.text)58if len(security_list) != 0:59for security in security_list:6061choose_share_keyboard = InlineKeyboardMarkup()62choose_share_keyboard.add(63InlineKeyboardButton(text=f"Купить", callback_data=f"buy:figi:{security.figi}"))6465try:66inst_type = security.instrument_type6768if inst_type == "share":69inst = "Акции"70elif inst_type == "future":71inst = "Фьючерсы"72elif inst_type == "bond":73inst = "Бонды"74elif inst_type == "etf":75inst = "ETF"76elif inst_type == "currency":77inst = "Валюта"78else:79inst = inst_type8081except:82inst = "Акции"8384await message.answer(85text=86f"🧾<b>{inst} {security.name}</b>\n"87f"FIGI: {security.figi}\n\n"88f"Бумаг в лоте: {security.lot}\n"89f"Средняя цена бумаги: {round(get_price_figi(user_id=message.from_user.id, figi=security.figi), 4)}{get_currency_sing(security.currency)}\n"90f"Итого стоимость: {round(security.lot * get_price_figi(user_id=message.from_user.id, figi=security.figi), 4)}{get_currency_sing(security.currency)}\n"91, reply_markup=choose_share_keyboard)9293await state.finish()94else:95await bot.send_message(chat_id=message.from_user.id, text=f"Такой бумаги нет!")96await bot.send_message(chat_id=message.from_user.id, text=f"Повторите ввод или напишите 'Отмена':")97return 09899100"""101Выбор количества лотов102"""103104105@dp.callback_query_handler(lambda c: c.data and c.data.startswith("buy:figi"))106async def b_choose_quantity(callback_query, state: FSMContext):107data = callback_query.data.split(":")108figi = data[2]109110# Проверяем, доступна ли она сейчас для покупки111if check_time(user_id=callback_query.from_user.id, figi=figi)[0] or get_account_type(112user_id=callback_query.from_user.id) == "sandbox":113114# Запишем в память115await state.update_data(b_chosen_figi=figi)116117# Создаём клавиатуру с примерами лотов118lot_keyboard = ReplyKeyboardMarkup()119lot_keyboard.add(f"1")120lot_keyboard.add(f"2")121lot_keyboard.add(f"3")122lot_keyboard.add(f"4")123lot_keyboard.add(f"Отмена")124125await bot.send_message(chat_id=callback_query.from_user.id, text="Укажите количество лотов для покупки:",126reply_markup=lot_keyboard)127128# Перейдём в следующее состояние129await BuyOrder.b_wait_quantity.set()130return131else:132await state.reset_state()133await bot.send_message(chat_id=callback_query.from_user.id, text="Торги ещё не начались!")134await bot.send_message(chat_id=callback_query.from_user.id,135text=check_time(user_id=callback_query.from_user.id, figi=figi)[1],136reply_markup=get_start_menu(callback_query.from_user.id))137138139"""140Третий хэндлер, который находится в состоянии b_wait_quantity141"""142143144@dp.message_handler(state=BuyOrder.b_wait_quantity)145async def b_choose_price(message: Message, state: FSMContext):146# Проверяем корректность введённых данных147try:148int(message.text)149except:150await message.answer("Вы ввели неверный формат!")151else:152if int(message.text) > 0:153154# Запишем в память155await state.update_data(b_chosen_quantity=message.text)156157user_data = await state.get_data()158price = get_price_figi(user_data['b_chosen_figi'], user_id=message.from_user.id)159160# Создадим клавиатуру с примерами цены на бумагу161price_keyboard = ReplyKeyboardMarkup()162163price_keyboard.add(f"Лучшая цена")164price_keyboard.add(f"{round(price * 1.02, 5)}")165price_keyboard.add(f"{round(price * 1.01, 5)}")166price_keyboard.add(f"{round(price * 1.00, 5)}")167price_keyboard.add(f"{round(price * 0.99, 5)}")168price_keyboard.add(f"{round(price * 0.98, 5)}")169price_keyboard.add(f"Отмена")170171# Включим клавиатуру172await message.answer("Укажите цену за бумагу:", reply_markup=price_keyboard)173await BuyOrder.b_wait_price.set()174175# В случае ошибки повторим запрос176else:177await message.answer("Введите корректное число лотов!")178179180"""181Последний хэндлер, который покупает бумаги182"""183184185@dp.message_handler(state=BuyOrder.b_wait_price)186async def b_finish(message: types.Message, state: FSMContext):187if message.text == "Лучшая цена":188189user_data = await state.get_data()190191await state.finish()192193# Продадим бумаги и выведем сообщение194195order = buy_order(figi=user_data['b_chosen_figi'], price=0.0,196quantity_lots=int(user_data['b_chosen_quantity']), user_id=message.from_user.id, via="bot")197198if order:199await message.answer(200f"Покупка ценных бумаг {security_name_by_figi(order.figi, message.from_user.id)} в количестве {order.lots_requested} лотов по цене {quotation_to_float(order.initial_order_price)}{get_currency_sing(order.initial_order_price.currency)}.\n",201reply_markup=get_start_menu(message.from_user.id))202else:203await message.answer("Ошибка! Вероятно, у Вас мало средств на счёте!")204else:205206try:207float(message.text)208except:209await message.answer("Вы ввели неверный формат!")210else:211user_data = await state.get_data()212price = get_price_figi(user_data['b_chosen_figi'], user_id=message.from_user.id)213214# Проверяем, что цена находится в разумных границах215216if price * 1.20 > float(message.text) > price * 0.80:217await state.finish()218219order = buy_order(figi=user_data['b_chosen_figi'], price=float(message.text),220quantity_lots=int(user_data['b_chosen_quantity']), user_id=message.from_user.id,221via="bot")222if order:223await message.answer(224f"Выставлен ордер на покупку ценных бумаг {security_name_by_figi(order.figi,message.from_user.id)} в количестве {order.lots_requested} лотов по цене {quotation_to_float(order.initial_order_price)}{get_currency_sing(order.initial_order_price.currency)}.\n",225reply_markup=get_start_menu(message.from_user.id))226else:227await message.answer("Ошибка! Вероятно, у Вас мало средств на счёте!")228229# В случае ошибки повторим запрос230else:231await message.answer("Введите корректную цену!")232return233234235