Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Проверка факта активности торгов на бирже #32

Open
AlekseyGur opened this issue Jun 5, 2023 · 9 comments

Comments

@AlekseyGur
Copy link
Contributor

Добрый день!

Вопрос: как можно проверить факт текущей активности торгов для акций (TQBR) ?
Это необходимо, чтобы в ночью/выходные/праздники не делать лишних запросов к бирже.

Смотрю документацию:
https://iss.moex.com/iss/reference/28

Подставляю нужное:
https://iss.moex.com/iss/engines/stock/markets/shares/boards.xml

Тут есть флаг "is_traded". Это он отвечает за активность? Или путаю его с чем-то?

Пожалуйста, поделитесь, если есть другие решения для проверки активности?

@WLM1ke
Copy link
Owner

WLM1ke commented Jun 5, 2023

Я проверяю с помощью этого https://iss.moex.com/iss/reference/26

@AlekseyGur
Copy link
Contributor Author

Я проверяю с помощью этого https://iss.moex.com/iss/reference/26

Но там в "till" показываются дата последней дневной свечи. Например, сейчас 6 июня, а в "till" стоит 5 июня. Из этого не получится понять идут ли торги прямо сейчас, в эту минуту.

http://iss.moex.com/iss/history/engines/stock/markets/shares/boards/TQBR/dates.xml

Есть ли какой способ проверить, что торги идут прямо сейчас?

@AlekseyGur
Copy link
Contributor Author

AlekseyGur commented Jun 6, 2023

Получил ответ на свой вопрос от саппорта моекса (цитата):

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

Думаю, стоит добавить функцию, которая будет возвращать True/False, если биржа открыта/закрыта. Причём даты работы биржи должны браться с её самой (с учётом праздников/перенесённых и сокращённых дней). Где-то в api я уже видел подобные данные, но не могу найти их сейчас...

UPD.
Нашёл: https://iss.moex.com/iss/engines/stock.xml

@WLM1ke
Copy link
Owner

WLM1ke commented Jun 6, 2023

А для каких целей вам нужно знать идут ли торги сейчас. ISS не предназначен для получения данных в риалтайм. Данные отдаются с задержкой, и если их много раз полить в течении дня вас с высокой вероятностью забанят. Для этого лучше у брокеров канал запрашивать. И эта табличка вам не скажет про торги в субботу из-за переноса рабочих дней, насколько я понимаю

@AlekseyGur
Copy link
Contributor Author

У некоторых брокеров есть лимит на запросы. И иногда эти лимиты довольно малы, потому что надо как загрузить данные котировок, так и проверить/выставить позиции.

С моекса беру дневные и часовые свечи. Они приходят без задержек. У них только в общем доступе нет свечей на короткие периоды, на последние 15 минут.

P.S.
Про граничения. Например, у Тинькоффа ограничение 100 запросов в немонятно сколько минут. И беда со свечами: они открываются/закрываются не в начале/конце периода, а по первому/последнему тику, который может быть непонятно когда. Из-за этого много неудобств.

Пока писать глобальную очередь с задержками для системы торгов не хочу. Легче брать котировки с моекса.

@AlekseyGur
Copy link
Contributor Author

AlekseyGur commented Jun 6, 2023

И эта табличка вам не скажет про торги в субботу из-за переноса рабочих дней, насколько я понимаю

Насколько понимаю, скажет. Например, 5 марта 2022 года (суббота) биржа работала, запись об этом исключении есть:

row date="2022-03-05" is_work_day="1" start_time="06:20:00" stop_time="23:59:59"

Для получения этих данных предлагаю добавить следующий метод в requests:

def get_work_time(
    session: requests.Session,
    engine: str = "stock",
    table: str = "timetable",
):
    """Получить данные по датам активности торговых сессий.

    Описание запроса - https://iss.moex.com/iss/reference/41
    
    :param session:
        Сессия интернет соединения.
    :param engine:
        Движок - по умолчанию акции.
    :param table:
        Таблица с данными, которую нужно вернуть:
            timetable - флаги активности торгов на рабочую неделю,
            dailytable - исключения из торгов
            
    :return:
        Список словарей, которые напрямую конвертируется в pandas.DataFrame.
    """
    url = f"https://iss.moex.com/iss/engines/{engine}.json"
    query = _make_query(table=table)
    return _get_short_data(session, url, table, query)

Возможно, не стоит добавлять в систему именно функцию проверки активности торгов. Потому что логично в ней использовать кеширование результата. А все его делают по-разному. Но вот мой вариант реализации без кеширования:

def is_trading_active(
    session: requests.Session,
    engine: str = "stock",
) -> bool:
    """Делает проверку активны ли сейчас торги на бирже.
    
    :param session:
        Сессия интернет соединения.
    :param engine:
        Движок - по умолчанию акции.
        
    :return:
        True - торги идут прямо сейчас
        False - торги остановлены
    """
    
    from datetime import datetime, time
    from zoneinfo import ZoneInfo

    now = datetime.now(ZoneInfo('Europe/Moscow'))
    cur_weekday = now.weekday()+1 # нумерация дней на moex [1..7]
    cur_date = now.strftime("%Y-%m-%d")
    cur_time = now.time()

    # находится ли текущий день в исключениях, идут ли сейчас торги
    wt = get_work_time(session=session, engine=engine, table="dailytable")
    ar_res = [i for i in wt if i['date']==cur_date]

    if ar_res: # попали в исключение
        res = ar_res[-1]
        
        if not res['is_work_day']:
            return False # торгов сегодня вообще нет
        elif cur_time < time.fromisoformat(res['start_time']):
            return False # торги ещё не начались
        elif cur_time >= time.fromisoformat(res['stop_time']):
            return False # торги уже закончились
        else:
            return True # день-исключение, когда торги идут

    # идут ли торги в текущем дне недели, в текущее время
    wt = get_work_time(session=session, engine=engine, table="timetable")
    res = [i for i in wt if i['week_day']==cur_weekday][-1]
    
    if not res['is_work_day']:
        return False # торгов сегодня вообще нет
    elif cur_time < time.fromisoformat(res['start_time']):
        return False # торги ещё не начались
    elif cur_time >= time.fromisoformat(res['stop_time']):
        return False # торги уже закончились

    return True # торги идут

@WLM1ke
Copy link
Owner

WLM1ke commented Jun 6, 2023

Не знаю как сейчас, но раньше последняя свеча была битая - там все равно задержка 15 минут. Ну и проблема в том, что людей реально банили

@AlekseyGur
Copy link
Contributor Author

раньше последняя свеча была битая - там все равно задержка 15 минут

Интересная информация. Прослежу изменяются ли данные часовых свечей со временем.

Пожалуйста, подскажите, а откуда обычно берете котировки? С какого сервиса?

Сам сейчас качаю с моекса каждый час все 400 акций TQBR, их данные последней свечи (если предыдущая история есть). Раз в день качаю ещё и дневные свечи. Пока что ни разу не схватил бан от моекса, даже если загружаю историю дневных свечей за последние 10 лет по всем инструментам без задержек между запросами внутри инструмента. Поэтому ничего плохого вообще сказать про апи моекса не могу. Очень нравится, ни одного бана не полуил (тьфу-тьфу-тьфу).

А вот от Тинькоффа очень много банов словил. Например, чтобы открыть позицию надо сделать запрос на ордер, стоп лос, проверить портфолио несколько раз (до и после) и т.д. И всё это по каждой позиции. И если позиций штук 10 одновременно надо открыть, то легко лювлю бан. Их лимит непонятно как работает...

@WLM1ke
Copy link
Owner

WLM1ke commented Jun 6, 2023

Я сам не ловил, но люди ловили

Я торгую на дневках и качаю их раз в день в час ночи по 1000 бумагам с использованием асинхронной версии этой библиотеки - соответсвенно посылаю много конкурентных запросов одновременно

Просто ISS это все-таки не риал-тайм API, по нему нет никаких SLA и закладываться на него опасно

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants