Как сделать костыль для Тинькофф Инвестиций своими руками или уведомления об action required for take profit / stop loss

    Есть такой брокер — Тинькофф Банк. И есть проблема в том, что на текущий момент этот брокер не имеет приказов take profit / stop loss. Поэтому, если вы хотите торговать более активно, то вам нужно костылить какое-то временное решение, пока в недрах Тинькоффа программисты разрабатывают киллер фичу take profit/stop loss, и под катом — одно из них.
    update: 22.03.2019, Брокер выкатил мажорную версию 3.0.0 в Google Play, в которой take profit/stop loss все-таки появились.

    Почему я решил написать эту статью здесь? Мне показалось, что Тинькофф Банк и его продукты довольно популярны среди айтишников, и, возможно, у кого-то есть такая же потребность, а желания или времени городить свой велосипед нет. Поэтому делюсь своим.

    Для начала — об альтернативных возможностях, предоставляемых собственно Брокером.
    Первое, у Тинькоффа есть лимитные заявки, которые появились в феврале 2019 (два года ждали, без шуток!), но они работают в пределах одного дня и что хуже — в небольшом денежном интервале, что на волатильном рынке создает неудобства. Просто нельзя задать значения меньше (больше) определенного порога, рассчитываемого от текущих котировок. Ну и задать больше одной лимитной заявки, вероятно, нельзя (у меня при попытке сохранить первую заявку мобильное приложение всегда крашится, а на сайте такой функциональности нет).
    Второе, внутри их мобильного приложения можно подписаться на изменение цены, установив абсолютный порог или порог на изменение в процентах (на увеличение или уменьшение), но вы можете установить один и только один порог на актив.

    Логика моего велосипеда проста:
    1) у нас есть thresholds (здесь и далее — пороги) для нашей ценной бумаги (актива), на который у нас должно происходить ручное действие take profit / stop loss. Пороги рассчитываем самостоятельно, исходя из цены покупки актива;
    2) мы должны парсить откуда-то данные текущей цены актива;
    3) посылать себе извещение, если один из порогов был достигнут.
    Несмотря на незамысловатое описание, есть нюансы в реализации :)

    1) Пока мой портфель состоял из одного актива, пороги прописал прямо в теле скрипта, а поиск бумаги сделан был даже не переменной, а просто магической строчкой. Плохое решение, но для проверки идеи было достаточно. По мере диверсификации портфеля я сделал файл, откуда грузятся ценные бумаги, биржи, на которых они торгуются и значения порогов.

    2) Поскольку моим активом была иностранная ценная бумага, которая торгуется на Санкт-Петербургской бирже, то сначала я решил парсить данные с сайта Санкт-Петербургской биржи, со следующей страницы: spbexchange.ru/ru/market-data/Default.aspx
    Сортировка на СПб бирже идёт по объему торгов, и моя ценная бумага всегда находилась по первой странице. Работало замечательно, но 8 марта всё сломалось. Почему-то TSLA оказалась аж на 25-ой странице, а их пагинатор грузит данные динамически через JS. Такую проблему можно решить «в лоб»: парсить все страницы, до тех пор, пока не найдем наш актив. Но такой подход не очень эффективен, если считать время выполнения цикла скрипта. Вместо этого я решил добавить парсинг с tradingview.com. Там не нужно лопатить длинные списки на большем количестве страниц. Там у каждого актива есть примерно такая ссылка:
    www.tradingview.com/symbols/NASDAQ-TSLA
    Мне казалось, что всё должно завестись быстро и просто, но возникла проблема — интересующие меня данные подгружаются через JS и обычный Requests с этим не справился.
    У этой проблемы есть три известных мне решения:
    PyQT, selenium (webdriver) и расширение Requests-HTML. Поскольку у меня в проекте уже был Requests, было решено использовать его же расширение.
    К сожалению, работало это решение не очень стабильно, пришлось поискать варианты решения.
        session = HTMLSession()
        r = session.get(url)
        my = r.html.render(timeout=30)
        selector = 'span.tv-symbol-header-quote__value.tv-symbol-header-quote__value--large.js-symbol-last'
        price = r.html.find(selector)[0].text
        r.close()
        session.close()

    Обратите внимание на timeout, а также вызовы метода close(). Их не во всех примерах можно встретить, но с ними работает лучше, чем без них.

    3) Регистрируемся на сервисе, который умеет посылать СМСки (sms.ru), берем их API, создаем ключ. До 5 СМСок в сутки — бесплатно. Мне — достаточно.
    Ключ выглядит так:
    24A41EA5-EEEE-CCCC-5555-094143C2EDDD
    а отправка СМС в первых версиях была реализована вот так:
    def send_message(mymessage):
        sms_url = 'https://sms.ru/sms/send?api_id=key&to=number&msg=message&json=1'
        sms_url = sms_url.replace('key', mykey)
        sms_url = sms_url.replace('number', mynumber)
        sms_url = sms_url.replace('message', mymessage)
        sms_response = requests.get(sms_url)


    Во время разработки возник следующей вопрос: а что делать, если мы уже послали пользователю СМС о пересечении порога? Пока проверок никаких не было, оно посылало СМС еще раз. Каждый раз. Довольно быстро «съел» бесплатный лимит и стал думать, что с этим делать. Пришлось добавить счетчик отосланных СМС (sms_counter), который мы проверяем перед вызовом send_message.

        global sms_counter
        sms_counter = sms_counter + 1


    Прицепом пойдет еще один вопрос: отлично, во время торговой сессии мы обрабатываем одно пересечение порога определенным активом, и нас это устраивает. Что делать к следующей торговой сессии? Было решено обнулять счетчик высланных СМС. Вариантов было три: хранить данные в БД (но у меня, на текущей момент, stateless приложение), парсить время/дату или перезапускать скрипт. Пока что я делаю третий вариант, но в перспективе перейду ко второму или к первому варианту.

    Сейчас решение уже работоспособно, и его можно скачать с Гитхаба
    Для пользователей, которые не понимают, что такое Python и как его настраивать, предлагаю попробовать запустить упакованное решение для Windows

    Планы для дальнейшего развития:
    1) парсить дату/время, для обнуления счетчика СМС (вместо перезапуска скрипта);
    2) сейчас это stateless приложение, но намереваюсь привинтить БД;
    3) после п.2, хочу добавить отслеживание резких скачков увеличение/уменьшение цены, относительно цены закрытия предыдущего дня;
    4) расширить «коммуникационные» возможности: больше путей (Telegram, Viber, голосовые звонки, другие варианты) и провайдеров (намерен добавить smsc.ru, так как sms.ru иногда теряет отзывчивость, и, хоть и посылает СМС, но скрипт не выполняется дальше до тех пор, пока мы не получим sms_response).

    Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

    Пользуетесь ли вы Тинькофф Инвестициями?

    Если вы пользуетесь Тинькофф Инвестициями, была ли полезна для вас эта статья?

    Поддержать автора
    Поделиться публикацией

    Комментарии 10

      +4
      Поэтому, если вы хотите торговать более активно, то вам нужно костылить какое-то временное решение


      Как насчёт того чтобы просто принять волевое решение и уйти к брокеру, у которого есть нормальные терминалы?
        +2
        Со временем, некоторые клиенты так и поступают.
        Учитывая тот невеселый факт, что с Тинькофф Брокера вывести деньги можно только в Тинькофф Банк. А вот далее, у него комиссия при обналички более 150 тысяч рублей.
          0
          Двухходовка: сначала банковским переводом на счёт «до востребования» в Сбер (правда идти может до трёх дней), потом в офисе сбера снимаем у операциониста со счёта (НЕ с карты) сколько надо. Если это самое надо больше 300-400К — лучше заказать деньги заранее.
            0
            У меня есть счета у двух наших брокеров, оба можно пополнять банковским переводом (думаю вообще все можно), а за рублёвый перевод тинькофф комиссию не берёт.
          +4
          В последней версии появились, уже можно не костылить так:
          • Стоп-лосс / тейк-профит
          • Стакан (на тарифах Трейдер и Премиум)
          • Несколько уведомлений на цену
          • Аналитика по портфелю
          • Инвестиционное профилирование и обновленный робот-советник

          И даже такое есть www.tinkoff.ru/invest/web-terminal
            0
            Странно, у меня в Андроид версии все без изменений.
              0
              Вчера выехала, версия 3.0.0
                0
                Сегодня из Google Play ставил, 2.9.1
                  0
                  Видимо еще не доехало обновление, сам недавно только обновился.
                    0
                    Мне в техподдержке Тинькофф рекомендовали по пятницам проверять багфиксы всех моих сообщений об ошибках. Завтра доедет, наверное)

          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

          Самое читаемое