Надо хоть немножечко осознавать, как работает asyncio.
create_task() возвращает объект класса Task, представляющий собой фоновую задачу. Эта задача уже запланирована к выполнению в рабочем цикле (loop) asyncio, и будет выполняться в фоне пока текущая корутина ожидает какой-нибудь другой операции.
Но если тебе надо дождаться завершения работы задачи, ты можешь сделать await на этом объекте.
Тогда текущая корутина приостановится, пока задача не завершится, и получит или возвращённое задачей значение, или выкинутое задачей исключение.
А теперь посмотри на свой код:
await asyncio.create_task(start_checking_price(1800))
Ты создаёшь задачу - и тут же говоришь программе, что тебе надо дождаться её завершения!
Ну как бы программа и делает в точности то, что ты от неё требуешь...
Подчёркиваю красным:
await asyncio.create_task(some_coro(...))
не имеет смысла практически никогда! Если тебе нужно запустить корутину и дождаться результата, делаешь просто
await some_coro(...)
.
А вот если тебе нужно запустить корутину параллельно текущей... Получится что-то типа такого:
# ...
check_task = asyncio.create_task(start_checking_price(1800)) # нету await, мы не ждём созданную задачу!
try:
await dp.start_polling()
finally:
check_task.cancel() # отменяем корутину
# внутри start_checking_price() текущий выполняемый await выкинет исключение CancelledError
# это исключение всплывёт наружу, если мы сделаем await, и позволит отработать
# блокам finally, with и т.п. инструментам. Также можно явно поймать это исключение,
# чтобы обработать отмену корутины. Но в твоём случае это не требуется.
try:
await check_task # даём корутине отработать завершение
except asyncio.CancelledError: # ловим всплывшее CancelledError
pass # всё ок, никакие действия не требуются
await my_bot.close()