commit ef0958239e883d6b308211b8ef43286b024a4998 Author: root Date: Sat Apr 18 23:26:45 2026 +0300 RAPTOR v18.4: Исправлена отчетность, активированы выходные diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a10444b --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +*.env +tok.env +state_prod.json +*.csv +*.log +venv/ +__pycache__/ diff --git a/audit_report.py b/audit_report.py new file mode 100644 index 0000000..ed5e813 --- /dev/null +++ b/audit_report.py @@ -0,0 +1,38 @@ +import os +from datetime import datetime, timedelta, timezone +from dotenv import load_dotenv +from t_tech.invest import Client + +os.environ['SSL_CERT_FILE'] = '/etc/ssl/certs/ca-certificates.crt' +os.environ['GRPC_DEFAULT_SSL_ROOTS_FILE_PATH'] = '/etc/ssl/certs/ca-certificates.crt' + +load_dotenv("/root/sber_bot/tok.env") +TOKEN = os.getenv("TINKOFF_TOKEN") + +def q_to_f(q): return q.units + q.nano/1e9 if q else 0 + +with Client(TOKEN, target="invest-public-api.tbank.ru:443") as client: + # 1. Загружаем справочник тикеров, чтобы не мучить API в цикле + instr_dict = {i.figi: i.ticker for i in client.instruments.shares().instruments} + accounts = client.users.get_accounts().accounts + + print(f"{'Дата (MSK)':<15} | {'Тикер':<6} | {'Тип':<8} | {'Цена':<8} | {'Кол':<4} | {'Сумма':<10}") + print("-" * 65) + + for acc in accounts: + ops = client.operations.get_operations( + account_id=acc.id, + from_=datetime.now(timezone.utc) - timedelta(days=7), + to=datetime.now(timezone.utc) + ).operations + + for o in ops: + if o.operation_type.name in ['OPERATION_TYPE_BUY', 'OPERATION_TYPE_SELL']: + ticker = instr_dict.get(o.figi, "N/A") + date = o.date.astimezone(timezone(timedelta(hours=3))).strftime("%d.%m %H:%M") + op_type = "BUY" if "BUY" in o.operation_type.name else "SELL" + price = q_to_f(o.price) + payment = q_to_f(o.payment) + + print(f"{date:<15} | {ticker:<6} | {op_type:<8} | {price:<8.2f} | {int(o.quantity):<4} | {payment:<10.2f}") +EOF diff --git a/bot.py b/bot.py new file mode 100644 index 0000000..5c55c07 --- /dev/null +++ b/bot.py @@ -0,0 +1,106 @@ +import time, os, requests, json, urllib3 +from datetime import datetime, timedelta, timezone, time as dtime +from dotenv import load_dotenv + +urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) +load_dotenv("tok.env") + +TOKEN = os.getenv("TINKOFF_TOKEN") +TG_TOKEN = os.getenv("TG_TOKEN") +TG_CHAT_ID = os.getenv("TG_CHAT_ID") +ACC_ID = os.getenv("ACCOUNT_ID") + +INSTRUMENT_UID = "a78b8349-a1dc-447d-9277-1d75826d089a" +BASE_URL = "https://invest-public-api.tbank.ru/rest" +STATE_FILE = "bot_state_prod.json" + +s = requests.Session() +s.headers.update({"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"}) + +def get_price(): + path = f"{BASE_URL}/tinkoff.public.invest.api.contract.v1.MarketDataService/GetLastPrices" + try: + r = s.post(path, json={"instrumentId": [INSTRUMENT_UID]}, timeout=5) + if r.status_code != 200: return None + res = r.json() + if 'lastPrices' in res and res['lastPrices']: + p = res['lastPrices'][0]['price'] + return int(p.get('units', 0)) + int(p.get('nano', 0)) / 1e9 + except: return None + return None + +def get_atr_steps(): + path = f"{BASE_URL}/tinkoff.public.invest.api.contract.v1.MarketDataService/GetCandles" + try: + now_utc = datetime.now(timezone.utc) + payload = { + "instrumentId": INSTRUMENT_UID, + "from": (now_utc - timedelta(days=2)).strftime('%Y-%m-%dT%H:%M:%SZ'), + "to": now_utc.strftime('%Y-%m-%dT%H:%M:%SZ'), + "interval": "CANDLE_INTERVAL_HOUR" + } + r = s.post(path, json=payload, timeout=10) + candles = r.json().get('candles', []) + if len(candles) < 2: return 1.1, 1.5 + + def to_f(p): return int(p.get('units', 0)) + int(p.get('nano', 0)) / 1e9 + trs = [to_f(c['high']) - to_f(c['low']) for c in candles[-14:]] + atr = sum(trs) / len(trs) + + buy_step = max(round(atr * 0.45, 2), 0.5) + return buy_step, round(buy_step * 1.2, 2) + except: return 1.1, 1.5 + +def post_order(direction): + path = f"{BASE_URL}/tinkoff.public.invest.api.contract.v1.OrdersService/PostOrder" + payload = { + "instrumentId": INSTRUMENT_UID, "quantity": 1, + "direction": direction, "orderType": "ORDER_TYPE_MARKET", + "accountId": ACC_ID, "orderId": f"p_{int(time.time())}" + } + try: + r = s.post(path, json=payload, timeout=10) + return r.status_code == 200 + except: return False + +def run(): + print("🚀 БОТ ЗАПУЩЕН") + state = {"phase": "BUY", "base_price": None} + if os.path.exists(STATE_FILE): + try: + with open(STATE_FILE, 'r') as f: state = json.load(f) + except: pass + + buy_step, profit_step = get_atr_steps() + + while True: + price = get_price() + if price: + if state['base_price'] is None: + state['base_price'] = price + with open(STATE_FILE, 'w') as f: json.dump(state, f) + print(f"\n🎯 База установлена: {price}") + + if state['phase'] == "BUY": + target = round(state['base_price'] - buy_step, 2) + else: + target = round(state['base_price'] + profit_step, 2) + + print(f"[{datetime.now().strftime('%H:%M:%S')}] Цена: {price:.2f} | Цель: {target:.2f} | {state['phase']} ", end='\r') + + if state['phase'] == "BUY" and price <= target: + if post_order("ORDER_DIRECTION_BUY"): + state.update({"phase": "SELL", "base_price": price}) + with open(STATE_FILE, 'w') as f: json.dump(state, f) + print(f"\n🛒 КУПЛЕНО по {price}") + + elif state['phase'] == "SELL" and price >= target: + if post_order("ORDER_DIRECTION_SELL"): + state.update({"phase": "BUY", "base_price": price}) + with open(STATE_FILE, 'w') as f: json.dump(state, f) + print(f"\n💰 ПРОДАНО по {price}") + + time.sleep(1) + +if __name__ == "__main__": + run() diff --git a/bot_state_prod.json b/bot_state_prod.json new file mode 100644 index 0000000..673a024 --- /dev/null +++ b/bot_state_prod.json @@ -0,0 +1 @@ +{"phase": "BUY", "base_price": 305.98} \ No newline at end of file diff --git a/check_acc.py b/check_acc.py new file mode 100644 index 0000000..833cbb1 --- /dev/null +++ b/check_acc.py @@ -0,0 +1,11 @@ +import os, requests, json +from dotenv import load_dotenv + +load_dotenv("tok.env") +TOKEN = os.getenv("TINKOFF_TOKEN") +URL = "https://sandbox-invest-public-api.tinkoff.ru/rest/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxAccounts" + +headers = {"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"} +r = requests.post(URL, json={}, headers=headers) + +print(json.dumps(r.json(), indent=4)) diff --git a/check_me.py b/check_me.py new file mode 100644 index 0000000..418b696 --- /dev/null +++ b/check_me.py @@ -0,0 +1,18 @@ +import os +from dotenv import load_dotenv +from t_tech.invest import Client + +load_dotenv("tok.env") +TOKEN = os.getenv("TINKOFF_TOKEN") + +with Client(TOKEN) as client: + accounts = client.users.get_accounts().accounts + print("--- ДОСТУПНЫЕ СЧЕТА ---") + for acc in accounts: + print(f"ID: {acc.id} | Имя: {acc.name} | Статус: {acc.status.name}") + + # Прямой запрос цены Сбера + price = client.market_data.get_last_prices(instrument_id=["a78b8349-a1dc-447d-9277-1d75826d089a"]) + p = price.last_prices[0].price + print(f"\n--- ЦЕНА ИЗ API ---") + print(f"Цена: {p.units + p.nano / 1e9} руб.") diff --git a/check_real.py b/check_real.py new file mode 100644 index 0000000..9cec40a --- /dev/null +++ b/check_real.py @@ -0,0 +1,28 @@ +import os +from dotenv import load_dotenv +from t_tech.invest import Client + +os.environ['SSL_CERT_FILE'] = '/etc/ssl/certs/ca-certificates.crt' +os.environ['GRPC_DEFAULT_SSL_ROOTS_FILE_PATH'] = '/etc/ssl/certs/ca-certificates.crt' + +load_dotenv("tok.env") +TOKEN = os.getenv("TINKOFF_TOKEN") + +with Client(TOKEN, target="invest-public-api.tbank.ru:443") as client: + # 1. Получаем инфо о счете + accounts = client.users.get_accounts().accounts + for acc in accounts: + print(f"\n--- ИНФОРМАЦИЯ О СЧЕТЕ ---") + print(f"Имя: {acc.name} | ID: {acc.id}") + print(f"Тип счета (API): {acc.type.name}") # Ищем ACCOUNT_TYPE_T_INVESTMENTS + + # 2. Проверяем баланс (реальный или фантики) + p = client.operations.get_portfolio(account_id=acc.id) + print(f"Баланс: {p.total_amount_currencies.units} {p.total_amount_currencies.currency}") + + # 3. Проверяем цену Сбера по актуальному UID + SBER_UID = "e6123145-9665-43e0-8413-cd61b8aa9b13" + lp = client.market_data.get_last_prices(instrument_id=[SBER_UID]).last_prices[0] + print(f"\n--- ПРОВЕРКА РЫНКА ---") + print(f"Цена SBER в API: {lp.price.units + lp.price.nano / 1e9}") + print(f"Дата цены (UTC): {lp.time.strftime('%Y-%m-%d %H:%M:%S')}") diff --git a/cloudflared.deb b/cloudflared.deb new file mode 100644 index 0000000..6b63ace Binary files /dev/null and b/cloudflared.deb differ diff --git a/config.json b/config.json new file mode 100644 index 0000000..277fd9b --- /dev/null +++ b/config.json @@ -0,0 +1,21 @@ +{ + "TICKER": "SBER", + "CLASS_CODE": "TQBR", + "ACCOUNT_ID": "2009330616", + "MAX_TICKER_BUDGET": 50000, + "WEB_PORT": 5000, + "DCA_STEPS": [0.15, 0.15, 0.2, 0.2, 0.3], + "RISK_FRACTION": 0.95, + "STEP_DISTANCE_ATR": 1.0, + "ATR_COEFF": 0.5, + "PROFIT_COEFF": 2.5, + "SL_COEFF": 2.0, + "TRAILING_REBOUND": 0.3, + "EARLY_EXIT_PCT": 0.010, + "RSI_BUY_THRESHOLD": 42, + "TREND_CANDLES": 20, + "COOLDOWN_MINUTES": 60, + "MAX_HOLD_HOURS": 48, + "DAILY_LOSS_LIMIT": -600, + "MAX_SPREAD": 0.0015 +} diff --git a/diag_session.py b/diag_session.py new file mode 100644 index 0000000..11a110e --- /dev/null +++ b/diag_session.py @@ -0,0 +1,48 @@ +import os +from datetime import datetime, timezone +from dotenv import load_dotenv +from t_tech.invest import Client, InstrumentIdType + +# Настройка SSL для российских сертификатов (уже настроена на вашем сервере) +os.environ['SSL_CERT_FILE'] = '/etc/ssl/certs/ca-certificates.crt' +os.environ['GRPC_DEFAULT_SSL_ROOTS_FILE_PATH'] = '/etc/ssl/certs/ca-certificates.crt' + +load_dotenv("tok.env") +TOKEN = os.getenv("TINKOFF_TOKEN") +SBER_UID = "a78b8349-a1dc-447d-9277-1d75826d089a" + +print("\n--- ЗАПУСК ДЕТЕКТОРА ЛЖИ API ---") + +try: + with Client(TOKEN, target="invest-public-api.tbank.ru:443") as client: + # 1. Проверяем статус торгов прямо сейчас + status = client.market_data.get_trading_status(instrument_id=SBER_UID) + print(f"🔹 Статус торгов: {status.trading_status.name}") + + # 2. Запрашиваем цену и ВРЕМЯ этой цены + lp_resp = client.market_data.get_last_prices(instrument_id=[SBER_UID]) + lp = lp_resp.last_prices[0] + actual_price = lp.price.units + lp.price.nano / 1e9 + + print(f"\n🔹 Цена в API: {actual_price} руб.") + print(f"🔹 Время цены (UTC): {lp.time.strftime('%Y-%m-%d %H:%M:%S')}") + + # Сравниваем время + now_utc = datetime.now(timezone.utc) + print(f"🔹 Ваше время (UTC): {now_utc.strftime('%Y-%m-%d %H:%M:%S')}") + + # 3. Список ваших счетов + accounts = client.users.get_accounts().accounts + print("\n--- ВАШИ ДОСТУПНЫЕ СЧЕТА ---") + for acc in accounts: + portfolio = client.operations.get_portfolio(account_id=acc.id) + print(f"ID: {acc.id} | Имя: {acc.name:10} | Тип: {acc.type.name} | Баланс: {portfolio.total_amount_currencies.units} руб.") + + if actual_price < 310: + print("\n🚨 ЗАКЛЮЧЕНИЕ: Ваш API-токен подключен к ДЕМО-КОНТУРУ.") + print("Цена 305.98 — это исторические данные мая 2024 года.") + else: + print("\n📈 ЗАКЛЮЧЕНИЕ: Вы на реальном рынке.") + +except Exception as e: + print(f"\n❌ ОШИБКА: {e}") diff --git a/final_audit.py b/final_audit.py new file mode 100644 index 0000000..7ff47a5 --- /dev/null +++ b/final_audit.py @@ -0,0 +1,53 @@ +import os +from datetime import datetime, timedelta, timezone +from dotenv import load_dotenv +from t_tech.invest import Client + +# Настройка SSL для вашего сервера +os.environ['SSL_CERT_FILE'] = '/etc/ssl/certs/ca-certificates.crt' +os.environ['GRPC_DEFAULT_SSL_ROOTS_FILE_PATH'] = '/etc/ssl/certs/ca-certificates.crt' + +load_dotenv("/root/sber_bot/tok.env") +TOKEN = os.getenv("TINKOFF_TOKEN") + +def q_to_f(q): + if not q: return 0.0 + return q.units + q.nano/1e9 + +with Client(TOKEN, target="invest-public-api.tbank.ru:443") as client: + # 1. Загружаем справочник акций, чтобы знать тикеры + print("⏳ Загрузка справочника инструментов...") + shares = client.instruments.shares().instruments + ticker_map = {s.uid: s.ticker for s in shares} + figi_map = {s.figi: s.ticker for s in shares} + + # 2. Получаем все счета + accounts = client.users.get_accounts().accounts + + print(f"\n{'ДАТА (MSK)':<15} | {'СЧЕТ':<15} | {'ТИКЕР':<6} | {'ТИП':<12} | {'СУММА':<12}") + print("-" * 70) + + for acc in accounts: + # Запрашиваем абсолютно все операции за 14 дней + ops = client.operations.get_operations( + account_id=acc.id, + from_=datetime.now(timezone.utc) - timedelta(days=14), + to=datetime.now(timezone.utc) + ).operations + + for o in ops: + ticker = ticker_map.get(o.instrument_uid) or figi_map.get(o.figi) or "" + + # Нам интересны только Сбер, Татнефть и движение денег + is_target = any(t in ticker for t in ["SBER", "TATN"]) + is_money = "PAYMENT" in o.operation_type.name or "DEPOSIT" in o.operation_type.name + + if is_target or is_money: + date = o.date.astimezone(timezone(timedelta(hours=3))).strftime("%d.%m %H:%M") + op_name = o.type + payment = q_to_f(o.payment) + + # Если это покупка/продажа, добавим цену для наглядности + price_str = f" @ {q_to_f(o.price):.2f}" if q_to_f(o.price) > 0 else "" + + print(f"{date:<15} | {acc.name[:15]:<15} | {ticker:<6} | {op_name[:12]:<12} | {payment:>10.2f} RUB {price_str}") diff --git a/final_bot.py b/final_bot.py new file mode 100644 index 0000000..5902e5e --- /dev/null +++ b/final_bot.py @@ -0,0 +1,318 @@ +import os, json, time, uuid, logging, requests, threading, csv +from datetime import datetime, timedelta, timezone, time as dtime +from flask import Flask, render_template_string +from dotenv import load_dotenv + +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +load_dotenv(os.path.join(BASE_DIR, "tok.env")) +logging.basicConfig( + level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s", + handlers=[logging.FileHandler(os.path.join(BASE_DIR, "bot.log")), logging.StreamHandler()] +) +os.environ['SSL_CERT_FILE'] = '/etc/ssl/certs/ca-certificates.crt' +os.environ['GRPC_DEFAULT_SSL_ROOTS_FILE_PATH'] = '/etc/ssl/certs/ca-certificates.crt' + +from t_tech.invest import Client, OrderDirection, OrderType, CandleInterval, InstrumentIdType + +MSK_TZ, STATE_FILE, CONFIG_FILE, TRADE_LOG, TELEMETRY_LOG = timezone(timedelta(hours=3)), os.path.join(BASE_DIR, "state_prod.json"), os.path.join(BASE_DIR, "config.json"), os.path.join(BASE_DIR, "trades.csv"), os.path.join(BASE_DIR, "market_telemetry.csv") +state_lock, TG_PROXY = threading.Lock(), "https://muddy-firefly-3862.y-afanasiev.workers.dev" + +def q_to_float(q): return q.units + q.nano / 1e9 if q else 0.0 + +def load_config(): + try: + with open(CONFIG_FILE, 'r') as f: return json.load(f) + # FIX: Добавлен ACCOUNT_ID в fallback для защиты от KeyError + except: return {"TICKER": "UNKNOWN", "WEB_PORT": 5000, "ACCOUNT_ID": ""} + +def save_state_atomic(state): + tmp = STATE_FILE + ".tmp" + with state_lock: + try: + with open(tmp, 'w') as f: json.dump(state, f, indent=2) + os.replace(tmp, STATE_FILE) + except Exception as e: logging.error(f"Save Error: {e}") + +def send_tg(msg, level="INFO"): + token, chat_id = os.getenv("TG_TOKEN"), os.getenv("TG_CHAT_ID") + if not token or not chat_id: return + icons = {"TRADE":"🛒","PROFIT":"💰","LOSS":"🩸","CRIT":"🚨","INFO":"🛰️","AI":"🧠"} + try: requests.post(f"{TG_PROXY}/bot{token}/sendMessage", json={"chat_id": chat_id, "text": f"{icons.get(level,'🤖')} *{level}*\n{msg}", "parse_mode": "Markdown"}, timeout=15) + except: pass + +def send_tg_report(file_path, caption=""): + token, chat_id = os.getenv("TG_TOKEN"), os.getenv("TG_CHAT_ID") + if not token or not chat_id or not os.path.exists(file_path): return + try: + with open(file_path, 'rb') as f: + requests.post(f"{TG_PROXY}/bot{token}/sendDocument", data={"chat_id": chat_id, "caption": caption}, files={"document": f}, timeout=30) + except: pass + +def calc_rsi(closes, period=14): + if len(closes) < period + 1: return 50.0 + gains, losses = [max(closes[i] - closes[i-1], 0) for i in range(1, len(closes))], [max(closes[i-1] - closes[i], 0) for i in range(1, len(closes))] + ag, al = sum(gains[-period:]) / period, sum(losses[-period:]) / period + return round(100 - 100 / (1 + ag / al), 1) if al > 0 else 100.0 + +def log_trade(action, price, lots, shares, reason="", pnl=0): + exists = os.path.isfile(TRADE_LOG) + with open(TRADE_LOG, 'a', newline='') as f: + w = csv.writer(f) + if not exists: w.writerow(["Date","Action","Price","Lots","Shares","Reason","PnL"]) + w.writerow([datetime.now(MSK_TZ).strftime("%Y-%m-%d %H:%M:%S"), action, price, lots, shares, reason, pnl]) + +def log_telemetry(ticker, price, rsi, trend, spread, vola): + exists = os.path.isfile(TELEMETRY_LOG) + with open(TELEMETRY_LOG, 'a', newline='') as f: + w = csv.writer(f) + if not exists: w.writerow(["Time","Ticker","Price","RSI","Trend","Spread","Vola%"]) + w.writerow([datetime.now(MSK_TZ).strftime("%H:%M:%S"), ticker, price, rsi, trend, spread, vola]) + +def generate_ai_prompt(conf): + prompt_file = os.path.join(BASE_DIR, "AI_PROMPT_WEEKLY.txt") + try: + with open(prompt_file, 'w') as f: + f.write("SYSTEM ROLE: Квантовый финансовый аналитик.\n") + f.write(f"TASK: Проанализировать работу торгового бота RAPTOR для тикера {conf.get('TICKER', 'UNKNOWN')}.\n\n") + f.write("--- CURRENT CONFIG ---\n") + # FIX: Вырезаем приватные данные перед отправкой ИИ + safe_conf = {k: v for k, v in conf.items() if k not in ('ACCOUNT_ID', 'TINKOFF_TOKEN')} + f.write(json.dumps(safe_conf, indent=2) + "\n\n") + f.write("--- LAST TRADES ---\n") + if os.path.exists(TRADE_LOG): + with open(TRADE_LOG, 'r') as tl: f.writelines(tl.readlines()[-10:]) + f.write("\n--- MARKET CONTEXT (Last Telemetry) ---\n") + if os.path.exists(TELEMETRY_LOG): + with open(TELEMETRY_LOG, 'r') as ml: f.writelines(ml.readlines()[-10:]) + f.write("\nQUESTION: На основе данных выше, предложи оптимизацию ATR_COEFF или STEP_DISTANCE_ATR.\n") + return prompt_file + except: return None + +app = Flask(__name__) +@app.route('/') +def index(): + now_tz = datetime.now(MSK_TZ) + # FIX: Оставили работу в выходные (без now_tz.weekday() > 4) + is_open = any([dtime(7, 0) <= now_tz.time() <= dtime(18, 45), dtime(19, 0) <= now_tz.time() <= dtime(23, 50)]) + time_str = now_tz.strftime("%H:%M:%S") + + def get_st(p): + # FIX: Добавлена last_vola в дефолтный словарь + d = {"phase":"OFFLINE","live_price":0,"total_shares":0,"current_step":0,"avg_price":0,"target_act":0,"profit_goal":0,"pnl":0,"daily_pnl":0,"deals_today":0,"trend":"N/A","last_rsi":50,"filter_status":"N/A","stop_loss":0,"last_atr":0,"last_vola":0.0} + try: + if os.path.exists(p): + with open(p, 'r') as f: data = json.load(f); d.update(data) + sh, lp, ap = d.get('total_shares', 0), d.get('live_price', 0), d.get('avg_price', 0) + d['pnl'] = round((lp - ap) * sh, 2) if sh > 0 else 0 + if d['phase'] == "SELL" and d.get('profit_goal', 0) > 0: + d['progress'] = round(min(100, max(0, (lp - ap) / (d['profit_goal'] - ap) * 100)), 1) + elif d['phase'] == "BUY" and d.get('target_act', 0) > 0: + base = d.get('base_price', lp) + if base - d['target_act'] != 0: d['progress'] = round(min(100, max(0, (base - lp) / (base - d['target_act']) * 100)), 1) + else: d['progress'] = 0 + else: d['progress'] = 0 + except: pass + return d + + sber = get_st("/root/sber_bot/state_prod.json") + gmkn = get_st("/root/gmkn_bot/state_prod.json") + + return render_template_string("""RAPTOR v18.4 UI + +
+

RAPTOR v18.4

+
+ {% if is_open %} + 🟢 РЫНОК ОТКРЫТ (Торги выходного дня) + {% else %} + 🔴 РЫНОК ЗАКРЫТ + {% endif %} + Сервер (МСК): {{ time_str }} +
+
+{% for n, d in [('SBER', sber), ('GMKN', gmkn)] %} +
{{ n }}{{ d.phase }} [ст.{{ d.current_step }}]
+
{{ d.live_price }}
+
{{ d.pnl }} ₽
+
+
+
Avg / Stop{{ d.avg_price }} / {{ d.stop_loss }}
+
Target (TP){{ d.profit_goal }}
+
Следующий вход{{ d.target_act }}
+
ATR / RSI / Vola{{ d.last_atr }} / {{ d.last_rsi }} / {{ d.last_vola }}%
+
Тренд / Фильтр{{ d.trend }} / {{ d.filter_status }}
+
Сделок / P&L дня{{ d.deals_today }} / {{ d.daily_pnl }} ₽
+
{% endfor %}
""", sber=sber, gmkn=gmkn, is_open=is_open, time_str=time_str) + +def is_market_open(): + now = datetime.now(MSK_TZ) + t = now.time() + # FIX: Торги выходного дня (работает 7 дней в неделю) + return any([dtime(7, 0) <= t <= dtime(18, 45), dtime(19, 0) <= t <= dtime(23, 50)]) + +def run_bot(): + conf = load_config() + acc_id = conf.get("ACCOUNT_ID", "") + if not acc_id: logging.warning("ACCOUNT_ID не задан в config.json!") + + state = {"phase": "BUY", "current_step": 0, "base_price": None, "live_price": 0, "total_shares": 0, "total_lots": 0, "avg_price": 0, "tp_activated": False, "target_act": 0, "profit_goal": 0, "stop_loss": 0, "max_p": 0, "buy_time_ts": 0, "last_sell_ts": 0, "deals_today": 0, "daily_pnl": 0.0, "last_date": str(datetime.now(MSK_TZ).date()), "trend": "WAIT", "last_rsi": 50, "filter_status": "INIT", "lot_size": 1, "last_atr": 0.0, "last_vola": 0.0, "reported": -1, "partial_sold": False, "ai_reported": -1} + if os.path.exists(STATE_FILE): + try: + with open(STATE_FILE, 'r') as f: state.update(json.load(f)) + except: pass + + with Client(os.getenv("TINKOFF_TOKEN"), target="invest-public-api.tbank.ru:443") as client: + try: + instr = client.instruments.share_by(id_type=InstrumentIdType.INSTRUMENT_ID_TYPE_TICKER, class_code=conf.get("CLASS_CODE", "TQBR"), id=conf.get("TICKER", "UNKNOWN")).instrument + target_uid, lot_size, min_inc = instr.uid, instr.lot, q_to_float(instr.min_price_increment) + state['lot_size'] = lot_size + except Exception as e: + logging.error(f"Init Error: {e}"); return + + last_indicators_ts = last_telemetry_ts = 0; atr = 2.0 + + while True: + try: + now = datetime.now(MSK_TZ) + if str(now.date()) != state.get('last_date'): + state.update({"deals_today": 0, "daily_pnl": 0.0, "last_date": str(now.date()), "reported": -1}) + + if now.hour == 23 and now.minute == 55 and state.get('reported') != now.day: + send_tg(f"📊 {conf['TICKER']} итог {now.strftime('%d.%m')}:\nСделок: {state['deals_today']}\nP&L дня: {state['daily_pnl']:+.0f} ₽", "INFO") + send_tg_report(TRADE_LOG, f"{conf['TICKER']} Trades") + state['reported'] = now.day; save_state_atomic(state) + + if now.weekday() == 6 and now.hour == 21 and state.get('ai_reported') != now.isocalendar()[1]: + prompt_path = generate_ai_prompt(conf) + if prompt_path: + send_tg(f"🧠 Сформирован бриф ИИ по {conf['TICKER']}.", "AI") + send_tg_report(prompt_path, f"AI Prompt {conf['TICKER']}") + state['ai_reported'] = now.isocalendar()[1]; save_state_atomic(state) + + if acc_id: + portfolio = client.operations.get_portfolio(account_id=acc_id) + pos = next((p for p in portfolio.positions if p.instrument_uid == target_uid), None) + state['total_shares'], state['total_lots'] = (int(q_to_float(pos.quantity)), int(q_to_float(pos.quantity)) // lot_size) if pos else (0, 0) + if pos and state['avg_price'] == 0: state['avg_price'] = q_to_float(pos.average_position_price) + + if state['total_shares'] == 0 and state['phase'] == "SELL": + state.update({"phase": "BUY", "current_step": 0, "avg_price": 0, "tp_activated": False, "max_p": 0, "buy_time_ts": 0, "profit_goal": 0, "stop_loss": 0, "partial_sold": False}) + + cur_p = q_to_float(client.market_data.get_last_prices(instrument_id=[target_uid]).last_prices[0].price) + + # FIX: Безопасная инициализация base_price ТОЛЬКО если цена > 0.1 + if cur_p > 0.1: + state['live_price'] = cur_p + if state.get('base_price') is None: + state['base_price'] = cur_p + + if not is_market_open(): save_state_atomic(state); time.sleep(60); continue + + if time.time() - last_indicators_ts > 900: + c = client.market_data.get_candles(instrument_id=target_uid, from_=datetime.now(timezone.utc) - timedelta(days=5), to=datetime.now(timezone.utc), interval=CandleInterval.CANDLE_INTERVAL_HOUR).candles + if len(c) >= 20: + closes = [q_to_float(x.close) for x in c] + state['trend'] = "UP" if cur_p > (sum(closes[-conf.get("TREND_CANDLES", 20):]) / conf.get("TREND_CANDLES", 20)) else "DOWN" + state['last_rsi'] = calc_rsi(closes) + trs = [max(q_to_float(c[i].high) - q_to_float(c[i].low), abs(q_to_float(c[i].high) - q_to_float(c[i-1].close))) for i in range(1, len(c))] + atr = sum(trs[-14:]) / 14; state['last_atr'] = round(atr, 2) + state['last_vola'] = round((atr / cur_p) * 100, 2) + last_indicators_ts = time.time() + + if time.time() - last_telemetry_ts > 900: + try: + ob = client.market_data.get_order_book(instrument_id=target_uid, depth=1) + spread = round((q_to_float(ob.asks[0].price) - q_to_float(ob.bids[0].price)) / q_to_float(ob.bids[0].price) * 100, 4) if ob.asks and ob.bids else 0.0 + log_telemetry(conf["TICKER"], cur_p, state.get('last_rsi', 50), state.get('trend', 'WAIT'), spread, state.get('last_vola', 0)) + except: pass + last_telemetry_ts = time.time() + + buy_step = max(round(atr * conf.get("ATR_COEFF", 0.5), 2), conf.get("MIN_BUY_STEP", 1.0)) + + if state['total_lots'] > 0: + state['phase'] = "SELL" + if state.get('max_p', 0) == 0: state['max_p'] = state['avg_price'] + if cur_p > state.get('max_p', 0): state['max_p'] = cur_p + sl_price = round(state['avg_price'] - buy_step * conf["SL_COEFF"], 2) + if state.get('tp_activated') or state.get('partial_sold'): + sl_price = max(sl_price, round(state['avg_price'] * 1.0008, 2)) + state['stop_loss'] = sl_price + if not state.get('profit_goal'): + tp_mult = conf["PROFIT_COEFF"] if state['trend'] == "UP" else conf["PROFIT_COEFF"] * 0.7 + state['profit_goal'] = round(state['avg_price'] + buy_step * tp_mult, 2) + if cur_p >= state['profit_goal']: state['tp_activated'] = True + rebound = max(buy_step * conf["TRAILING_REBOUND"], min_inc * 3) + is_tp, is_sl = state.get('tp_activated') and cur_p <= state['max_p'] - rebound, cur_p <= sl_price + is_time = state.get('buy_time_ts', 0) > 0 and now.timestamp() > state['buy_time_ts'] + conf["MAX_HOLD_HOURS"] * 3600 + + if not state.get('partial_sold') and state['total_lots'] >= 2 and cur_p >= state['avg_price'] * (1 + conf.get("EARLY_EXIT_PCT", 0.01)): + qty_to_sell = state['total_lots'] // 2 + res = client.orders.post_order(instrument_id=target_uid, quantity=qty_to_sell, direction=OrderDirection.ORDER_DIRECTION_SELL, account_id=acc_id, order_type=OrderType.ORDER_TYPE_MARKET, order_id=str(uuid.uuid4())) + p_sold = q_to_float(res.executed_order_price) or cur_p + pnl = round((p_sold - state['avg_price']) * (qty_to_sell * lot_size), 2) + state['daily_pnl'] = round(state.get('daily_pnl', 0) + pnl, 2) + # FIX: Убран deals_today += 1 при частичной продаже (по замечанию аудитора) + state['partial_sold'] = True + log_trade("PARTIAL_SELL", p_sold, qty_to_sell, qty_to_sell * lot_size, "EarlyExit", pnl) + send_tg(f"💰 {conf['TICKER']} Частичная фиксация 50%\nP&L: {pnl:+.2f} ₽", "PROFIT") + + if is_tp or is_sl or is_time: + reason = ("TP" if is_tp else ("SL" if is_sl else "TIME")) + res = client.orders.post_order(instrument_id=target_uid, quantity=state['total_lots'], direction=OrderDirection.ORDER_DIRECTION_SELL, account_id=acc_id, order_type=OrderType.ORDER_TYPE_MARKET, order_id=str(uuid.uuid4())) + p_sold = q_to_float(res.executed_order_price) or cur_p + pnl = round((p_sold - state['avg_price']) * state['total_shares'], 2) + state['daily_pnl'] = round(state.get('daily_pnl', 0) + pnl, 2); state['deals_today'] += 1 + log_trade("SELL", p_sold, state['total_lots'], state['total_shares'], reason, pnl) + send_tg(f"{conf['TICKER']} [{reason}]\nP&L: {pnl:+.2f} ₽", "PROFIT" if pnl > 0 else "LOSS") + state.update({"phase": "BUY", "current_step": 0, "total_shares": 0, "total_lots": 0, "avg_price": 0, "tp_activated": False, "max_p": 0, "stop_loss": 0, "profit_goal": 0, "buy_time_ts": 0, "base_price": cur_p, "last_sell_ts": now.timestamp(), "partial_sold": False}) + + if state['phase'] == "BUY": + if state.get('daily_pnl', 0) <= conf["DAILY_LOSS_LIMIT"]: + state['filter_status'] = f"LIMIT {state['daily_pnl']:.0f}₽"; save_state_atomic(state); time.sleep(300); continue + step = state['current_step'] + cooldown_ok, trend_ok, rsi_ok = now.timestamp() > state.get('last_sell_ts', 0) + conf["COOLDOWN_MINUTES"] * 60, state.get('trend') == "UP", state.get('last_rsi', 50) < conf["RSI_BUY_THRESHOLD"] + filters_ok = (cooldown_ok and trend_ok and rsi_ok) if step == 0 else True + + # FIX: Корректный статус фильтра для дашборда на шагах DCA > 0 + if step > 0: + state['filter_status'] = f"Ожидание DCA ст.{step+1}" + else: + if not cooldown_ok: state['filter_status'] = "COOLDOWN" + elif not trend_ok: state['filter_status'] = "TREND DOWN" + elif not rsi_ok: state['filter_status'] = f"RSI {state.get('last_rsi', 50):.0f}" + else: state['filter_status'] = "OK" + + if filters_ok and step < len(conf.get("DCA_STEPS", [])): + if step == 0 and cur_p > state.get('base_price', cur_p): state['base_price'] = cur_p + state['target_act'] = round(state['base_price'] - (buy_step * conf.get("STEP_DISTANCE_ATR", 1.0)) * (step + 1), 2) + if cur_p <= state['target_act'] and acc_id: + step_budget = conf["MAX_TICKER_BUDGET"] * conf["DCA_STEPS"][step] * conf["RISK_FRACTION"] + qty = int(step_budget // (cur_p * lot_size)) + if qty >= 1: + res = client.orders.post_order(instrument_id=target_uid, quantity=qty, direction=OrderDirection.ORDER_DIRECTION_BUY, account_id=acc_id, order_type=OrderType.ORDER_TYPE_MARKET, order_id=str(uuid.uuid4())) + p_bought = q_to_float(res.executed_order_price) or cur_p + if state['buy_time_ts'] == 0: state['buy_time_ts'] = now.timestamp() + state['current_step'] += 1 + log_trade("BUY", p_bought, qty, qty * lot_size, f"Step{state['current_step']}") + send_tg(f"🛒 {conf['TICKER']} шаг {state['current_step']} @ {p_bought:.2f}", "TRADE") + elif step == 0: state['target_act'] = round(state['base_price'] - buy_step, 2) + save_state_atomic(state); time.sleep(2) + except Exception as e: logging.error(f"Loop Error: {e}"); time.sleep(10) + +if __name__ == "__main__": + conf_main = load_config() + threading.Thread(target=lambda: app.run(host='0.0.0.0', port=conf_main.get("WEB_PORT", 5000), use_reloader=False), daemon=True).start() + while True: + try: run_bot() + except KeyboardInterrupt: break + except Exception as e: logging.error(f"Fatal: {e}"); time.sleep(10) diff --git a/find_new_acc.py b/find_new_acc.py new file mode 100644 index 0000000..bbb2608 --- /dev/null +++ b/find_new_acc.py @@ -0,0 +1,42 @@ +import os +from dotenv import load_dotenv +from t_tech.invest import Client + +# Настройка SSL для работы с российскими сертификатами (уже настроена на вашем сервере) +os.environ['SSL_CERT_FILE'] = '/etc/ssl/certs/ca-certificates.crt' +os.environ['GRPC_DEFAULT_SSL_ROOTS_FILE_PATH'] = '/etc/ssl/certs/ca-certificates.crt' + +load_dotenv("tok.env") +TOKEN = os.getenv("TINKOFF_TOKEN") +SBER_UID = "a78b8349-a1dc-447d-9277-1d75826d089a" + +print("\n--- СКАНИРОВАНИЕ ОБНОВЛЕННОГО ДОСТУПА ---") + +try: + # Подключаемся к НОВОМУ боевому адресу из документации + with Client(TOKEN, target="invest-public-api.tbank.ru:443") as client: + + # 1. Запрашиваем цену и ВРЕМЯ этой цены + price_resp = client.market_data.get_last_prices(instrument_id=[SBER_UID]) + lp = price_resp.last_prices[0] + actual_price = lp.price.units + lp.price.nano / 1e9 + price_date = lp.time + + print(f"🌍 ТЕКУЩАЯ ЦЕНА В API: {actual_price} руб.") + print(f"📅 ДАТА ЦЕНЫ В API: {price_date.strftime('%Y-%m-%d %H:%M:%S')} UTC") + + if actual_price < 310: + print("\n🚨 ВНИМАНИЕ: Цена всё еще ИСТОРИЧЕСКАЯ (305 руб). Проблема в аккаунте!") + else: + print("\n✅ УРА! API показывает РЕАЛЬНУЮ рыночную цену!") + + # 2. Получаем список всех счетов (ищем новый ACCOUNT_ID) + accounts = client.users.get_accounts().accounts + print("\n--- СПИСОК ВАШИХ СЧЕТОВ ---") + for acc in accounts: + print(f"🔹 Имя: {acc.name:15} | ID: {acc.id}") + print(f" Тип: {acc.type.name:20} | Статус: {acc.status.name}") + print("-" * 50) + +except Exception as e: + print(f"\n❌ ОШИБКА: {e}") diff --git a/find_real_id.py b/find_real_id.py new file mode 100644 index 0000000..632e055 --- /dev/null +++ b/find_real_id.py @@ -0,0 +1,33 @@ +import os +from dotenv import load_dotenv +from t_tech.invest import Client + +# Настройка SSL +os.environ['SSL_CERT_FILE'] = '/etc/ssl/certs/ca-certificates.crt' +os.environ['GRPC_DEFAULT_SSL_ROOTS_FILE_PATH'] = '/etc/ssl/certs/ca-certificates.crt' + +load_dotenv("tok.env") +TOKEN = os.getenv("TINKOFF_TOKEN") + +with Client(TOKEN, target="invest-public-api.tbank.ru:443") as client: + # Получаем цену из котировок (MarketData) + price_resp = client.market_data.get_last_prices(instrument_id=["a78b8349-a1dc-447d-9277-1d75826d089a"]) + market_price = price_resp.last_prices[0].price + actual_price = market_price.units + market_price.nano / 1e9 + + print(f"\n--- ПРОВЕРКА РЫНКА ---") + print(f"Текущая цена SBER в API: {actual_price} руб.") + + # Получаем список всех счетов + accounts = client.users.get_accounts().accounts + print("\n--- ВАШИ СЧЕТА ---") + for acc in accounts: + # Запрашиваем баланс по каждому счету + portfolio = client.operations.get_portfolio(account_id=acc.id) + balance = portfolio.total_amount_currencies.units + print(f"Счет: {acc.name:15} | ID: {acc.id} | Баланс: {balance} руб. | Тип: {acc.type.name}") + + print("\n--- ИНСТРУКЦИЯ ---") + print("1. Если цена выше 310 — API отдает реальные данные.") + print("2. Найдите счет, где ваш РЕАЛЬНЫЙ баланс (не 0 и не 1 000 000 виртуальных рублей).") + print("3. Скопируйте его ID в tok.env.") diff --git a/full_audit.py b/full_audit.py new file mode 100644 index 0000000..14c9977 --- /dev/null +++ b/full_audit.py @@ -0,0 +1,37 @@ +import os +from datetime import datetime, timedelta, timezone +from dotenv import load_dotenv +from t_tech.invest import Client + +os.environ['SSL_CERT_FILE'] = '/etc/ssl/certs/ca-certificates.crt' +os.environ['GRPC_DEFAULT_SSL_ROOTS_FILE_PATH'] = '/etc/ssl/certs/ca-certificates.crt' + +load_dotenv("/root/sber_bot/tok.env") +TOKEN = os.getenv("TINKOFF_TOKEN") + +def q_to_f(q): return q.units + q.nano/1e9 if q else 0 + +with Client(TOKEN, target="invest-public-api.tbank.ru:443") as client: + # 1. Загружаем справочник тикеров, чтобы не мучить API в цикле + instr_dict = {i.figi: i.ticker for i in client.instruments.shares().instruments} + accounts = client.users.get_accounts().accounts + + print(f"{'Дата (MSK)':<15} | {'Тикер':<6} | {'Тип':<8} | {'Цена':<8} | {'Кол':<4} | {'Сумма':<10}") + print("-" * 65) + + for acc in accounts: + ops = client.operations.get_operations( + account_id=acc.id, + from_=datetime.now(timezone.utc) - timedelta(days=7), + to=datetime.now(timezone.utc) + ).operations + + for o in ops: + if o.operation_type.name in ['OPERATION_TYPE_BUY', 'OPERATION_TYPE_SELL']: + ticker = instr_dict.get(o.figi, "N/A") + date = o.date.astimezone(timezone(timedelta(hours=3))).strftime("%d.%m %H:%M") + op_type = "BUY" if "BUY" in o.operation_type.name else "SELL" + price = q_to_f(o.price) + payment = q_to_f(o.payment) + + print(f"{date:<15} | {ticker:<6} | {op_type:<8} | {price:<8.2f} | {int(o.quantity):<4} | {payment:<10.2f}") diff --git a/full_audit_v2.py b/full_audit_v2.py new file mode 100644 index 0000000..f6b9d8d --- /dev/null +++ b/full_audit_v2.py @@ -0,0 +1,41 @@ +import os +from datetime import datetime, timedelta, timezone +from dotenv import load_dotenv +from t_tech.invest import Client + +os.environ['SSL_CERT_FILE'] = '/etc/ssl/certs/ca-certificates.crt' +os.environ['GRPC_DEFAULT_SSL_ROOTS_FILE_PATH'] = '/etc/ssl/certs/ca-certificates.crt' + +load_dotenv("/root/sber_bot/tok.env") +TOKEN = os.getenv("TINKOFF_TOKEN") + +def q_to_f(q): return q.units + q.nano/1e9 if q else 0 + +with Client(TOKEN, target="invest-public-api.tbank.ru:443") as client: + # Загружаем тикеры + shares = client.instruments.shares().instruments + ticker_map = {s.uid: s.ticker for s in shares} + figi_map = {s.figi: s.ticker for s in shares} + + accounts = client.users.get_accounts().accounts + + print(f"{'Дата (MSK)':<15} | {'Счет':<12} | {'Тикер':<6} | {'Тип':<5} | {'Цена':<8} | {'Сумма':<10}") + print("-" * 80) + + for acc in accounts: + ops = client.operations.get_operations( + account_id=acc.id, + from_=datetime.now(timezone.utc) - timedelta(days=10), + to=datetime.now(timezone.utc) + ).operations + + for o in ops: + if "TYPE_BUY" in o.operation_type.name or "TYPE_SELL" in o.operation_type.name: + # Определяем тикер + t = ticker_map.get(o.instrument_uid) or figi_map.get(o.figi) or "N/A" + date = o.date.astimezone(timezone(timedelta(hours=3))).strftime("%d.%m %H:%M") + op_type = "BUY" if "BUY" in o.operation_type.name else "SELL" + price = q_to_f(o.price) + payment = q_to_f(o.payment) + + print(f"{date:<15} | {acc.name[:12]:<12} | {t:<6} | {op_type:<5} | {price:<8.2f} | {payment:<10.2f}") diff --git a/get_id.py b/get_id.py new file mode 100644 index 0000000..1bac85f --- /dev/null +++ b/get_id.py @@ -0,0 +1,24 @@ +import os +from dotenv import load_dotenv +from t_tech.invest import Client + +# Настройка SSL для работы с российскими сертификатами +os.environ['SSL_CERT_FILE'] = '/etc/ssl/certs/ca-certificates.crt' +os.environ['GRPC_DEFAULT_SSL_ROOTS_FILE_PATH'] = '/etc/ssl/certs/ca-certificates.crt' + +load_dotenv("tok.env") +TOKEN = os.getenv("TINKOFF_TOKEN") + +print("\n--- ЗАПРОС СПИСКА ВАШИХ РЕАЛЬНЫХ СЧЕТОВ ---") + +try: + with Client(TOKEN, target="invest-public-api.tbank.ru:443") as client: + accounts = client.users.get_accounts().accounts + if not accounts: + print("❌ Счета не найдены. Проверьте права вашего токена!") + else: + for acc in accounts: + print(f"🔹 Имя: {acc.name:15} | ID: {acc.id} | Тип: {acc.type.name}") + print("\n✅ СКОПИРУЙТЕ НУЖНЫЙ ID И ВСТАВЬТЕ ЕГО В tok.env") +except Exception as e: + print(f"❌ Ошибка подключения: {e}") diff --git a/get_today_trades.py b/get_today_trades.py new file mode 100644 index 0000000..18be040 --- /dev/null +++ b/get_today_trades.py @@ -0,0 +1,24 @@ +import os, requests +from datetime import datetime, timedelta, timezone +from dotenv import load_dotenv +from t_tech.invest import Client + +os.environ['SSL_CERT_FILE'] = '/etc/ssl/certs/ca-certificates.crt' +os.environ['GRPC_DEFAULT_SSL_ROOTS_FILE_PATH'] = '/etc/ssl/certs/ca-certificates.crt' + +load_dotenv("/root/sber_bot/tok.env") +TOKEN = os.getenv("TINKOFF_TOKEN") +ACC_ID = os.getenv("ACCOUNT_ID") + +def q_to_f(q): return q.units + q.nano/1e9 if q else 0 + +with Client(TOKEN, target="invest-public-api.tbank.ru:443") as client: + from_date = datetime.now(timezone.utc) - timedelta(days=1) + to_date = datetime.now(timezone.utc) + + print(f"\n--- РЕАЛЬНЫЕ СДЕЛКИ ЗА 24 ЧАСА (Счет {ACC_ID}) ---") + ops = client.operations.get_operations(account_id=ACC_ID, from_=from_date, to=to_date).operations + + for o in ops: + if o.operation_type.name in ['OPERATION_TYPE_BUY', 'OPERATION_TYPE_SELL']: + print(f"{o.date.strftime('%H:%M:%S')} | {o.type} | {q_to_f(o.price)} руб. | {o.quantity} шт. | Итог: {q_to_f(o.payment)} руб.") diff --git a/hardcopy.0 b/hardcopy.0 new file mode 100644 index 0000000..499718f --- /dev/null +++ b/hardcopy.0 @@ -0,0 +1,33 @@ +[22:17:39] K=>:: 318.80 | &5;L BUY: 317.01 +[22:17:40] K=>:: 318.79 | &5;L BUY: 317.01 +[22:17:41] K=>:: 318.79 | &5;L BUY: 317.01 +[22:17:42] K=>:: 318.79 | &5;L BUY: 317.01 +[22:17:43] K=>:: 318.80 | &5;L BUY: 317.01 +[22:17:44] K=>:: 318.80 | &5;L BUY: 317.01 +[22:17:45] K=>:: 318.79 | &5;L BUY: 317.01 +[22:17:46] K=>:: 318.79 | &5;L BUY: 317.01 +[22:17:47] K=>:: 318.79 | &5;L BUY: 317.01 +[22:17:48] K=>:: 318.79 | &5;L BUY: 317.01 +[22:17:49] K=>:: 318.79 | &5;L BUY: 317.01 +[22:17:50] K=>:: 318.79 | &5;L BUY: 317.01 +[22:17:51] K=>:: 318.79 | &5;L BUY: 317.01 +[22:17:52] K=>:: 318.79 | &5;L BUY: 317.01 +[22:17:53] K=>:: 318.79 | &5;L BUY: 317.01 +[22:17:54] K=>:: 318.79 | &5;L BUY: 317.01 +[22:17:56] K=>:: 318.79 | &5;L BUY: 317.01 +[22:17:57] K=>:: 318.79 | &5;L BUY: 317.01 +[22:17:58] K=>:: 318.79 | &5;L BUY: 317.01 +[22:17:59] K=>:: 318.79 | &5;L BUY: 317.01 +[22:18:00] K=>:: 318.79 | &5;L BUY: 317.01 +[22:18:01] K=>:: 318.79 | &5;L BUY: 317.01 +[22:18:02] K=>:: 318.79 | &5;L BUY: 317.01 +[22:18:03] K=>:: 318.79 | &5;L BUY: 317.01 +[22:18:04] K=>:: 318.79 | &5;L BUY: 317.01 +[22:18:05] K=>:: 318.79 | &5;L BUY: 317.01 +[22:18:06] K=>:: 318.79 | &5;L BUY: 317.01 +[22:18:07] K=>:: 318.79 | &5;L BUY: 317.01 +[22:18:08] K=>:: 318.79 | &5;L BUY: 317.01 +[22:18:09] K=>:: 318.79 | &5;L BUY: 317.01 +[22:18:10] K=>:: 318.79 | &5;L BUY: 317.01 +[22:18:11] K=>:: 318.80 | &5;L BUY: 317.01 + diff --git a/invest-python-master.zip b/invest-python-master.zip new file mode 100644 index 0000000..4b4174a Binary files /dev/null and b/invest-python-master.zip differ diff --git a/invest-python-master/.github/ISSUE_TEMPLATE/bug_report.yaml b/invest-python-master/.github/ISSUE_TEMPLATE/bug_report.yaml new file mode 100644 index 0000000..2a17e9b --- /dev/null +++ b/invest-python-master/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -0,0 +1,166 @@ +name: Bug Report +description: Сообщить об ошибке +title: '[Bug] Title' +labels: +- bug +assignees: +- daxartio +body: +- type: markdown + attributes: + value: 'Спасибо, что нашли время заполнить этот отчет об ошибке! + + ' +- type: textarea + id: what-happened + attributes: + label: Что случилось? + description: Краткое описание. + validations: + required: true +- type: textarea + id: to-reproduce + attributes: + label: Воспроизведение + description: Код повторяющий кейс + render: Python + validations: + required: false +- type: dropdown + id: package-version + attributes: + label: T-Tech Invest Version + description: Какая версия библиотеки используется? + options: + - 0.3.5 + - 0.3.4 + - 0.3.3 + - 0.3.2 + - 0.3.1 + - 0.2.0-beta118 + - 0.2.0-beta117 + - 0.2.0-beta116 + - 0.2.0-beta115 + - 0.2.0-beta114 + - 0.2.0-beta113 + - 0.2.0-beta112 + - 0.2.0-beta111 + - 0.2.0-beta110 + - 0.2.0-beta109 + - 0.2.0-beta108 + - 0.2.0-beta107 + - 0.2.0-beta106 + - 0.2.0-beta105 + - 0.2.0-beta104 + - 0.2.0-beta103 + - 0.2.0-beta101 + - 0.2.0-beta100 + - 0.2.0-beta99 + - 0.2.0-beta98 + - 0.2.0-beta97 + - 0.2.0-beta96 + - 0.2.0-beta95 + - 0.2.0-beta94 + - 0.2.0-beta93 + - 0.2.0-beta92 + - 0.2.0-beta91 + - 0.2.0-beta90 + - 0.2.0-beta89 + - 0.2.0-beta88 + - 0.2.0-beta87 + - 0.2.0-beta86 + - 0.2.0-beta85 + - 0.2.0-beta84 + - 0.2.0-beta83 + - 0.2.0-beta82 + - 0.2.0-beta81 + - 0.2.0-beta80 + - 0.2.0-beta79 + - 0.2.0-beta78 + - 0.2.0-beta77 + - 0.2.0-beta76 + - 0.2.0-beta75 + - 0.2.0-beta74 + - 0.2.0-beta73 + - 0.2.0-beta72 + - 0.2.0-beta71 + - 0.2.0-beta70 + - 0.2.0-beta69 + - 0.2.0-beta68 + - 0.2.0-beta67 + - 0.2.0-beta66 + - 0.2.0-beta65 + - 0.2.0-beta64 + - 0.2.0-beta63 + - 0.2.0-beta62 + - 0.2.0-beta61 + - 0.2.0-beta60 + - 0.2.0-beta59 + - 0.2.0-beta58 + - 0.2.0-beta57 + - 0.2.0-beta56 + - 0.2.0-beta55 + - 0.2.0-beta54 + - 0.2.0-beta53 + - 0.2.0-beta52 + - 0.2.0-beta51 + - 0.2.0-beta50 + - 0.2.0-beta49 + - 0.2.0-beta48 + - 0.2.0-beta47 + - 0.2.0-beta46 + - 0.2.0-beta45 + - 0.2.0-beta44 + - 0.2.0-beta43 + - 0.2.0-beta42 + - 0.2.0-beta41 + - 0.2.0-beta40 + - 0.2.0-beta39 + - 0.2.0-beta38 + - 0.2.0-beta37 + - 0.2.0-beta36 + - 0.2.0-beta35 + - 0.2.0-beta34 + - 0.2.0-beta33 + - 0.2.0-beta32 + - 0.2.0-beta31 + - 0.2.0-beta30 + - 0.2.0-beta29 + - 0.2.0-beta28 + - 0.2.0-beta27 + - Другая + validations: + required: true +- type: dropdown + id: python-version + attributes: + label: Python Version + description: Какая версия Python-а используется? + options: + - '3.11' + - '3.10' + - '3.9' + - '3.8' + - Другая + validations: + required: true +- type: dropdown + id: os + attributes: + label: OS + description: Ваша операционная система. + options: + - Windows + - Linux + - Mac OS + - Mac OS (m1) + - Другая + validations: + required: true +- type: textarea + id: logs + attributes: + label: Логи + description: Скопируйте и вставьте сюда логи. Не забудьте скрыть чувствительные + данные. + render: Shell diff --git a/invest-python-master/.github/ISSUE_TEMPLATE/feature_request.yaml b/invest-python-master/.github/ISSUE_TEMPLATE/feature_request.yaml new file mode 100644 index 0000000..8ca5e0b --- /dev/null +++ b/invest-python-master/.github/ISSUE_TEMPLATE/feature_request.yaml @@ -0,0 +1,25 @@ +name: Feature request +description: Предложите идею для этого проекта +title: "[Feature] Title" +labels: ["enhancement"] +body: + - type: textarea + id: description + attributes: + label: Описание + validations: + required: true + - type: textarea + id: to-resolve + attributes: + label: Желаемое решение + description: Что нужно сделать? + validations: + required: false + - type: textarea + id: additional + attributes: + label: Дополнительно + description: Фрагменты кода, описание апи, ... + validations: + required: false diff --git a/invest-python-master/.github/ISSUE_TEMPLATE/issue.yaml b/invest-python-master/.github/ISSUE_TEMPLATE/issue.yaml new file mode 100644 index 0000000..52e1376 --- /dev/null +++ b/invest-python-master/.github/ISSUE_TEMPLATE/issue.yaml @@ -0,0 +1,156 @@ +name: Custom Issue +description: Проблемы, вопросы, ... +body: +- type: textarea + id: what-happened + attributes: + label: Что случилось? + description: Краткое описание. + validations: + required: true +- type: textarea + id: to-reproduce + attributes: + label: Воспроизведение + description: Код повторяющий кейс + render: Python + validations: + required: false +- type: dropdown + id: package-version + attributes: + label: T-Tech Invest Version + description: Какая версия библиотеки используется? + options: + - 0.3.5 + - 0.3.4 + - 0.3.3 + - 0.3.2 + - 0.3.1 + - 0.2.0-beta118 + - 0.2.0-beta117 + - 0.2.0-beta116 + - 0.2.0-beta115 + - 0.2.0-beta114 + - 0.2.0-beta113 + - 0.2.0-beta112 + - 0.2.0-beta111 + - 0.2.0-beta110 + - 0.2.0-beta109 + - 0.2.0-beta108 + - 0.2.0-beta107 + - 0.2.0-beta106 + - 0.2.0-beta105 + - 0.2.0-beta104 + - 0.2.0-beta103 + - 0.2.0-beta101 + - 0.2.0-beta100 + - 0.2.0-beta99 + - 0.2.0-beta98 + - 0.2.0-beta97 + - 0.2.0-beta96 + - 0.2.0-beta95 + - 0.2.0-beta94 + - 0.2.0-beta93 + - 0.2.0-beta92 + - 0.2.0-beta91 + - 0.2.0-beta90 + - 0.2.0-beta89 + - 0.2.0-beta88 + - 0.2.0-beta87 + - 0.2.0-beta86 + - 0.2.0-beta85 + - 0.2.0-beta84 + - 0.2.0-beta83 + - 0.2.0-beta82 + - 0.2.0-beta81 + - 0.2.0-beta80 + - 0.2.0-beta79 + - 0.2.0-beta78 + - 0.2.0-beta77 + - 0.2.0-beta76 + - 0.2.0-beta75 + - 0.2.0-beta74 + - 0.2.0-beta73 + - 0.2.0-beta72 + - 0.2.0-beta71 + - 0.2.0-beta70 + - 0.2.0-beta69 + - 0.2.0-beta68 + - 0.2.0-beta67 + - 0.2.0-beta66 + - 0.2.0-beta65 + - 0.2.0-beta64 + - 0.2.0-beta63 + - 0.2.0-beta62 + - 0.2.0-beta61 + - 0.2.0-beta60 + - 0.2.0-beta59 + - 0.2.0-beta58 + - 0.2.0-beta57 + - 0.2.0-beta56 + - 0.2.0-beta55 + - 0.2.0-beta54 + - 0.2.0-beta53 + - 0.2.0-beta52 + - 0.2.0-beta51 + - 0.2.0-beta50 + - 0.2.0-beta49 + - 0.2.0-beta48 + - 0.2.0-beta47 + - 0.2.0-beta46 + - 0.2.0-beta45 + - 0.2.0-beta44 + - 0.2.0-beta43 + - 0.2.0-beta42 + - 0.2.0-beta41 + - 0.2.0-beta40 + - 0.2.0-beta39 + - 0.2.0-beta38 + - 0.2.0-beta37 + - 0.2.0-beta36 + - 0.2.0-beta35 + - 0.2.0-beta34 + - 0.2.0-beta33 + - 0.2.0-beta32 + - 0.2.0-beta31 + - 0.2.0-beta30 + - 0.2.0-beta29 + - 0.2.0-beta28 + - 0.2.0-beta27 + - Другая + validations: + required: true +- type: dropdown + id: python-version + attributes: + label: Python Version + description: Какая версия Python-а используется? + options: + - '3.11' + - '3.10' + - '3.9' + - '3.8' + - Другая + validations: + required: true +- type: dropdown + id: os + attributes: + label: OS + description: Ваша операционная система. + options: + - Windows + - Linux + - Mac OS + - Mac OS (m1) + - Другая + validations: + required: true +- type: textarea + id: logs + attributes: + label: Логи + description: Скопируйте и вставьте сюда логи. Не забудьте скрыть чувствительные + данные. + render: Shell diff --git a/invest-python-master/.github/PULL_REQUEST_TEMPLATE.md b/invest-python-master/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..defc554 --- /dev/null +++ b/invest-python-master/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,3 @@ + + + diff --git a/invest-python-master/.github/workflows/bumpversion.yml b/invest-python-master/.github/workflows/bumpversion.yml new file mode 100644 index 0000000..cf0e3f5 --- /dev/null +++ b/invest-python-master/.github/workflows/bumpversion.yml @@ -0,0 +1,35 @@ +name: Bump version + +on: + push: + branches: [main] + paths: + - "tinkoff/**" + - "!tinkoff/invest/__init__.py" + - "!tinkoff/invest/constants.py" + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + token: ${{ secrets.BOT_ACCESS_TOKEN }} + + - name: Git user + run: | + git config --local user.name 'github-actions[bot]' + git config --local user.email 'github-actions[bot]@users.noreply.github.com' + + - name: Install python dependencies + run: make install-poetry install-bump + + - name: Bump version + run: make bump-version v=$(make next-version) + + - name: Push + run: | + git push + git push --tags diff --git a/invest-python-master/.github/workflows/check.yml b/invest-python-master/.github/workflows/check.yml new file mode 100644 index 0000000..b0891e1 --- /dev/null +++ b/invest-python-master/.github/workflows/check.yml @@ -0,0 +1,49 @@ +name: CI Tests/Lints + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + workflow_dispatch: + +jobs: + build-ubuntu: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - uses: actions/setup-python@v4 + with: + python-version: '3.8' + + - name: Install python dependencies + run: make install-poetry install + + - name: Run linters + run: make lint + + - name: Test docs + run: make docs + + - name: Run test + run: make test + env: + INVEST_SANDBOX_TOKEN: ${{ secrets.INVEST_SANDBOX_TOKEN }} + INVEST_TOKEN: ${{ secrets.INVEST_TOKEN }} + + build-windows: + runs-on: windows-latest + steps: + - uses: actions/checkout@v2 + + - name: Install make + run: choco install make + + - name: Install python dependencies + run: make install-poetry install + + - name: Run test + run: make test + env: + INVEST_SANDBOX_TOKEN: ${{ secrets.INVEST_SANDBOX_TOKEN }} diff --git a/invest-python-master/.github/workflows/check_pr_title.yml b/invest-python-master/.github/workflows/check_pr_title.yml new file mode 100644 index 0000000..456d5a1 --- /dev/null +++ b/invest-python-master/.github/workflows/check_pr_title.yml @@ -0,0 +1,16 @@ +name: Check PR title +on: + pull_request_target: + types: + - opened + - reopened + - edited + - synchronize + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: aslafy-z/conventional-pr-title-action@v3 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/invest-python-master/.github/workflows/github_pages.yml b/invest-python-master/.github/workflows/github_pages.yml new file mode 100644 index 0000000..b6e622e --- /dev/null +++ b/invest-python-master/.github/workflows/github_pages.yml @@ -0,0 +1,24 @@ +name: Github pages + +on: + push: + branches: [ main ] + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Install python dependencies + run: make install-poetry install-docs + + - name: Generate docs + run: make docs + + - name: Deploy pages + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./site diff --git a/invest-python-master/.github/workflows/pypi.yml b/invest-python-master/.github/workflows/pypi.yml new file mode 100644 index 0000000..2853ea6 --- /dev/null +++ b/invest-python-master/.github/workflows/pypi.yml @@ -0,0 +1,25 @@ +name: Publish to PYPI + +on: + push: + tags: + - '*' + release: + types: + - created + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Install poetry + run: make install-poetry + + - name: Publish package to pypi + run: make publish + env: + pypi_username: ${{ secrets.PYPI_USERNAME }} + pypi_password: ${{ secrets.PYPI_PASSWORD }} diff --git a/invest-python-master/.gitignore b/invest-python-master/.gitignore new file mode 100644 index 0000000..efc3e5a --- /dev/null +++ b/invest-python-master/.gitignore @@ -0,0 +1,149 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv* +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ +tests/pytest.ini + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +.env + +docs/README.md +docs/CHANGELOG.md +docs/CONTRIBUTING.md + +.idea +.market_data_cache +.DS_Store diff --git a/invest-python-master/BREAKING_CHANGES.md b/invest-python-master/BREAKING_CHANGES.md new file mode 100644 index 0000000..b863946 --- /dev/null +++ b/invest-python-master/BREAKING_CHANGES.md @@ -0,0 +1,7 @@ +# Breaking changes +## 0.3.0 +- Package naming changed to `t_tech` with all corresponding subpackages +## 0.2.0-beta60 +- `MarketDataCache` was moved to [t_tech/invest/caching/market_data_cache/cache.py](t_tech/invest/caching/market_data_cache/cache.py). +- The correct import is now `from t_tech.invest.caching.market_data_cache.cache import MarketDataCache` instead of `from t_tech.invest.services import MarketDataCache`. +- Import in [download_all_candles.py](examples/download_all_candles.py) was also corrected. \ No newline at end of file diff --git a/invest-python-master/CHANGELOG.md b/invest-python-master/CHANGELOG.md new file mode 100644 index 0000000..f20743e --- /dev/null +++ b/invest-python-master/CHANGELOG.md @@ -0,0 +1,3 @@ +# Changelog + +You can see [the commits](https://github.com/RussianInvestments/invest-python/commits/main) diff --git a/invest-python-master/CONTRIBUTING.md b/invest-python-master/CONTRIBUTING.md new file mode 100644 index 0000000..acfdd0a --- /dev/null +++ b/invest-python-master/CONTRIBUTING.md @@ -0,0 +1,143 @@ +# Contributing + +Спасибо за участие в проекте T-Invest! + +## Быстрый старт + +1. Сделайте [fork](https://opensource.tbank.ru/invest/invest-python/-/forks/new) проекта +2. Склонируйте репозиторий на свой локальный компьютер + ```bash + git clone https://opensource.tbank.ru//invest-python.git + ``` + > Вы должны использовать свой username вместо `username` +3. Создайте новую ветку для ваших изменений + ```bash + git checkout -b branch_name + ``` +4. Добавьте изменения и выполните команды на локальной машине (см. ниже) + 1. Установите зависимости + 2. Проверьте свой код с помощью тестов и линтеров +5. Создайте коммит своих изменений. Формат описан ниже + ```bash + git add . + git commit -m "feat: add new feature" + ``` +6. Отправьте свои изменения на github + ```bash + git push + ``` +7. Создайте Pull Request в этот репозиторий + +## Commit Message Format + +Мы придерживаемся соглашений [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) для наименование коммитов. + +> A specification for adding human and machine readable meaning to commit messages. + +Body и Footer можно указать по желанию. + +### Commit Message Header + +``` +(): + │ │ │ + │ │ └─⫸ Summary in present tense. Not capitalized. No period at the end. + │ │ + │ └─⫸ Commit Scope: grpc, async, mypy, schemas, sandbox + │ + └─⫸ Commit Type: feat|fix|build|ci|docs|perf|refactor|test|chore +``` + +#### Type + +| feat | Features | A new feature | +|----------|--------------------------|--------------------------------------------------------------------------------------------------------| +| fix | Bug Fixes | A bug fix | +| docs | Documentation | Documentation only changes | +| style | Styles | Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc) | +| refactor | Code Refactoring | A code change that neither fixes a bug nor adds a feature | +| perf | Performance Improvements | A code change that improves performance | +| test | Tests | Adding missing tests or correcting existing tests | +| build | Builds | Changes that affect the build system or external dependencies (example scopes: mypy, pip, pytest) | +| ci | Continuous Integrations | Changes to our CI configuration files and scripts (example scopes: Github Actions) | +| chore | Chores | Other changes that don't modify src or test files | +| revert | Reverts | Reverts a previous commit | + +## Выполнение команд на локальной машине + +Для работы с проектом рекомендуем использовать [poetry](https://pypi.org/project/poetry/). + +Также рекомендуем использовать таск раннер make. Все команды описаны в Makefile. Вы можете их скопировать и запускать напрямую. + +## Установка зависимостей + +``` +make install-poetry +make install +``` + +### Виртуальное окружение + +По умолчанию, poetry создает виртуальное окружение в директории `~/.cache/pypoetry/virtualenvs/`. Чтобы создавать виртуальное окружение в директории проекта, выполните команду: + +``` +poetry config virtualenvs.in-project true +``` + +Вы можете сами создать виртуальное окружение в директории проекта: + +``` +python -m venv .venv +``` + +poetry будет использовать его. + +### Запуск тестов + +``` +make test +``` + +### Запуск линтеров + +``` +make lint +``` + +### Запуск автоформатирования + +``` +make format +``` + +### Загрузка proto файлов + +``` +make download-protos +``` + +По дефолту загружает из ветки `main`. + +### Генерация клиента + +``` +make gen-grpc +``` + +Затем, добавить изменения в модули: +- t_tech/invest/\_\_init__.py +- t_tech/invest/async_services.py +- t_tech/invest/schemas.py +- t_tech/invest/services.py + +### Загрузка proto файлов и генерация клиента + +Можно упростить все до одной команды. + +``` +make gen-client +``` + +### Release новой версии + +Релиз новой версии происходит автоматически после слияния изменений в main ветку. diff --git a/invest-python-master/LICENSE b/invest-python-master/LICENSE new file mode 100644 index 0000000..faab910 --- /dev/null +++ b/invest-python-master/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2023 Tinkoff + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/invest-python-master/Makefile b/invest-python-master/Makefile new file mode 100644 index 0000000..61ba634 --- /dev/null +++ b/invest-python-master/Makefile @@ -0,0 +1,106 @@ +PYTHONPATH = PYTHONPATH=./ +POETRY_RUN = poetry run + +PROTO_DIR = protos/t_tech/invest/grpc +PACKAGE_PROTO_DIR = t_tech/invest/grpc +OUT = . +PROTOS = protos + +TEST = $(POETRY_RUN) pytest $(args) +MAIN_CODE = t_tech examples scripts +CODE = tests $(MAIN_CODE) + +.PHONY: test +test: + $(TEST) --cov + +.PHONY: test-fast +test-fast: + $(TEST) + +.PHONY: test-sandbox +test-sandbox: + $(TEST) --test-sandbox --cov + +.PHONY: lint +lint: + $(POETRY_RUN) ruff $(CODE) + $(POETRY_RUN) black --check $(CODE) + $(POETRY_RUN) pytest --dead-fixtures --dup-fixtures + $(POETRY_RUN) mypy $(MAIN_CODE) + $(POETRY_RUN) poetry check + +.PHONY: format +format: + $(POETRY_RUN) isort $(CODE) + $(POETRY_RUN) black $(CODE) + $(POETRY_RUN) ruff --fix $(CODE) + +.PHONY: check +check: lint test + +.PHONY: docs +docs: + mkdir -p ./docs + cp README.md ./docs/ + cp CHANGELOG.md ./docs/ + cp CONTRIBUTING.md ./docs/ + $(POETRY_RUN) mkdocs build -s -v + +.PHONY: docs-serve +docs-serve: + $(POETRY_RUN) mkdocs serve + +.PHONY: next-version +next-version: + @$(POETRY_RUN) python -m scripts.version + +.PHONY: bump-version +bump-version: + poetry version $(v) + $(POETRY_RUN) python -m scripts.update_package_version $(v) + $(POETRY_RUN) python -m scripts.update_issue_templates $(v) + git add . && git commit -m "chore(release): bump version to $(v)" + git tag -a $(v) -m "" + +.PHONY: install-poetry +install-poetry: + pip install poetry==2.3.2 + +.PHONY: install-docs +install-docs: + poetry install --only docs + +.PHONY: install-bump +install-bump: + poetry install --only bump + +.PHONY: install +install: + poetry install -E all + +.PHONY: publish +publish: + @poetry publish --build --no-interaction --username=$(pypi_username) --password=$(pypi_password) + +.PHONY: publish-opensource +publish-opensource: + @poetry publish --build --no-interaction -r opensource --username=$(pypi_username) --password=$(pypi_password) + +.PHONY: config-opensource +config-opensource: + @poetry config repositories.opensource https://opensource.tbank.ru/api/v4/projects/238/packages/pypi + +.PHONY: download-protos +download-protos: + $(POETRY_RUN) python -m scripts.download_protos + +.PHONY: gen-grpc +gen-grpc: + rm -r ${PACKAGE_PROTO_DIR} + $(POETRY_RUN) python -m grpc_tools.protoc -I${PROTOS} --python_out=${OUT} --mypy_out=${OUT} --grpc_python_out=${OUT} ${PROTO_DIR}/google/api/*.proto + $(POETRY_RUN) python -m grpc_tools.protoc -I${PROTOS} --python_out=${OUT} --mypy_out=${OUT} --grpc_python_out=${OUT} ${PROTO_DIR}/*.proto + touch ${PACKAGE_PROTO_DIR}/__init__.py + +.PHONY: gen-client +gen-client: download-protos gen-grpc diff --git a/invest-python-master/README.md b/invest-python-master/README.md new file mode 100644 index 0000000..eaa56b0 --- /dev/null +++ b/invest-python-master/README.md @@ -0,0 +1,84 @@ +# T-Invest + +[![PyPI](https://img.shields.io/gitlab/v/release/238?gitlab_url=https%3A%2F%2Fopensource.tbank.ru)](https://opensource.tbank.ru/invest/invest-python/-/packages) +[![PyPI - Python Version](https://img.shields.io/python/required-version-toml?tomlFilePath=https://opensource.tbank.ru/invest/invest-python/-/raw/master/pyproject.toml)](https://www.python.org/downloads/) +[![Opensource](https://img.shields.io/gitlab/license/238?gitlab_url=https%3A%2F%2Fopensource.tbank.ru)](https://opensource.tbank.ru/invest/invest-python/-/blob/master/LICENSE) + +[//]: # (![PyPI - Downloads](https://img.shields.io/pypi/dw/t-investments)) + +Данный репозиторий предоставляет клиент для взаимодействия с торговой платформой +[Т-Инвестиции](https://www.tbank.ru/invest/) на языке Python. + +Проект является продуктом независимой разработки и не связан с какими-либо компаниями. Библиотека распространяется +свободно и не является коммерческим продуктом или официальным выпуском какого-либо стороннего разработчика. Все +исходные материалы, архитектура и реализация созданы самостоятельно. + +The project is the result of independent development and is not affiliated with any companies. The library is +distributed freely and is not a commercial product or official release of any third-party vendor. All source materials, +architecture, and implementation were created independently. + + +- [Документация](https://opensource.tbank.ru/invest/invest-python/-/blob/master/README.md?ref_type=heads) +- [Документация по Invest API](https://developer.tbank.ru/invest/intro/intro) + +## Начало работы + + + +``` +$ pip install t-tech-investments --index-url https://opensource.tbank.ru/api/v4/projects/238/packages/pypi/simple +``` + +## Возможности + +- ☑ Синхронный и асинхронный GRPC клиент +- ☑ Возможность отменить все заявки +- ☑ Выгрузка истории котировок "от" и "до" +- ☑ Кеширование данных +- ☑ Торговая стратегия + +## Как пользоваться + +### Получить список аккаунтов + +```python +from t_tech.invest import Client + +TOKEN = 'token' + +with Client(TOKEN) as client: + print(client.users.get_accounts()) +``` + +### Переопределить target + +В T-Invest API есть два контура - "боевой", предназначенный для исполнения ордеров на бирже и "песочница", +предназначенный для тестирования API и торговых гипотез, заявки с которого не выводятся на биржу, +а исполняются в эмуляторе. + +Переключение между контурами реализовано через target, INVEST_GRPC_API - "боевой", INVEST_GRPC_API_SANDBOX - "песочница" + +```python +from t_tech.invest import Client +from t_tech.invest.constants import INVEST_GRPC_API + +TOKEN = 'token' + +with Client(TOKEN, target=INVEST_GRPC_API) as client: + print(client.users.get_accounts()) +``` + +> :warning: **Не публикуйте токены в общедоступные репозитории** +
+ +Остальные примеры доступны в [examples](https://opensource.tbank.ru/invest/invest-python/-/tree/master/examples). + +## Contribution + +Для тех, кто хочет внести свои изменения в проект. + +- [CONTRIBUTING](https://opensource.tbank.ru/invest/invest-python/-/blob/master/CONTRIBUTING.md) + +## License + +Лицензия [The Apache License](https://opensource.tbank.ru/invest/invest-python/-/blob/master/LICENSE). diff --git a/invest-python-master/conftest.py b/invest-python-master/conftest.py new file mode 100644 index 0000000..9b1c6a6 --- /dev/null +++ b/invest-python-master/conftest.py @@ -0,0 +1,18 @@ +import pytest + + +def pytest_addoption(parser): + parser.addoption( + "--test-sandbox", + action="store_true", + default=False, + help="Run sandbox tests", + ) + + +def pytest_collection_modifyitems(config, items): + if not config.getoption("--test-sandbox"): + skipper = pytest.mark.skip(reason="Only run when --test-sandbox is given") + for item in items: + if "test_sandbox" in item.keywords: + item.add_marker(skipper) diff --git a/invest-python-master/docs/api/clients.md b/invest-python-master/docs/api/clients.md new file mode 100644 index 0000000..b87e3ff --- /dev/null +++ b/invest-python-master/docs/api/clients.md @@ -0,0 +1,4 @@ + +# Clients + +::: t_tech.invest.clients diff --git a/invest-python-master/docs/examples.md b/invest-python-master/docs/examples.md new file mode 100644 index 0000000..6eabff3 --- /dev/null +++ b/invest-python-master/docs/examples.md @@ -0,0 +1,122 @@ +Больше примеров доступно [здесь](https://github.com/RussianInvestments/invest-python/tree/main/examples). + +## Получение и вывод в консоль свечей с часовым интервалом за год +[examples/all_candles.py](https://github.com/RussianInvestments/invest-python/blob/main/examples/all_candles.py) +~~~python +{% include "../examples/all_candles.py" %} +~~~ +## Асинхронная функция получения и вывода в консоль свечей с часовым интервалом за год +[examples/async_all_candles.py](https://github.com/RussianInvestments/invest-python/blob/main/examples/async_all_candles.py) +~~~python +{% include "../examples/async_all_candles.py" %} +~~~ +## Асинхронная функция получения и вывода счетов пользователя +[examples/async_client.py](https://github.com/RussianInvestments/invest-python/blob/main/examples/async_client.py) +~~~python +{% include "../examples/async_client.py" %} +~~~ +## Асинхронная функция получения и вывода минутных свечей +[examples/async_retrying_client.py](https://github.com/RussianInvestments/invest-python/blob/main/examples/async_retrying_client.py) +~~~python +{% include "../examples/async_retrying_client.py" %} +~~~ +## Подписка на стрим котировок по минутным свечам и вывод получаемых свечей в консоль +[examples/async_stream_client.py](https://github.com/RussianInvestments/invest-python/blob/main/examples/async_stream_client.py) +~~~python +{% include "../examples/async_stream_client.py" %} +~~~ +## Отмена всех выставленных поручений +[examples/cancel_orders.py](https://github.com/RussianInvestments/invest-python/blob/main/examples/cancel_orders.py) +~~~python +{% include "../examples/cancel_orders.py" %} +~~~ +## Функция получения и вывода счетов клиента +[examples/client.py](https://github.com/RussianInvestments/invest-python/blob/main/examples/client.py) +~~~python +{% include "../examples/client.py" %} +~~~ +## Загрузка и вывод всех минутных свечей по интрументу +[examples/download_all_candles.py](https://github.com/RussianInvestments/invest-python/blob/main/examples/download_all_candles.py) +~~~python +{% include "../examples/download_all_candles.py" %} +~~~ +## Асинхронная подписка на стрим минутных свечей +[examples/easy_async_stream_client.py](https://github.com/RussianInvestments/invest-python/blob/main/examples/easy_async_stream_client.py) +~~~python +{% include "../examples/easy_async_stream_client.py" %} +~~~ +## Простая подписка на стрим минутных свечей +[examples/easy_stream_client.py](https://github.com/RussianInvestments/invest-python/blob/main/examples/easy_stream_client.py) +~~~python +{% include "../examples/easy_stream_client.py" %} +~~~ +## Получение списка операций и их постраничный вывод +[examples/get_operations_by_cursor.py](https://github.com/RussianInvestments/invest-python/blob/main/examples/get_operations_by_cursor.py) +~~~python +{% include "../examples/get_operations_by_cursor.py" %} +~~~ +## Функция кэширования инструментов +[examples/instrument_cache.py](https://github.com/RussianInvestments/invest-python/blob/main/examples/instrument_cache.py) +~~~python +{% include "../examples/instrument_cache.py" %} +~~~ +## Функция получения списка инструментов подходящих под строку query +[examples/instruments/instruments.py](https://github.com/RussianInvestments/invest-python/blob/main/examples/instruments/instruments.py) +~~~python +{% include "../examples/instruments/instruments.py" %} +~~~ +## Функция логгирования ошибок +[examples/logger.py](https://github.com/RussianInvestments/invest-python/blob/main/examples/logger.py) +~~~python +{% include "../examples/logger.py" %} +~~~ +## Подписка на стрим портфолио и вывод информации +[examples/porfolio_stream_client.py](https://github.com/RussianInvestments/invest-python/blob/main/examples/porfolio_stream_client.py) +~~~python +{% include "../examples/porfolio_stream_client.py" %} +~~~ +## Подписка на стрим позиций и вывод информации +[examples/positions_stream.py](https://github.com/RussianInvestments/invest-python/blob/main/examples/positions_stream.py) +~~~python +{% include "../examples/positions_stream.py" %} +~~~ +## Функция получения и вывода минутных свечей +[examples/retrying_client.py](https://github.com/RussianInvestments/invest-python/blob/main/examples/retrying_client.py) +~~~python +{% include "../examples/retrying_client.py" %} +~~~ +## Получение и вывод информации об аккаунте пользователя в песочнице +[examples/sandbox_client.py](https://github.com/RussianInvestments/invest-python/blob/main/examples/sandbox_client.py) +~~~python +{% include "../examples/sandbox_client.py" %} +~~~ +## Подписка на стрим минутных свечей и их вывод +[examples/stream_client.py](https://github.com/RussianInvestments/invest-python/blob/main/examples/stream_client.py) +~~~python +{% include "../examples/stream_client.py" %} +~~~ +## Создание тэйк-профит стоп ордера +[examples/wiseplat_create_take_profit_stop_order.py](https://github.com/RussianInvestments/invest-python/blob/main/examples/wiseplat_create_take_profit_stop_order.py) +~~~python +{% include "../examples/wiseplat_create_take_profit_stop_order.py" %} +~~~ +## Отмена всех выставленных стоп ордеров +[examples/wiseplat_cancel_all_stop_orders.py](https://github.com/RussianInvestments/invest-python/blob/main/examples/wiseplat_cancel_all_stop_orders.py) +~~~python +{% include "../examples/wiseplat_cancel_all_stop_orders.py" %} +~~~ +## Получение figi для тикера +[examples/wiseplat_get_figi_for_ticker.py](https://github.com/RussianInvestments/invest-python/blob/main/examples/wiseplat_get_figi_for_ticker.py) +~~~python +{% include "../examples/wiseplat_get_figi_for_ticker.py" %} +~~~ +## Получение / установка баланса для песочницы. Получение / закрытие всех песочниц. Создание новой песочницы. +[examples/wiseplat_set_get_sandbox_balance.py](https://github.com/RussianInvestments/invest-python/blob/main/examples/wiseplat_set_get_sandbox_balance.py) +~~~python +{% include "../examples/wiseplat_set_get_sandbox_balance.py" %} +~~~ +## Пример live стратегии для нескольких тикеров. Вывод OHLCV для каждой сформировавшейся свечи. +[examples/wiseplat_live_strategy_print_ohlcv.py](https://github.com/RussianInvestments/invest-python/blob/main/examples/wiseplat_live_strategy_print_ohlcv.py) +~~~python +{% include "../examples/wiseplat_live_strategy_print_ohlcv.py" %} +~~~ diff --git a/invest-python-master/docs/robots.md b/invest-python-master/docs/robots.md new file mode 100644 index 0000000..bb1a8ff --- /dev/null +++ b/invest-python-master/docs/robots.md @@ -0,0 +1,16 @@ +## Примеры готовых роботов + +| Ссылка на репозиторий | Описание | +|------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [tromario/tinkoff-invest-volume-analysis-robot](https://github.com/tromario/tinkoff-invest-volume-analysis-robot) | Проектом был реализован один из методов работы с профилем рынка - реакция на максимальный горизонтальный объем внутри дня за выбранный период.Основной объем работы был заложен в математический аппарат. Работа имеет визуализацию алгоритма. | +| [qwertyo1/tinkoff-trading-bot](https://github.com/qwertyo1/tinkoff-trading-bot) | Проектом реализована простая интервальная стратегия. Несложный код поможет начинающим разработчикам быстро разобраться, запустить, проверить и доработать торговую стратегию под свои цели. Простое ведение статистики через sqllite. | +| [karpp/investRobot](https://github.com/karpp/investRobot) | investRobot - это робот для алгоритмической торговли на бирже Тинькофф Инвестиций посредством Tinkoff Invest API. В качестве демонстрации представлена одна торговая стратегия, основанная на индикаторе двух скользящих средних. | +| [EIDiamond/invest-bot](https://github.com/EIDiamond/invest-bot) | Робот интрадей торговли на Московской бирже с возможность информирования о сделках и результатах торговли в Telegram чат.Удобное решение опционального включения\выключения информирования в Телеграм. Без подключения Телеграм чата все события и результаты пишутся в лог файл. | + +## Готовые стратегии + +Функция создает дополнительный столбец с действиями ("ma200_support_action"), куда записываются сигналы на шорт или лонг по условиям. +Затем данные агрегируются и выводятся в виде списка акций, по которым пришли сигналы, в порядке убывания даты сигнала. +~~~python +{% include "../examples/strategies/moving_average.py" %} +~~~ diff --git a/invest-python-master/examples/README.md b/invest-python-master/examples/README.md new file mode 100644 index 0000000..1de40bd --- /dev/null +++ b/invest-python-master/examples/README.md @@ -0,0 +1,13 @@ +Cначала нужно добавить токен в переменную окружения. + + + +```console +$ export INVEST_TOKEN=YOUR_TOKEN +``` + +А потом можно запускать примеры + +```console +$ python examples/client.py +``` diff --git a/invest-python-master/examples/__init__.py b/invest-python-master/examples/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/invest-python-master/examples/all_candles.py b/invest-python-master/examples/all_candles.py new file mode 100644 index 0000000..8df0de3 --- /dev/null +++ b/invest-python-master/examples/all_candles.py @@ -0,0 +1,25 @@ +import os +from datetime import timedelta + +from t_tech.invest import CandleInterval, Client +from t_tech.invest.schemas import CandleSource +from t_tech.invest.utils import now + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + for candle in client.get_all_candles( + instrument_id="BBG004730N88", + from_=now() - timedelta(days=365), + interval=CandleInterval.CANDLE_INTERVAL_HOUR, + candle_source_type=CandleSource.CANDLE_SOURCE_UNSPECIFIED, + ): + print(candle) + + return 0 + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/async_all_candles.py b/invest-python-master/examples/async_all_candles.py new file mode 100644 index 0000000..bf4a9b7 --- /dev/null +++ b/invest-python-master/examples/async_all_candles.py @@ -0,0 +1,24 @@ +import asyncio +import os +from datetime import timedelta + +from t_tech.invest import AsyncClient, CandleInterval +from t_tech.invest.schemas import CandleSource +from t_tech.invest.utils import now + +TOKEN = os.environ["INVEST_TOKEN"] + + +async def main(): + async with AsyncClient(TOKEN) as client: + async for candle in client.get_all_candles( + instrument_id="BBG004730N88", + from_=now() - timedelta(days=365), + interval=CandleInterval.CANDLE_INTERVAL_HOUR, + candle_source_type=CandleSource.CANDLE_SOURCE_EXCHANGE, + ): + print(candle) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/async_client.py b/invest-python-master/examples/async_client.py new file mode 100644 index 0000000..a2b9671 --- /dev/null +++ b/invest-python-master/examples/async_client.py @@ -0,0 +1,15 @@ +import asyncio +import os + +from t_tech.invest import AsyncClient + +TOKEN = os.environ["INVEST_TOKEN"] + + +async def main(): + async with AsyncClient(TOKEN) as client: + print(await client.users.get_accounts()) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/async_get_candles_with_limit.py b/invest-python-master/examples/async_get_candles_with_limit.py new file mode 100644 index 0000000..0ba4bb3 --- /dev/null +++ b/invest-python-master/examples/async_get_candles_with_limit.py @@ -0,0 +1,25 @@ +import asyncio +import os + +from t_tech.invest import AsyncClient, CandleInterval +from t_tech.invest.utils import now + +TOKEN = os.environ["INVEST_TOKEN"] + + +async def main(): + async with AsyncClient(TOKEN) as client: + candles = await client.market_data.get_candles( + instrument_id="BBG004730N88", + to=now(), + limit=3, + interval=CandleInterval.CANDLE_INTERVAL_HOUR, + ) + for candle in candles.candles: + print(candle) + + return 0 + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/async_get_insider_deals.py b/invest-python-master/examples/async_get_insider_deals.py new file mode 100644 index 0000000..3a21f0b --- /dev/null +++ b/invest-python-master/examples/async_get_insider_deals.py @@ -0,0 +1,38 @@ +"""Example - How to get list of insider deals. + Request data in loop with batches of 10 records. +""" +import asyncio +import logging +import os + +from t_tech.invest import AsyncClient +from t_tech.invest.schemas import GetInsiderDealsRequest + +TOKEN = os.environ["INVEST_TOKEN"] + +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + + +async def main(): + async with AsyncClient(TOKEN) as client: + deals = [] + + next_cursor = None + while True: + response = await client.instruments.get_insider_deals( + request=GetInsiderDealsRequest( + instrument_id="BBG004730N88", limit=10, next_cursor=next_cursor + ) + ) + deals.extend(response.insider_deals) + if not next_cursor: + break + next_cursor = response.next_cursor + print("Insider deals:") + for deal in deals: + print(deal) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/async_get_last_prices.py b/invest-python-master/examples/async_get_last_prices.py new file mode 100644 index 0000000..d42c226 --- /dev/null +++ b/invest-python-master/examples/async_get_last_prices.py @@ -0,0 +1,20 @@ +import asyncio +import os + +from t_tech.invest import AsyncClient, InstrumentStatus + +TOKEN = os.environ["INVEST_TOKEN"] + + +async def main(): + async with AsyncClient(TOKEN) as client: + print( + await client.market_data.get_last_prices( + figi=["BBG004730ZJ9"], + instrument_status=InstrumentStatus.INSTRUMENT_STATUS_ALL, + ) + ) # pylint:disable=line-too-long + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/async_get_market_values.py b/invest-python-master/examples/async_get_market_values.py new file mode 100644 index 0000000..e285219 --- /dev/null +++ b/invest-python-master/examples/async_get_market_values.py @@ -0,0 +1,28 @@ +import asyncio +import os + +from t_tech.invest import AsyncClient +from t_tech.invest.schemas import GetMarketValuesRequest, MarketValueType + +TOKEN = os.environ["INVEST_TOKEN"] + + +async def main(): + async with AsyncClient(TOKEN) as client: + market_values = await client.market_data.get_market_values( + request=GetMarketValuesRequest( + instrument_id=["BBG004730N88", "64c0da45-4c90-41d4-b053-0c66c7a8ddcd"], + values=[ + MarketValueType.INSTRUMENT_VALUE_LAST_PRICE, + MarketValueType.INSTRUMENT_VALUE_CLOSE_PRICE, + ], + ) + ) + for instrument in market_values.instruments: + print(instrument.instrument_uid) + for value in instrument.values: + print(value) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/async_get_orders.py b/invest-python-master/examples/async_get_orders.py new file mode 100644 index 0000000..bfd174b --- /dev/null +++ b/invest-python-master/examples/async_get_orders.py @@ -0,0 +1,39 @@ +"""Example - How to get list of orders for 1 last hour (maximum requesting period).""" +import asyncio +import datetime +import logging +import os + +from t_tech.invest import AsyncClient +from t_tech.invest.schemas import OrderExecutionReportStatus + +TOKEN = os.environ["INVEST_TOKEN"] + +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + + +async def main(): + async with AsyncClient(TOKEN) as client: + response = await client.users.get_accounts() + account, *_ = response.accounts + account_id = account.id + + now = datetime.datetime.now() + orders = await client.orders.get_orders( + account_id=account_id, + from_=now - datetime.timedelta(hours=1), + to=now, + # filter only executed or partially executed orders + execution_status=[ + OrderExecutionReportStatus.EXECUTION_REPORT_STATUS_FILL, + OrderExecutionReportStatus.EXECUTION_REPORT_STATUS_PARTIALLYFILL, + ], + ) + print("Orders list:") + for order in orders.orders: + print(order) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/async_get_risk_rates.py b/invest-python-master/examples/async_get_risk_rates.py new file mode 100644 index 0000000..6fee0f7 --- /dev/null +++ b/invest-python-master/examples/async_get_risk_rates.py @@ -0,0 +1,22 @@ +import asyncio +import os + +from t_tech.invest import AsyncClient +from t_tech.invest.schemas import RiskRatesRequest + +TOKEN = os.environ["INVEST_TOKEN"] + + +async def main(): + async with AsyncClient(TOKEN) as client: + request = RiskRatesRequest() + request.instrument_id = ["BBG001M2SC01", "BBG004730N88"] + r = await client.instruments.get_risk_rates(request=request) + for i in r.instrument_risk_rates: + print(i.instrument_uid) + print(i.short_risk_rate) + print(i.long_risk_rate) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/async_get_sandbox_max_lots.py b/invest-python-master/examples/async_get_sandbox_max_lots.py new file mode 100644 index 0000000..76c88a3 --- /dev/null +++ b/invest-python-master/examples/async_get_sandbox_max_lots.py @@ -0,0 +1,22 @@ +import asyncio +import os + +from t_tech.invest import GetMaxLotsRequest +from t_tech.invest.sandbox.async_client import AsyncSandboxClient +from t_tech.invest.sandbox.client import SandboxClient + +TOKEN = os.environ["INVEST_SANDBOX_TOKEN"] + + +async def main(): + async with AsyncSandboxClient(TOKEN) as client: + account_id = (await client.users.get_accounts()).accounts[0].id + request = GetMaxLotsRequest( + account_id=account_id, + instrument_id="BBG004730N88", + ) + print(await client.sandbox.get_sandbox_max_lots(request=request)) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/async_get_signals.py b/invest-python-master/examples/async_get_signals.py new file mode 100644 index 0000000..9c073fa --- /dev/null +++ b/invest-python-master/examples/async_get_signals.py @@ -0,0 +1,26 @@ +"""Example - How to get Signals""" +import asyncio +import datetime +import os + +from t_tech.invest import AsyncClient +from t_tech.invest.schemas import GetSignalsRequest, SignalState + +TOKEN = os.environ["INVEST_TOKEN"] + + +async def main(): + async with AsyncClient(TOKEN) as client: + request = GetSignalsRequest() + request.instrument_uid = "e6123145-9665-43e0-8413-cd61b8aa9b13" # Сбербанк + request.active = SignalState.SIGNAL_STATE_ALL # все сигналы + request.from_ = datetime.datetime.now() - datetime.timedelta( + weeks=4 + ) # сигналы, созданные не больше чем 4 недели назад + r = await client.signals.get_signals(request=request) + for signal in r.signals: + print(signal) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/async_get_strategies.py b/invest-python-master/examples/async_get_strategies.py new file mode 100644 index 0000000..1d1a21c --- /dev/null +++ b/invest-python-master/examples/async_get_strategies.py @@ -0,0 +1,19 @@ +"""Example - How to get all strategies""" +import asyncio +import os + +from t_tech.invest import AsyncClient +from t_tech.invest.schemas import GetStrategiesRequest + +TOKEN = os.environ["INVEST_TOKEN"] + + +async def main(): + async with AsyncClient(TOKEN) as client: + r = await client.signals.get_strategies(request=GetStrategiesRequest()) + for strategy in r.strategies: + print(strategy) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/async_get_tech_analysis.py b/invest-python-master/examples/async_get_tech_analysis.py new file mode 100644 index 0000000..f09313d --- /dev/null +++ b/invest-python-master/examples/async_get_tech_analysis.py @@ -0,0 +1,41 @@ +import asyncio +import os +from datetime import timedelta +from decimal import Decimal + +from t_tech.invest import AsyncClient +from t_tech.invest.schemas import ( + Deviation, + GetTechAnalysisRequest, + IndicatorInterval, + IndicatorType, + Smoothing, + TypeOfPrice, +) +from t_tech.invest.utils import decimal_to_quotation, now + +TOKEN = os.environ["INVEST_TOKEN"] + + +async def main(): + async with AsyncClient(TOKEN) as client: + request = GetTechAnalysisRequest( + indicator_type=IndicatorType.INDICATOR_TYPE_RSI, + instrument_uid="6542a064-6633-44ba-902f-710c97507522", + from_=now() - timedelta(days=7), + to=now(), + interval=IndicatorInterval.INDICATOR_INTERVAL_4_HOUR, + type_of_price=TypeOfPrice.TYPE_OF_PRICE_AVG, + length=42, + deviation=Deviation( + deviation_multiplier=decimal_to_quotation(Decimal(1.0)), + ), + smoothing=Smoothing(fast_length=13, slow_length=7, signal_smoothing=3), + ) + response = await client.market_data.get_tech_analysis(request=request) + for indicator in response.technical_indicators: + print(indicator.signal) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/async_get_trading_statuses.py b/invest-python-master/examples/async_get_trading_statuses.py new file mode 100644 index 0000000..bd91c66 --- /dev/null +++ b/invest-python-master/examples/async_get_trading_statuses.py @@ -0,0 +1,18 @@ +import asyncio +import os + +from t_tech.invest import AsyncClient + +token = os.environ["INVEST_TOKEN"] + + +async def main(): + async with AsyncClient(token) as client: + statuses = await client.market_data.get_trading_statuses( + instrument_ids=["BBG004730N88"] + ) + print(statuses) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/async_indicatives.py b/invest-python-master/examples/async_indicatives.py new file mode 100644 index 0000000..1509621 --- /dev/null +++ b/invest-python-master/examples/async_indicatives.py @@ -0,0 +1,19 @@ +import asyncio +import os + +from t_tech.invest import AsyncClient +from t_tech.invest.schemas import IndicativesRequest + +TOKEN = os.environ["INVEST_TOKEN"] + + +async def main(): + async with AsyncClient(TOKEN) as client: + request = IndicativesRequest() + indicatives = await client.instruments.indicatives(request=request) + for instrument in indicatives.instruments: + print(instrument.name) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/async_instrument_favorites.py b/invest-python-master/examples/async_instrument_favorites.py new file mode 100644 index 0000000..47e6699 --- /dev/null +++ b/invest-python-master/examples/async_instrument_favorites.py @@ -0,0 +1,55 @@ +import asyncio +import os + +from t_tech.invest import AsyncClient +from t_tech.invest.schemas import ( + CreateFavoriteGroupRequest, + DeleteFavoriteGroupRequest, + EditFavoritesActionType as At, + EditFavoritesRequestInstrument, + GetFavoriteGroupsRequest, +) + +TOKEN = os.environ["INVEST_TOKEN"] + + +async def main(): + async with AsyncClient(TOKEN) as client: + r = await client.instruments.get_favorites() + + print("Список избранных инструментов:") + for i in r.favorite_instruments: + print(f"{i.ticker} - {i.name}") + + request = CreateFavoriteGroupRequest() + request.group_name = "My test favorite group" + request.group_color = "aa0000" # red color + r = await client.instruments.create_favorite_group(request=request) + group_id = r.group_id + print(f"Создана новая группа избранного с ИД: {group_id}") + + await client.instruments.edit_favorites( + instruments=[EditFavoritesRequestInstrument(instrument_id="BBG001M2SC01")], + action_type=At.EDIT_FAVORITES_ACTION_TYPE_ADD, + group_id=group_id, + ) + + request = GetFavoriteGroupsRequest() + request.instrument_id = ["BBG001M2SC01"] + r = await client.instruments.get_favorite_groups(request=request) + print(f"Список групп избранного:") + for i in r.groups: + print( + f"{i.group_id} - {i.group_name}. Количество элементов: {i.size}. " + f"Содержит выбранный инструмент {request.instrument_id[0]}: " + f"{i.contains_instrument} " + ) + + request = DeleteFavoriteGroupRequest() + request.group_id = group_id + await client.instruments.delete_favorite_group(request=request) + print(f"Удалена группа избранного с ИД: {group_id}") + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/async_operations_stream.py b/invest-python-master/examples/async_operations_stream.py new file mode 100644 index 0000000..dc9798e --- /dev/null +++ b/invest-python-master/examples/async_operations_stream.py @@ -0,0 +1,27 @@ +import asyncio +import os + +from t_tech.invest import AsyncClient +from t_tech.invest.schemas import OperationsStreamRequest, PingDelaySettings + +TOKEN = os.environ["INVEST_TOKEN"] + + +async def main(): + async with AsyncClient(TOKEN) as client: + accounts = await client.users.get_accounts() + accounts = [i.id for i in accounts.accounts] + print(f"Subscribe for operations on accounts: {accounts}") + async for operation in client.operations_stream.operations_stream( + OperationsStreamRequest( + accounts=accounts, + ping_settings=PingDelaySettings( + ping_delay_ms=10_000, + ), + ) + ): + print(operation) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/async_order_state_stream.py b/invest-python-master/examples/async_order_state_stream.py new file mode 100644 index 0000000..0bf4c6f --- /dev/null +++ b/invest-python-master/examples/async_order_state_stream.py @@ -0,0 +1,19 @@ +import asyncio +import os + +from t_tech.invest import AsyncClient +from t_tech.invest.schemas import OrderStateStreamRequest + +TOKEN = os.environ["INVEST_TOKEN"] + + +async def main(): + async with AsyncClient(TOKEN) as client: + request = OrderStateStreamRequest() + stream = client.orders_stream.order_state_stream(request=request) + async for order_state in stream: + print(order_state) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/async_post_order_async.py b/invest-python-master/examples/async_post_order_async.py new file mode 100644 index 0000000..289ae12 --- /dev/null +++ b/invest-python-master/examples/async_post_order_async.py @@ -0,0 +1,28 @@ +import asyncio +import os +from uuid import uuid4 + +from t_tech.invest import AsyncClient +from t_tech.invest.schemas import OrderDirection, OrderType, PostOrderAsyncRequest + +TOKEN = os.environ["INVEST_TOKEN"] + + +async def main(): + async with AsyncClient(TOKEN) as client: + accounts = await client.users.get_accounts() + account_id = accounts.accounts[0].id + request = PostOrderAsyncRequest( + order_type=OrderType.ORDER_TYPE_MARKET, + direction=OrderDirection.ORDER_DIRECTION_BUY, + instrument_id="BBG004730ZJ9", + quantity=1, + account_id=account_id, + order_id=str(uuid4()), + ) + response = await client.orders.post_order_async(request=request) + print(response) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/async_retrying_client.py b/invest-python-master/examples/async_retrying_client.py new file mode 100644 index 0000000..25061db --- /dev/null +++ b/invest-python-master/examples/async_retrying_client.py @@ -0,0 +1,29 @@ +import asyncio +import logging +import os +from datetime import timedelta + +from t_tech.invest import CandleInterval +from t_tech.invest.retrying.aio.client import AsyncRetryingClient +from t_tech.invest.retrying.settings import RetryClientSettings +from t_tech.invest.utils import now + +logging.basicConfig(format="%(asctime)s %(levelname)s:%(message)s", level=logging.DEBUG) + +TOKEN = os.environ["INVEST_TOKEN"] + +retry_settings = RetryClientSettings(use_retry=True, max_retry_attempt=2) + + +async def main(): + async with AsyncRetryingClient(TOKEN, settings=retry_settings) as client: + async for candle in client.get_all_candles( + figi="BBG000B9XRY4", + from_=now() - timedelta(days=301), + interval=CandleInterval.CANDLE_INTERVAL_1_MIN, + ): + print(candle) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/async_stream_client.py b/invest-python-master/examples/async_stream_client.py new file mode 100644 index 0000000..3bef880 --- /dev/null +++ b/invest-python-master/examples/async_stream_client.py @@ -0,0 +1,41 @@ +import asyncio +import os +from typing import AsyncIterable + +from t_tech.invest import ( + AsyncClient, + CandleInstrument, + MarketDataRequest, + SubscribeCandlesRequest, + SubscriptionAction, + SubscriptionInterval, +) + +TOKEN = os.environ["INVEST_TOKEN"] + + +async def main(): + async def request_iterator(): + yield MarketDataRequest( + subscribe_candles_request=SubscribeCandlesRequest( + subscription_action=SubscriptionAction.SUBSCRIPTION_ACTION_SUBSCRIBE, + instruments=[ + CandleInstrument( + figi="BBG004730N88", + interval=SubscriptionInterval.SUBSCRIPTION_INTERVAL_ONE_MINUTE, + ) + ], + ) + ) + while True: + await asyncio.sleep(1) + + async with AsyncClient(TOKEN) as client: + async for marketdata in client.market_data_stream.market_data_stream( + request_iterator() + ): + print(marketdata) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/cancel_orders.py b/invest-python-master/examples/cancel_orders.py new file mode 100644 index 0000000..32eb1d9 --- /dev/null +++ b/invest-python-master/examples/cancel_orders.py @@ -0,0 +1,23 @@ +import logging +import os + +from t_tech.invest import Client + +TOKEN = os.environ["INVEST_TOKEN"] + +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + + +def main(): + with Client(TOKEN) as client: + response = client.users.get_accounts() + account, *_ = response.accounts + account_id = account.id + logger.info("Orders: %s", client.orders.get_orders(account_id=account_id)) + client.cancel_all_orders(account_id=account.id) + logger.info("Orders: %s", client.orders.get_orders(account_id=account_id)) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/client.py b/invest-python-master/examples/client.py new file mode 100644 index 0000000..98a9399 --- /dev/null +++ b/invest-python-master/examples/client.py @@ -0,0 +1,14 @@ +import os + +from t_tech.invest import Client + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + print(client.users.get_accounts()) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/download_all_candles.py b/invest-python-master/examples/download_all_candles.py new file mode 100644 index 0000000..3e7f78a --- /dev/null +++ b/invest-python-master/examples/download_all_candles.py @@ -0,0 +1,32 @@ +import logging +import os +from datetime import timedelta +from pathlib import Path + +from t_tech.invest import CandleInterval, Client +from t_tech.invest.caching.market_data_cache.cache import MarketDataCache +from t_tech.invest.caching.market_data_cache.cache_settings import ( + MarketDataCacheSettings, +) +from t_tech.invest.utils import now + +TOKEN = os.environ["INVEST_TOKEN"] +logging.basicConfig(format="%(levelname)s: %(message)s", level=logging.DEBUG) + + +def main(): + with Client(TOKEN) as client: + settings = MarketDataCacheSettings(base_cache_dir=Path("market_data_cache")) + market_data_cache = MarketDataCache(settings=settings, services=client) + for candle in market_data_cache.get_all_candles( + figi="BBG004730N88", + from_=now() - timedelta(days=1), + interval=CandleInterval.CANDLE_INTERVAL_HOUR, + ): + print(candle.time, candle.is_complete) + + return 0 + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/easy_async_stream_client.py b/invest-python-master/examples/easy_async_stream_client.py new file mode 100644 index 0000000..7c22bf9 --- /dev/null +++ b/invest-python-master/examples/easy_async_stream_client.py @@ -0,0 +1,46 @@ +import asyncio +import os + +from t_tech.invest import ( + AsyncClient, + CandleInstrument, + InfoInstrument, + MarketDataResponse, + SubscriptionInterval, + TradeInstrument, +) +from t_tech.invest.async_services import AsyncMarketDataStreamManager + +TOKEN = os.environ["INVEST_TOKEN"] + + +async def main(): + async with AsyncClient(TOKEN) as client: + market_data_stream: AsyncMarketDataStreamManager = ( + client.create_market_data_stream() + ) + market_data_stream.candles.waiting_close().subscribe( + [ + CandleInstrument( + figi="BBG004730N88", + interval=SubscriptionInterval.SUBSCRIPTION_INTERVAL_ONE_MINUTE, + ) + ] + ) + market_data_stream.trades.subscribe( + [ + TradeInstrument( + figi="BBG004730N88", + ) + ] + ) + async for marketdata in market_data_stream: + marketdata: MarketDataResponse = marketdata + print(marketdata) + market_data_stream.info.subscribe([InfoInstrument(figi="BBG004730N88")]) + if marketdata.subscribe_info_response: + market_data_stream.stop() + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/easy_stream_client.py b/invest-python-master/examples/easy_stream_client.py new file mode 100644 index 0000000..5726db3 --- /dev/null +++ b/invest-python-master/examples/easy_stream_client.py @@ -0,0 +1,28 @@ +import os + +from t_tech.invest import CandleInstrument, Client, InfoInstrument, SubscriptionInterval +from t_tech.invest.services import MarketDataStreamManager + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + market_data_stream: MarketDataStreamManager = client.create_market_data_stream() + market_data_stream.candles.waiting_close().subscribe( + [ + CandleInstrument( + figi="BBG004730N88", + interval=SubscriptionInterval.SUBSCRIPTION_INTERVAL_ONE_MINUTE, + ) + ] + ) + for marketdata in market_data_stream: + print(marketdata) + market_data_stream.info.subscribe([InfoInstrument(figi="BBG004730N88")]) + if marketdata.subscribe_info_response: + market_data_stream.stop() + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/get_active_orders.py b/invest-python-master/examples/get_active_orders.py new file mode 100644 index 0000000..f67c1a7 --- /dev/null +++ b/invest-python-master/examples/get_active_orders.py @@ -0,0 +1,29 @@ +"""Example - How to get list of active orders.""" + +import logging +import os + +from t_tech.invest import Client + +TOKEN = os.environ["INVEST_TOKEN"] + +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + + +def main(): + with Client(TOKEN) as client: + response = client.users.get_accounts() + account, *_ = response.accounts + account_id = account.id + + orders = client.orders.get_orders( + account_id=account_id, + ) + print("Active orders:") + for order in orders.orders: + print(order) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/get_candles_with_limit.py b/invest-python-master/examples/get_candles_with_limit.py new file mode 100644 index 0000000..4884e5d --- /dev/null +++ b/invest-python-master/examples/get_candles_with_limit.py @@ -0,0 +1,23 @@ +import os + +from t_tech.invest import CandleInterval, Client +from t_tech.invest.utils import now + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + for candle in client.market_data.get_candles( + instrument_id="BBG004730N88", + to=now(), + limit=24, + interval=CandleInterval.CANDLE_INTERVAL_HOUR, + ).candles: + print(candle) + + return 0 + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/get_last_prices.py b/invest-python-master/examples/get_last_prices.py new file mode 100644 index 0000000..482617c --- /dev/null +++ b/invest-python-master/examples/get_last_prices.py @@ -0,0 +1,19 @@ +import os + +from t_tech.invest import Client, InstrumentStatus + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + print( + client.market_data.get_last_prices( + figi=["BBG004730ZJ9"], + instrument_status=InstrumentStatus.INSTRUMENT_STATUS_BASE, + ) + ) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/get_last_trades.py b/invest-python-master/examples/get_last_trades.py new file mode 100644 index 0000000..e9488ee --- /dev/null +++ b/invest-python-master/examples/get_last_trades.py @@ -0,0 +1,20 @@ +import os + +from t_tech.invest import Client +from t_tech.invest.schemas import TradeSourceType + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + print( + client.market_data.get_last_trades( + instrument_id="BBG004730ZJ9", + trade_source=TradeSourceType.TRADE_SOURCE_EXCHANGE, + ) + ) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/get_market_values.py b/invest-python-master/examples/get_market_values.py new file mode 100644 index 0000000..ac39cdd --- /dev/null +++ b/invest-python-master/examples/get_market_values.py @@ -0,0 +1,27 @@ +import os + +from t_tech.invest import Client +from t_tech.invest.schemas import GetMarketValuesRequest, MarketValueType + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + for values in client.market_data.get_market_values( + request=GetMarketValuesRequest( + instrument_id=["BBG004730N88"], + values=[ + MarketValueType.INSTRUMENT_VALUE_LAST_PRICE, + MarketValueType.INSTRUMENT_VALUE_CLOSE_PRICE, + ], + ) + ).instruments: + for value in values.values: + print(value) + + return 0 + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/get_operations_by_cursor.py b/invest-python-master/examples/get_operations_by_cursor.py new file mode 100644 index 0000000..2b4ea41 --- /dev/null +++ b/invest-python-master/examples/get_operations_by_cursor.py @@ -0,0 +1,28 @@ +import os +from pprint import pprint + +from t_tech.invest import Client, GetOperationsByCursorRequest + +token = os.environ["INVEST_TOKEN"] + + +with Client(token) as client: + accounts = client.users.get_accounts() + account_id = accounts.accounts[0].id + + def get_request(cursor=""): + return GetOperationsByCursorRequest( + account_id=account_id, + instrument_id="BBG004730N88", + cursor=cursor, + limit=1, + ) + + operations = client.operations.get_operations_by_cursor(get_request()) + print(operations) + depth = 10 + while operations.has_next and depth > 0: + request = get_request(cursor=operations.next_cursor) + operations = client.operations.get_operations_by_cursor(request) + pprint(operations) + depth -= 1 diff --git a/invest-python-master/examples/get_orders.py b/invest-python-master/examples/get_orders.py new file mode 100644 index 0000000..e4773b7 --- /dev/null +++ b/invest-python-master/examples/get_orders.py @@ -0,0 +1,38 @@ +"""Example - How to get list of orders for 1 last hour (maximum requesting period).""" +import datetime +import logging +import os + +from t_tech.invest import Client +from t_tech.invest.schemas import OrderExecutionReportStatus + +TOKEN = os.environ["INVEST_TOKEN"] + +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + + +def main(): + with Client(TOKEN) as client: + response = client.users.get_accounts() + account, *_ = response.accounts + account_id = account.id + + now = datetime.datetime.now() + orders = client.orders.get_orders( + account_id=account_id, + from_=now - datetime.timedelta(hours=1), + to=now, + # filter only executed or partially executed orders + execution_status=[ + OrderExecutionReportStatus.EXECUTION_REPORT_STATUS_FILL, + OrderExecutionReportStatus.EXECUTION_REPORT_STATUS_PARTIALLYFILL, + ], + ) + print("Orders list:") + for order in orders.orders: + print(order) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/get_risk_rates.py b/invest-python-master/examples/get_risk_rates.py new file mode 100644 index 0000000..0598c4f --- /dev/null +++ b/invest-python-master/examples/get_risk_rates.py @@ -0,0 +1,21 @@ +import os + +from t_tech.invest import Client +from t_tech.invest.schemas import RiskRatesRequest + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + request = RiskRatesRequest() + request.instrument_id = ["BBG001M2SC01", "BBG004730N88"] + r = client.instruments.get_risk_rates(request=request) + for i in r.instrument_risk_rates: + print(i.instrument_uid) + print(i.short_risk_rate) + print(i.long_risk_rate) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/get_sandbox_max_lots.py b/invest-python-master/examples/get_sandbox_max_lots.py new file mode 100644 index 0000000..a0dd5b3 --- /dev/null +++ b/invest-python-master/examples/get_sandbox_max_lots.py @@ -0,0 +1,20 @@ +import os + +from t_tech.invest import GetMaxLotsRequest +from t_tech.invest.sandbox.client import SandboxClient + +TOKEN = os.environ["INVEST_SANDBOX_TOKEN"] + + +def main(): + with SandboxClient(TOKEN) as client: + account_id = client.users.get_accounts().accounts[0].id + request = GetMaxLotsRequest( + account_id=account_id, + instrument_id="BBG004730N88", + ) + print(client.sandbox.get_sandbox_max_lots(request=request)) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/get_signals.py b/invest-python-master/examples/get_signals.py new file mode 100644 index 0000000..ee19494 --- /dev/null +++ b/invest-python-master/examples/get_signals.py @@ -0,0 +1,22 @@ +"""Example - How to get Signals with filtering""" + +import os + +from t_tech.invest import Client +from t_tech.invest.schemas import GetSignalsRequest, SignalState + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + request = GetSignalsRequest() + request.instrument_uid = "e6123145-9665-43e0-8413-cd61b8aa9b13" # Сбербанк + request.active = SignalState.SIGNAL_STATE_ACTIVE # только активные сигналы + r = client.signals.get_signals(request=request) + for signal in r.signals: + print(signal) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/get_strategies.py b/invest-python-master/examples/get_strategies.py new file mode 100644 index 0000000..424cd87 --- /dev/null +++ b/invest-python-master/examples/get_strategies.py @@ -0,0 +1,19 @@ +"""Example - How to get Strategies""" + +import os + +from t_tech.invest import Client +from t_tech.invest.schemas import GetStrategiesRequest + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + r = client.signals.get_strategies(request=GetStrategiesRequest()) + for strategy in r.strategies: + print(strategy) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/get_tech_analysis.py b/invest-python-master/examples/get_tech_analysis.py new file mode 100644 index 0000000..bc1868b --- /dev/null +++ b/invest-python-master/examples/get_tech_analysis.py @@ -0,0 +1,40 @@ +import os +from datetime import timedelta +from decimal import Decimal + +from t_tech.invest import Client +from t_tech.invest.schemas import ( + Deviation, + GetTechAnalysisRequest, + IndicatorInterval, + IndicatorType, + Smoothing, + TypeOfPrice, +) +from t_tech.invest.utils import decimal_to_quotation, now + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + request = GetTechAnalysisRequest( + indicator_type=IndicatorType.INDICATOR_TYPE_RSI, + instrument_uid="6542a064-6633-44ba-902f-710c97507522", + from_=now() - timedelta(days=7), + to=now(), + interval=IndicatorInterval.INDICATOR_INTERVAL_4_HOUR, + type_of_price=TypeOfPrice.TYPE_OF_PRICE_AVG, + length=42, + deviation=Deviation( + deviation_multiplier=decimal_to_quotation(Decimal(1.0)), + ), + smoothing=Smoothing(fast_length=13, slow_length=7, signal_smoothing=3), + ) + response = client.market_data.get_tech_analysis(request=request) + for indicator in response.technical_indicators: + print(indicator.signal) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/get_trading_statuses.py b/invest-python-master/examples/get_trading_statuses.py new file mode 100644 index 0000000..0c3b7b5 --- /dev/null +++ b/invest-python-master/examples/get_trading_statuses.py @@ -0,0 +1,10 @@ +import os + +from t_tech.invest import Client + +token = os.environ["INVEST_TOKEN"] + + +with Client(token) as client: + statuses = client.market_data.get_trading_statuses(instrument_ids=["BBG004730N88"]) + print(statuses) diff --git a/invest-python-master/examples/instrument_cache.py b/invest-python-master/examples/instrument_cache.py new file mode 100644 index 0000000..6a1ebcf --- /dev/null +++ b/invest-python-master/examples/instrument_cache.py @@ -0,0 +1,44 @@ +import logging +import os +from pprint import pprint + +from t_tech.invest import Client, InstrumentIdType +from t_tech.invest.caching.instruments_cache.instruments_cache import InstrumentsCache +from t_tech.invest.caching.instruments_cache.settings import InstrumentsCacheSettings + +TOKEN = os.environ["INVEST_TOKEN"] + + +logging.basicConfig(level=logging.INFO) + + +def main(): + with Client(TOKEN) as client: + inst = client.instruments.etfs().instruments[-1] + pprint(inst) + + from_server = client.instruments.etf_by( + id_type=InstrumentIdType.INSTRUMENT_ID_TYPE_UID, + class_code=inst.class_code, + id=inst.uid, + ) + pprint(from_server) + + settings = InstrumentsCacheSettings() + instruments_cache = InstrumentsCache( + settings=settings, instruments_service=client.instruments + ) + + from_cache = instruments_cache.etf_by( + id_type=InstrumentIdType.INSTRUMENT_ID_TYPE_UID, + class_code=inst.class_code, + id=inst.uid, + ) + pprint(from_cache) + + if str(from_server) != str(from_cache): + raise Exception("cache miss") + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/instruments/async_get_asset_reports.py b/invest-python-master/examples/instruments/async_get_asset_reports.py new file mode 100644 index 0000000..8a663b4 --- /dev/null +++ b/invest-python-master/examples/instruments/async_get_asset_reports.py @@ -0,0 +1,28 @@ +import asyncio +import os +from datetime import timedelta + +from t_tech.invest import AsyncClient +from t_tech.invest.schemas import GetAssetReportsRequest +from t_tech.invest.utils import now + +TOKEN = os.environ["INVEST_TOKEN"] + + +async def main(): + async with AsyncClient(TOKEN) as client: + instruments = await client.instruments.find_instrument( + query="Тинькофф Квадратные метры" + ) + instrument = instruments.instruments[0] + print(instrument.name) + request = GetAssetReportsRequest( + instrument_id=instrument.uid, + from_=now() - timedelta(days=7), + to=now(), + ) + print(await client.instruments.get_asset_reports(request=request)) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/instruments/async_get_assets.py b/invest-python-master/examples/instruments/async_get_assets.py new file mode 100644 index 0000000..e8e7388 --- /dev/null +++ b/invest-python-master/examples/instruments/async_get_assets.py @@ -0,0 +1,24 @@ +import asyncio +import os + +from t_tech.invest import AsyncClient +from t_tech.invest.schemas import AssetsRequest, InstrumentStatus, InstrumentType + +TOKEN = os.environ["INVEST_TOKEN"] + + +async def main(): + async with AsyncClient(TOKEN) as client: + r = await client.instruments.get_assets( + request=AssetsRequest( + instrument_type=InstrumentType.INSTRUMENT_TYPE_SHARE, + instrument_status=InstrumentStatus.INSTRUMENT_STATUS_BASE, + ) # pylint:disable=line-too-long + ) + print("BASE SHARE ASSETS") + for bond in r.assets: + print(bond) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/instruments/async_get_bond_events.py b/invest-python-master/examples/instruments/async_get_bond_events.py new file mode 100644 index 0000000..d1c3274 --- /dev/null +++ b/invest-python-master/examples/instruments/async_get_bond_events.py @@ -0,0 +1,27 @@ +import asyncio +import os + +from t_tech.invest import AsyncClient, InstrumentType +from t_tech.invest.schemas import EventType, GetBondEventsRequest + +TOKEN = os.environ["INVEST_TOKEN"] + + +async def main(): + async with AsyncClient(TOKEN) as client: + bond = ( + await client.instruments.find_instrument( + query="Тинькофф Банк выпуск 1", + instrument_kind=InstrumentType.INSTRUMENT_TYPE_BOND, + ) + ).instruments[0] + + request = GetBondEventsRequest( + instrument_id=bond.uid, + type=EventType.EVENT_TYPE_CALL, + ) + print(await client.instruments.get_bond_events(request=request)) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/instruments/async_get_bonds.py b/invest-python-master/examples/instruments/async_get_bonds.py new file mode 100644 index 0000000..14ac696 --- /dev/null +++ b/invest-python-master/examples/instruments/async_get_bonds.py @@ -0,0 +1,20 @@ +import asyncio +import os + +from t_tech.invest import AsyncClient +from t_tech.invest.schemas import InstrumentExchangeType + +TOKEN = os.environ["INVEST_TOKEN"] + + +async def main(): + async with AsyncClient(TOKEN) as client: + bonds = await client.instruments.bonds( + instrument_exchange=InstrumentExchangeType.INSTRUMENT_EXCHANGE_UNSPECIFIED, + ) + for bond in bonds.instruments: + print(bond) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/instruments/async_get_consensus_forecasts.py b/invest-python-master/examples/instruments/async_get_consensus_forecasts.py new file mode 100644 index 0000000..a6025a6 --- /dev/null +++ b/invest-python-master/examples/instruments/async_get_consensus_forecasts.py @@ -0,0 +1,22 @@ +import asyncio +import os + +from t_tech.invest import AsyncClient +from t_tech.invest.schemas import GetConsensusForecastsRequest, Page + +TOKEN = os.environ["INVEST_TOKEN"] + + +async def main(): + async with AsyncClient(TOKEN) as client: + request = GetConsensusForecastsRequest( + paging=Page(page_number=0, limit=2), + ) + response = await client.instruments.get_consensus_forecasts(request=request) + print(response.page) + for forecast in response.items: + print(forecast.uid, forecast.consensus.name) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/instruments/async_get_forecast_by.py b/invest-python-master/examples/instruments/async_get_forecast_by.py new file mode 100644 index 0000000..9b40164 --- /dev/null +++ b/invest-python-master/examples/instruments/async_get_forecast_by.py @@ -0,0 +1,23 @@ +import asyncio +import os + +from t_tech.invest import AsyncClient +from t_tech.invest.schemas import GetForecastRequest + +TOKEN = os.environ["INVEST_TOKEN"] + + +async def main(): + async with AsyncClient(TOKEN) as client: + instrument = ( + await client.instruments.find_instrument( + query="Сбер Банк - привилегированные акции" + ) + ).instruments[0] + request = GetForecastRequest(instrument_id=instrument.uid) + response = await client.instruments.get_forecast_by(request=request) + print(instrument.name, response.consensus.recommendation.name) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/instruments/async_structured_notes.py b/invest-python-master/examples/instruments/async_structured_notes.py new file mode 100644 index 0000000..49965a1 --- /dev/null +++ b/invest-python-master/examples/instruments/async_structured_notes.py @@ -0,0 +1,22 @@ +import asyncio +import os + +from t_tech.invest import AsyncClient +from t_tech.invest.schemas import InstrumentsRequest, InstrumentStatus + + +async def main(): + token = os.environ["INVEST_TOKEN"] + + with AsyncClient(token) as client: + r = await client.instruments.structured_notes( + request=InstrumentsRequest( + instrument_status=InstrumentStatus.INSTRUMENT_STATUS_ALL + ) + ) + for note in r.instruments: + print(note) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/instruments/async_structured_notes_by.py b/invest-python-master/examples/instruments/async_structured_notes_by.py new file mode 100644 index 0000000..b0c6d16 --- /dev/null +++ b/invest-python-master/examples/instruments/async_structured_notes_by.py @@ -0,0 +1,21 @@ +import asyncio +import os + +from t_tech.invest import AsyncClient +from t_tech.invest.schemas import InstrumentIdType, InstrumentRequest + + +async def main(): + token = os.environ["INVEST_TOKEN"] + + with AsyncClient(token) as client: + r = await client.instruments.structured_note_by( + request=InstrumentRequest( + id_type=InstrumentIdType.INSTRUMENT_ID_TYPE_FIGI, id="BBG012S2DCJ8" + ) + ) + print(r.instrument) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/instruments/get_asset_fundamentals.py b/invest-python-master/examples/instruments/get_asset_fundamentals.py new file mode 100644 index 0000000..a59b8c7 --- /dev/null +++ b/invest-python-master/examples/instruments/get_asset_fundamentals.py @@ -0,0 +1,18 @@ +import os + +from t_tech.invest import Client +from t_tech.invest.schemas import GetAssetFundamentalsRequest + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + request = GetAssetFundamentalsRequest( + assets=["40d89385-a03a-4659-bf4e-d3ecba011782"], + ) + print(client.instruments.get_asset_fundamentals(request=request)) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/instruments/get_asset_reports.py b/invest-python-master/examples/instruments/get_asset_reports.py new file mode 100644 index 0000000..0089cc8 --- /dev/null +++ b/invest-python-master/examples/instruments/get_asset_reports.py @@ -0,0 +1,27 @@ +import os +from datetime import timedelta + +from t_tech.invest import Client +from t_tech.invest.schemas import GetAssetReportsRequest +from t_tech.invest.utils import now + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + instruments = client.instruments.find_instrument( + query="Тинькофф Квадратные метры" + ) + instrument = instruments.instruments[0] + print(instrument.name) + request = GetAssetReportsRequest( + instrument_id=instrument.uid, + from_=now() - timedelta(days=7), + to=now(), + ) + print(client.instruments.get_asset_reports(request=request)) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/instruments/get_assets.py b/invest-python-master/examples/instruments/get_assets.py new file mode 100644 index 0000000..ce30a5b --- /dev/null +++ b/invest-python-master/examples/instruments/get_assets.py @@ -0,0 +1,28 @@ +import os + +from t_tech.invest import Client +from t_tech.invest.schemas import AssetsRequest, InstrumentStatus, InstrumentType + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + r = client.instruments.get_assets( + request=AssetsRequest(instrument_type=InstrumentType.INSTRUMENT_TYPE_BOND) + ) + print("BONDS") + for bond in r.assets: + print(bond) + r = client.instruments.get_assets( + request=AssetsRequest( + instrument_status=InstrumentStatus.INSTRUMENT_STATUS_BASE + ) + ) + print("BASE ASSETS") + for bond in r.assets: + print(bond) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/instruments/get_bond_events.py b/invest-python-master/examples/instruments/get_bond_events.py new file mode 100644 index 0000000..0127275 --- /dev/null +++ b/invest-python-master/examples/instruments/get_bond_events.py @@ -0,0 +1,24 @@ +import os + +from t_tech.invest import Client +from t_tech.invest.schemas import EventType, GetBondEventsRequest, InstrumentType + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + bond = client.instruments.find_instrument( + query="Тинькофф Банк выпуск 1", + instrument_kind=InstrumentType.INSTRUMENT_TYPE_BOND, + ).instruments[0] + + request = GetBondEventsRequest( + instrument_id=bond.uid, + type=EventType.EVENT_TYPE_CALL, + ) + print(client.instruments.get_bond_events(request=request)) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/instruments/get_bonds.py b/invest-python-master/examples/instruments/get_bonds.py new file mode 100644 index 0000000..1a859aa --- /dev/null +++ b/invest-python-master/examples/instruments/get_bonds.py @@ -0,0 +1,19 @@ +import os + +from t_tech.invest import Client +from t_tech.invest.schemas import InstrumentExchangeType + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + r = client.instruments.bonds( + instrument_exchange=InstrumentExchangeType.INSTRUMENT_EXCHANGE_UNSPECIFIED + ) + for bond in r.instruments: + print(bond) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/instruments/get_brands.py b/invest-python-master/examples/instruments/get_brands.py new file mode 100644 index 0000000..1dfaa44 --- /dev/null +++ b/invest-python-master/examples/instruments/get_brands.py @@ -0,0 +1,18 @@ +"""Example - How to get Brands""" + +import os + +from t_tech.invest import Client + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + r = client.instruments.get_brands() + for brand in r.brands: + print(brand) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/instruments/get_consensus_forecasts.py b/invest-python-master/examples/instruments/get_consensus_forecasts.py new file mode 100644 index 0000000..d3391d3 --- /dev/null +++ b/invest-python-master/examples/instruments/get_consensus_forecasts.py @@ -0,0 +1,28 @@ +import os +from datetime import timedelta + +from t_tech.invest import Client +from t_tech.invest.schemas import ( + GetAssetReportsRequest, + GetConsensusForecastsRequest, + InstrumentIdType, + Page, +) +from t_tech.invest.utils import now + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + request = GetConsensusForecastsRequest( + paging=Page(page_number=0, limit=2), + ) + response = client.instruments.get_consensus_forecasts(request=request) + print(response.page) + for forecast in response.items: + print(forecast.uid, forecast.consensus.name) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/instruments/get_dfa_by.py b/invest-python-master/examples/instruments/get_dfa_by.py new file mode 100644 index 0000000..1c2a5cb --- /dev/null +++ b/invest-python-master/examples/instruments/get_dfa_by.py @@ -0,0 +1,20 @@ +import os + +from t_tech.invest import Client, InstrumentIdType, InstrumentRequest + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + dfa = client.instruments.dfa_by( + request=InstrumentRequest( + id_type=InstrumentIdType.INSTRUMENT_ID_TYPE_POSITION_UID, + id="ce604b33-70c7-4609-9f42-075dbd9fe278", + ) + ) + print(dfa) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/instruments/get_dfas.py b/invest-python-master/examples/instruments/get_dfas.py new file mode 100644 index 0000000..65f800e --- /dev/null +++ b/invest-python-master/examples/instruments/get_dfas.py @@ -0,0 +1,16 @@ +import os + +from t_tech.invest import Client + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + r = client.instruments.dfas() + for dfa in r.instruments: + print(dfa) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/instruments/get_forecast_by.py b/invest-python-master/examples/instruments/get_forecast_by.py new file mode 100644 index 0000000..4c7bfd4 --- /dev/null +++ b/invest-python-master/examples/instruments/get_forecast_by.py @@ -0,0 +1,28 @@ +import os +from datetime import timedelta + +from t_tech.invest import Client +from t_tech.invest.schemas import ( + GetAssetReportsRequest, + GetConsensusForecastsRequest, + GetForecastRequest, + InstrumentIdType, + Page, +) +from t_tech.invest.utils import now + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + instrument = client.instruments.find_instrument( + query="Сбер Банк - привилегированные акции" + ).instruments[0] + request = GetForecastRequest(instrument_id=instrument.uid) + response = client.instruments.get_forecast_by(request=request) + print(instrument.name, response.consensus.recommendation.name) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/instruments/get_insider_deals.py b/invest-python-master/examples/instruments/get_insider_deals.py new file mode 100644 index 0000000..afc9ac4 --- /dev/null +++ b/invest-python-master/examples/instruments/get_insider_deals.py @@ -0,0 +1,37 @@ +"""Example - How to get list of insider deals. + Request data in loop with batches of 10 records. +""" +import logging +import os + +from t_tech.invest import Client +from t_tech.invest.schemas import GetInsiderDealsRequest + +TOKEN = os.environ["INVEST_TOKEN"] + +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + + +def main(): + with Client(TOKEN) as client: + deals = [] + + next_cursor = None + while True: + response = client.instruments.get_insider_deals( + request=GetInsiderDealsRequest( + instrument_id="BBG004730N88", limit=10, next_cursor=next_cursor + ) + ) + deals.extend(response.insider_deals) + next_cursor = response.next_cursor + if not next_cursor: + break + print("Insider deals:") + for deal in deals: + print(deal) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/instruments/indicatives.py b/invest-python-master/examples/instruments/indicatives.py new file mode 100644 index 0000000..7f4b486 --- /dev/null +++ b/invest-python-master/examples/instruments/indicatives.py @@ -0,0 +1,18 @@ +import os + +from t_tech.invest import Client +from t_tech.invest.schemas import IndicativesRequest + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + request = IndicativesRequest() + indicatives = client.instruments.indicatives(request=request) + for instrument in indicatives.instruments: + print(instrument.name) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/instruments/instrument_favorites.py b/invest-python-master/examples/instruments/instrument_favorites.py new file mode 100644 index 0000000..abb2556 --- /dev/null +++ b/invest-python-master/examples/instruments/instrument_favorites.py @@ -0,0 +1,54 @@ +import os + +from t_tech.invest import Client +from t_tech.invest.schemas import ( + CreateFavoriteGroupRequest, + DeleteFavoriteGroupRequest, + EditFavoritesActionType as At, + EditFavoritesRequestInstrument, + GetFavoriteGroupsRequest, +) + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + r = client.instruments.get_favorites() + + print("Список избранных инструментов:") + for i in r.favorite_instruments: + print(f"{i.uid} - {i.name}") + + request = CreateFavoriteGroupRequest() + request.group_name = "My test favorite group" + request.group_color = "aa0000" # red color + r = client.instruments.create_favorite_group(request=request) + group_id = r.group_id + print(f"Создана новая группа избранного с ИД: {group_id}") + + client.instruments.edit_favorites( + instruments=[EditFavoritesRequestInstrument(instrument_id="BBG001M2SC01")], + action_type=At.EDIT_FAVORITES_ACTION_TYPE_ADD, + group_id=group_id, + ) + + request = GetFavoriteGroupsRequest() + request.instrument_id = ["BBG001M2SC01"] + r = client.instruments.get_favorite_groups(request=request) + print(f"Список групп избранного:") + for i in r.groups: + print( + f"{i.group_id} - {i.group_name}. Количество элементов: {i.size}. " + f"Содержит выбранный инструмент {request.instrument_id[0]}: " + f"{i.contains_instrument} " + ) + + request = DeleteFavoriteGroupRequest() + request.group_id = group_id + client.instruments.delete_favorite_group(request=request) + print(f"Удалена группа избранного с ИД: {group_id}") + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/instruments/instrument_find_by_ticker.py b/invest-python-master/examples/instruments/instrument_find_by_ticker.py new file mode 100644 index 0000000..ce85e46 --- /dev/null +++ b/invest-python-master/examples/instruments/instrument_find_by_ticker.py @@ -0,0 +1,19 @@ +import os + +from t_tech.invest import Client, InstrumentIdType + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + r = client.instruments.get_instrument_by( + id_type=InstrumentIdType.INSTRUMENT_ID_TYPE_TICKER, + id="LKOH", + class_code="TQBR", + ) + print(r.instrument) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/instruments/instruments.py b/invest-python-master/examples/instruments/instruments.py new file mode 100644 index 0000000..3c69057 --- /dev/null +++ b/invest-python-master/examples/instruments/instruments.py @@ -0,0 +1,16 @@ +import os + +from t_tech.invest import Client + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + r = client.instruments.find_instrument(query="BBG001M2SC01") + for i in r.instruments: + print(i) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/instruments/options.py b/invest-python-master/examples/instruments/options.py new file mode 100644 index 0000000..fe4c6d5 --- /dev/null +++ b/invest-python-master/examples/instruments/options.py @@ -0,0 +1,16 @@ +import os + +from t_tech.invest import Client + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + r = client.instruments.options() + for instrument in r.instruments: + print(instrument) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/instruments/structured_notes.py b/invest-python-master/examples/instruments/structured_notes.py new file mode 100644 index 0000000..d01aebf --- /dev/null +++ b/invest-python-master/examples/instruments/structured_notes.py @@ -0,0 +1,21 @@ +import os + +from t_tech.invest import Client +from t_tech.invest.schemas import InstrumentsRequest, InstrumentStatus + + +def main(): + token = os.environ["INVEST_TOKEN"] + + with Client(token) as client: + r = client.instruments.structured_notes( + request=InstrumentsRequest( + instrument_status=InstrumentStatus.INSTRUMENT_STATUS_ALL + ) + ) + for note in r.instruments: + print(note) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/instruments/structured_notes_by.py b/invest-python-master/examples/instruments/structured_notes_by.py new file mode 100644 index 0000000..e132adc --- /dev/null +++ b/invest-python-master/examples/instruments/structured_notes_by.py @@ -0,0 +1,21 @@ +import os + +from t_tech.invest import Client +from t_tech.invest.schemas import InstrumentIdType, InstrumentRequest + + +def main(): + token = os.environ["INVEST_TOKEN"] + + with Client(token) as client: + r = client.instruments.structured_note_by( + request=InstrumentRequest( + id_type=InstrumentIdType.INSTRUMENT_ID_TYPE_UID, + id="1d7dfabb-9e82-4de4-8add-8475db83d2bd", + ) + ) + print(r.instrument) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/logger.py b/invest-python-master/examples/logger.py new file mode 100644 index 0000000..75d18aa --- /dev/null +++ b/invest-python-master/examples/logger.py @@ -0,0 +1,23 @@ +import logging +import os + +from t_tech.invest import Client, RequestError + +TOKEN = os.environ["INVEST_TOKEN"] + +logging.basicConfig(format="%(asctime)s %(levelname)s:%(message)s", level=logging.INFO) +logger = logging.getLogger(__name__) + + +def main(): + with Client(TOKEN) as client: + _ = client.users.get_accounts().accounts + try: + client.users.get_margin_attributes(account_id="123") + except RequestError as err: + tracking_id = err.metadata.tracking_id if err.metadata else "" + logger.error("Error tracking_id=%s code=%s", tracking_id, str(err.code)) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/market_order_stop_order.py b/invest-python-master/examples/market_order_stop_order.py new file mode 100644 index 0000000..c6b64d6 --- /dev/null +++ b/invest-python-master/examples/market_order_stop_order.py @@ -0,0 +1,137 @@ +""" +Алгоритм: + +выставляем рыночный ордер по дешевой бумаге +если он не исполнен - возвращаем ошибку (код и message) +если он исполнен и вернулся его идентификатор, +то выставляем тейкпрофит на цену +5% к цене покупки +и стоплосс на -2% к цене покупки. +Контур выбираем: песочница или боевой. + +Примеры дешевых акций: +BBG001M2SC01 84.120000000р +BBG000K3STR7 134.900000000р +BBG00F9XX7H4 142.000000000р +""" +import logging +import os +import uuid +from datetime import timedelta +from decimal import Decimal + +from t_tech.invest import ( + Client, + OrderDirection, + OrderExecutionReportStatus, + OrderType, + PostOrderResponse, + StopOrderDirection, + StopOrderExpirationType, + StopOrderType, +) +from t_tech.invest.services import Services +from t_tech.invest.utils import decimal_to_quotation, money_to_decimal, now + +TOKEN = os.environ["INVEST_TOKEN"] + +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + + +QUANTITY = 1 +INSTRUMENT_ID = "BBG001M2SC01" +TAKE_PROFIT_PERCENTAGE = 0.05 +STOP_LOSS_PERCENTAGE = -0.02 +MIN_PRICE_STEP = 0.02 +STOP_ORDER_EXPIRE_DURATION = timedelta(hours=1) +EXPIRATION_TYPE = StopOrderExpirationType.STOP_ORDER_EXPIRATION_TYPE_GOOD_TILL_DATE + + +def main(): + logger.info("Using Real market") + with Client(TOKEN) as client: + response = client.users.get_accounts() + account, *_ = response.accounts + account_id = account.id + + order_id = str(uuid.uuid4()) + + logger.info( + "Placing order for %s security of %s, with order_id=%s", + QUANTITY, + INSTRUMENT_ID, + order_id, + ) + post_order_response: PostOrderResponse = client.orders.post_order( + quantity=QUANTITY, + direction=OrderDirection.ORDER_DIRECTION_BUY, + account_id=account_id, + order_type=OrderType.ORDER_TYPE_MARKET, + order_id=order_id, + instrument_id=INSTRUMENT_ID, + ) + + status = post_order_response.execution_report_status + if status == OrderExecutionReportStatus.EXECUTION_REPORT_STATUS_FILL: + logger.info("Order was fulfilled, posting stop orders.") + + post_stop_orders( + client=client, + account_id=account_id, + post_order_response=post_order_response, + ) + else: + logger.info( + 'Order was not fulfilled: (%s) "%s"', + post_order_response.execution_report_status, + post_order_response.message, + ) + logger.info("Cancelling all orders.") + client.cancel_all_orders(account_id=account_id) + + +def post_stop_orders( + client: Services, account_id: str, post_order_response: PostOrderResponse +): + executed_order_price = money_to_decimal(post_order_response.executed_order_price) + take_profit_price = executed_order_price * Decimal((1 + TAKE_PROFIT_PERCENTAGE)) + take_profit_price -= take_profit_price % Decimal(MIN_PRICE_STEP) + take_profit_response = client.stop_orders.post_stop_order( + quantity=QUANTITY, + price=decimal_to_quotation(take_profit_price), + stop_price=decimal_to_quotation(take_profit_price), + direction=StopOrderDirection.STOP_ORDER_DIRECTION_SELL, + account_id=account_id, + stop_order_type=StopOrderType.STOP_ORDER_TYPE_TAKE_PROFIT, + instrument_id=INSTRUMENT_ID, + expire_date=now() + STOP_ORDER_EXPIRE_DURATION, + expiration_type=EXPIRATION_TYPE, + order_id=str(uuid.uuid4()), + ) + logger.info( + "Take profit order was placed stop_order_id=%s. Price: %s", + take_profit_response.stop_order_id, + take_profit_price, + ) + stop_loss_price = executed_order_price * Decimal((1 + STOP_LOSS_PERCENTAGE)) + stop_loss_price -= stop_loss_price % Decimal(MIN_PRICE_STEP) + take_profit_response = client.stop_orders.post_stop_order( + quantity=QUANTITY, + stop_price=decimal_to_quotation(stop_loss_price), + direction=StopOrderDirection.STOP_ORDER_DIRECTION_SELL, + account_id=account_id, + stop_order_type=StopOrderType.STOP_ORDER_TYPE_STOP_LOSS, + instrument_id=INSTRUMENT_ID, + expire_date=now() + STOP_ORDER_EXPIRE_DURATION, + expiration_type=EXPIRATION_TYPE, + order_id=str(uuid.uuid4()), + ) + logger.info( + "Stop loss order was placed stop_order_id=%s. Price: %s", + take_profit_response.stop_order_id, + stop_loss_price, + ) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/max_lots.py b/invest-python-master/examples/max_lots.py new file mode 100644 index 0000000..af9002a --- /dev/null +++ b/invest-python-master/examples/max_lots.py @@ -0,0 +1,36 @@ +"""Example - How to get available limits.""" + +import logging +import os + +from t_tech.invest import Client, GetMaxLotsRequest + +TOKEN = os.environ["INVEST_TOKEN"] + +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + + +INSTRUMENT_ID = "TCS00A105GE2" + + +def main(): + logger.info("Getting Max Lots") + with Client(TOKEN) as client: + response = client.users.get_accounts() + account, *_ = response.accounts + account_id = account.id + + logger.info( + "Calculating available order amount for instrument=%s and market price", + INSTRUMENT_ID, + ) + get_max_lots = client.orders.get_max_lots( + GetMaxLotsRequest(account_id=account_id, instrument_id=INSTRUMENT_ID) + ) + + print(get_max_lots) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/open_sandbox_account.py b/invest-python-master/examples/open_sandbox_account.py new file mode 100644 index 0000000..7898dad --- /dev/null +++ b/invest-python-master/examples/open_sandbox_account.py @@ -0,0 +1,15 @@ +import os + +from t_tech.invest.sandbox.client import SandboxClient + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with SandboxClient(TOKEN) as client: + print(client.sandbox.open_sandbox_account(name="tcs")) + print(client.users.get_accounts()) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/operations_stream.py b/invest-python-master/examples/operations_stream.py new file mode 100644 index 0000000..cd54cb1 --- /dev/null +++ b/invest-python-master/examples/operations_stream.py @@ -0,0 +1,26 @@ +import os + +from t_tech.invest import Client +from t_tech.invest.schemas import OperationsStreamRequest, PingDelaySettings + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + accounts = client.users.get_accounts().accounts + accounts = [i.id for i in accounts] + print(f"Subscribe for operations on accounts: {accounts}") + for operation in client.operations_stream.operations_stream( + OperationsStreamRequest( + accounts=accounts, + ping_settings=PingDelaySettings( + ping_delay_ms=5000, + ), + ) + ): + print(operation) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/order_price.py b/invest-python-master/examples/order_price.py new file mode 100644 index 0000000..3d96074 --- /dev/null +++ b/invest-python-master/examples/order_price.py @@ -0,0 +1,48 @@ +"""Example - How to get order price.""" + +import logging +import os +from decimal import Decimal + +from t_tech.invest import Client, GetOrderPriceRequest, OrderDirection +from t_tech.invest.utils import decimal_to_quotation + +TOKEN = os.environ["INVEST_TOKEN"] + +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + + +INSTRUMENT_ID = "TCS00A105GE2" +QUANTITY = 1 +PRICE = 230.1 + + +def main(): + logger.info("Getting Max Lots") + with Client(TOKEN) as client: + response = client.users.get_accounts() + account, *_ = response.accounts + account_id = account.id + + logger.info( + "Get pre-trade order commission and price for instrument=%s, quantity=%s and price=%s", + INSTRUMENT_ID, + QUANTITY, + PRICE, + ) + get_order_price = client.orders.get_order_price( + GetOrderPriceRequest( + account_id=account_id, + instrument_id=INSTRUMENT_ID, + quantity=QUANTITY, + direction=OrderDirection.ORDER_DIRECTION_BUY, + price=decimal_to_quotation(Decimal(PRICE)), + ) + ) + + print(get_order_price) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/order_state_stream.py b/invest-python-master/examples/order_state_stream.py new file mode 100644 index 0000000..cfb9d00 --- /dev/null +++ b/invest-python-master/examples/order_state_stream.py @@ -0,0 +1,19 @@ +import os + +from t_tech.invest import Client +from t_tech.invest.schemas import OrderStateStreamRequest + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + request = OrderStateStreamRequest() + request.ping_delay_millis = 10000 + stream = client.orders_stream.order_state_stream(request=request) + for order_state in stream: + print(order_state) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/porfolio_stream_client.py b/invest-python-master/examples/porfolio_stream_client.py new file mode 100644 index 0000000..4379f1e --- /dev/null +++ b/invest-python-master/examples/porfolio_stream_client.py @@ -0,0 +1,18 @@ +import os + +from t_tech.invest import Client + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + accounts = client.users.get_accounts() + for portfolio in client.operations_stream.portfolio_stream( + accounts=[acc.id for acc in accounts.accounts], ping_delay_ms=60_000 + ): + print(portfolio) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/positions_stream.py b/invest-python-master/examples/positions_stream.py new file mode 100644 index 0000000..b1cd906 --- /dev/null +++ b/invest-python-master/examples/positions_stream.py @@ -0,0 +1,19 @@ +import os + +from t_tech.invest import Client + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + response = client.users.get_accounts() + accounts = [account.id for account in response.accounts] + for response in client.operations_stream.positions_stream( + accounts=accounts, with_initial_positions=True + ): # noqa:E501 # pylint:disable=line-too-long + print(response) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/post_order.py b/invest-python-master/examples/post_order.py new file mode 100644 index 0000000..fdd5059 --- /dev/null +++ b/invest-python-master/examples/post_order.py @@ -0,0 +1,36 @@ +"""Example - How to Post order""" + +import os +from uuid import uuid4 + +from t_tech.invest import Client, OrderDirection, OrderType +from t_tech.invest.sandbox.client import SandboxClient + +TOKEN = os.environ["INVEST_TOKEN"] + +""" +Примеры дешевых акций: +BBG001M2SC01 84.120000000р +BBG000K3STR7 134.900000000р +BBG00F9XX7H4 142.000000000р +""" + + +def main(): + with Client(TOKEN) as client: + accounts = client.users.get_accounts() + account_id = accounts.accounts[0].id + + response = client.orders.post_order( + order_type=OrderType.ORDER_TYPE_MARKET, + direction=OrderDirection.ORDER_DIRECTION_BUY, + instrument_id="BBG004730ZJ9", + quantity=1, + account_id=account_id, + order_id=str(uuid4()), + ) + print(response) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/post_order_async.py b/invest-python-master/examples/post_order_async.py new file mode 100644 index 0000000..8e6e450 --- /dev/null +++ b/invest-python-master/examples/post_order_async.py @@ -0,0 +1,30 @@ +"""Example - How to get Post Order""" + +import os +from uuid import uuid4 + +from t_tech.invest import Client, OrderDirection, OrderType +from t_tech.invest.schemas import PostOrderAsyncRequest + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + accounts = client.users.get_accounts() + account_id = accounts.accounts[0].id + + request = PostOrderAsyncRequest( + order_type=OrderType.ORDER_TYPE_MARKET, + direction=OrderDirection.ORDER_DIRECTION_BUY, + instrument_id="BBG004730ZJ9", + quantity=1, + account_id=account_id, + order_id=str(uuid4()), + ) + response = client.orders.post_order_async(request=request) + print(response) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/retrying_client.py b/invest-python-master/examples/retrying_client.py new file mode 100644 index 0000000..69cd9a5 --- /dev/null +++ b/invest-python-master/examples/retrying_client.py @@ -0,0 +1,22 @@ +import logging +import os +from datetime import timedelta + +from t_tech.invest import CandleInterval +from t_tech.invest.retrying.settings import RetryClientSettings +from t_tech.invest.retrying.sync.client import RetryingClient +from t_tech.invest.utils import now + +logging.basicConfig(format="%(asctime)s %(levelname)s:%(message)s", level=logging.DEBUG) + +TOKEN = os.environ["INVEST_TOKEN"] + +retry_settings = RetryClientSettings(use_retry=True, max_retry_attempt=2) + +with RetryingClient(TOKEN, settings=retry_settings) as client: + for candle in client.get_all_candles( + figi="BBG000B9XRY4", + from_=now() - timedelta(days=301), + interval=CandleInterval.CANDLE_INTERVAL_1_MIN, + ): + print(candle) diff --git a/invest-python-master/examples/sandbox/async_sandbox_get_order_price.py b/invest-python-master/examples/sandbox/async_sandbox_get_order_price.py new file mode 100644 index 0000000..c9d52a7 --- /dev/null +++ b/invest-python-master/examples/sandbox/async_sandbox_get_order_price.py @@ -0,0 +1,40 @@ +import asyncio +import os + +from _decimal import Decimal + +from t_tech.invest import utils +from t_tech.invest.sandbox.async_client import AsyncSandboxClient +from t_tech.invest.schemas import ( + GetOrderPriceRequest, + GetOrderPriceResponse, + OrderDirection, +) + + +async def main(): + token = os.environ["INVEST_TOKEN"] + + async with AsyncSandboxClient(token) as client: + accounts = await client.users.get_accounts() + account_id = accounts.accounts[0].id + response = await get_async_order_price(client, account_id, 105) + print(utils.money_to_decimal(response.total_order_amount)) + + +async def get_async_order_price( + sandbox_service, account_id, price +) -> GetOrderPriceResponse: + return await sandbox_service.sandbox.get_sandbox_order_price( + request=GetOrderPriceRequest( + account_id=account_id, + instrument_id="BBG004730ZJ9", + direction=OrderDirection.ORDER_DIRECTION_BUY, + quantity=1, + price=utils.decimal_to_quotation(Decimal(price)), + ) + ) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/sandbox/sandbox_cancel_stop_order.py b/invest-python-master/examples/sandbox/sandbox_cancel_stop_order.py new file mode 100644 index 0000000..6b4a8e4 --- /dev/null +++ b/invest-python-master/examples/sandbox/sandbox_cancel_stop_order.py @@ -0,0 +1,41 @@ +import os + +from t_tech.invest.sandbox.client import SandboxClient +from t_tech.invest.schemas import ( + CancelStopOrderRequest, + CancelStopOrderResponse, + GetStopOrdersRequest, + StopOrderStatusOption, +) + + +def main(): + token = os.environ["INVEST_TOKEN"] + + with SandboxClient(token) as client: + accounts = client.users.get_accounts() + account_id = accounts.accounts[0].id + stop_orders = client.sandbox.get_sandbox_stop_orders( + request=GetStopOrdersRequest( + account_id=account_id, + status=StopOrderStatusOption.STOP_ORDER_STATUS_ACTIVE, + ) + ) + stop_order_id = stop_orders.stop_orders[0].stop_order_id + response = cancel_stop_order(client, account_id, stop_order_id) + print(f"Отменена отложенная заявка id={stop_order_id}: {response}") + + +def cancel_stop_order( + sandbox_service, account_id, stop_order_id +) -> CancelStopOrderResponse: + return sandbox_service.sandbox.cancel_sandbox_stop_order( + request=CancelStopOrderRequest( + account_id=account_id, + stop_order_id=stop_order_id, + ) + ) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/sandbox/sandbox_get_order_price.py b/invest-python-master/examples/sandbox/sandbox_get_order_price.py new file mode 100644 index 0000000..53cfe52 --- /dev/null +++ b/invest-python-master/examples/sandbox/sandbox_get_order_price.py @@ -0,0 +1,39 @@ +import os + +from _decimal import Decimal + +from t_tech.invest import utils +from t_tech.invest.sandbox.client import SandboxClient +from t_tech.invest.schemas import ( + GetOrderPriceRequest, + GetOrderPriceResponse, + OrderDirection, +) + + +def main(): + token = os.environ["INVEST_TOKEN"] + + with SandboxClient(token) as client: + accounts = client.users.get_accounts() + account_id = accounts.accounts[0].id + response = get_order_price(client, account_id, "BBG004730ZJ9", 105) + print(utils.money_to_decimal(response.total_order_amount)) + + +def get_order_price( + sandbox_service, account_id, instrument_id, price +) -> GetOrderPriceResponse: + return sandbox_service.sandbox.get_sandbox_order_price( + request=GetOrderPriceRequest( + account_id=account_id, + instrument_id=instrument_id, + direction=OrderDirection.ORDER_DIRECTION_BUY, + quantity=1, + price=utils.decimal_to_quotation(Decimal(price)), + ) + ) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/sandbox/sandbox_get_stop_orders.py b/invest-python-master/examples/sandbox/sandbox_get_stop_orders.py new file mode 100644 index 0000000..30c6d52 --- /dev/null +++ b/invest-python-master/examples/sandbox/sandbox_get_stop_orders.py @@ -0,0 +1,36 @@ +import os + +from t_tech.invest.sandbox.client import SandboxClient +from t_tech.invest.schemas import ( + GetStopOrdersRequest, + GetStopOrdersResponse, + StopOrderStatusOption, +) + + +def main(): + token = os.environ["INVEST_TOKEN"] + + with SandboxClient(token) as client: + accounts = client.users.get_accounts() + account_id = accounts.accounts[0].id + response = get_stop_orders( + client, account_id, StopOrderStatusOption.STOP_ORDER_STATUS_ACTIVE + ) + if len(response.stop_orders) > 0: + print(response.stop_orders) + else: + print("Активных отложенных заявок не найдено") + + +def get_stop_orders(sandbox_service, account_id, status) -> GetStopOrdersResponse: + return sandbox_service.sandbox.get_sandbox_stop_orders( + request=GetStopOrdersRequest( + account_id=account_id, + status=status, + ) + ) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/sandbox/sandbox_post_stop_order.py b/invest-python-master/examples/sandbox/sandbox_post_stop_order.py new file mode 100644 index 0000000..5e1f854 --- /dev/null +++ b/invest-python-master/examples/sandbox/sandbox_post_stop_order.py @@ -0,0 +1,58 @@ +import os +import uuid + +from _decimal import Decimal + +from t_tech.invest import ( + PostStopOrderRequest, + PostStopOrderRequestTrailingData, + PostStopOrderResponse, + StopOrderExpirationType, + StopOrderType, +) +from t_tech.invest.sandbox.client import SandboxClient +from t_tech.invest.schemas import Quotation, StopOrderDirection, TrailingValueType +from t_tech.invest.utils import decimal_to_quotation + + +def main(): + token = os.environ["INVEST_TOKEN"] + + with SandboxClient(token) as client: + accounts = client.users.get_accounts() + account_id = accounts.accounts[0].id + response = post_stop_order( + client, + account_id, + "BBG004730ZJ9", + stop_order_direction=StopOrderDirection.STOP_ORDER_DIRECTION_BUY, + quantity=1, + price=Quotation(units=10, nano=0), + ) + print(response) + + +def post_stop_order( + sandbox_service, account_id, instrument_id, stop_order_direction, quantity, price +) -> PostStopOrderResponse: + return sandbox_service.sandbox.post_sandbox_stop_order( + request=PostStopOrderRequest( + account_id=account_id, + instrument_id=instrument_id, + direction=stop_order_direction, + quantity=quantity, + price=price, + order_id=str(uuid.uuid4()), + expiration_type=StopOrderExpirationType.STOP_ORDER_EXPIRATION_TYPE_GOOD_TILL_CANCEL, + stop_price=price, + stop_order_type=StopOrderType.STOP_ORDER_TYPE_TAKE_PROFIT, + trailing_data=PostStopOrderRequestTrailingData( + indent_type=TrailingValueType.TRAILING_VALUE_RELATIVE, + indent=decimal_to_quotation(Decimal(1)), + ), + ) + ) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/sandbox_client.py b/invest-python-master/examples/sandbox_client.py new file mode 100644 index 0000000..1a15c5a --- /dev/null +++ b/invest-python-master/examples/sandbox_client.py @@ -0,0 +1,14 @@ +import os + +from t_tech.invest.sandbox.client import SandboxClient + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with SandboxClient(TOKEN) as client: + print(client.users.get_info()) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/strategies/moving_average.py b/invest-python-master/examples/strategies/moving_average.py new file mode 100644 index 0000000..8323af4 --- /dev/null +++ b/invest-python-master/examples/strategies/moving_average.py @@ -0,0 +1,84 @@ +import logging +import os +from datetime import timedelta +from decimal import Decimal + +from matplotlib import pyplot as plt + +from t_tech.invest import CandleInterval, Client +from t_tech.invest.strategies.base.account_manager import AccountManager +from t_tech.invest.strategies.moving_average.plotter import MovingAverageStrategyPlotter +from t_tech.invest.strategies.moving_average.signal_executor import ( + MovingAverageSignalExecutor, +) +from t_tech.invest.strategies.moving_average.strategy import MovingAverageStrategy +from t_tech.invest.strategies.moving_average.strategy_settings import ( + MovingAverageStrategySettings, +) +from t_tech.invest.strategies.moving_average.strategy_state import ( + MovingAverageStrategyState, +) +from t_tech.invest.strategies.moving_average.supervisor import ( + MovingAverageStrategySupervisor, +) +from t_tech.invest.strategies.moving_average.trader import MovingAverageStrategyTrader + +logging.basicConfig(format="%(asctime)s %(levelname)s:%(message)s", level=logging.INFO) +logger = logging.getLogger(__name__) + + +TOKEN = os.environ["INVEST_TOKEN"] +FIGI = os.environ["INVEST_FIGI"] +ACCOUNT_ID = os.environ["INVEST_ACCOUNT_ID"] + + +def main(): + with Client(TOKEN) as services: + settings = MovingAverageStrategySettings( + share_id=FIGI, + account_id=ACCOUNT_ID, + max_transaction_price=Decimal(10000), + candle_interval=CandleInterval.CANDLE_INTERVAL_1_MIN, + long_period=timedelta(minutes=100), + short_period=timedelta(minutes=20), + std_period=timedelta(minutes=30), + ) + + account_manager = AccountManager(services=services, strategy_settings=settings) + state = MovingAverageStrategyState() + strategy = MovingAverageStrategy( + settings=settings, + account_manager=account_manager, + state=state, + ) + signal_executor = MovingAverageSignalExecutor( + services=services, + state=state, + settings=settings, + ) + supervisor = MovingAverageStrategySupervisor() + trader = MovingAverageStrategyTrader( + strategy=strategy, + settings=settings, + services=services, + state=state, + signal_executor=signal_executor, + account_manager=account_manager, + supervisor=supervisor, + ) + plotter = MovingAverageStrategyPlotter(settings=settings) + + initial_balance = account_manager.get_current_balance() + + for i in range(5): + logger.info("Trade %s", i) + trader.trade() + + current_balance = account_manager.get_current_balance() + + logger.info("Initial balance %s", initial_balance) + logger.info("Current balance %s", current_balance) + + events = supervisor.get_events() + plotter.plot(events) + plt.show() diff --git a/invest-python-master/examples/strategies/param-search.ipynb b/invest-python-master/examples/strategies/param-search.ipynb new file mode 100644 index 0000000..af5a78f --- /dev/null +++ b/invest-python-master/examples/strategies/param-search.ipynb @@ -0,0 +1,1546 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Образец работы стратегии\n", + "В этом файле представлен образец простешей стратегии.\n", + "\n", + "Формат самого файла - notebook, записная книжка. Это специальный формат файлов, в котором каждый кусочек кода можно исполнять отдельно.\n", + "\n", + "Для того, чтобы исполнить ячейку - нужно нажать Shift+Enter. После одиночного нажатия активной ячейкой ставится следующая. Для работы достаточно поочередно понажимать эту комбинацию до последней ячейки, где и запустится основная программа." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Добавляем директорию основной папки в PATH\n", + "## Посмотрите как это можно пофиксить. Возможно на проде такого не будет\n", + "Здесь Python понимает, что ему нужно обращать внимание на главную папку с библиотекой. Ничего дополнительно нажимать не надо, только исполнить ячейку." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import os\n", + "\n", + "path = os.getcwd()\n", + "repo_folder = os.path.dirname(os.path.dirname(path))\n", + "sys.path.append(repo_folder)\n", + "!set PATH=%PATH%;%APPDATA%\\Python\\Scripts" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Загружаем все необходимые библиотеки для запуска скрипта\n", + "Здесь загружаются основные библиотеки для работы программы.\n", + "Загрузки представлены в виде \"from ... import ...\". Это значит, что из библиотеки decimal (from decimal) мы загружаем функционад Decimal (import Decimal). Это может как отдельные спецфункции, так и сложные алгоритмы." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "pycharm": { + "is_executing": true + } + }, + "outputs": [], + "source": [ + "import logging\n", + "\n", + "from t_tech.invest.mock_services import MockedClient\n", + "from decimal import Decimal\n", + "from t_tech.invest.strategies.moving_average.strategy_settings import (\n", + " MovingAverageStrategySettings,\n", + ")\n", + "from t_tech.invest import CandleInterval, MoneyValue\n", + "from t_tech.invest.strategies.moving_average.signal_executor import (\n", + " MovingAverageSignalExecutor,\n", + ")\n", + "from t_tech.invest.strategies.moving_average.supervisor import (\n", + " MovingAverageStrategySupervisor,\n", + ")\n", + "from t_tech.invest.strategies.moving_average.strategy_state import (\n", + " MovingAverageStrategyState,\n", + ")\n", + "from t_tech.invest.strategies.moving_average.strategy import MovingAverageStrategy\n", + "from t_tech.invest.strategies.moving_average.trader import MovingAverageStrategyTrader\n", + "from datetime import timedelta, datetime, timezone\n", + "from t_tech.invest.typedefs import ShareId, AccountId\n", + "from t_tech.invest.strategies.base.account_manager import AccountManager\n", + "from t_tech.invest.strategies.moving_average.plotter import (\n", + " MovingAverageStrategyPlotter,\n", + ")\n", + "\n", + "\n", + "logging.basicConfig(format=\"%(asctime)s %(levelname)s:%(message)s\", level=logging.INFO)\n", + "logger = logging.getLogger(__name__)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Загружаем токен\n", + "Здесь мы указываем токен для работы с программой.\n", + "Токен - этой такой ключ-идентификатор, который позволяет программе понять что вы это вы.\n", + "Инструкция здесь: https://www.tbank.ru/invest/open-api/\n", + "\n", + "Для работы нам нужен sandbox токен.\n", + "\n", + "Sandbox - это такая внутрення виртуальная площадка, на которой ценовые и потоковые данные полностью совпадают с реальным рынком, но портфель и заявки могут быть заданы самим пользователем. Эдакая песочница (что и отражено в названии) для того, чтобы испытать интерфейс и инфраструктуру без угрозы настоящему аккаунту с настоящими деньгами.\n", + "\n", + "При получении sandbox токена вы не рискуете ничем, кроме виртуальных денег на вашем счете :)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "pycharm": { + "is_executing": true + } + }, + "outputs": [], + "source": [ + "# sandbox token\n", + "token = \"\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Раздел с настройками\n", + "Здесь вводятся основные настройки стратегии, по которой будут определяться сигналы.\n", + "\n", + "Стратегия основана на том, что цена время от времени возвращается к своей длинной средней. Если в это время зайти по направлению этой средней, то можно совершить достаточно эффективную сделку с точки зрения прибыль/убытка.\n", + "\n", + "Для запуска стратегии необходимо задать следующие параметры:\n", + "\n", + " - long_ma - количество периодов для расчета длинной скользяшки\n", + " - short_ma - количество периодов для расчета короткой скользяшки\n", + " - std_period - количество периодов для расчета волатильности инструмента\n", + " - timeframe - выбранная размерность свечей для расчета\n", + " \n", + " В переменную stocks записываются акции, на которых будет тестироваться стратегия." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "long_ma = 240\n", + "short_ma = 60\n", + "std_period = 30\n", + "timaframe = CandleInterval.CANDLE_INTERVAL_1_MIN\n", + "n, m, s, tf = long_ma, short_ma, std_period, timaframe\n", + "period = 1 # сюда добавить переход от tf к числу или отрекдактировать код снизу\n", + "\n", + "stocks = {\n", + " \"AAPL\": {\"figi\": \"BBG000B9XRY4\"},\n", + " \"MSFT\": {\"figi\": \"BBG000BPH459\"},\n", + " # \"GOOG\":{\"figi\":\"BBG009S3NB30\"}, гугл не работает\n", + " \"AMZN\": {\"figi\": \"BBG000BVPV84\"},\n", + " \"TSLA\": {\"figi\": \"BBG000N9MNX3\"},\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Блок с определением дат для бектестинга\n", + "Здесь задаются временные пределы для даты, на котором будет производиться бектестинг (проверка на исторических данных).\n", + "\n", + "По умолчанию задаются как зависимости от количества периодов." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "def start_datetime() -> datetime:\n", + " return datetime(year=2022, month=2, day=1, hour=17, tzinfo=timezone.utc)\n", + "\n", + "\n", + "# тут надо проставлять сдвиг даты в зависимости от выбранного тф\n", + "# что-то вроде CandleInterval.CANDLE_INTERVAL_1_MIN.seconds * (m+n) для real_market_data_test_from\n", + "real_market_data_test_from = start_datetime() - timedelta(\n", + " minutes=(n + m) * 2\n", + ") # с какой даты начинают считаться индикаторы\n", + "real_market_data_test_start = (\n", + " start_datetime()\n", + ") # с какой даты начинает работать стратегия\n", + "real_market_data_test_end = start_datetime() + timedelta(\n", + " days=2\n", + ") # когда все заканчивается" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Запуск бектестинга\n", + "В этой ячейке основной исполняемый код для проверки стратегии. В конце определяется инструмент, для которого наилучшим образом подходит данная стратегия\n", + "\n", + "По завершении стратегии можно вызывать картинку с графиком цены акции и сделками (если были).\n", + "\n", + "## Обеспечить такой выбор через обращение к полю events в виде events(best_stock)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2022-02-01 20:00:00,000 INFO:5f7a771f14f01b5b76ac68ea714f344a GetCandles\n", + "2022-02-01 20:00:00,000 INFO:5635e1dbaa249a58e111c29dae684006 GetCandles\n", + "2022-02-01 20:00:00,000 INFO:fb56d92d981e55d59805908a21abce24 GetCandles\n", + "2022-02-01 20:00:00,000 INFO:Loading candles for period 5:00:00 from 2022-02-01 17:00:00+00:00\n", + "2022-02-01 20:00:00,000 INFO:Marginal trade is active\n", + "2022-02-01 20:00:00,000 INFO:Got enough data for strategy\n", + "2022-02-01 20:00:00,000 INFO:Trade 0\n", + "2022-02-01 20:00:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:00:00,000 INFO:Refreshing data\n", + "2022-02-01 20:00:00,000 INFO:Data refreshed\n", + "2022-02-01 20:00:00,000 INFO:Strategy predict\n", + "2022-02-01 20:00:00,000 INFO:Got signals [OpenLongMarketOrder(lots=115, direction=)]\n", + "2022-02-01 20:00:00,000 INFO:Trying to execute signal OpenLongMarketOrder(lots=115, direction=)\n", + "2022-02-01 20:00:00,000 WARNING:Operation: OrderDirection.ORDER_DIRECTION_BUY, -20026.10000000\n", + "2022-02-01 20:00:00,000 INFO:Signal executed OpenLongMarketOrder(lots=115, direction=)\n", + "2022-02-01 20:00:00,000 INFO:Trade 1\n", + "2022-02-01 20:00:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:00:00,000 INFO:Refreshing data\n", + "2022-02-01 20:01:00,000 INFO:Data refreshed\n", + "2022-02-01 20:01:00,000 INFO:Strategy predict\n", + "2022-02-01 20:01:00,000 INFO:Trade 2\n", + "2022-02-01 20:01:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:01:00,000 INFO:Refreshing data\n", + "2022-02-01 20:02:00,000 INFO:Data refreshed\n", + "2022-02-01 20:02:00,000 INFO:Strategy predict\n", + "2022-02-01 20:02:00,000 INFO:Trade 3\n", + "2022-02-01 20:02:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:02:00,000 INFO:Refreshing data\n", + "2022-02-01 20:03:00,000 INFO:Data refreshed\n", + "2022-02-01 20:03:00,000 INFO:Strategy predict\n", + "2022-02-01 20:03:00,000 INFO:Trade 4\n", + "2022-02-01 20:03:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:03:00,000 INFO:Refreshing data\n", + "2022-02-01 20:04:00,000 INFO:Data refreshed\n", + "2022-02-01 20:04:00,000 INFO:Strategy predict\n", + "2022-02-01 20:04:00,000 INFO:Trade 5\n", + "2022-02-01 20:04:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:04:00,000 INFO:Refreshing data\n", + "2022-02-01 20:05:00,000 INFO:Data refreshed\n", + "2022-02-01 20:05:00,000 INFO:Strategy predict\n", + "2022-02-01 20:05:00,000 INFO:Trade 6\n", + "2022-02-01 20:05:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:05:00,000 INFO:Refreshing data\n", + "2022-02-01 20:06:00,000 INFO:Data refreshed\n", + "2022-02-01 20:06:00,000 INFO:Strategy predict\n", + "2022-02-01 20:06:00,000 INFO:Trade 7\n", + "2022-02-01 20:06:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:06:00,000 INFO:Refreshing data\n", + "2022-02-01 20:07:00,000 INFO:Data refreshed\n", + "2022-02-01 20:07:00,000 INFO:Strategy predict\n", + "2022-02-01 20:07:00,000 INFO:Trade 8\n", + "2022-02-01 20:07:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:07:00,000 INFO:Refreshing data\n", + "2022-02-01 20:08:00,000 INFO:Data refreshed\n", + "2022-02-01 20:08:00,000 INFO:Strategy predict\n", + "2022-02-01 20:08:00,000 INFO:Trade 9\n", + "2022-02-01 20:08:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:08:00,000 INFO:Refreshing data\n", + "2022-02-01 20:09:00,000 INFO:Data refreshed\n", + "2022-02-01 20:09:00,000 INFO:Strategy predict\n", + "2022-02-01 20:09:00,000 INFO:Trade 10\n", + "2022-02-01 20:09:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:09:00,000 INFO:Refreshing data\n", + "2022-02-01 20:10:00,000 INFO:Data refreshed\n", + "2022-02-01 20:10:00,000 INFO:Strategy predict\n", + "2022-02-01 20:10:00,000 INFO:Trade 11\n", + "2022-02-01 20:10:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:10:00,000 INFO:Refreshing data\n", + "2022-02-01 20:11:00,000 INFO:Data refreshed\n", + "2022-02-01 20:11:00,000 INFO:Strategy predict\n", + "2022-02-01 20:11:00,000 INFO:Trade 12\n", + "2022-02-01 20:11:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:11:00,000 INFO:Refreshing data\n", + "2022-02-01 20:12:00,000 INFO:Data refreshed\n", + "2022-02-01 20:12:00,000 INFO:Strategy predict\n", + "2022-02-01 20:12:00,000 INFO:Trade 13\n", + "2022-02-01 20:12:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:12:00,000 INFO:Refreshing data\n", + "2022-02-01 20:13:00,000 INFO:Data refreshed\n", + "2022-02-01 20:13:00,000 INFO:Strategy predict\n", + "2022-02-01 20:13:00,000 INFO:Trade 14\n", + "2022-02-01 20:13:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:13:00,000 INFO:Refreshing data\n", + "2022-02-01 20:14:00,000 INFO:Data refreshed\n", + "2022-02-01 20:14:00,000 INFO:Strategy predict\n", + "2022-02-01 20:14:00,000 INFO:Trade 15\n", + "2022-02-01 20:14:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:14:00,000 INFO:Refreshing data\n", + "2022-02-01 20:15:00,000 INFO:Data refreshed\n", + "2022-02-01 20:15:00,000 INFO:Strategy predict\n", + "2022-02-01 20:15:00,000 INFO:Trade 16\n", + "2022-02-01 20:15:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:15:00,000 INFO:Refreshing data\n", + "2022-02-01 20:16:00,000 INFO:Data refreshed\n", + "2022-02-01 20:16:00,000 INFO:Strategy predict\n", + "2022-02-01 20:16:00,000 INFO:Trade 17\n", + "2022-02-01 20:16:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:16:00,000 INFO:Refreshing data\n", + "2022-02-01 20:17:00,000 INFO:Data refreshed\n", + "2022-02-01 20:17:00,000 INFO:Strategy predict\n", + "2022-02-01 20:17:00,000 INFO:Trade 18\n", + "2022-02-01 20:17:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:17:00,000 INFO:Refreshing data\n", + "2022-02-01 20:18:00,000 INFO:Data refreshed\n", + "2022-02-01 20:18:00,000 INFO:Strategy predict\n", + "2022-02-01 20:18:00,000 INFO:Trade 19\n", + "2022-02-01 20:18:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:18:00,000 INFO:Refreshing data\n", + "2022-02-01 20:19:00,000 INFO:Data refreshed\n", + "2022-02-01 20:19:00,000 INFO:Strategy predict\n", + "2022-02-01 20:19:00,000 INFO:Trade 20\n", + "2022-02-01 20:19:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:19:00,000 INFO:Refreshing data\n", + "2022-02-01 20:20:00,000 INFO:Data refreshed\n", + "2022-02-01 20:20:00,000 INFO:Strategy predict\n", + "2022-02-01 20:20:00,000 INFO:Trade 21\n", + "2022-02-01 20:20:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:20:00,000 INFO:Refreshing data\n", + "2022-02-01 20:21:00,000 INFO:Data refreshed\n", + "2022-02-01 20:21:00,000 INFO:Strategy predict\n", + "2022-02-01 20:21:00,000 INFO:Trade 22\n", + "2022-02-01 20:21:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:21:00,000 INFO:Refreshing data\n", + "2022-02-01 20:22:00,000 INFO:Data refreshed\n", + "2022-02-01 20:22:00,000 INFO:Strategy predict\n", + "2022-02-01 20:22:00,000 INFO:Trade 23\n", + "2022-02-01 20:22:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:22:00,000 INFO:Refreshing data\n", + "2022-02-01 20:23:00,000 INFO:Data refreshed\n", + "2022-02-01 20:23:00,000 INFO:Strategy predict\n", + "2022-02-01 20:23:00,000 INFO:Trade 24\n", + "2022-02-01 20:23:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:23:00,000 INFO:Refreshing data\n", + "2022-02-01 20:24:00,000 INFO:Data refreshed\n", + "2022-02-01 20:24:00,000 INFO:Strategy predict\n", + "2022-02-01 20:24:00,000 INFO:Trade 25\n", + "2022-02-01 20:24:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:24:00,000 INFO:Refreshing data\n", + "2022-02-01 20:25:00,000 INFO:Data refreshed\n", + "2022-02-01 20:25:00,000 INFO:Strategy predict\n", + "2022-02-01 20:25:00,000 INFO:Trade 26\n", + "2022-02-01 20:25:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:25:00,000 INFO:Refreshing data\n", + "2022-02-01 20:26:00,000 INFO:Data refreshed\n", + "2022-02-01 20:26:00,000 INFO:Strategy predict\n", + "2022-02-01 20:26:00,000 INFO:Trade 27\n", + "2022-02-01 20:26:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:26:00,000 INFO:Refreshing data\n", + "2022-02-01 20:27:00,000 INFO:Data refreshed\n", + "2022-02-01 20:27:00,000 INFO:Strategy predict\n", + "2022-02-01 20:27:00,000 INFO:Trade 28\n", + "2022-02-01 20:27:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:27:00,000 INFO:Refreshing data\n", + "2022-02-01 20:28:00,000 INFO:Data refreshed\n", + "2022-02-01 20:28:00,000 INFO:Strategy predict\n", + "2022-02-01 20:28:00,000 INFO:Trade 29\n", + "2022-02-01 20:28:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:28:00,000 INFO:Refreshing data\n", + "2022-02-01 20:29:00,000 INFO:Data refreshed\n", + "2022-02-01 20:29:00,000 INFO:Strategy predict\n", + "2022-02-01 20:29:00,000 INFO:Trade 30\n", + "2022-02-01 20:29:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:29:00,000 INFO:Refreshing data\n", + "2022-02-01 20:30:00,000 INFO:Data refreshed\n", + "2022-02-01 20:30:00,000 INFO:Strategy predict\n", + "2022-02-01 20:30:00,000 INFO:Trade 31\n", + "2022-02-01 20:30:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:30:00,000 INFO:Refreshing data\n", + "2022-02-01 20:31:00,000 INFO:Data refreshed\n", + "2022-02-01 20:31:00,000 INFO:Strategy predict\n", + "2022-02-01 20:31:00,000 INFO:Trade 32\n", + "2022-02-01 20:31:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:31:00,000 INFO:Refreshing data\n", + "2022-02-01 20:32:00,000 INFO:Data refreshed\n", + "2022-02-01 20:32:00,000 INFO:Strategy predict\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2022-02-01 20:32:00,000 INFO:Trade 33\n", + "2022-02-01 20:32:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:32:00,000 INFO:Refreshing data\n", + "2022-02-01 20:33:00,000 INFO:Data refreshed\n", + "2022-02-01 20:33:00,000 INFO:Strategy predict\n", + "2022-02-01 20:33:00,000 INFO:Trade 34\n", + "2022-02-01 20:33:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:33:00,000 INFO:Refreshing data\n", + "2022-02-01 20:34:00,000 INFO:Data refreshed\n", + "2022-02-01 20:34:00,000 INFO:Strategy predict\n", + "2022-02-01 20:34:00,000 INFO:Trade 35\n", + "2022-02-01 20:34:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:34:00,000 INFO:Refreshing data\n", + "2022-02-01 20:35:00,000 INFO:Data refreshed\n", + "2022-02-01 20:35:00,000 INFO:Strategy predict\n", + "2022-02-01 20:35:00,000 INFO:Trade 36\n", + "2022-02-01 20:35:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:35:00,000 INFO:Refreshing data\n", + "2022-02-01 20:36:00,000 INFO:Data refreshed\n", + "2022-02-01 20:36:00,000 INFO:Strategy predict\n", + "2022-02-01 20:36:00,000 INFO:Trade 37\n", + "2022-02-01 20:36:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:36:00,000 INFO:Refreshing data\n", + "2022-02-01 20:37:00,000 INFO:Data refreshed\n", + "2022-02-01 20:37:00,000 INFO:Strategy predict\n", + "2022-02-01 20:37:00,000 INFO:Trade 38\n", + "2022-02-01 20:37:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:37:00,000 INFO:Refreshing data\n", + "2022-02-01 20:38:00,000 INFO:Data refreshed\n", + "2022-02-01 20:38:00,000 INFO:Strategy predict\n", + "2022-02-01 20:38:00,000 INFO:Trade 39\n", + "2022-02-01 20:38:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:38:00,000 INFO:Refreshing data\n", + "2022-02-01 20:39:00,000 INFO:Data refreshed\n", + "2022-02-01 20:39:00,000 INFO:Strategy predict\n", + "2022-02-01 20:39:00,000 INFO:Trade 40\n", + "2022-02-01 20:39:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:39:00,000 INFO:Refreshing data\n", + "2022-02-01 20:40:00,000 INFO:Data refreshed\n", + "2022-02-01 20:40:00,000 INFO:Strategy predict\n", + "2022-02-01 20:40:00,000 INFO:Trade 41\n", + "2022-02-01 20:40:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:40:00,000 INFO:Refreshing data\n", + "2022-02-01 20:41:00,000 INFO:Data refreshed\n", + "2022-02-01 20:41:00,000 INFO:Strategy predict\n", + "2022-02-01 20:41:00,000 INFO:Trade 42\n", + "2022-02-01 20:41:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:41:00,000 INFO:Refreshing data\n", + "2022-02-01 20:42:00,000 INFO:Data refreshed\n", + "2022-02-01 20:42:00,000 INFO:Strategy predict\n", + "2022-02-01 20:42:00,000 INFO:Trade 43\n", + "2022-02-01 20:42:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:42:00,000 INFO:Refreshing data\n", + "2022-02-01 20:43:00,000 INFO:Data refreshed\n", + "2022-02-01 20:43:00,000 INFO:Strategy predict\n", + "2022-02-01 20:43:00,000 INFO:Trade 44\n", + "2022-02-01 20:43:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:43:00,000 INFO:Refreshing data\n", + "2022-02-01 20:44:00,000 INFO:Data refreshed\n", + "2022-02-01 20:44:00,000 INFO:Strategy predict\n", + "2022-02-01 20:44:00,000 INFO:Trade 45\n", + "2022-02-01 20:44:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:44:00,000 INFO:Refreshing data\n", + "2022-02-01 20:45:00,000 INFO:Data refreshed\n", + "2022-02-01 20:45:00,000 INFO:Strategy predict\n", + "2022-02-01 20:45:00,000 INFO:Trade 46\n", + "2022-02-01 20:45:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:45:00,000 INFO:Refreshing data\n", + "2022-02-01 20:46:00,000 INFO:Data refreshed\n", + "2022-02-01 20:46:00,000 INFO:Strategy predict\n", + "2022-02-01 20:46:00,000 INFO:Trade 47\n", + "2022-02-01 20:46:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:46:00,000 INFO:Refreshing data\n", + "2022-02-01 20:47:00,000 INFO:Data refreshed\n", + "2022-02-01 20:47:00,000 INFO:Strategy predict\n", + "2022-02-01 20:47:00,000 INFO:Trade 48\n", + "2022-02-01 20:47:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:47:00,000 INFO:Refreshing data\n", + "2022-02-01 20:48:00,000 INFO:Data refreshed\n", + "2022-02-01 20:48:00,000 INFO:Strategy predict\n", + "2022-02-01 20:48:00,000 INFO:Trade 49\n", + "2022-02-01 20:48:00,000 INFO:Balance: 24.59000000\n", + "2022-02-01 20:48:00,000 INFO:Refreshing data\n", + "2022-02-01 20:49:00,000 INFO:Data refreshed\n", + "2022-02-01 20:49:00,000 INFO:Strategy predict\n", + "2022-02-01 20:00:00,000 INFO:cb36fb2b70b07bfe4e18102e815e5251 GetCandles\n", + "2022-02-01 20:00:00,000 INFO:de985340a1531dc91e108ff0eff51feb GetCandles\n", + "2022-02-01 20:00:00,000 INFO:213c3c87452019436e51a8cdafd1b00e GetCandles\n", + "2022-02-01 20:00:00,000 INFO:Loading candles for period 5:00:00 from 2022-02-01 17:00:00+00:00\n", + "2022-02-01 20:00:00,000 INFO:Marginal trade is active\n", + "2022-02-01 20:00:00,000 INFO:Got enough data for strategy\n", + "2022-02-01 20:00:00,000 INFO:Trade 0\n", + "2022-02-01 20:00:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:00:00,000 INFO:Refreshing data\n", + "2022-02-01 20:00:00,000 INFO:Data refreshed\n", + "2022-02-01 20:00:00,000 INFO:Strategy predict\n", + "2022-02-01 20:00:00,000 INFO:Trade try complete\n", + "2022-02-01 20:00:00,000 INFO:Trade 1\n", + "2022-02-01 20:00:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:00:00,000 INFO:Refreshing data\n", + "2022-02-01 20:01:00,000 INFO:Data refreshed\n", + "2022-02-01 20:01:00,000 INFO:Strategy predict\n", + "2022-02-01 20:01:00,000 INFO:Trade try complete\n", + "2022-02-01 20:01:00,000 INFO:Trade 2\n", + "2022-02-01 20:01:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:01:00,000 INFO:Refreshing data\n", + "2022-02-01 20:02:00,000 INFO:Data refreshed\n", + "2022-02-01 20:02:00,000 INFO:Strategy predict\n", + "2022-02-01 20:02:00,000 INFO:Trade try complete\n", + "2022-02-01 20:02:00,000 INFO:Trade 3\n", + "2022-02-01 20:02:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:02:00,000 INFO:Refreshing data\n", + "2022-02-01 20:03:00,000 INFO:Data refreshed\n", + "2022-02-01 20:03:00,000 INFO:Strategy predict\n", + "2022-02-01 20:03:00,000 INFO:Trade try complete\n", + "2022-02-01 20:03:00,000 INFO:Trade 4\n", + "2022-02-01 20:03:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:03:00,000 INFO:Refreshing data\n", + "2022-02-01 20:04:00,000 INFO:Data refreshed\n", + "2022-02-01 20:04:00,000 INFO:Strategy predict\n", + "2022-02-01 20:04:00,000 INFO:Trade try complete\n", + "2022-02-01 20:04:00,000 INFO:Trade 5\n", + "2022-02-01 20:04:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:04:00,000 INFO:Refreshing data\n", + "2022-02-01 20:05:00,000 INFO:Data refreshed\n", + "2022-02-01 20:05:00,000 INFO:Strategy predict\n", + "2022-02-01 20:05:00,000 INFO:Trade try complete\n", + "2022-02-01 20:05:00,000 INFO:Trade 6\n", + "2022-02-01 20:05:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:05:00,000 INFO:Refreshing data\n", + "2022-02-01 20:06:00,000 INFO:Data refreshed\n", + "2022-02-01 20:06:00,000 INFO:Strategy predict\n", + "2022-02-01 20:06:00,000 INFO:Trade try complete\n", + "2022-02-01 20:06:00,000 INFO:Trade 7\n", + "2022-02-01 20:06:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:06:00,000 INFO:Refreshing data\n", + "2022-02-01 20:07:00,000 INFO:Data refreshed\n", + "2022-02-01 20:07:00,000 INFO:Strategy predict\n", + "2022-02-01 20:07:00,000 INFO:Trade try complete\n", + "2022-02-01 20:07:00,000 INFO:Trade 8\n", + "2022-02-01 20:07:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:07:00,000 INFO:Refreshing data\n", + "2022-02-01 20:08:00,000 INFO:Data refreshed\n", + "2022-02-01 20:08:00,000 INFO:Strategy predict\n", + "2022-02-01 20:08:00,000 INFO:Trade try complete\n", + "2022-02-01 20:08:00,000 INFO:Trade 9\n", + "2022-02-01 20:08:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:08:00,000 INFO:Refreshing data\n", + "2022-02-01 20:09:00,000 INFO:Data refreshed\n", + "2022-02-01 20:09:00,000 INFO:Strategy predict\n", + "2022-02-01 20:09:00,000 INFO:Trade try complete\n", + "2022-02-01 20:09:00,000 INFO:Trade 10\n", + "2022-02-01 20:09:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:09:00,000 INFO:Refreshing data\n", + "2022-02-01 20:10:00,000 INFO:Data refreshed\n", + "2022-02-01 20:10:00,000 INFO:Strategy predict\n", + "2022-02-01 20:10:00,000 INFO:Trade try complete\n", + "2022-02-01 20:10:00,000 INFO:Trade 11\n", + "2022-02-01 20:10:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:10:00,000 INFO:Refreshing data\n", + "2022-02-01 20:11:00,000 INFO:Data refreshed\n", + "2022-02-01 20:11:00,000 INFO:Strategy predict\n", + "2022-02-01 20:11:00,000 INFO:Trade try complete\n", + "2022-02-01 20:11:00,000 INFO:Trade 12\n", + "2022-02-01 20:11:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:11:00,000 INFO:Refreshing data\n", + "2022-02-01 20:12:00,000 INFO:Data refreshed\n", + "2022-02-01 20:12:00,000 INFO:Strategy predict\n", + "2022-02-01 20:12:00,000 INFO:Trade try complete\n", + "2022-02-01 20:12:00,000 INFO:Trade 13\n", + "2022-02-01 20:12:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:12:00,000 INFO:Refreshing data\n", + "2022-02-01 20:13:00,000 INFO:Data refreshed\n", + "2022-02-01 20:13:00,000 INFO:Strategy predict\n", + "2022-02-01 20:13:00,000 INFO:Trade try complete\n", + "2022-02-01 20:13:00,000 INFO:Trade 14\n", + "2022-02-01 20:13:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:13:00,000 INFO:Refreshing data\n", + "2022-02-01 20:14:00,000 INFO:Data refreshed\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2022-02-01 20:14:00,000 INFO:Strategy predict\n", + "2022-02-01 20:14:00,000 INFO:Trade try complete\n", + "2022-02-01 20:14:00,000 INFO:Trade 15\n", + "2022-02-01 20:14:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:14:00,000 INFO:Refreshing data\n", + "2022-02-01 20:15:00,000 INFO:Data refreshed\n", + "2022-02-01 20:15:00,000 INFO:Strategy predict\n", + "2022-02-01 20:15:00,000 INFO:Trade try complete\n", + "2022-02-01 20:15:00,000 INFO:Trade 16\n", + "2022-02-01 20:15:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:15:00,000 INFO:Refreshing data\n", + "2022-02-01 20:16:00,000 INFO:Data refreshed\n", + "2022-02-01 20:16:00,000 INFO:Strategy predict\n", + "2022-02-01 20:16:00,000 INFO:Trade try complete\n", + "2022-02-01 20:16:00,000 INFO:Trade 17\n", + "2022-02-01 20:16:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:16:00,000 INFO:Refreshing data\n", + "2022-02-01 20:17:00,000 INFO:Data refreshed\n", + "2022-02-01 20:17:00,000 INFO:Strategy predict\n", + "2022-02-01 20:17:00,000 INFO:Trade try complete\n", + "2022-02-01 20:17:00,000 INFO:Trade 18\n", + "2022-02-01 20:17:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:17:00,000 INFO:Refreshing data\n", + "2022-02-01 20:18:00,000 INFO:Data refreshed\n", + "2022-02-01 20:18:00,000 INFO:Strategy predict\n", + "2022-02-01 20:18:00,000 INFO:Trade try complete\n", + "2022-02-01 20:18:00,000 INFO:Trade 19\n", + "2022-02-01 20:18:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:18:00,000 INFO:Refreshing data\n", + "2022-02-01 20:19:00,000 INFO:Data refreshed\n", + "2022-02-01 20:19:00,000 INFO:Strategy predict\n", + "2022-02-01 20:19:00,000 INFO:Trade try complete\n", + "2022-02-01 20:19:00,000 INFO:Trade 20\n", + "2022-02-01 20:19:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:19:00,000 INFO:Refreshing data\n", + "2022-02-01 20:20:00,000 INFO:Data refreshed\n", + "2022-02-01 20:20:00,000 INFO:Strategy predict\n", + "2022-02-01 20:20:00,000 INFO:Trade try complete\n", + "2022-02-01 20:20:00,000 INFO:Trade 21\n", + "2022-02-01 20:20:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:20:00,000 INFO:Refreshing data\n", + "2022-02-01 20:21:00,000 INFO:Data refreshed\n", + "2022-02-01 20:21:00,000 INFO:Strategy predict\n", + "2022-02-01 20:21:00,000 INFO:Trade try complete\n", + "2022-02-01 20:21:00,000 INFO:Trade 22\n", + "2022-02-01 20:21:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:21:00,000 INFO:Refreshing data\n", + "2022-02-01 20:22:00,000 INFO:Data refreshed\n", + "2022-02-01 20:22:00,000 INFO:Strategy predict\n", + "2022-02-01 20:22:00,000 INFO:Trade try complete\n", + "2022-02-01 20:22:00,000 INFO:Trade 23\n", + "2022-02-01 20:22:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:22:00,000 INFO:Refreshing data\n", + "2022-02-01 20:23:00,000 INFO:Data refreshed\n", + "2022-02-01 20:23:00,000 INFO:Strategy predict\n", + "2022-02-01 20:23:00,000 INFO:Trade try complete\n", + "2022-02-01 20:23:00,000 INFO:Trade 24\n", + "2022-02-01 20:23:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:23:00,000 INFO:Refreshing data\n", + "2022-02-01 20:24:00,000 INFO:Data refreshed\n", + "2022-02-01 20:24:00,000 INFO:Strategy predict\n", + "2022-02-01 20:24:00,000 INFO:Trade try complete\n", + "2022-02-01 20:24:00,000 INFO:Trade 25\n", + "2022-02-01 20:24:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:24:00,000 INFO:Refreshing data\n", + "2022-02-01 20:25:00,000 INFO:Data refreshed\n", + "2022-02-01 20:25:00,000 INFO:Strategy predict\n", + "2022-02-01 20:25:00,000 INFO:Trade try complete\n", + "2022-02-01 20:25:00,000 INFO:Trade 26\n", + "2022-02-01 20:25:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:25:00,000 INFO:Refreshing data\n", + "2022-02-01 20:26:00,000 INFO:Data refreshed\n", + "2022-02-01 20:26:00,000 INFO:Strategy predict\n", + "2022-02-01 20:26:00,000 INFO:Trade try complete\n", + "2022-02-01 20:26:00,000 INFO:Trade 27\n", + "2022-02-01 20:26:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:26:00,000 INFO:Refreshing data\n", + "2022-02-01 20:27:00,000 INFO:Data refreshed\n", + "2022-02-01 20:27:00,000 INFO:Strategy predict\n", + "2022-02-01 20:27:00,000 INFO:Trade try complete\n", + "2022-02-01 20:27:00,000 INFO:Trade 28\n", + "2022-02-01 20:27:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:27:00,000 INFO:Refreshing data\n", + "2022-02-01 20:28:00,000 INFO:Data refreshed\n", + "2022-02-01 20:28:00,000 INFO:Strategy predict\n", + "2022-02-01 20:28:00,000 INFO:Trade try complete\n", + "2022-02-01 20:28:00,000 INFO:Trade 29\n", + "2022-02-01 20:28:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:28:00,000 INFO:Refreshing data\n", + "2022-02-01 20:29:00,000 INFO:Data refreshed\n", + "2022-02-01 20:29:00,000 INFO:Strategy predict\n", + "2022-02-01 20:29:00,000 INFO:Trade try complete\n", + "2022-02-01 20:29:00,000 INFO:Trade 30\n", + "2022-02-01 20:29:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:29:00,000 INFO:Refreshing data\n", + "2022-02-01 20:30:00,000 INFO:Data refreshed\n", + "2022-02-01 20:30:00,000 INFO:Strategy predict\n", + "2022-02-01 20:30:00,000 INFO:Trade try complete\n", + "2022-02-01 20:30:00,000 INFO:Trade 31\n", + "2022-02-01 20:30:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:30:00,000 INFO:Refreshing data\n", + "2022-02-01 20:31:00,000 INFO:Data refreshed\n", + "2022-02-01 20:31:00,000 INFO:Strategy predict\n", + "2022-02-01 20:31:00,000 INFO:Trade try complete\n", + "2022-02-01 20:31:00,000 INFO:Trade 32\n", + "2022-02-01 20:31:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:31:00,000 INFO:Refreshing data\n", + "2022-02-01 20:32:00,000 INFO:Data refreshed\n", + "2022-02-01 20:32:00,000 INFO:Strategy predict\n", + "2022-02-01 20:32:00,000 INFO:Trade try complete\n", + "2022-02-01 20:32:00,000 INFO:Trade 33\n", + "2022-02-01 20:32:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:32:00,000 INFO:Refreshing data\n", + "2022-02-01 20:33:00,000 INFO:Data refreshed\n", + "2022-02-01 20:33:00,000 INFO:Strategy predict\n", + "2022-02-01 20:33:00,000 INFO:Trade try complete\n", + "2022-02-01 20:33:00,000 INFO:Trade 34\n", + "2022-02-01 20:33:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:33:00,000 INFO:Refreshing data\n", + "2022-02-01 20:34:00,000 INFO:Data refreshed\n", + "2022-02-01 20:34:00,000 INFO:Strategy predict\n", + "2022-02-01 20:34:00,000 INFO:Trade try complete\n", + "2022-02-01 20:34:00,000 INFO:Trade 35\n", + "2022-02-01 20:34:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:34:00,000 INFO:Refreshing data\n", + "2022-02-01 20:35:00,000 INFO:Data refreshed\n", + "2022-02-01 20:35:00,000 INFO:Strategy predict\n", + "2022-02-01 20:35:00,000 INFO:Trade try complete\n", + "2022-02-01 20:35:00,000 INFO:Trade 36\n", + "2022-02-01 20:35:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:35:00,000 INFO:Refreshing data\n", + "2022-02-01 20:36:00,000 INFO:Data refreshed\n", + "2022-02-01 20:36:00,000 INFO:Strategy predict\n", + "2022-02-01 20:36:00,000 INFO:Trade try complete\n", + "2022-02-01 20:36:00,000 INFO:Trade 37\n", + "2022-02-01 20:36:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:36:00,000 INFO:Refreshing data\n", + "2022-02-01 20:37:00,000 INFO:Data refreshed\n", + "2022-02-01 20:37:00,000 INFO:Strategy predict\n", + "2022-02-01 20:37:00,000 INFO:Trade try complete\n", + "2022-02-01 20:37:00,000 INFO:Trade 38\n", + "2022-02-01 20:37:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:37:00,000 INFO:Refreshing data\n", + "2022-02-01 20:38:00,000 INFO:Data refreshed\n", + "2022-02-01 20:38:00,000 INFO:Strategy predict\n", + "2022-02-01 20:38:00,000 INFO:Trade try complete\n", + "2022-02-01 20:38:00,000 INFO:Trade 39\n", + "2022-02-01 20:38:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:38:00,000 INFO:Refreshing data\n", + "2022-02-01 20:39:00,000 INFO:Data refreshed\n", + "2022-02-01 20:39:00,000 INFO:Strategy predict\n", + "2022-02-01 20:39:00,000 INFO:Trade try complete\n", + "2022-02-01 20:39:00,000 INFO:Trade 40\n", + "2022-02-01 20:39:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:39:00,000 INFO:Refreshing data\n", + "2022-02-01 20:40:00,000 INFO:Data refreshed\n", + "2022-02-01 20:40:00,000 INFO:Strategy predict\n", + "2022-02-01 20:40:00,000 INFO:Trade try complete\n", + "2022-02-01 20:40:00,000 INFO:Trade 41\n", + "2022-02-01 20:40:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:40:00,000 INFO:Refreshing data\n", + "2022-02-01 20:41:00,000 INFO:Data refreshed\n", + "2022-02-01 20:41:00,000 INFO:Strategy predict\n", + "2022-02-01 20:41:00,000 INFO:Trade try complete\n", + "2022-02-01 20:41:00,000 INFO:Trade 42\n", + "2022-02-01 20:41:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:41:00,000 INFO:Refreshing data\n", + "2022-02-01 20:42:00,000 INFO:Data refreshed\n", + "2022-02-01 20:42:00,000 INFO:Strategy predict\n", + "2022-02-01 20:42:00,000 INFO:Trade try complete\n", + "2022-02-01 20:42:00,000 INFO:Trade 43\n", + "2022-02-01 20:42:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:42:00,000 INFO:Refreshing data\n", + "2022-02-01 20:43:00,000 INFO:Data refreshed\n", + "2022-02-01 20:43:00,000 INFO:Strategy predict\n", + "2022-02-01 20:43:00,000 INFO:Trade try complete\n", + "2022-02-01 20:43:00,000 INFO:Trade 44\n", + "2022-02-01 20:43:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:43:00,000 INFO:Refreshing data\n", + "2022-02-01 20:44:00,000 INFO:Data refreshed\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2022-02-01 20:44:00,000 INFO:Strategy predict\n", + "2022-02-01 20:44:00,000 INFO:Trade try complete\n", + "2022-02-01 20:44:00,000 INFO:Trade 45\n", + "2022-02-01 20:44:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:44:00,000 INFO:Refreshing data\n", + "2022-02-01 20:45:00,000 INFO:Data refreshed\n", + "2022-02-01 20:45:00,000 INFO:Strategy predict\n", + "2022-02-01 20:45:00,000 INFO:Got signals [OpenShortMarketOrder(lots=65, direction=)]\n", + "2022-02-01 20:45:00,000 INFO:Trying to execute signal OpenShortMarketOrder(lots=65, direction=)\n", + "2022-02-01 20:45:00,000 WARNING:Operation: OrderDirection.ORDER_DIRECTION_SELL, 19919.25000000\n", + "2022-02-01 20:45:00,000 INFO:Signal executed OpenShortMarketOrder(lots=65, direction=)\n", + "2022-02-01 20:45:00,000 INFO:Trade 46\n", + "2022-02-01 20:45:00,000 INFO:Balance: 39969.94000000\n", + "2022-02-01 20:45:00,000 INFO:Refreshing data\n", + "2022-02-01 20:46:00,000 INFO:Data refreshed\n", + "2022-02-01 20:46:00,000 INFO:Strategy predict\n", + "2022-02-01 20:46:00,000 INFO:Trade 47\n", + "2022-02-01 20:46:00,000 INFO:Balance: 39969.94000000\n", + "2022-02-01 20:46:00,000 INFO:Refreshing data\n", + "2022-02-01 20:47:00,000 INFO:Data refreshed\n", + "2022-02-01 20:47:00,000 INFO:Strategy predict\n", + "2022-02-01 20:47:00,000 INFO:Trade 48\n", + "2022-02-01 20:47:00,000 INFO:Balance: 39969.94000000\n", + "2022-02-01 20:47:00,000 INFO:Refreshing data\n", + "2022-02-01 20:48:00,000 INFO:Data refreshed\n", + "2022-02-01 20:48:00,000 INFO:Strategy predict\n", + "2022-02-01 20:48:00,000 INFO:Trade 49\n", + "2022-02-01 20:48:00,000 INFO:Balance: 39969.94000000\n", + "2022-02-01 20:48:00,000 INFO:Refreshing data\n", + "2022-02-01 20:49:00,000 INFO:Data refreshed\n", + "2022-02-01 20:49:00,000 INFO:Strategy predict\n", + "2022-02-01 20:00:00,000 INFO:73b4915626a6f9fae3d6b1faadd2b3f0 GetCandles\n", + "2022-02-01 20:00:00,000 INFO:4943406ce66bed9baba9031e69d8f5a3 GetCandles\n", + "2022-02-01 20:00:00,000 INFO:c782d925a41d3def35dd4269ce2f13f4 GetCandles\n", + "2022-02-01 20:00:00,000 INFO:Loading candles for period 5:00:00 from 2022-02-01 17:00:00+00:00\n", + "2022-02-01 20:00:00,000 INFO:Marginal trade is active\n", + "2022-02-01 20:00:00,000 INFO:Got enough data for strategy\n", + "2022-02-01 20:00:00,000 INFO:Trade 0\n", + "2022-02-01 20:00:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:00:00,000 INFO:Refreshing data\n", + "2022-02-01 20:00:00,000 INFO:Data refreshed\n", + "2022-02-01 20:00:00,000 INFO:Strategy predict\n", + "2022-02-01 20:00:00,000 INFO:Trade try complete\n", + "2022-02-01 20:00:00,000 INFO:Trade 1\n", + "2022-02-01 20:00:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:00:00,000 INFO:Refreshing data\n", + "2022-02-01 20:01:00,000 INFO:Data refreshed\n", + "2022-02-01 20:01:00,000 INFO:Strategy predict\n", + "2022-02-01 20:01:00,000 INFO:Trade try complete\n", + "2022-02-01 20:01:00,000 INFO:Trade 2\n", + "2022-02-01 20:01:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:01:00,000 INFO:Refreshing data\n", + "2022-02-01 20:02:00,000 INFO:Data refreshed\n", + "2022-02-01 20:02:00,000 INFO:Strategy predict\n", + "2022-02-01 20:02:00,000 INFO:Trade try complete\n", + "2022-02-01 20:02:00,000 INFO:Trade 3\n", + "2022-02-01 20:02:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:02:00,000 INFO:Refreshing data\n", + "2022-02-01 20:03:00,000 INFO:Data refreshed\n", + "2022-02-01 20:03:00,000 INFO:Strategy predict\n", + "2022-02-01 20:03:00,000 INFO:Trade try complete\n", + "2022-02-01 20:03:00,000 INFO:Trade 4\n", + "2022-02-01 20:03:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:03:00,000 INFO:Refreshing data\n", + "2022-02-01 20:04:00,000 INFO:Data refreshed\n", + "2022-02-01 20:04:00,000 INFO:Strategy predict\n", + "2022-02-01 20:04:00,000 INFO:Trade try complete\n", + "2022-02-01 20:04:00,000 INFO:Trade 5\n", + "2022-02-01 20:04:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:04:00,000 INFO:Refreshing data\n", + "2022-02-01 20:05:00,000 INFO:Data refreshed\n", + "2022-02-01 20:05:00,000 INFO:Strategy predict\n", + "2022-02-01 20:05:00,000 INFO:Trade try complete\n", + "2022-02-01 20:05:00,000 INFO:Trade 6\n", + "2022-02-01 20:05:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:05:00,000 INFO:Refreshing data\n", + "2022-02-01 20:06:00,000 INFO:Data refreshed\n", + "2022-02-01 20:06:00,000 INFO:Strategy predict\n", + "2022-02-01 20:06:00,000 INFO:Trade try complete\n", + "2022-02-01 20:06:00,000 INFO:Trade 7\n", + "2022-02-01 20:06:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:06:00,000 INFO:Refreshing data\n", + "2022-02-01 20:07:00,000 INFO:Data refreshed\n", + "2022-02-01 20:07:00,000 INFO:Strategy predict\n", + "2022-02-01 20:07:00,000 INFO:Trade try complete\n", + "2022-02-01 20:07:00,000 INFO:Trade 8\n", + "2022-02-01 20:07:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:07:00,000 INFO:Refreshing data\n", + "2022-02-01 20:08:00,000 INFO:Data refreshed\n", + "2022-02-01 20:08:00,000 INFO:Strategy predict\n", + "2022-02-01 20:08:00,000 INFO:Trade try complete\n", + "2022-02-01 20:08:00,000 INFO:Trade 9\n", + "2022-02-01 20:08:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:08:00,000 INFO:Refreshing data\n", + "2022-02-01 20:09:00,000 INFO:Data refreshed\n", + "2022-02-01 20:09:00,000 INFO:Strategy predict\n", + "2022-02-01 20:09:00,000 INFO:Trade try complete\n", + "2022-02-01 20:09:00,000 INFO:Trade 10\n", + "2022-02-01 20:09:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:09:00,000 INFO:Refreshing data\n", + "2022-02-01 20:10:00,000 INFO:Data refreshed\n", + "2022-02-01 20:10:00,000 INFO:Strategy predict\n", + "2022-02-01 20:10:00,000 INFO:Trade try complete\n", + "2022-02-01 20:10:00,000 INFO:Trade 11\n", + "2022-02-01 20:10:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:10:00,000 INFO:Refreshing data\n", + "2022-02-01 20:11:00,000 INFO:Data refreshed\n", + "2022-02-01 20:11:00,000 INFO:Strategy predict\n", + "2022-02-01 20:11:00,000 INFO:Trade try complete\n", + "2022-02-01 20:11:00,000 INFO:Trade 12\n", + "2022-02-01 20:11:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:11:00,000 INFO:Refreshing data\n", + "2022-02-01 20:12:00,000 INFO:Data refreshed\n", + "2022-02-01 20:12:00,000 INFO:Strategy predict\n", + "2022-02-01 20:12:00,000 INFO:Trade try complete\n", + "2022-02-01 20:12:00,000 INFO:Trade 13\n", + "2022-02-01 20:12:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:12:00,000 INFO:Refreshing data\n", + "2022-02-01 20:13:00,000 INFO:Data refreshed\n", + "2022-02-01 20:13:00,000 INFO:Strategy predict\n", + "2022-02-01 20:13:00,000 INFO:Trade try complete\n", + "2022-02-01 20:13:00,000 INFO:Trade 14\n", + "2022-02-01 20:13:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:13:00,000 INFO:Refreshing data\n", + "2022-02-01 20:14:00,000 INFO:Data refreshed\n", + "2022-02-01 20:14:00,000 INFO:Strategy predict\n", + "2022-02-01 20:14:00,000 INFO:Got signals [OpenShortMarketOrder(lots=6, direction=)]\n", + "2022-02-01 20:14:00,000 INFO:Trying to execute signal OpenShortMarketOrder(lots=6, direction=)\n", + "2022-02-01 20:14:00,000 WARNING:Operation: OrderDirection.ORDER_DIRECTION_SELL, 17938.92000000\n", + "2022-02-01 20:14:00,000 INFO:Signal executed OpenShortMarketOrder(lots=6, direction=)\n", + "2022-02-01 20:14:00,000 INFO:Trade 15\n", + "2022-02-01 20:14:00,000 INFO:Balance: 37989.61000000\n", + "2022-02-01 20:14:00,000 INFO:Refreshing data\n", + "2022-02-01 20:15:00,000 INFO:Data refreshed\n", + "2022-02-01 20:15:00,000 INFO:Strategy predict\n", + "2022-02-01 20:15:00,000 INFO:Trade 16\n", + "2022-02-01 20:15:00,000 INFO:Balance: 37989.61000000\n", + "2022-02-01 20:15:00,000 INFO:Refreshing data\n", + "2022-02-01 20:16:00,000 INFO:Data refreshed\n", + "2022-02-01 20:16:00,000 INFO:Strategy predict\n", + "2022-02-01 20:16:00,000 INFO:Trade 17\n", + "2022-02-01 20:16:00,000 INFO:Balance: 37989.61000000\n", + "2022-02-01 20:16:00,000 INFO:Refreshing data\n", + "2022-02-01 20:17:00,000 INFO:Data refreshed\n", + "2022-02-01 20:17:00,000 INFO:Strategy predict\n", + "2022-02-01 20:17:00,000 INFO:Trade 18\n", + "2022-02-01 20:17:00,000 INFO:Balance: 37989.61000000\n", + "2022-02-01 20:17:00,000 INFO:Refreshing data\n", + "2022-02-01 20:18:00,000 INFO:Data refreshed\n", + "2022-02-01 20:18:00,000 INFO:Strategy predict\n", + "2022-02-01 20:18:00,000 INFO:Trade 19\n", + "2022-02-01 20:18:00,000 INFO:Balance: 37989.61000000\n", + "2022-02-01 20:18:00,000 INFO:Refreshing data\n", + "2022-02-01 20:19:00,000 INFO:Data refreshed\n", + "2022-02-01 20:19:00,000 INFO:Strategy predict\n", + "2022-02-01 20:19:00,000 INFO:Trade 20\n", + "2022-02-01 20:19:00,000 INFO:Balance: 37989.61000000\n", + "2022-02-01 20:19:00,000 INFO:Refreshing data\n", + "2022-02-01 20:20:00,000 INFO:Data refreshed\n", + "2022-02-01 20:20:00,000 INFO:Strategy predict\n", + "2022-02-01 20:20:00,000 INFO:Got signals [CloseShortMarketOrder(lots=6, direction=), OpenLongMarketOrder(lots=12, direction=)]\n", + "2022-02-01 20:20:00,000 INFO:Trying to execute signal CloseShortMarketOrder(lots=6, direction=)\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2022-02-01 20:20:00,000 WARNING:Operation: OrderDirection.ORDER_DIRECTION_BUY, -17977.44000000\n", + "2022-02-01 20:20:00,000 INFO:Signal executed CloseShortMarketOrder(lots=6, direction=)\n", + "2022-02-01 20:20:00,000 INFO:Trying to execute signal OpenLongMarketOrder(lots=12, direction=)\n", + "2022-02-01 20:20:00,000 WARNING:Operation: OrderDirection.ORDER_DIRECTION_BUY, -35954.88000000\n", + "2022-02-01 20:20:00,000 INFO:Signal executed OpenLongMarketOrder(lots=12, direction=)\n", + "2022-02-01 20:20:00,000 INFO:Trade 21\n", + "2022-02-01 20:20:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:20:00,000 INFO:Refreshing data\n", + "2022-02-01 20:21:00,000 INFO:Data refreshed\n", + "2022-02-01 20:21:00,000 INFO:Strategy predict\n", + "2022-02-01 20:21:00,000 INFO:Trade 22\n", + "2022-02-01 20:21:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:21:00,000 INFO:Refreshing data\n", + "2022-02-01 20:22:00,000 INFO:Data refreshed\n", + "2022-02-01 20:22:00,000 INFO:Strategy predict\n", + "2022-02-01 20:22:00,000 INFO:Trade 23\n", + "2022-02-01 20:22:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:22:00,000 INFO:Refreshing data\n", + "2022-02-01 20:23:00,000 INFO:Data refreshed\n", + "2022-02-01 20:23:00,000 INFO:Strategy predict\n", + "2022-02-01 20:23:00,000 INFO:Trade 24\n", + "2022-02-01 20:23:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:23:00,000 INFO:Refreshing data\n", + "2022-02-01 20:24:00,000 INFO:Data refreshed\n", + "2022-02-01 20:24:00,000 INFO:Strategy predict\n", + "2022-02-01 20:24:00,000 INFO:Trade 25\n", + "2022-02-01 20:24:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:24:00,000 INFO:Refreshing data\n", + "2022-02-01 20:25:00,000 INFO:Data refreshed\n", + "2022-02-01 20:25:00,000 INFO:Strategy predict\n", + "2022-02-01 20:25:00,000 INFO:Trade 26\n", + "2022-02-01 20:25:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:25:00,000 INFO:Refreshing data\n", + "2022-02-01 20:26:00,000 INFO:Data refreshed\n", + "2022-02-01 20:26:00,000 INFO:Strategy predict\n", + "2022-02-01 20:26:00,000 INFO:Trade 27\n", + "2022-02-01 20:26:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:26:00,000 INFO:Refreshing data\n", + "2022-02-01 20:27:00,000 INFO:Data refreshed\n", + "2022-02-01 20:27:00,000 INFO:Strategy predict\n", + "2022-02-01 20:27:00,000 INFO:Trade 28\n", + "2022-02-01 20:27:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:27:00,000 INFO:Refreshing data\n", + "2022-02-01 20:28:00,000 INFO:Data refreshed\n", + "2022-02-01 20:28:00,000 INFO:Strategy predict\n", + "2022-02-01 20:28:00,000 INFO:Trade 29\n", + "2022-02-01 20:28:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:28:00,000 INFO:Refreshing data\n", + "2022-02-01 20:29:00,000 INFO:Data refreshed\n", + "2022-02-01 20:29:00,000 INFO:Strategy predict\n", + "2022-02-01 20:29:00,000 INFO:Trade 30\n", + "2022-02-01 20:29:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:29:00,000 INFO:Refreshing data\n", + "2022-02-01 20:30:00,000 INFO:Data refreshed\n", + "2022-02-01 20:30:00,000 INFO:Strategy predict\n", + "2022-02-01 20:30:00,000 INFO:Trade 31\n", + "2022-02-01 20:30:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:30:00,000 INFO:Refreshing data\n", + "2022-02-01 20:31:00,000 INFO:Data refreshed\n", + "2022-02-01 20:31:00,000 INFO:Strategy predict\n", + "2022-02-01 20:31:00,000 INFO:Trade 32\n", + "2022-02-01 20:31:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:31:00,000 INFO:Refreshing data\n", + "2022-02-01 20:32:00,000 INFO:Data refreshed\n", + "2022-02-01 20:32:00,000 INFO:Strategy predict\n", + "2022-02-01 20:32:00,000 INFO:Trade 33\n", + "2022-02-01 20:32:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:32:00,000 INFO:Refreshing data\n", + "2022-02-01 20:33:00,000 INFO:Data refreshed\n", + "2022-02-01 20:33:00,000 INFO:Strategy predict\n", + "2022-02-01 20:33:00,000 INFO:Trade 34\n", + "2022-02-01 20:33:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:33:00,000 INFO:Refreshing data\n", + "2022-02-01 20:34:00,000 INFO:Data refreshed\n", + "2022-02-01 20:34:00,000 INFO:Strategy predict\n", + "2022-02-01 20:34:00,000 INFO:Trade 35\n", + "2022-02-01 20:34:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:34:00,000 INFO:Refreshing data\n", + "2022-02-01 20:35:00,000 INFO:Data refreshed\n", + "2022-02-01 20:35:00,000 INFO:Strategy predict\n", + "2022-02-01 20:35:00,000 INFO:Trade 36\n", + "2022-02-01 20:35:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:35:00,000 INFO:Refreshing data\n", + "2022-02-01 20:36:00,000 INFO:Data refreshed\n", + "2022-02-01 20:36:00,000 INFO:Strategy predict\n", + "2022-02-01 20:36:00,000 INFO:Trade 37\n", + "2022-02-01 20:36:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:36:00,000 INFO:Refreshing data\n", + "2022-02-01 20:37:00,000 INFO:Data refreshed\n", + "2022-02-01 20:37:00,000 INFO:Strategy predict\n", + "2022-02-01 20:37:00,000 INFO:Trade 38\n", + "2022-02-01 20:37:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:37:00,000 INFO:Refreshing data\n", + "2022-02-01 20:38:00,000 INFO:Data refreshed\n", + "2022-02-01 20:38:00,000 INFO:Strategy predict\n", + "2022-02-01 20:38:00,000 INFO:Trade 39\n", + "2022-02-01 20:38:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:38:00,000 INFO:Refreshing data\n", + "2022-02-01 20:39:00,000 INFO:Data refreshed\n", + "2022-02-01 20:39:00,000 INFO:Strategy predict\n", + "2022-02-01 20:39:00,000 INFO:Trade 40\n", + "2022-02-01 20:39:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:39:00,000 INFO:Refreshing data\n", + "2022-02-01 20:40:00,000 INFO:Data refreshed\n", + "2022-02-01 20:40:00,000 INFO:Strategy predict\n", + "2022-02-01 20:40:00,000 INFO:Trade 41\n", + "2022-02-01 20:40:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:40:00,000 INFO:Refreshing data\n", + "2022-02-01 20:41:00,000 INFO:Data refreshed\n", + "2022-02-01 20:41:00,000 INFO:Strategy predict\n", + "2022-02-01 20:41:00,000 INFO:Trade 42\n", + "2022-02-01 20:41:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:41:00,000 INFO:Refreshing data\n", + "2022-02-01 20:42:00,000 INFO:Data refreshed\n", + "2022-02-01 20:42:00,000 INFO:Strategy predict\n", + "2022-02-01 20:42:00,000 INFO:Trade 43\n", + "2022-02-01 20:42:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:42:00,000 INFO:Refreshing data\n", + "2022-02-01 20:43:00,000 INFO:Data refreshed\n", + "2022-02-01 20:43:00,000 INFO:Strategy predict\n", + "2022-02-01 20:43:00,000 INFO:Trade 44\n", + "2022-02-01 20:43:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:43:00,000 INFO:Refreshing data\n", + "2022-02-01 20:44:00,000 INFO:Data refreshed\n", + "2022-02-01 20:44:00,000 INFO:Strategy predict\n", + "2022-02-01 20:44:00,000 INFO:Trade 45\n", + "2022-02-01 20:44:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:44:00,000 INFO:Refreshing data\n", + "2022-02-01 20:45:00,000 INFO:Data refreshed\n", + "2022-02-01 20:45:00,000 INFO:Strategy predict\n", + "2022-02-01 20:45:00,000 INFO:Trade 46\n", + "2022-02-01 20:45:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:45:00,000 INFO:Refreshing data\n", + "2022-02-01 20:46:00,000 INFO:Data refreshed\n", + "2022-02-01 20:46:00,000 INFO:Strategy predict\n", + "2022-02-01 20:46:00,000 INFO:Trade 47\n", + "2022-02-01 20:46:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:46:00,000 INFO:Refreshing data\n", + "2022-02-01 20:47:00,000 INFO:Data refreshed\n", + "2022-02-01 20:47:00,000 INFO:Strategy predict\n", + "2022-02-01 20:47:00,000 INFO:Trade 48\n", + "2022-02-01 20:47:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:47:00,000 INFO:Refreshing data\n", + "2022-02-01 20:48:00,000 INFO:Data refreshed\n", + "2022-02-01 20:48:00,000 INFO:Strategy predict\n", + "2022-02-01 20:48:00,000 INFO:Trade 49\n", + "2022-02-01 20:48:00,000 INFO:Balance: -15942.71000000\n", + "2022-02-01 20:48:00,000 INFO:Refreshing data\n", + "2022-02-01 20:49:00,000 INFO:Data refreshed\n", + "2022-02-01 20:49:00,000 INFO:Strategy predict\n", + "2022-02-01 20:00:00,000 INFO:25bf6d098f590bda1b9d184a554c0001 GetCandles\n", + "2022-02-01 20:00:00,000 INFO:fee88ad1df39149c099a9f286c6af805 GetCandles\n", + "2022-02-01 20:00:00,000 INFO:ad1bc7bd9ca8fdbd1e4b8e706627a2bc GetCandles\n", + "2022-02-01 20:00:00,000 INFO:Loading candles for period 5:00:00 from 2022-02-01 17:00:00+00:00\n", + "2022-02-01 20:00:00,000 INFO:Marginal trade is active\n", + "2022-02-01 20:00:00,000 INFO:Got enough data for strategy\n", + "2022-02-01 20:00:00,000 INFO:Trade 0\n", + "2022-02-01 20:00:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:00:00,000 INFO:Refreshing data\n", + "2022-02-01 20:00:00,000 INFO:Data refreshed\n", + "2022-02-01 20:00:00,000 INFO:Strategy predict\n", + "2022-02-01 20:00:00,000 INFO:Trade try complete\n", + "2022-02-01 20:00:00,000 INFO:Trade 1\n", + "2022-02-01 20:00:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:00:00,000 INFO:Refreshing data\n", + "2022-02-01 20:01:00,000 INFO:Data refreshed\n", + "2022-02-01 20:01:00,000 INFO:Strategy predict\n", + "2022-02-01 20:01:00,000 INFO:Trade try complete\n", + "2022-02-01 20:01:00,000 INFO:Trade 2\n", + "2022-02-01 20:01:00,000 INFO:Balance: 20050.69000000\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2022-02-01 20:01:00,000 INFO:Refreshing data\n", + "2022-02-01 20:02:00,000 INFO:Data refreshed\n", + "2022-02-01 20:02:00,000 INFO:Strategy predict\n", + "2022-02-01 20:02:00,000 INFO:Trade try complete\n", + "2022-02-01 20:02:00,000 INFO:Trade 3\n", + "2022-02-01 20:02:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:02:00,000 INFO:Refreshing data\n", + "2022-02-01 20:03:00,000 INFO:Data refreshed\n", + "2022-02-01 20:03:00,000 INFO:Strategy predict\n", + "2022-02-01 20:03:00,000 INFO:Trade try complete\n", + "2022-02-01 20:03:00,000 INFO:Trade 4\n", + "2022-02-01 20:03:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:03:00,000 INFO:Refreshing data\n", + "2022-02-01 20:04:00,000 INFO:Data refreshed\n", + "2022-02-01 20:04:00,000 INFO:Strategy predict\n", + "2022-02-01 20:04:00,000 INFO:Trade try complete\n", + "2022-02-01 20:04:00,000 INFO:Trade 5\n", + "2022-02-01 20:04:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:04:00,000 INFO:Refreshing data\n", + "2022-02-01 20:05:00,000 INFO:Data refreshed\n", + "2022-02-01 20:05:00,000 INFO:Strategy predict\n", + "2022-02-01 20:05:00,000 INFO:Trade try complete\n", + "2022-02-01 20:05:00,000 INFO:Trade 6\n", + "2022-02-01 20:05:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:05:00,000 INFO:Refreshing data\n", + "2022-02-01 20:06:00,000 INFO:Data refreshed\n", + "2022-02-01 20:06:00,000 INFO:Strategy predict\n", + "2022-02-01 20:06:00,000 INFO:Trade try complete\n", + "2022-02-01 20:06:00,000 INFO:Trade 7\n", + "2022-02-01 20:06:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:06:00,000 INFO:Refreshing data\n", + "2022-02-01 20:07:00,000 INFO:Data refreshed\n", + "2022-02-01 20:07:00,000 INFO:Strategy predict\n", + "2022-02-01 20:07:00,000 INFO:Trade try complete\n", + "2022-02-01 20:07:00,000 INFO:Trade 8\n", + "2022-02-01 20:07:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:07:00,000 INFO:Refreshing data\n", + "2022-02-01 20:08:00,000 INFO:Data refreshed\n", + "2022-02-01 20:08:00,000 INFO:Strategy predict\n", + "2022-02-01 20:08:00,000 INFO:Trade try complete\n", + "2022-02-01 20:08:00,000 INFO:Trade 9\n", + "2022-02-01 20:08:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:08:00,000 INFO:Refreshing data\n", + "2022-02-01 20:09:00,000 INFO:Data refreshed\n", + "2022-02-01 20:09:00,000 INFO:Strategy predict\n", + "2022-02-01 20:09:00,000 INFO:Trade try complete\n", + "2022-02-01 20:09:00,000 INFO:Trade 10\n", + "2022-02-01 20:09:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:09:00,000 INFO:Refreshing data\n", + "2022-02-01 20:10:00,000 INFO:Data refreshed\n", + "2022-02-01 20:10:00,000 INFO:Strategy predict\n", + "2022-02-01 20:10:00,000 INFO:Trade try complete\n", + "2022-02-01 20:10:00,000 INFO:Trade 11\n", + "2022-02-01 20:10:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:10:00,000 INFO:Refreshing data\n", + "2022-02-01 20:11:00,000 INFO:Data refreshed\n", + "2022-02-01 20:11:00,000 INFO:Strategy predict\n", + "2022-02-01 20:11:00,000 INFO:Trade try complete\n", + "2022-02-01 20:11:00,000 INFO:Trade 12\n", + "2022-02-01 20:11:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:11:00,000 INFO:Refreshing data\n", + "2022-02-01 20:12:00,000 INFO:Data refreshed\n", + "2022-02-01 20:12:00,000 INFO:Strategy predict\n", + "2022-02-01 20:12:00,000 INFO:Trade try complete\n", + "2022-02-01 20:12:00,000 INFO:Trade 13\n", + "2022-02-01 20:12:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:12:00,000 INFO:Refreshing data\n", + "2022-02-01 20:13:00,000 INFO:Data refreshed\n", + "2022-02-01 20:13:00,000 INFO:Strategy predict\n", + "2022-02-01 20:13:00,000 INFO:Trade try complete\n", + "2022-02-01 20:13:00,000 INFO:Trade 14\n", + "2022-02-01 20:13:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:13:00,000 INFO:Refreshing data\n", + "2022-02-01 20:14:00,000 INFO:Data refreshed\n", + "2022-02-01 20:14:00,000 INFO:Strategy predict\n", + "2022-02-01 20:14:00,000 INFO:Trade try complete\n", + "2022-02-01 20:14:00,000 INFO:Trade 15\n", + "2022-02-01 20:14:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:14:00,000 INFO:Refreshing data\n", + "2022-02-01 20:15:00,000 INFO:Data refreshed\n", + "2022-02-01 20:15:00,000 INFO:Strategy predict\n", + "2022-02-01 20:15:00,000 INFO:Trade try complete\n", + "2022-02-01 20:15:00,000 INFO:Trade 16\n", + "2022-02-01 20:15:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:15:00,000 INFO:Refreshing data\n", + "2022-02-01 20:16:00,000 INFO:Data refreshed\n", + "2022-02-01 20:16:00,000 INFO:Strategy predict\n", + "2022-02-01 20:16:00,000 INFO:Trade try complete\n", + "2022-02-01 20:16:00,000 INFO:Trade 17\n", + "2022-02-01 20:16:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:16:00,000 INFO:Refreshing data\n", + "2022-02-01 20:17:00,000 INFO:Data refreshed\n", + "2022-02-01 20:17:00,000 INFO:Strategy predict\n", + "2022-02-01 20:17:00,000 INFO:Trade try complete\n", + "2022-02-01 20:17:00,000 INFO:Trade 18\n", + "2022-02-01 20:17:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:17:00,000 INFO:Refreshing data\n", + "2022-02-01 20:18:00,000 INFO:Data refreshed\n", + "2022-02-01 20:18:00,000 INFO:Strategy predict\n", + "2022-02-01 20:18:00,000 INFO:Trade try complete\n", + "2022-02-01 20:18:00,000 INFO:Trade 19\n", + "2022-02-01 20:18:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:18:00,000 INFO:Refreshing data\n", + "2022-02-01 20:19:00,000 INFO:Data refreshed\n", + "2022-02-01 20:19:00,000 INFO:Strategy predict\n", + "2022-02-01 20:19:00,000 INFO:Trade try complete\n", + "2022-02-01 20:19:00,000 INFO:Trade 20\n", + "2022-02-01 20:19:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:19:00,000 INFO:Refreshing data\n", + "2022-02-01 20:20:00,000 INFO:Data refreshed\n", + "2022-02-01 20:20:00,000 INFO:Strategy predict\n", + "2022-02-01 20:20:00,000 INFO:Trade try complete\n", + "2022-02-01 20:20:00,000 INFO:Trade 21\n", + "2022-02-01 20:20:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:20:00,000 INFO:Refreshing data\n", + "2022-02-01 20:21:00,000 INFO:Data refreshed\n", + "2022-02-01 20:21:00,000 INFO:Strategy predict\n", + "2022-02-01 20:21:00,000 INFO:Trade try complete\n", + "2022-02-01 20:21:00,000 INFO:Trade 22\n", + "2022-02-01 20:21:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:21:00,000 INFO:Refreshing data\n", + "2022-02-01 20:22:00,000 INFO:Data refreshed\n", + "2022-02-01 20:22:00,000 INFO:Strategy predict\n", + "2022-02-01 20:22:00,000 INFO:Trade try complete\n", + "2022-02-01 20:22:00,000 INFO:Trade 23\n", + "2022-02-01 20:22:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:22:00,000 INFO:Refreshing data\n", + "2022-02-01 20:23:00,000 INFO:Data refreshed\n", + "2022-02-01 20:23:00,000 INFO:Strategy predict\n", + "2022-02-01 20:23:00,000 INFO:Trade try complete\n", + "2022-02-01 20:23:00,000 INFO:Trade 24\n", + "2022-02-01 20:23:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:23:00,000 INFO:Refreshing data\n", + "2022-02-01 20:24:00,000 INFO:Data refreshed\n", + "2022-02-01 20:24:00,000 INFO:Strategy predict\n", + "2022-02-01 20:24:00,000 INFO:Trade try complete\n", + "2022-02-01 20:24:00,000 INFO:Trade 25\n", + "2022-02-01 20:24:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:24:00,000 INFO:Refreshing data\n", + "2022-02-01 20:25:00,000 INFO:Data refreshed\n", + "2022-02-01 20:25:00,000 INFO:Strategy predict\n", + "2022-02-01 20:25:00,000 INFO:Trade try complete\n", + "2022-02-01 20:25:00,000 INFO:Trade 26\n", + "2022-02-01 20:25:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:25:00,000 INFO:Refreshing data\n", + "2022-02-01 20:26:00,000 INFO:Data refreshed\n", + "2022-02-01 20:26:00,000 INFO:Strategy predict\n", + "2022-02-01 20:26:00,000 INFO:Trade try complete\n", + "2022-02-01 20:26:00,000 INFO:Trade 27\n", + "2022-02-01 20:26:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:26:00,000 INFO:Refreshing data\n", + "2022-02-01 20:27:00,000 INFO:Data refreshed\n", + "2022-02-01 20:27:00,000 INFO:Strategy predict\n", + "2022-02-01 20:27:00,000 INFO:Trade try complete\n", + "2022-02-01 20:27:00,000 INFO:Trade 28\n", + "2022-02-01 20:27:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:27:00,000 INFO:Refreshing data\n", + "2022-02-01 20:28:00,000 INFO:Data refreshed\n", + "2022-02-01 20:28:00,000 INFO:Strategy predict\n", + "2022-02-01 20:28:00,000 INFO:Trade try complete\n", + "2022-02-01 20:28:00,000 INFO:Trade 29\n", + "2022-02-01 20:28:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:28:00,000 INFO:Refreshing data\n", + "2022-02-01 20:29:00,000 INFO:Data refreshed\n", + "2022-02-01 20:29:00,000 INFO:Strategy predict\n", + "2022-02-01 20:29:00,000 INFO:Trade try complete\n", + "2022-02-01 20:29:00,000 INFO:Trade 30\n", + "2022-02-01 20:29:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:29:00,000 INFO:Refreshing data\n", + "2022-02-01 20:30:00,000 INFO:Data refreshed\n", + "2022-02-01 20:30:00,000 INFO:Strategy predict\n", + "2022-02-01 20:30:00,000 INFO:Trade try complete\n", + "2022-02-01 20:30:00,000 INFO:Trade 31\n", + "2022-02-01 20:30:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:30:00,000 INFO:Refreshing data\n", + "2022-02-01 20:31:00,000 INFO:Data refreshed\n", + "2022-02-01 20:31:00,000 INFO:Strategy predict\n", + "2022-02-01 20:31:00,000 INFO:Trade try complete\n", + "2022-02-01 20:31:00,000 INFO:Trade 32\n", + "2022-02-01 20:31:00,000 INFO:Balance: 20050.69000000\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2022-02-01 20:31:00,000 INFO:Refreshing data\n", + "2022-02-01 20:32:00,000 INFO:Data refreshed\n", + "2022-02-01 20:32:00,000 INFO:Strategy predict\n", + "2022-02-01 20:32:00,000 INFO:Trade try complete\n", + "2022-02-01 20:32:00,000 INFO:Trade 33\n", + "2022-02-01 20:32:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:32:00,000 INFO:Refreshing data\n", + "2022-02-01 20:33:00,000 INFO:Data refreshed\n", + "2022-02-01 20:33:00,000 INFO:Strategy predict\n", + "2022-02-01 20:33:00,000 INFO:Trade try complete\n", + "2022-02-01 20:33:00,000 INFO:Trade 34\n", + "2022-02-01 20:33:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:33:00,000 INFO:Refreshing data\n", + "2022-02-01 20:34:00,000 INFO:Data refreshed\n", + "2022-02-01 20:34:00,000 INFO:Strategy predict\n", + "2022-02-01 20:34:00,000 INFO:Trade try complete\n", + "2022-02-01 20:34:00,000 INFO:Trade 35\n", + "2022-02-01 20:34:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:34:00,000 INFO:Refreshing data\n", + "2022-02-01 20:35:00,000 INFO:Data refreshed\n", + "2022-02-01 20:35:00,000 INFO:Strategy predict\n", + "2022-02-01 20:35:00,000 INFO:Trade try complete\n", + "2022-02-01 20:35:00,000 INFO:Trade 36\n", + "2022-02-01 20:35:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:35:00,000 INFO:Refreshing data\n", + "2022-02-01 20:36:00,000 INFO:Data refreshed\n", + "2022-02-01 20:36:00,000 INFO:Strategy predict\n", + "2022-02-01 20:36:00,000 INFO:Trade try complete\n", + "2022-02-01 20:36:00,000 INFO:Trade 37\n", + "2022-02-01 20:36:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:36:00,000 INFO:Refreshing data\n", + "2022-02-01 20:37:00,000 INFO:Data refreshed\n", + "2022-02-01 20:37:00,000 INFO:Strategy predict\n", + "2022-02-01 20:37:00,000 INFO:Trade try complete\n", + "2022-02-01 20:37:00,000 INFO:Trade 38\n", + "2022-02-01 20:37:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:37:00,000 INFO:Refreshing data\n", + "2022-02-01 20:38:00,000 INFO:Data refreshed\n", + "2022-02-01 20:38:00,000 INFO:Strategy predict\n", + "2022-02-01 20:38:00,000 INFO:Trade try complete\n", + "2022-02-01 20:38:00,000 INFO:Trade 39\n", + "2022-02-01 20:38:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:38:00,000 INFO:Refreshing data\n", + "2022-02-01 20:39:00,000 INFO:Data refreshed\n", + "2022-02-01 20:39:00,000 INFO:Strategy predict\n", + "2022-02-01 20:39:00,000 INFO:Trade try complete\n", + "2022-02-01 20:39:00,000 INFO:Trade 40\n", + "2022-02-01 20:39:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:39:00,000 INFO:Refreshing data\n", + "2022-02-01 20:40:00,000 INFO:Data refreshed\n", + "2022-02-01 20:40:00,000 INFO:Strategy predict\n", + "2022-02-01 20:40:00,000 INFO:Trade try complete\n", + "2022-02-01 20:40:00,000 INFO:Trade 41\n", + "2022-02-01 20:40:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:40:00,000 INFO:Refreshing data\n", + "2022-02-01 20:41:00,000 INFO:Data refreshed\n", + "2022-02-01 20:41:00,000 INFO:Strategy predict\n", + "2022-02-01 20:41:00,000 INFO:Trade try complete\n", + "2022-02-01 20:41:00,000 INFO:Trade 42\n", + "2022-02-01 20:41:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:41:00,000 INFO:Refreshing data\n", + "2022-02-01 20:42:00,000 INFO:Data refreshed\n", + "2022-02-01 20:42:00,000 INFO:Strategy predict\n", + "2022-02-01 20:42:00,000 INFO:Trade try complete\n", + "2022-02-01 20:42:00,000 INFO:Trade 43\n", + "2022-02-01 20:42:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:42:00,000 INFO:Refreshing data\n", + "2022-02-01 20:43:00,000 INFO:Data refreshed\n", + "2022-02-01 20:43:00,000 INFO:Strategy predict\n", + "2022-02-01 20:43:00,000 INFO:Trade try complete\n", + "2022-02-01 20:43:00,000 INFO:Trade 44\n", + "2022-02-01 20:43:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:43:00,000 INFO:Refreshing data\n", + "2022-02-01 20:44:00,000 INFO:Data refreshed\n", + "2022-02-01 20:44:00,000 INFO:Strategy predict\n", + "2022-02-01 20:44:00,000 INFO:Trade try complete\n", + "2022-02-01 20:44:00,000 INFO:Trade 45\n", + "2022-02-01 20:44:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:44:00,000 INFO:Refreshing data\n", + "2022-02-01 20:45:00,000 INFO:Data refreshed\n", + "2022-02-01 20:45:00,000 INFO:Strategy predict\n", + "2022-02-01 20:45:00,000 INFO:Trade try complete\n", + "2022-02-01 20:45:00,000 INFO:Trade 46\n", + "2022-02-01 20:45:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:45:00,000 INFO:Refreshing data\n", + "2022-02-01 20:46:00,000 INFO:Data refreshed\n", + "2022-02-01 20:46:00,000 INFO:Strategy predict\n", + "2022-02-01 20:46:00,000 INFO:Trade try complete\n", + "2022-02-01 20:46:00,000 INFO:Trade 47\n", + "2022-02-01 20:46:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:46:00,000 INFO:Refreshing data\n", + "2022-02-01 20:47:00,000 INFO:Data refreshed\n", + "2022-02-01 20:47:00,000 INFO:Strategy predict\n", + "2022-02-01 20:47:00,000 INFO:Trade try complete\n", + "2022-02-01 20:47:00,000 INFO:Trade 48\n", + "2022-02-01 20:47:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:47:00,000 INFO:Refreshing data\n", + "2022-02-01 20:48:00,000 INFO:Data refreshed\n", + "2022-02-01 20:48:00,000 INFO:Strategy predict\n", + "2022-02-01 20:48:00,000 INFO:Trade try complete\n", + "2022-02-01 20:48:00,000 INFO:Trade 49\n", + "2022-02-01 20:48:00,000 INFO:Balance: 20050.69000000\n", + "2022-02-01 20:48:00,000 INFO:Refreshing data\n", + "2022-02-01 20:49:00,000 INFO:Data refreshed\n", + "2022-02-01 20:49:00,000 INFO:Strategy predict\n", + "2022-02-01 20:49:00,000 INFO:Trade try complete\n" + ] + }, + { + "data": { + "text/plain": [ + "'MSFT'" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "balances = {}\n", + "\n", + "for stock in stocks:\n", + " figi = ShareId(stocks[stock][\"figi\"])\n", + "\n", + " balance = MoneyValue(currency=\"rub\", units=20050, nano=690000000)\n", + "\n", + " account_id = AccountId(\"1337007228\")\n", + " settings = MovingAverageStrategySettings(\n", + " share_id=figi, # figi конкретной ценной бумаги\n", + " account_id=account_id, # неважно для sandbox\n", + " max_transaction_price=Decimal(\n", + " 10000\n", + " ), # максимальный объем сделки - зависит от размера портфеля. сейчас фиксировано\n", + " candle_interval=tf, # тф - таймфрейм\n", + " long_period=timedelta(minutes=n * period), # длинная скользяшка\n", + " short_period=timedelta(minutes=m * period), # короткая скользяшка\n", + " std_period=timedelta(minutes=s * period), # количество периодов для стд\n", + " )\n", + "\n", + " with MockedClient(\n", + " token=token,\n", + " settings=settings,\n", + " real_market_data_test_from=real_market_data_test_from,\n", + " real_market_data_test_start=real_market_data_test_start,\n", + " real_market_data_test_end=real_market_data_test_end,\n", + " balance=balance,\n", + " ) as mocked_services:\n", + " account_manager = AccountManager(\n", + " services=mocked_services, strategy_settings=settings\n", + " )\n", + " state = MovingAverageStrategyState()\n", + " strategy = MovingAverageStrategy(\n", + " settings=settings,\n", + " account_manager=account_manager,\n", + " state=state,\n", + " )\n", + " supervisor = MovingAverageStrategySupervisor()\n", + " signal_executor = MovingAverageSignalExecutor(\n", + " services=mocked_services,\n", + " state=state,\n", + " settings=settings,\n", + " )\n", + " moving_average_strategy_trader = MovingAverageStrategyTrader(\n", + " strategy=strategy,\n", + " settings=settings,\n", + " services=mocked_services,\n", + " state=state,\n", + " signal_executor=signal_executor,\n", + " account_manager=account_manager,\n", + " supervisor=supervisor,\n", + " )\n", + " plotter = MovingAverageStrategyPlotter(settings=settings)\n", + "\n", + " initial_balance = account_manager.get_current_balance()\n", + "\n", + " for i in range(50):\n", + " logger.info(\"Trade %s\", i)\n", + " moving_average_strategy_trader.trade()\n", + "\n", + " balances[stock] = balance.units\n", + "\n", + "best_stock = max(balances, key=balances.get)\n", + "best_stock" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Вывод картинки" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "events = supervisor.get_events()\n", + "plotter.plot(events)\n", + "\n", + "current_balance = account_manager.get_current_balance()\n", + "# assert initial_balance != current_balance\n", + "# logger.info(\"Initial balance %s\", initial_balance)\n", + "# logger.info(\"Current balance %s\", current_balance)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": ".venv" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.3" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/invest-python-master/examples/strategies/real-time-render.ipynb b/invest-python-master/examples/strategies/real-time-render.ipynb new file mode 100644 index 0000000..ee1725f --- /dev/null +++ b/invest-python-master/examples/strategies/real-time-render.ipynb @@ -0,0 +1,254 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Param search" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Imports" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import logging\n", + "\n", + "from t_tech.invest.mock_services import MockedSandboxClient\n", + "from decimal import Decimal\n", + "from t_tech.invest.strategies.moving_average.strategy_settings import (\n", + " MovingAverageStrategySettings,\n", + ")\n", + "from t_tech.invest import CandleInterval, MoneyValue\n", + "from t_tech.invest.strategies.moving_average.signal_executor import (\n", + " MovingAverageSignalExecutor,\n", + ")\n", + "from t_tech.invest.strategies.moving_average.supervisor import (\n", + " MovingAverageStrategySupervisor,\n", + ")\n", + "from t_tech.invest.strategies.moving_average.strategy_state import (\n", + " MovingAverageStrategyState,\n", + ")\n", + "from t_tech.invest.strategies.moving_average.strategy import MovingAverageStrategy\n", + "from t_tech.invest.strategies.moving_average.trader import MovingAverageStrategyTrader\n", + "from datetime import timedelta, datetime, timezone\n", + "from t_tech.invest.typedefs import ShareId, AccountId\n", + "from t_tech.invest.strategies.base.account_manager import AccountManager\n", + "from t_tech.invest.strategies.moving_average.plotter import (\n", + " MovingAverageStrategyPlotter,\n", + ")\n", + "\n", + "\n", + "logging.basicConfig(format=\"%(asctime)s %(levelname)s:%(message)s\", level=logging.INFO)\n", + "logger = logging.getLogger(__name__)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Setup" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "token = " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Settings" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "figi = ShareId(\"BBG0013HGFT4\")\n", + "account_id = AccountId(\"1337007228\")\n", + "settings = MovingAverageStrategySettings(\n", + " share_id=figi,\n", + " account_id=account_id,\n", + " max_transaction_price=Decimal(10000),\n", + " candle_interval=CandleInterval.CANDLE_INTERVAL_1_MIN,\n", + " long_period=timedelta(minutes=100),\n", + " short_period=timedelta(minutes=50),\n", + " std_period=timedelta(minutes=30),\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Stocks for date" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "def start_datetime() -> datetime:\n", + " return datetime(year=2022, month=2, day=16, hour=17, tzinfo=timezone.utc)\n", + "\n", + "\n", + "real_market_data_test_from = start_datetime() - timedelta(days=1)\n", + "real_market_data_test_start = start_datetime()\n", + "real_market_data_test_end = start_datetime() + timedelta(days=3)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Initial balance" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "balance = MoneyValue(currency=\"rub\", units=20050, nano=690000000)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Trader" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "data": { + "image/png": "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LvVTpqZ+ytQ01NWVHadZmztpzQXa6sq1MspLJd+abdShbb6w/4Bc9Zk9c+eMeTnh8kmZPuuVsmPBCjsdlez/reTao5IXnyo7DQDrgQINAOBdVleulVFeViv5WGGzrp3yg6N3ybcO3TH/747H85UbH8jzr7xRdixIttk3OewnyU2nJLPvLzsNAB+SAg0AgGZvh8275prTh+XQXfvms9dMzX/84fG8/ubSsmPR2vXdNTnuF8l/fSV58May0wDwISjQAABoEYqiyMcG1+TWz+2VXpt0zJGXTMiN9z6XZcutj0aJemydnPqbZMZvkzu+kSxbUnYiANaBAg0AgBalfds2OWVkbW46a2Semvd6jrzkntzz5PyyY9GaddwkOfbqpHPP5BdHJgvmlZ0IgA9IgQYAQIvUbaP2+cdPbJ+LTxiSayc/m9PH35snX1hQdixaq6JI9vlaMuqLyTWHJ89PKzsRAB9Au7IDAABAY9qq58a55NN75N66l/L1m6dnx8275u8PGJgeG3coOxqt0YADkx7bJDePSYZ9NtnthLITAbAWjEADAKBV2LO2R3555sjssdWmOfHySbns7qfy5tJlZceiNeq57Yp10Z64I7njH5Plvg4BmjoFGgAArUabNkUO261fbvv8XlmyrJLDfzIhv3toTioVGw2wgXXskhz986RD5+TGk5PFr5edCIAqFGgAALQ6ndq3zef32y5XnbZn/jJzfo67bFIe+NsrZceitWnTJvnYN5PtD02uPixpmFN2IgDWwBpoAAC0Wptt0infP3LnzJjbkO/9bkY27dw+/3DI4PTrvlHZ0WhNdjsx6b5lcu3RyRE/S/rsXHYiAN7FCDQAAFq9wX265qrP7JnDh/TLmddMzYW/n5EFby4tOxatSe3eyTHjk9s+lzzxh7LTAPAuCjQAAEhSFEX2G7RZbvvcXunTbaMc/dMJuX7Kc1m23PpobCC9BiQn35bc88Nk8mVlpwFgFaZwAkALMWb8hZlZPytJMqCmf8aNPvftcxPGnpf506enfvK96Vpbm1EXnF9WzBap2ue+2rkkmTNxcvqOHP6B3m9drpkw9rw01NX5818L7dq2yckjtsphu22eS+58Kkdeck++etCg7DOwd9nRaA027pmcfEvy688nLz2VHPy9pE3bslMBtHoKNABoIWbWz8rdM6ev9lxDXV1envHEBk7UelT7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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2022-03-15 21:00:05,649 INFO:9b1ca1a8bebe24b983bd1cd009ddd572 GetSandboxPortfolio\n", + "2022-03-15 21:00:05,650 INFO:Balance: 20050.69000000\n", + "2022-03-15 21:00:05,650 INFO:Refreshing data\n" + ] + } + ], + "source": [ + "with MockedSandboxClient(\n", + " token=token,\n", + " balance=balance,\n", + ") as mocked_services:\n", + " account_manager = AccountManager(\n", + " services=mocked_services, strategy_settings=settings\n", + " )\n", + " state = MovingAverageStrategyState()\n", + " strategy = MovingAverageStrategy(\n", + " settings=settings,\n", + " account_manager=account_manager,\n", + " state=state,\n", + " )\n", + " supervisor = MovingAverageStrategySupervisor()\n", + " signal_executor = MovingAverageSignalExecutor(\n", + " services=mocked_services,\n", + " state=state,\n", + " settings=settings,\n", + " )\n", + " moving_average_strategy_trader = MovingAverageStrategyTrader(\n", + " strategy=strategy,\n", + " settings=settings,\n", + " services=mocked_services,\n", + " state=state,\n", + " signal_executor=signal_executor,\n", + " account_manager=account_manager,\n", + " supervisor=supervisor,\n", + " )\n", + " plotter = MovingAverageStrategyPlotter(settings=settings)\n", + "\n", + " initial_balance = account_manager.get_current_balance()\n", + "\n", + " for i in range(50):\n", + " logger.info(\"Trade %s\", i)\n", + " events = list(supervisor.get_events())\n", + " plotter.plot(events)\n", + " try:\n", + " moving_average_strategy_trader.trade()\n", + " except Exception:\n", + " pass" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "current_balance = account_manager.get_current_balance()\n", + "assert initial_balance != current_balance\n", + "logger.info(\"Initial balance %s\", initial_balance)\n", + "logger.info(\"Current balance %s\", current_balance)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.0" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/invest-python-master/examples/stream_client.py b/invest-python-master/examples/stream_client.py new file mode 100644 index 0000000..23db2bd --- /dev/null +++ b/invest-python-master/examples/stream_client.py @@ -0,0 +1,43 @@ +import os +import time + +from t_tech.invest import ( + CandleInstrument, + Client, + MarketDataRequest, + SubscribeCandlesRequest, + SubscriptionAction, + SubscriptionInterval, +) +from t_tech.invest.schemas import CandleSource + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + def request_iterator(): + yield MarketDataRequest( + subscribe_candles_request=SubscribeCandlesRequest( + waiting_close=True, + subscription_action=SubscriptionAction.SUBSCRIPTION_ACTION_SUBSCRIBE, + candle_source_type=CandleSource.CANDLE_SOURCE_EXCHANGE, + instruments=[ + CandleInstrument( + figi="BBG004730N88", + interval=SubscriptionInterval.SUBSCRIPTION_INTERVAL_ONE_MINUTE, + ) + ], + ) + ) + while True: + time.sleep(1) + + with Client(TOKEN) as client: + for marketdata in client.market_data_stream.market_data_stream( + request_iterator() + ): + print(marketdata) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/trailing_stop.py b/invest-python-master/examples/trailing_stop.py new file mode 100644 index 0000000..2bd34fe --- /dev/null +++ b/invest-python-master/examples/trailing_stop.py @@ -0,0 +1,78 @@ +"""Example - Trailing Stop Take Profit order. +spread=0.5 relative value +indent=0.5 absolute value +""" + +import json +import logging +import os +from decimal import Decimal + +from t_tech.invest import ( + Client, + ExchangeOrderType, + GetStopOrdersRequest, + PostStopOrderRequest, + PostStopOrderRequestTrailingData, + StopOrderDirection, + StopOrderExpirationType, + StopOrderTrailingData, + StopOrderType, + TakeProfitType, +) +from t_tech.invest.schemas import TrailingValueType +from t_tech.invest.utils import decimal_to_quotation + +TOKEN = os.environ["INVEST_TOKEN"] + +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + + +INSTRUMENT_ID = "TCS00A105GE2" +QUANTITY = 1 +PRICE = 230.500000000 +STOPPRICE = 230 +INDENT = 0.5 +SPREAD = 0.5 + + +def main(): + logger.info("Getting Max Lots") + with Client(TOKEN) as client: + response = client.users.get_accounts() + account, *_ = response.accounts + account_id = account.id + + logger.info( + "Post take profit stop order for instrument=%s and trailing parameters: indent=%s, spread=%s, price=%s ", + INSTRUMENT_ID, + INDENT, + SPREAD, + STOPPRICE, + ) + + post_stop_order = client.stop_orders.post_stop_order( + quantity=QUANTITY, + price=decimal_to_quotation(Decimal(PRICE)), + stop_price=decimal_to_quotation(Decimal(STOPPRICE)), + direction=StopOrderDirection.STOP_ORDER_DIRECTION_SELL, + account_id=account_id, + stop_order_type=StopOrderType.STOP_ORDER_TYPE_TAKE_PROFIT, + instrument_id=INSTRUMENT_ID, + expiration_type=StopOrderExpirationType.STOP_ORDER_EXPIRATION_TYPE_GOOD_TILL_CANCEL, + exchange_order_type=ExchangeOrderType.EXCHANGE_ORDER_TYPE_LIMIT, + take_profit_type=TakeProfitType.TAKE_PROFIT_TYPE_TRAILING, + trailing_data=StopOrderTrailingData( + indent=decimal_to_quotation(Decimal(INDENT)), + indent_type=TrailingValueType.TRAILING_VALUE_ABSOLUTE, + spread=decimal_to_quotation(Decimal(SPREAD)), + spread_type=TrailingValueType.TRAILING_VALUE_RELATIVE, + ), + ) + + print(post_stop_order) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/users/async_currency_transfer.py b/invest-python-master/examples/users/async_currency_transfer.py new file mode 100644 index 0000000..6500cf6 --- /dev/null +++ b/invest-python-master/examples/users/async_currency_transfer.py @@ -0,0 +1,41 @@ +import asyncio +import os +import uuid + +from _decimal import Decimal + +from t_tech.invest import AccountType, AsyncClient +from t_tech.invest.schemas import CurrencyTransferRequest +from t_tech.invest.utils import decimal_to_money + + +async def main(): + token = os.environ["INVEST_TOKEN"] + + async with AsyncClient(token) as client: + accounts = [ + i + for i in (await client.users.get_accounts()).accounts + if i.type == AccountType.ACCOUNT_TYPE_TINKOFF + ] + + if len(accounts) < 2: + print("Недостаточно счетов для демонстрации") + return + + from_account_id = accounts[0].id + to_account_id = accounts[1].id + + await client.users.currency_transfer( + CurrencyTransferRequest( + from_account_id=from_account_id, + to_account_id=to_account_id, + amount=decimal_to_money(Decimal(1), "rub"), + transaction_id=str(uuid.uuid4()), + ) + ) + print("Перевод выполнен") + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/users/async_get_bank_accounts.py b/invest-python-master/examples/users/async_get_bank_accounts.py new file mode 100644 index 0000000..20f0589 --- /dev/null +++ b/invest-python-master/examples/users/async_get_bank_accounts.py @@ -0,0 +1,16 @@ +import asyncio +import os + +from t_tech.invest import AsyncClient + + +async def main(): + token = os.environ["INVEST_TOKEN"] + + async with AsyncClient(token) as client: + response = await client.users.get_bank_accounts() + print(response) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/users/async_pay_in.py b/invest-python-master/examples/users/async_pay_in.py new file mode 100644 index 0000000..2e5c977 --- /dev/null +++ b/invest-python-master/examples/users/async_pay_in.py @@ -0,0 +1,41 @@ +import asyncio +import os + +from _decimal import Decimal + +from t_tech.invest import AccountType, AsyncClient +from t_tech.invest.schemas import PayInRequest +from t_tech.invest.utils import decimal_to_money + + +async def main(): + token = os.environ["INVEST_TOKEN"] + + async with AsyncClient(token) as client: + accounts = [ + i + for i in (await client.users.get_accounts()).accounts + if i.type == AccountType.ACCOUNT_TYPE_TINKOFF + ] + + bank_accounts = await client.users.get_bank_accounts() + + if len(accounts) < 1 or len(bank_accounts.bank_accounts) < 1: + print("Недостаточно счетов для демонстрации") + return + + from_account_id = bank_accounts.bank_accounts[0].id + to_account_id = accounts[0].id + + await client.users.pay_in( + PayInRequest( + from_account_id=from_account_id, + to_account_id=to_account_id, + amount=decimal_to_money(Decimal(1), "rub"), + ) + ) + print("Пополнение выполнено") + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/invest-python-master/examples/users/currency_transfer.py b/invest-python-master/examples/users/currency_transfer.py new file mode 100644 index 0000000..a38a1a1 --- /dev/null +++ b/invest-python-master/examples/users/currency_transfer.py @@ -0,0 +1,40 @@ +import os +import uuid + +from _decimal import Decimal + +from t_tech.invest import AccountType, Client +from t_tech.invest.schemas import CurrencyTransferRequest +from t_tech.invest.utils import decimal_to_money + + +def main(): + token = os.environ["INVEST_TOKEN"] + + with Client(token) as client: + accounts = [ + i + for i in client.users.get_accounts().accounts + if i.type == AccountType.ACCOUNT_TYPE_TINKOFF + ] + + if len(accounts) < 2: + print("Недостаточно счетов для демонстрации") + return + + from_account_id = accounts[0].id + to_account_id = accounts[1].id + + client.users.currency_transfer( + CurrencyTransferRequest( + from_account_id=from_account_id, + to_account_id=to_account_id, + amount=decimal_to_money(Decimal(1), "rub"), + transaction_id=str(uuid.uuid4()), + ) + ) + print("Перевод выполнен") + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/users/get_bank_accounts.py b/invest-python-master/examples/users/get_bank_accounts.py new file mode 100644 index 0000000..d6882a1 --- /dev/null +++ b/invest-python-master/examples/users/get_bank_accounts.py @@ -0,0 +1,15 @@ +import os + +from t_tech.invest import Client + + +def main(): + token = os.environ["INVEST_TOKEN"] + + with Client(token) as client: + response = client.users.get_bank_accounts() + print(response) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/users/get_user_info.py b/invest-python-master/examples/users/get_user_info.py new file mode 100644 index 0000000..7c35c8c --- /dev/null +++ b/invest-python-master/examples/users/get_user_info.py @@ -0,0 +1,15 @@ +import os + +from t_tech.invest import Client + +TOKEN = os.environ["INVEST_TOKEN"] + + +def main(): + with Client(TOKEN) as client: + response = client.users.get_info() + print(response) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/users/pay_in.py b/invest-python-master/examples/users/pay_in.py new file mode 100644 index 0000000..1999aed --- /dev/null +++ b/invest-python-master/examples/users/pay_in.py @@ -0,0 +1,40 @@ +import os + +from _decimal import Decimal + +from t_tech.invest import AccountType, Client +from t_tech.invest.schemas import PayInRequest +from t_tech.invest.utils import decimal_to_money + + +def main(): + token = os.environ["INVEST_TOKEN"] + + with Client(token) as client: + accounts = [ + i + for i in client.users.get_accounts().accounts + if i.type == AccountType.ACCOUNT_TYPE_TINKOFF + ] + + bank_accounts = client.users.get_bank_accounts().bank_accounts + + if len(accounts) < 1 or len(bank_accounts) < 1: + print("Недостаточно счетов для демонстрации") + return + + from_account_id = bank_accounts[0].id + to_account_id = accounts[0].id + + client.users.pay_in( + PayInRequest( + from_account_id=from_account_id, + to_account_id=to_account_id, + amount=decimal_to_money(Decimal(1), "rub"), + ) + ) + print("Пополнение выполнено") + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/wiseplat_cancel_all_stop_orders.py b/invest-python-master/examples/wiseplat_cancel_all_stop_orders.py new file mode 100644 index 0000000..1eb0ad6 --- /dev/null +++ b/invest-python-master/examples/wiseplat_cancel_all_stop_orders.py @@ -0,0 +1,39 @@ +"""Example - How to cancel all stop orders.""" +import logging +import os + +from t_tech.invest import Client +from t_tech.invest.exceptions import InvestError + +TOKEN = os.environ["INVEST_TOKEN"] + +logging.basicConfig(format="%(asctime)s %(levelname)s:%(message)s", level=logging.DEBUG) +logger = logging.getLogger(__name__) + + +def main(): + """Example - How to cancel all stop orders.""" + with Client(TOKEN) as client: + response = client.users.get_accounts() + account, *_ = response.accounts + account_id = account.id + + try: + stop_orders_response = client.stop_orders.get_stop_orders( + account_id=account_id + ) + logger.info("Stop Orders: %s", stop_orders_response) + for stop_order in stop_orders_response.stop_orders: + client.stop_orders.cancel_stop_order( + account_id=account_id, stop_order_id=stop_order.stop_order_id + ) + logger.info("Stop Order: %s was canceled.", stop_order.stop_order_id) + logger.info( + "Orders: %s", client.stop_orders.get_stop_orders(account_id=account_id) + ) + except InvestError as error: + logger.error("Failed to cancel all orders. Error: %s", error) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/wiseplat_create_take_profit_stop_order.py b/invest-python-master/examples/wiseplat_create_take_profit_stop_order.py new file mode 100644 index 0000000..80c95be --- /dev/null +++ b/invest-python-master/examples/wiseplat_create_take_profit_stop_order.py @@ -0,0 +1,92 @@ +"""Example - How to create takeprofit buy order.""" +import logging +import os +from decimal import Decimal + +from t_tech.invest import ( + Client, + InstrumentIdType, + StopOrderDirection, + StopOrderExpirationType, + StopOrderType, +) +from t_tech.invest.exceptions import InvestError +from t_tech.invest.utils import decimal_to_quotation, quotation_to_decimal + +TOKEN = os.environ["INVEST_TOKEN"] + +logging.basicConfig(format="%(asctime)s %(levelname)s:%(message)s", level=logging.DEBUG) +logger = logging.getLogger(__name__) + + +def main(): + """Example - How to create takeprofit buy order.""" + with Client(TOKEN) as client: + response = client.users.get_accounts() + account, *_ = response.accounts + account_id = account.id + logger.info("Orders: %s", client.orders.get_orders(account_id=account_id)) + + figi = "BBG004730ZJ9" # BBG004730ZJ9 - VTBR / BBG004730N88 - SBER + + # getting the last price for instrument + last_price = ( + client.market_data.get_last_prices(figi=[figi]).last_prices[0].price + ) + last_price = quotation_to_decimal(last_price) + print(f"figi, last price = {last_price}") + + # setting the percentage by which the takeprofit stop order + # should be set below the last price + percent_down = 5 + + # calculation of the price for takeprofit stop order + calculated_price = last_price - last_price * Decimal(percent_down / 100) + print(f"calculated_price = {calculated_price}") + + # getting the min price increment and the number of digits after point + min_price_increment = client.instruments.get_instrument_by( + id_type=InstrumentIdType.INSTRUMENT_ID_TYPE_FIGI, id=figi + ).instrument.min_price_increment + number_digits_after_point = 9 - len(str(min_price_increment.nano)) + 1 + min_price_increment = quotation_to_decimal(min_price_increment) + print( + f"min_price_increment = {min_price_increment}, " + f"number_digits_after_point={number_digits_after_point}" + ) + + # calculation of the price for instrument which is + # divisible to min price increment + calculated_price = ( + round(calculated_price / min_price_increment) * min_price_increment + ) + print( + f"let's send stop order at price = " + f"{calculated_price:.{number_digits_after_point}f} divisible to " + f"min price increment {min_price_increment}" + ) + + # creating takeprofit buy order + stop_order_type = StopOrderType.STOP_ORDER_TYPE_TAKE_PROFIT + direction = StopOrderDirection.STOP_ORDER_DIRECTION_BUY + exp_type = StopOrderExpirationType.STOP_ORDER_EXPIRATION_TYPE_GOOD_TILL_CANCEL + try: + response = client.stop_orders.post_stop_order( + figi=figi, + quantity=1, + price=decimal_to_quotation(Decimal(calculated_price)), + stop_price=decimal_to_quotation(Decimal(calculated_price)), + direction=direction, + account_id=account_id, + expiration_type=exp_type, + stop_order_type=stop_order_type, + expire_date=None, + ) + print(response) + print("stop_order_id=", response.stop_order_id) + except InvestError as error: + logger.error("Posting trade takeprofit order failed. Exception: %s", error) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/wiseplat_get_figi_for_ticker.py b/invest-python-master/examples/wiseplat_get_figi_for_ticker.py new file mode 100644 index 0000000..ea67c53 --- /dev/null +++ b/invest-python-master/examples/wiseplat_get_figi_for_ticker.py @@ -0,0 +1,68 @@ +"""Example - How to get figi by name of ticker.""" +import logging +import os + +from pandas import DataFrame + +from t_tech.invest import Client, SecurityTradingStatus +from t_tech.invest.services import InstrumentsService +from t_tech.invest.utils import quotation_to_decimal + +TOKEN = os.environ["INVEST_TOKEN"] + +logging.basicConfig(format="%(asctime)s %(levelname)s:%(message)s", level=logging.DEBUG) +logger = logging.getLogger(__name__) + + +def main(): + """Example - How to get figi by name of ticker.""" + + ticker = "VTBR" # "BRH3" "SBER" "VTBR" + + with Client(TOKEN) as client: + instruments: InstrumentsService = client.instruments + tickers = [] + for method in ["shares", "bonds", "etfs", "currencies", "futures"]: + for item in getattr(instruments, method)().instruments: + tickers.append( + { + "name": item.name, + "ticker": item.ticker, + "class_code": item.class_code, + "figi": item.figi, + "uid": item.uid, + "type": method, + "min_price_increment": quotation_to_decimal( + item.min_price_increment + ), + "scale": 9 - len(str(item.min_price_increment.nano)) + 1, + "lot": item.lot, + "trading_status": str( + SecurityTradingStatus(item.trading_status).name + ), + "api_trade_available_flag": item.api_trade_available_flag, + "currency": item.currency, + "exchange": item.exchange, + "buy_available_flag": item.buy_available_flag, + "sell_available_flag": item.sell_available_flag, + "short_enabled_flag": item.short_enabled_flag, + "klong": quotation_to_decimal(item.klong), + "kshort": quotation_to_decimal(item.kshort), + } + ) + + tickers_df = DataFrame(tickers) + + ticker_df = tickers_df[tickers_df["ticker"] == ticker] + if ticker_df.empty: + logger.error("There is no such ticker: %s", ticker) + return + + figi = ticker_df["figi"].iloc[0] + print(f"\nTicker {ticker} have figi={figi}\n") + print(f"Additional info for this {ticker} ticker:") + print(ticker_df.iloc[0]) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/examples/wiseplat_live_strategy_print_ohlcv.py b/invest-python-master/examples/wiseplat_live_strategy_print_ohlcv.py new file mode 100644 index 0000000..2e3d203 --- /dev/null +++ b/invest-python-master/examples/wiseplat_live_strategy_print_ohlcv.py @@ -0,0 +1,152 @@ +""" + This code is an example of applying Trading Strategy for several Tickers. + The strategy in this code is for demonstration only purposes + - it outputs OHLCV values. + Author: Oleg Shpagin, my github: https://github.com/WISEPLAT +""" + +import asyncio +import logging +import os +from datetime import timedelta +from typing import List, Optional + +from t_tech.invest import AioRequestError, AsyncClient, CandleInterval, HistoricCandle +from t_tech.invest.async_services import AsyncServices +from t_tech.invest.utils import now + +TOKEN = os.environ["INVEST_TOKEN"] + +logging.basicConfig(format="%(asctime)s %(levelname)s:%(message)s", level=logging.DEBUG) +logger = logging.getLogger(__name__) + + +class LogOnlyCandlesStrategy: + """This class is responsible for a strategy. You can put here + your methods for your strategy.""" + + def __init__( + self, + figi: str, + timeframe: CandleInterval, + days_back: int, + check_interval: int, + client: Optional[AsyncServices], + ): + self.account_id = None + self.figi = figi + self.timeframe = timeframe + self.days_back = days_back + self.check_interval = check_interval + self.client = client + self.candles: List[HistoricCandle] = [] + + async def get_historical_data(self): + """ + Gets historical data for the instrument. Returns list of candles. + Requests all the candles of timeframe from days_back to now. + + :return: list of HistoricCandle + """ + logger.debug( + "Start getting historical data for %s days back from now. figi=%s", + self.days_back, + self.figi, + ) + async for candle in self.client.get_all_candles( + figi=self.figi, + from_=now() - timedelta(days=self.days_back), + to=now(), + interval=self.timeframe, + ): + if candle not in self.candles: + if candle.is_complete: + self.candles.append(candle) + logger.debug("Found %s - figi=%s", candle, self.figi) + + async def ensure_market_open(self): + """ + Ensure that the market is open. Loop until the instrument is available. + :return: when instrument is available for trading + """ + trading_status = await self.client.market_data.get_trading_status( + figi=self.figi + ) + while not ( + trading_status.market_order_available_flag + and trading_status.api_trade_available_flag + ): + logger.debug("Waiting for the market to open. figi=%s", self.figi) + await asyncio.sleep(60) + trading_status = await self.client.market_data.get_trading_status( + figi=self.figi + ) + + async def main_cycle(self): + """Main cycle for live strategy.""" + while True: + try: + await self.ensure_market_open() + await self.get_historical_data() + + # put your strategy code here for live + # to generate signals for buying or selling tickers + logger.debug( + "- live mode: run some strategy code to buy or sell - figi=%s", + self.figi, + ) + + except AioRequestError as are: + logger.error("Client error %s", are) + + await asyncio.sleep(self.check_interval) + + async def start(self): + """Strategy starts from this function.""" + if self.account_id is None: + try: + self.account_id = ( + (await self.client.users.get_accounts()).accounts.pop().id + ) + except AioRequestError as are: + logger.error("Error taking account id. Stopping strategy. %s", are) + return + await self.main_cycle() + + +async def run_strategy(portfolio, timeframe, days_back, check_interval): + """From this function we are starting + strategy for every ticker from portfolio. + """ + async with AsyncClient(token=TOKEN, app_name="TinkoffApp") as client: + strategy_tasks = [] + for instrument in portfolio: + strategy = LogOnlyCandlesStrategy( + figi=instrument, + timeframe=timeframe, + days_back=days_back, + check_interval=check_interval, + client=client, + ) + strategy_tasks.append(asyncio.create_task(strategy.start())) + await asyncio.gather(*strategy_tasks) + + +if __name__ == "__main__": + sber_figi = "BBG004730N88" + vtbr_figi = "BBG004730ZJ9" + portfolio = {sber_figi, vtbr_figi} + timeframe = CandleInterval.CANDLE_INTERVAL_1_MIN + days_back = 1 + check_interval = 10 # seconds to check interval for new completed candle + + loop = asyncio.get_event_loop() + task = loop.create_task( + run_strategy( + portfolio=portfolio, + timeframe=timeframe, + days_back=days_back, + check_interval=check_interval, + ) + ) + loop.run_until_complete(task) diff --git a/invest-python-master/examples/wiseplat_set_get_sandbox_balance.py b/invest-python-master/examples/wiseplat_set_get_sandbox_balance.py new file mode 100644 index 0000000..79d1d65 --- /dev/null +++ b/invest-python-master/examples/wiseplat_set_get_sandbox_balance.py @@ -0,0 +1,96 @@ +""" Example - How to set/get balance for sandbox account. + How to get/close all sandbox accounts. + How to open new sandbox account. """ + +import logging +import os +from datetime import datetime +from decimal import Decimal + +from t_tech.invest import MoneyValue +from t_tech.invest.sandbox.client import SandboxClient +from t_tech.invest.utils import decimal_to_quotation, quotation_to_decimal + +TOKEN = os.environ["INVEST_TOKEN"] + +logging.basicConfig(format="%(asctime)s %(levelname)s:%(message)s", level=logging.DEBUG) +logger = logging.getLogger(__name__) + + +def add_money_sandbox(client, account_id, money, currency="rub"): + """Function to add money to sandbox account.""" + money = decimal_to_quotation(Decimal(money)) + return client.sandbox.sandbox_pay_in( + account_id=account_id, + amount=MoneyValue(units=money.units, nano=money.nano, currency=currency), + ) + + +def main(): + """Example - How to set/get balance for sandbox account. + How to get/close all sandbox accounts. + How to open new sandbox account.""" + with SandboxClient(TOKEN) as client: + # get all sandbox accounts + sandbox_accounts = client.users.get_accounts() + print(sandbox_accounts) + + # close all sandbox accounts + for sandbox_account in sandbox_accounts.accounts: + client.sandbox.close_sandbox_account(account_id=sandbox_account.id) + + # open new sandbox account + sandbox_account = client.sandbox.open_sandbox_account() + print(sandbox_account.account_id) + + account_id = sandbox_account.account_id + + # add initial 2 000 000 to sandbox account + print(add_money_sandbox(client=client, account_id=account_id, money=2000000)) + logger.info( + "positions: %s", client.operations.get_positions(account_id=account_id) + ) + print( + "money: ", + float( + quotation_to_decimal( + client.operations.get_positions(account_id=account_id).money[0] + ) + ), + ) + + logger.info("orders: %s", client.orders.get_orders(account_id=account_id)) + logger.info( + "positions: %s", client.operations.get_positions(account_id=account_id) + ) + logger.info( + "portfolio: %s", client.operations.get_portfolio(account_id=account_id) + ) + logger.info( + "operations: %s", + client.operations.get_operations( + account_id=account_id, + from_=datetime(2023, 1, 1), + to=datetime(2023, 2, 5), + ), + ) + logger.info( + "withdraw_limits: %s", + client.operations.get_withdraw_limits(account_id=account_id), + ) + + # add + 2 000 000 to sandbox account, total is 4 000 000 + print(add_money_sandbox(client=client, account_id=account_id, money=2000000)) + logger.info( + "positions: %s", client.operations.get_positions(account_id=account_id) + ) + + # close new sandbox account + sandbox_account = client.sandbox.close_sandbox_account( + account_id=sandbox_account.account_id + ) + print(sandbox_account) + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/mkdocs.yml b/invest-python-master/mkdocs.yml new file mode 100644 index 0000000..a5ca6a4 --- /dev/null +++ b/invest-python-master/mkdocs.yml @@ -0,0 +1,49 @@ +site_name: T-Invest Python SDK +site_url: https://RussianInvestments.github.io/invest-python/ +site_description: 'Python SDK, gRPC client, bot examples' + +repo_name: 'RussianInvestments/invest-python' +repo_url: 'https://github.com/RussianInvestments/invest-python' +edit_uri: "edit/main/docs/" + +copyright: 'Copyright © 2023 T-technologies' + +use_directory_urls: true +nav: + - 'Главная': 'README.md' + - 'API Reference': + - Clients: api/clients.md + - 'Примеры': 'examples.md' + - 'Готовые работы': 'robots.md' + - 'Список изменений': 'CHANGELOG.md' + - 'Участие в проекте': 'CONTRIBUTING.md' + +theme: + name: material + language: ru + palette: + primary: black + accent: yellow + +plugins: +- include-markdown +- termynal: {} +- search: + lang: ru +- mkdocstrings: + default_handler: python + handlers: + python: + rendering: + show_source: false + +extra_css: + - custom.css + +markdown_extensions: + - admonition + - codehilite + - pymdownx.superfences + - tables + - pymdownx.tasklist: + custom_checkbox: true diff --git a/invest-python-master/poetry.lock b/invest-python-master/poetry.lock new file mode 100644 index 0000000..dfca531 --- /dev/null +++ b/invest-python-master/poetry.lock @@ -0,0 +1,3608 @@ +# This file is automatically @generated by Poetry 2.3.2 and should not be changed by hand. + +[[package]] +name = "appnope" +version = "0.1.4" +description = "Disable App Nap on macOS >= 10.9" +optional = false +python-versions = ">=3.6" +groups = ["dev"] +markers = "sys_platform == \"darwin\"" +files = [ + {file = "appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c"}, + {file = "appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee"}, +] + +[[package]] +name = "asttokens" +version = "3.0.1" +description = "Annotate AST trees with source code positions" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "asttokens-3.0.1-py3-none-any.whl", hash = "sha256:15a3ebc0f43c2d0a50eeafea25e19046c68398e487b9f1f5b517f7c0f40f976a"}, + {file = "asttokens-3.0.1.tar.gz", hash = "sha256:71a4ee5de0bde6a31d64f6b13f2293ac190344478f081c3d1bccfcf5eacb0cb7"}, +] + +[package.extras] +astroid = ["astroid (>=2,<5)"] +test = ["astroid (>=2,<5)", "pytest (<9.0)", "pytest-cov", "pytest-xdist"] + +[[package]] +name = "babel" +version = "2.17.0" +description = "Internationalization utilities" +optional = false +python-versions = ">=3.8" +groups = ["docs"] +files = [ + {file = "babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2"}, + {file = "babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d"}, +] + +[package.dependencies] +pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""} + +[package.extras] +dev = ["backports.zoneinfo ; python_version < \"3.9\"", "freezegun (>=1.0,<2.0)", "jinja2 (>=3.0)", "pytest (>=6.0)", "pytest-cov", "pytz", "setuptools", "tzdata ; sys_platform == \"win32\""] + +[[package]] +name = "backcall" +version = "0.2.0" +description = "Specifications for callback functions passed in to an API" +optional = false +python-versions = "*" +groups = ["dev"] +files = [ + {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, + {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, +] + +[[package]] +name = "backrefs" +version = "5.7.post1" +description = "A wrapper around re and regex that adds additional back references." +optional = false +python-versions = ">=3.8" +groups = ["docs"] +markers = "python_version < \"3.10\"" +files = [ + {file = "backrefs-5.7.post1-py310-none-any.whl", hash = "sha256:c5e3fd8fd185607a7cb1fefe878cfb09c34c0be3c18328f12c574245f1c0287e"}, + {file = "backrefs-5.7.post1-py311-none-any.whl", hash = "sha256:712ea7e494c5bf3291156e28954dd96d04dc44681d0e5c030adf2623d5606d51"}, + {file = "backrefs-5.7.post1-py312-none-any.whl", hash = "sha256:a6142201c8293e75bce7577ac29e1a9438c12e730d73a59efdd1b75528d1a6c5"}, + {file = "backrefs-5.7.post1-py38-none-any.whl", hash = "sha256:ec61b1ee0a4bfa24267f6b67d0f8c5ffdc8e0d7dc2f18a2685fd1d8d9187054a"}, + {file = "backrefs-5.7.post1-py39-none-any.whl", hash = "sha256:05c04af2bf752bb9a6c9dcebb2aff2fab372d3d9d311f2a138540e307756bd3a"}, + {file = "backrefs-5.7.post1.tar.gz", hash = "sha256:8b0f83b770332ee2f1c8244f4e03c77d127a0fa529328e6a0e77fa25bee99678"}, +] + +[package.extras] +extras = ["regex"] + +[[package]] +name = "backrefs" +version = "6.2" +description = "A wrapper around re and regex that adds additional back references." +optional = false +python-versions = ">=3.9" +groups = ["docs"] +markers = "python_version >= \"3.10\"" +files = [ + {file = "backrefs-6.2-py310-none-any.whl", hash = "sha256:0fdc7b012420b6b144410342caeb8adc54c6866cf12064abc9bb211302e496f8"}, + {file = "backrefs-6.2-py311-none-any.whl", hash = "sha256:08aa7fae530c6b2361d7bdcbda1a7c454e330cc9dbcd03f5c23205e430e5c3be"}, + {file = "backrefs-6.2-py312-none-any.whl", hash = "sha256:c3f4b9cb2af8cda0d87ab4f57800b57b95428488477be164dd2b47be54db0c90"}, + {file = "backrefs-6.2-py313-none-any.whl", hash = "sha256:12df81596ab511f783b7d87c043ce26bc5b0288cf3bb03610fe76b8189282b2b"}, + {file = "backrefs-6.2-py314-none-any.whl", hash = "sha256:e5f805ae09819caa1aa0623b4a83790e7028604aa2b8c73ba602c4454e665de7"}, + {file = "backrefs-6.2-py39-none-any.whl", hash = "sha256:664e33cd88c6840b7625b826ecf2555f32d491800900f5a541f772c485f7cda7"}, + {file = "backrefs-6.2.tar.gz", hash = "sha256:f44ff4d48808b243b6c0cdc6231e22195c32f77046018141556c66f8bab72a49"}, +] + +[package.extras] +extras = ["regex"] + +[[package]] +name = "black" +version = "23.12.1" +description = "The uncompromising code formatter." +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "black-23.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e0aaf6041986767a5e0ce663c7a2f0e9eaf21e6ff87a5f95cbf3675bfd4c41d2"}, + {file = "black-23.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c88b3711d12905b74206227109272673edce0cb29f27e1385f33b0163c414bba"}, + {file = "black-23.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a920b569dc6b3472513ba6ddea21f440d4b4c699494d2e972a1753cdc25df7b0"}, + {file = "black-23.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:3fa4be75ef2a6b96ea8d92b1587dd8cb3a35c7e3d51f0738ced0781c3aa3a5a3"}, + {file = "black-23.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8d4df77958a622f9b5a4c96edb4b8c0034f8434032ab11077ec6c56ae9f384ba"}, + {file = "black-23.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:602cfb1196dc692424c70b6507593a2b29aac0547c1be9a1d1365f0d964c353b"}, + {file = "black-23.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c4352800f14be5b4864016882cdba10755bd50805c95f728011bcb47a4afd59"}, + {file = "black-23.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:0808494f2b2df923ffc5723ed3c7b096bd76341f6213989759287611e9837d50"}, + {file = "black-23.12.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:25e57fd232a6d6ff3f4478a6fd0580838e47c93c83eaf1ccc92d4faf27112c4e"}, + {file = "black-23.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2d9e13db441c509a3763a7a3d9a49ccc1b4e974a47be4e08ade2a228876500ec"}, + {file = "black-23.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d1bd9c210f8b109b1762ec9fd36592fdd528485aadb3f5849b2740ef17e674e"}, + {file = "black-23.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:ae76c22bde5cbb6bfd211ec343ded2163bba7883c7bc77f6b756a1049436fbb9"}, + {file = "black-23.12.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1fa88a0f74e50e4487477bc0bb900c6781dbddfdfa32691e780bf854c3b4a47f"}, + {file = "black-23.12.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a4d6a9668e45ad99d2f8ec70d5c8c04ef4f32f648ef39048d010b0689832ec6d"}, + {file = "black-23.12.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b18fb2ae6c4bb63eebe5be6bd869ba2f14fd0259bda7d18a46b764d8fb86298a"}, + {file = "black-23.12.1-cp38-cp38-win_amd64.whl", hash = "sha256:c04b6d9d20e9c13f43eee8ea87d44156b8505ca8a3c878773f68b4e4812a421e"}, + {file = "black-23.12.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e1b38b3135fd4c025c28c55ddfc236b05af657828a8a6abe5deec419a0b7055"}, + {file = "black-23.12.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4f0031eaa7b921db76decd73636ef3a12c942ed367d8c3841a0739412b260a54"}, + {file = "black-23.12.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97e56155c6b737854e60a9ab1c598ff2533d57e7506d97af5481141671abf3ea"}, + {file = "black-23.12.1-cp39-cp39-win_amd64.whl", hash = "sha256:dd15245c8b68fe2b6bd0f32c1556509d11bb33aec9b5d0866dd8e2ed3dba09c2"}, + {file = "black-23.12.1-py3-none-any.whl", hash = "sha256:78baad24af0f033958cad29731e27363183e140962595def56423e626f4bee3e"}, + {file = "black-23.12.1.tar.gz", hash = "sha256:4ce3ef14ebe8d9509188014d96af1c456a910d5b5cbf434a09fef7e024b3d0d5"}, +] + +[package.dependencies] +click = ">=8.0.0" +ipython = {version = ">=7.8.0", optional = true, markers = "extra == \"jupyter\""} +mypy-extensions = ">=0.4.3" +packaging = ">=22.0" +pathspec = ">=0.9.0" +platformdirs = ">=2" +tokenize-rt = {version = ">=3.2.0", optional = true, markers = "extra == \"jupyter\""} +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.7.4) ; sys_platform != \"win32\" or implementation_name != \"pypy\"", "aiohttp (>=3.7.4,!=3.9.0) ; sys_platform == \"win32\" and implementation_name == \"pypy\""] +jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] +uvloop = ["uvloop (>=0.15.2)"] + +[[package]] +name = "bracex" +version = "2.5.post1" +description = "Bash style brace expander." +optional = false +python-versions = ">=3.8" +groups = ["docs"] +files = [ + {file = "bracex-2.5.post1-py3-none-any.whl", hash = "sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6"}, + {file = "bracex-2.5.post1.tar.gz", hash = "sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6"}, +] + +[[package]] +name = "cachetools" +version = "5.5.2" +description = "Extensible memoizing collections and decorators" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "cachetools-5.5.2-py3-none-any.whl", hash = "sha256:d26a22bcc62eb95c3beabd9f1ee5e820d3d2704fe2967cbe350e20c8ffcd3f0a"}, + {file = "cachetools-5.5.2.tar.gz", hash = "sha256:1a661caa9175d26759571b2e19580f9d6393969e5dfca11fdb1f947a23e640d4"}, +] + +[[package]] +name = "certifi" +version = "2025.11.12" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.7" +groups = ["main", "dev", "docs"] +files = [ + {file = "certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b"}, + {file = "certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.4" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7" +groups = ["dev", "docs"] +files = [ + {file = "charset_normalizer-3.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e824f1492727fa856dd6eda4f7cee25f8518a12f3c4a56a74e8095695089cf6d"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4bd5d4137d500351a30687c2d3971758aac9a19208fc110ccb9d7188fbe709e8"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:027f6de494925c0ab2a55eab46ae5129951638a49a34d87f4c3eda90f696b4ad"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f820802628d2694cb7e56db99213f930856014862f3fd943d290ea8438d07ca8"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:798d75d81754988d2565bff1b97ba5a44411867c0cf32b77a7e8f8d84796b10d"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d1bb833febdff5c8927f922386db610b49db6e0d4f4ee29601d71e7c2694313"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9cd98cdc06614a2f768d2b7286d66805f94c48cde050acdbbb7db2600ab3197e"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:077fbb858e903c73f6c9db43374fd213b0b6a778106bc7032446a8e8b5b38b93"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:244bfb999c71b35de57821b8ea746b24e863398194a4014e4c76adc2bbdfeff0"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:64b55f9dce520635f018f907ff1b0df1fdc31f2795a922fb49dd14fbcdf48c84"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:faa3a41b2b66b6e50f84ae4a68c64fcd0c44355741c6374813a800cd6695db9e"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6515f3182dbe4ea06ced2d9e8666d97b46ef4c75e326b79bb624110f122551db"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cc00f04ed596e9dc0da42ed17ac5e596c6ccba999ba6bd92b0e0aef2f170f2d6"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-win32.whl", hash = "sha256:f34be2938726fc13801220747472850852fe6b1ea75869a048d6f896838c896f"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:a61900df84c667873b292c3de315a786dd8dac506704dea57bc957bd31e22c7d"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-win_arm64.whl", hash = "sha256:cead0978fc57397645f12578bfd2d5ea9138ea0fac82b2f63f7f7c6877986a69"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-win32.whl", hash = "sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ce8a0633f41a967713a59c4139d29110c07e826d131a316b50ce11b1d79b4f84"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaabd426fe94daf8fd157c32e571c85cb12e66692f15516a83a03264b08d06c3"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c4ef880e27901b6cc782f1b95f82da9313c0eb95c3af699103088fa0ac3ce9ac"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2aaba3b0819274cc41757a1da876f810a3e4d7b6eb25699253a4effef9e8e4af"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:778d2e08eda00f4256d7f672ca9fef386071c9202f5e4607920b86d7803387f2"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f155a433c2ec037d4e8df17d18922c3a0d9b3232a396690f17175d2946f0218d"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a8bf8d0f749c5757af2142fe7903a9df1d2e8aa3841559b2bad34b08d0e2bcf3"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:194f08cbb32dc406d6e1aea671a68be0823673db2832b38405deba2fb0d88f63"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:6aee717dcfead04c6eb1ce3bd29ac1e22663cdea57f943c87d1eab9a025438d7"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:cd4b7ca9984e5e7985c12bc60a6f173f3c958eae74f3ef6624bb6b26e2abbae4"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_riscv64.whl", hash = "sha256:b7cf1017d601aa35e6bb650b6ad28652c9cd78ee6caff19f3c28d03e1c80acbf"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e912091979546adf63357d7e2ccff9b44f026c075aeaf25a52d0e95ad2281074"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:5cb4d72eea50c8868f5288b7f7f33ed276118325c1dfd3957089f6b519e1382a"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-win32.whl", hash = "sha256:837c2ce8c5a65a2035be9b3569c684358dfbf109fd3b6969630a87535495ceaa"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:44c2a8734b333e0578090c4cd6b16f275e07aa6614ca8715e6c038e865e70576"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a9768c477b9d7bd54bc0c86dbaebdec6f03306675526c9927c0e8a04e8f94af9"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1bee1e43c28aa63cb16e5c14e582580546b08e535299b8b6158a7c9c768a1f3d"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:fd44c878ea55ba351104cb93cc85e74916eb8fa440ca7903e57575e97394f608"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0f04b14ffe5fdc8c4933862d8306109a2c51e0704acfa35d51598eb45a1e89fc"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:cd09d08005f958f370f539f186d10aec3377d55b9eeb0d796025d4886119d76e"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4fe7859a4e3e8457458e2ff592f15ccb02f3da787fcd31e0183879c3ad4692a1"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fa09f53c465e532f4d3db095e0c55b615f010ad81803d383195b6b5ca6cbf5f3"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7fa17817dc5625de8a027cb8b26d9fefa3ea28c8253929b8d6649e705d2835b6"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:5947809c8a2417be3267efc979c47d76a079758166f7d43ef5ae8e9f92751f88"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:4902828217069c3c5c71094537a8e623f5d097858ac6ca8252f7b4d10b7560f1"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:7c308f7e26e4363d79df40ca5b2be1c6ba9f02bdbccfed5abddb7859a6ce72cf"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2c9d3c380143a1fedbff95a312aa798578371eb29da42106a29019368a475318"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:cb01158d8b88ee68f15949894ccc6712278243d95f344770fa7593fa2d94410c"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-win32.whl", hash = "sha256:2677acec1a2f8ef614c6888b5b4ae4060cc184174a938ed4e8ef690e15d3e505"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:f8e160feb2aed042cd657a72acc0b481212ed28b1b9a95c0cee1621b524e1966"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-win_arm64.whl", hash = "sha256:b5d84d37db046c5ca74ee7bb47dd6cbc13f80665fdde3e8040bdd3fb015ecb50"}, + {file = "charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f"}, + {file = "charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a"}, +] + +[[package]] +name = "click" +version = "8.1.8" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +groups = ["dev", "docs"] +files = [ + {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, + {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "codecov" +version = "2.1.13" +description = "Hosted coverage reports for GitHub, Bitbucket and Gitlab" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +groups = ["dev"] +files = [ + {file = "codecov-2.1.13-py2.py3-none-any.whl", hash = "sha256:c2ca5e51bba9ebb43644c43d0690148a55086f7f5e6fd36170858fa4206744d5"}, + {file = "codecov-2.1.13.tar.gz", hash = "sha256:2362b685633caeaf45b9951a9b76ce359cd3581dd515b430c6c3f5dfb4d92a8c"}, +] + +[package.dependencies] +coverage = "*" +requests = ">=2.7.9" + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["dev", "docs"] +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] +markers = {dev = "platform_system == \"Windows\" or sys_platform == \"win32\""} + +[[package]] +name = "contourpy" +version = "1.1.1" +description = "Python library for calculating contours of 2D quadrilateral grids" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +markers = "python_version <= \"3.10\"" +files = [ + {file = "contourpy-1.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:46e24f5412c948d81736509377e255f6040e94216bf1a9b5ea1eaa9d29f6ec1b"}, + {file = "contourpy-1.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e48694d6a9c5a26ee85b10130c77a011a4fedf50a7279fa0bdaf44bafb4299d"}, + {file = "contourpy-1.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a66045af6cf00e19d02191ab578a50cb93b2028c3eefed999793698e9ea768ae"}, + {file = "contourpy-1.1.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ebf42695f75ee1a952f98ce9775c873e4971732a87334b099dde90b6af6a916"}, + {file = "contourpy-1.1.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6aec19457617ef468ff091669cca01fa7ea557b12b59a7908b9474bb9674cf0"}, + {file = "contourpy-1.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:462c59914dc6d81e0b11f37e560b8a7c2dbab6aca4f38be31519d442d6cde1a1"}, + {file = "contourpy-1.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6d0a8efc258659edc5299f9ef32d8d81de8b53b45d67bf4bfa3067f31366764d"}, + {file = "contourpy-1.1.1-cp310-cp310-win32.whl", hash = "sha256:d6ab42f223e58b7dac1bb0af32194a7b9311065583cc75ff59dcf301afd8a431"}, + {file = "contourpy-1.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:549174b0713d49871c6dee90a4b499d3f12f5e5f69641cd23c50a4542e2ca1eb"}, + {file = "contourpy-1.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:407d864db716a067cc696d61fa1ef6637fedf03606e8417fe2aeed20a061e6b2"}, + {file = "contourpy-1.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe80c017973e6a4c367e037cb31601044dd55e6bfacd57370674867d15a899b"}, + {file = "contourpy-1.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e30aaf2b8a2bac57eb7e1650df1b3a4130e8d0c66fc2f861039d507a11760e1b"}, + {file = "contourpy-1.1.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3de23ca4f381c3770dee6d10ead6fff524d540c0f662e763ad1530bde5112532"}, + {file = "contourpy-1.1.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:566f0e41df06dfef2431defcfaa155f0acfa1ca4acbf8fd80895b1e7e2ada40e"}, + {file = "contourpy-1.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b04c2f0adaf255bf756cf08ebef1be132d3c7a06fe6f9877d55640c5e60c72c5"}, + {file = "contourpy-1.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d0c188ae66b772d9d61d43c6030500344c13e3f73a00d1dc241da896f379bb62"}, + {file = "contourpy-1.1.1-cp311-cp311-win32.whl", hash = "sha256:0683e1ae20dc038075d92e0e0148f09ffcefab120e57f6b4c9c0f477ec171f33"}, + {file = "contourpy-1.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:8636cd2fc5da0fb102a2504fa2c4bea3cbc149533b345d72cdf0e7a924decc45"}, + {file = "contourpy-1.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:560f1d68a33e89c62da5da4077ba98137a5e4d3a271b29f2f195d0fba2adcb6a"}, + {file = "contourpy-1.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24216552104ae8f3b34120ef84825400b16eb6133af2e27a190fdc13529f023e"}, + {file = "contourpy-1.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56de98a2fb23025882a18b60c7f0ea2d2d70bbbcfcf878f9067234b1c4818442"}, + {file = "contourpy-1.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:07d6f11dfaf80a84c97f1a5ba50d129d9303c5b4206f776e94037332e298dda8"}, + {file = "contourpy-1.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1eaac5257a8f8a047248d60e8f9315c6cff58f7803971170d952555ef6344a7"}, + {file = "contourpy-1.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19557fa407e70f20bfaba7d55b4d97b14f9480856c4fb65812e8a05fe1c6f9bf"}, + {file = "contourpy-1.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:081f3c0880712e40effc5f4c3b08feca6d064cb8cfbb372ca548105b86fd6c3d"}, + {file = "contourpy-1.1.1-cp312-cp312-win32.whl", hash = "sha256:059c3d2a94b930f4dafe8105bcdc1b21de99b30b51b5bce74c753686de858cb6"}, + {file = "contourpy-1.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:f44d78b61740e4e8c71db1cf1fd56d9050a4747681c59ec1094750a658ceb970"}, + {file = "contourpy-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:70e5a10f8093d228bb2b552beeb318b8928b8a94763ef03b858ef3612b29395d"}, + {file = "contourpy-1.1.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8394e652925a18ef0091115e3cc191fef350ab6dc3cc417f06da66bf98071ae9"}, + {file = "contourpy-1.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bd5680f844c3ff0008523a71949a3ff5e4953eb7701b28760805bc9bcff217"}, + {file = "contourpy-1.1.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:66544f853bfa85c0d07a68f6c648b2ec81dafd30f272565c37ab47a33b220684"}, + {file = "contourpy-1.1.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0c02b75acfea5cab07585d25069207e478d12309557f90a61b5a3b4f77f46ce"}, + {file = "contourpy-1.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41339b24471c58dc1499e56783fedc1afa4bb018bcd035cfb0ee2ad2a7501ef8"}, + {file = "contourpy-1.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f29fb0b3f1217dfe9362ec55440d0743fe868497359f2cf93293f4b2701b8251"}, + {file = "contourpy-1.1.1-cp38-cp38-win32.whl", hash = "sha256:f9dc7f933975367251c1b34da882c4f0e0b2e24bb35dc906d2f598a40b72bfc7"}, + {file = "contourpy-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:498e53573e8b94b1caeb9e62d7c2d053c263ebb6aa259c81050766beb50ff8d9"}, + {file = "contourpy-1.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ba42e3810999a0ddd0439e6e5dbf6d034055cdc72b7c5c839f37a7c274cb4eba"}, + {file = "contourpy-1.1.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6c06e4c6e234fcc65435223c7b2a90f286b7f1b2733058bdf1345d218cc59e34"}, + {file = "contourpy-1.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca6fab080484e419528e98624fb5c4282148b847e3602dc8dbe0cb0669469887"}, + {file = "contourpy-1.1.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:93df44ab351119d14cd1e6b52a5063d3336f0754b72736cc63db59307dabb718"}, + {file = "contourpy-1.1.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eafbef886566dc1047d7b3d4b14db0d5b7deb99638d8e1be4e23a7c7ac59ff0f"}, + {file = "contourpy-1.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efe0fab26d598e1ec07d72cf03eaeeba8e42b4ecf6b9ccb5a356fde60ff08b85"}, + {file = "contourpy-1.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f08e469821a5e4751c97fcd34bcb586bc243c39c2e39321822060ba902eac49e"}, + {file = "contourpy-1.1.1-cp39-cp39-win32.whl", hash = "sha256:bfc8a5e9238232a45ebc5cb3bfee71f1167064c8d382cadd6076f0d51cff1da0"}, + {file = "contourpy-1.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:c84fdf3da00c2827d634de4fcf17e3e067490c4aea82833625c4c8e6cdea0887"}, + {file = "contourpy-1.1.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:229a25f68046c5cf8067d6d6351c8b99e40da11b04d8416bf8d2b1d75922521e"}, + {file = "contourpy-1.1.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a10dab5ea1bd4401c9483450b5b0ba5416be799bbd50fc7a6cc5e2a15e03e8a3"}, + {file = "contourpy-1.1.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:4f9147051cb8fdb29a51dc2482d792b3b23e50f8f57e3720ca2e3d438b7adf23"}, + {file = "contourpy-1.1.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a75cc163a5f4531a256f2c523bd80db509a49fc23721b36dd1ef2f60ff41c3cb"}, + {file = "contourpy-1.1.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b53d5769aa1f2d4ea407c65f2d1d08002952fac1d9e9d307aa2e1023554a163"}, + {file = "contourpy-1.1.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:11b836b7dbfb74e049c302bbf74b4b8f6cb9d0b6ca1bf86cfa8ba144aedadd9c"}, + {file = "contourpy-1.1.1.tar.gz", hash = "sha256:96ba37c2e24b7212a77da85004c38e7c4d155d3e72a45eeaf22c1f03f607e8ab"}, +] + +[package.dependencies] +numpy = {version = ">=1.16,<2.0", markers = "python_version <= \"3.11\""} + +[package.extras] +bokeh = ["bokeh", "selenium"] +docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] +mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.4.1)", "types-Pillow"] +test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] +test-no-images = ["pytest", "pytest-cov", "wurlitzer"] + +[[package]] +name = "contourpy" +version = "1.3.3" +description = "Python library for calculating contours of 2D quadrilateral grids" +optional = false +python-versions = ">=3.11" +groups = ["main", "dev"] +markers = "python_version >= \"3.11\"" +files = [ + {file = "contourpy-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:709a48ef9a690e1343202916450bc48b9e51c049b089c7f79a267b46cffcdaa1"}, + {file = "contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381"}, + {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:929ddf8c4c7f348e4c0a5a3a714b5c8542ffaa8c22954862a46ca1813b667ee7"}, + {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9e999574eddae35f1312c2b4b717b7885d4edd6cb46700e04f7f02db454e67c1"}, + {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0bf67e0e3f482cb69779dd3061b534eb35ac9b17f163d851e2a547d56dba0a3a"}, + {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db"}, + {file = "contourpy-1.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:598c3aaece21c503615fd59c92a3598b428b2f01bfb4b8ca9c4edeecc2438620"}, + {file = "contourpy-1.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:322ab1c99b008dad206d406bb61d014cf0174df491ae9d9d0fac6a6fda4f977f"}, + {file = "contourpy-1.3.3-cp311-cp311-win32.whl", hash = "sha256:fd907ae12cd483cd83e414b12941c632a969171bf90fc937d0c9f268a31cafff"}, + {file = "contourpy-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42"}, + {file = "contourpy-1.3.3-cp311-cp311-win_arm64.whl", hash = "sha256:15ff10bfada4bf92ec8b31c62bf7c1834c244019b4a33095a68000d7075df470"}, + {file = "contourpy-1.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb"}, + {file = "contourpy-1.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6"}, + {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7"}, + {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8"}, + {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea"}, + {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1"}, + {file = "contourpy-1.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7"}, + {file = "contourpy-1.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411"}, + {file = "contourpy-1.3.3-cp312-cp312-win32.whl", hash = "sha256:023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69"}, + {file = "contourpy-1.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b"}, + {file = "contourpy-1.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc"}, + {file = "contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5"}, + {file = "contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1"}, + {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:348ac1f5d4f1d66d3322420f01d42e43122f43616e0f194fc1c9f5d830c5b286"}, + {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:655456777ff65c2c548b7c454af9c6f33f16c8884f11083244b5819cc214f1b5"}, + {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:644a6853d15b2512d67881586bd03f462c7ab755db95f16f14d7e238f2852c67"}, + {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9"}, + {file = "contourpy-1.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a15459b0f4615b00bbd1e91f1b9e19b7e63aea7483d03d804186f278c0af2659"}, + {file = "contourpy-1.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca0fdcd73925568ca027e0b17ab07aad764be4706d0a925b89227e447d9737b7"}, + {file = "contourpy-1.3.3-cp313-cp313-win32.whl", hash = "sha256:b20c7c9a3bf701366556e1b1984ed2d0cedf999903c51311417cf5f591d8c78d"}, + {file = "contourpy-1.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263"}, + {file = "contourpy-1.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:fd914713266421b7536de2bfa8181aa8c699432b6763a0ea64195ebe28bff6a9"}, + {file = "contourpy-1.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:88df9880d507169449d434c293467418b9f6cbe82edd19284aa0409e7fdb933d"}, + {file = "contourpy-1.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d06bb1f751ba5d417047db62bca3c8fde202b8c11fb50742ab3ab962c81e8216"}, + {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e4e6b05a45525357e382909a4c1600444e2a45b4795163d3b22669285591c1ae"}, + {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ab3074b48c4e2cf1a960e6bbeb7f04566bf36b1861d5c9d4d8ac04b82e38ba20"}, + {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c3d53c796f8647d6deb1abe867daeb66dcc8a97e8455efa729516b997b8ed99"}, + {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50ed930df7289ff2a8d7afeb9603f8289e5704755c7e5c3bbd929c90c817164b"}, + {file = "contourpy-1.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4feffb6537d64b84877da813a5c30f1422ea5739566abf0bd18065ac040e120a"}, + {file = "contourpy-1.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2b7e9480ffe2b0cd2e787e4df64270e3a0440d9db8dc823312e2c940c167df7e"}, + {file = "contourpy-1.3.3-cp313-cp313t-win32.whl", hash = "sha256:283edd842a01e3dcd435b1c5116798d661378d83d36d337b8dde1d16a5fc9ba3"}, + {file = "contourpy-1.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:87acf5963fc2b34825e5b6b048f40e3635dd547f590b04d2ab317c2619ef7ae8"}, + {file = "contourpy-1.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:3c30273eb2a55024ff31ba7d052dde990d7d8e5450f4bbb6e913558b3d6c2301"}, + {file = "contourpy-1.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fde6c716d51c04b1c25d0b90364d0be954624a0ee9d60e23e850e8d48353d07a"}, + {file = "contourpy-1.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cbedb772ed74ff5be440fa8eee9bd49f64f6e3fc09436d9c7d8f1c287b121d77"}, + {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22e9b1bd7a9b1d652cd77388465dc358dafcd2e217d35552424aa4f996f524f5"}, + {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a22738912262aa3e254e4f3cb079a95a67132fc5a063890e224393596902f5a4"}, + {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:afe5a512f31ee6bd7d0dda52ec9864c984ca3d66664444f2d72e0dc4eb832e36"}, + {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f64836de09927cba6f79dcd00fdd7d5329f3fccc633468507079c829ca4db4e3"}, + {file = "contourpy-1.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1fd43c3be4c8e5fd6e4f2baeae35ae18176cf2e5cced681cca908addf1cdd53b"}, + {file = "contourpy-1.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6afc576f7b33cf00996e5c1102dc2a8f7cc89e39c0b55df93a0b78c1bd992b36"}, + {file = "contourpy-1.3.3-cp314-cp314-win32.whl", hash = "sha256:66c8a43a4f7b8df8b71ee1840e4211a3c8d93b214b213f590e18a1beca458f7d"}, + {file = "contourpy-1.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:cf9022ef053f2694e31d630feaacb21ea24224be1c3ad0520b13d844274614fd"}, + {file = "contourpy-1.3.3-cp314-cp314-win_arm64.whl", hash = "sha256:95b181891b4c71de4bb404c6621e7e2390745f887f2a026b2d99e92c17892339"}, + {file = "contourpy-1.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:33c82d0138c0a062380332c861387650c82e4cf1747aaa6938b9b6516762e772"}, + {file = "contourpy-1.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ea37e7b45949df430fe649e5de8351c423430046a2af20b1c1961cae3afcda77"}, + {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d304906ecc71672e9c89e87c4675dc5c2645e1f4269a5063b99b0bb29f232d13"}, + {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca658cd1a680a5c9ea96dc61cdbae1e85c8f25849843aa799dfd3cb370ad4fbe"}, + {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ab2fd90904c503739a75b7c8c5c01160130ba67944a7b77bbf36ef8054576e7f"}, + {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7301b89040075c30e5768810bc96a8e8d78085b47d8be6e4c3f5a0b4ed478a0"}, + {file = "contourpy-1.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2a2a8b627d5cc6b7c41a4beff6c5ad5eb848c88255fda4a8745f7e901b32d8e4"}, + {file = "contourpy-1.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:fd6ec6be509c787f1caf6b247f0b1ca598bef13f4ddeaa126b7658215529ba0f"}, + {file = "contourpy-1.3.3-cp314-cp314t-win32.whl", hash = "sha256:e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae"}, + {file = "contourpy-1.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc"}, + {file = "contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b"}, + {file = "contourpy-1.3.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cd5dfcaeb10f7b7f9dc8941717c6c2ade08f587be2226222c12b25f0483ed497"}, + {file = "contourpy-1.3.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:0c1fc238306b35f246d61a1d416a627348b5cf0648648a031e14bb8705fcdfe8"}, + {file = "contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70f9aad7de812d6541d29d2bbf8feb22ff7e1c299523db288004e3157ff4674e"}, + {file = "contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ed3657edf08512fc3fe81b510e35c2012fbd3081d2e26160f27ca28affec989"}, + {file = "contourpy-1.3.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:3d1a3799d62d45c18bafd41c5fa05120b96a28079f2393af559b843d1a966a77"}, + {file = "contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880"}, +] + +[package.dependencies] +numpy = ">=1.25" + +[package.extras] +bokeh = ["bokeh", "selenium"] +docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] +mypy = ["bokeh", "contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.17.0)", "types-Pillow"] +test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] +test-no-images = ["pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist", "wurlitzer"] + +[[package]] +name = "coverage" +version = "7.6.1" +description = "Code coverage measurement for Python" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "coverage-7.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16"}, + {file = "coverage-7.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959"}, + {file = "coverage-7.6.1-cp310-cp310-win32.whl", hash = "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232"}, + {file = "coverage-7.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0"}, + {file = "coverage-7.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93"}, + {file = "coverage-7.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133"}, + {file = "coverage-7.6.1-cp311-cp311-win32.whl", hash = "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c"}, + {file = "coverage-7.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6"}, + {file = "coverage-7.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778"}, + {file = "coverage-7.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d"}, + {file = "coverage-7.6.1-cp312-cp312-win32.whl", hash = "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5"}, + {file = "coverage-7.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb"}, + {file = "coverage-7.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106"}, + {file = "coverage-7.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155"}, + {file = "coverage-7.6.1-cp313-cp313-win32.whl", hash = "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a"}, + {file = "coverage-7.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129"}, + {file = "coverage-7.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e"}, + {file = "coverage-7.6.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3"}, + {file = "coverage-7.6.1-cp313-cp313t-win32.whl", hash = "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f"}, + {file = "coverage-7.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657"}, + {file = "coverage-7.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6db04803b6c7291985a761004e9060b2bca08da6d04f26a7f2294b8623a0c1a0"}, + {file = "coverage-7.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f1adfc8ac319e1a348af294106bc6a8458a0f1633cc62a1446aebc30c5fa186a"}, + {file = "coverage-7.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a95324a9de9650a729239daea117df21f4b9868ce32e63f8b650ebe6cef5595b"}, + {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b43c03669dc4618ec25270b06ecd3ee4fa94c7f9b3c14bae6571ca00ef98b0d3"}, + {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8929543a7192c13d177b770008bc4e8119f2e1f881d563fc6b6305d2d0ebe9de"}, + {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a09ece4a69cf399510c8ab25e0950d9cf2b42f7b3cb0374f95d2e2ff594478a6"}, + {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9054a0754de38d9dbd01a46621636689124d666bad1936d76c0341f7d71bf569"}, + {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0dbde0f4aa9a16fa4d754356a8f2e36296ff4d83994b2c9d8398aa32f222f989"}, + {file = "coverage-7.6.1-cp38-cp38-win32.whl", hash = "sha256:da511e6ad4f7323ee5702e6633085fb76c2f893aaf8ce4c51a0ba4fc07580ea7"}, + {file = "coverage-7.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:3f1156e3e8f2872197af3840d8ad307a9dd18e615dc64d9ee41696f287c57ad8"}, + {file = "coverage-7.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:abd5fd0db5f4dc9289408aaf34908072f805ff7792632250dcb36dc591d24255"}, + {file = "coverage-7.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:547f45fa1a93154bd82050a7f3cddbc1a7a4dd2a9bf5cb7d06f4ae29fe94eaf8"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645786266c8f18a931b65bfcefdbf6952dd0dea98feee39bd188607a9d307ed2"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e0b2df163b8ed01d515807af24f63de04bebcecbd6c3bfeff88385789fdf75a"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:609b06f178fe8e9f89ef676532760ec0b4deea15e9969bf754b37f7c40326dbc"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:702855feff378050ae4f741045e19a32d57d19f3e0676d589df0575008ea5004"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:2bdb062ea438f22d99cba0d7829c2ef0af1d768d1e4a4f528087224c90b132cb"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9c56863d44bd1c4fe2abb8a4d6f5371d197f1ac0ebdee542f07f35895fc07f36"}, + {file = "coverage-7.6.1-cp39-cp39-win32.whl", hash = "sha256:6e2cd258d7d927d09493c8df1ce9174ad01b381d4729a9d8d4e38670ca24774c"}, + {file = "coverage-7.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:06a737c882bd26d0d6ee7269b20b12f14a8704807a01056c80bb881a4b2ce6ca"}, + {file = "coverage-7.6.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df"}, + {file = "coverage-7.6.1.tar.gz", hash = "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d"}, +] + +[package.dependencies] +tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} + +[package.extras] +toml = ["tomli ; python_full_version <= \"3.11.0a6\""] + +[[package]] +name = "cycler" +version = "0.12.1" +description = "Composable style cycles" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +files = [ + {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"}, + {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"}, +] +markers = {main = "extra == \"all\""} + +[package.extras] +docs = ["ipython", "matplotlib", "numpydoc", "sphinx"] +tests = ["pytest", "pytest-cov", "pytest-xdist"] + +[[package]] +name = "decorator" +version = "5.2.1" +description = "Decorators for Humans" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a"}, + {file = "decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360"}, +] + +[[package]] +name = "deprecation" +version = "2.1.0" +description = "A library to handle automated deprecations" +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "deprecation-2.1.0-py2.py3-none-any.whl", hash = "sha256:a10811591210e1fb0e768a8c25517cabeabcba6f0bf96564f8ff45189f90b14a"}, + {file = "deprecation-2.1.0.tar.gz", hash = "sha256:72b3bde64e5d778694b0cf68178aed03d15e15477116add3fb773e581f9518ff"}, +] + +[package.dependencies] +packaging = "*" + +[[package]] +name = "exceptiongroup" +version = "1.3.1" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +groups = ["dev"] +markers = "python_version <= \"3.10\"" +files = [ + {file = "exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598"}, + {file = "exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219"}, +] + +[package.dependencies] +typing-extensions = {version = ">=4.6.0", markers = "python_version < \"3.13\""} + +[package.extras] +test = ["pytest (>=6)"] + +[[package]] +name = "executing" +version = "2.2.1" +description = "Get the currently executing AST node of a frame, and other information" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "executing-2.2.1-py2.py3-none-any.whl", hash = "sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017"}, + {file = "executing-2.2.1.tar.gz", hash = "sha256:3632cc370565f6648cc328b32435bd120a1e4ebb20c77e3fdde9a13cd1e533c4"}, +] + +[package.extras] +tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich ; python_version >= \"3.11\""] + +[[package]] +name = "fonttools" +version = "4.57.0" +description = "Tools to manipulate font files" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +files = [ + {file = "fonttools-4.57.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:babe8d1eb059a53e560e7bf29f8e8f4accc8b6cfb9b5fd10e485bde77e71ef41"}, + {file = "fonttools-4.57.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:81aa97669cd726349eb7bd43ca540cf418b279ee3caba5e2e295fb4e8f841c02"}, + {file = "fonttools-4.57.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0e9618630edd1910ad4f07f60d77c184b2f572c8ee43305ea3265675cbbfe7e"}, + {file = "fonttools-4.57.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:34687a5d21f1d688d7d8d416cb4c5b9c87fca8a1797ec0d74b9fdebfa55c09ab"}, + {file = "fonttools-4.57.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:69ab81b66ebaa8d430ba56c7a5f9abe0183afefd3a2d6e483060343398b13fb1"}, + {file = "fonttools-4.57.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d639397de852f2ccfb3134b152c741406752640a266d9c1365b0f23d7b88077f"}, + {file = "fonttools-4.57.0-cp310-cp310-win32.whl", hash = "sha256:cc066cb98b912f525ae901a24cd381a656f024f76203bc85f78fcc9e66ae5aec"}, + {file = "fonttools-4.57.0-cp310-cp310-win_amd64.whl", hash = "sha256:7a64edd3ff6a7f711a15bd70b4458611fb240176ec11ad8845ccbab4fe6745db"}, + {file = "fonttools-4.57.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3871349303bdec958360eedb619169a779956503ffb4543bb3e6211e09b647c4"}, + {file = "fonttools-4.57.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c59375e85126b15a90fcba3443eaac58f3073ba091f02410eaa286da9ad80ed8"}, + {file = "fonttools-4.57.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:967b65232e104f4b0f6370a62eb33089e00024f2ce143aecbf9755649421c683"}, + {file = "fonttools-4.57.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39acf68abdfc74e19de7485f8f7396fa4d2418efea239b7061d6ed6a2510c746"}, + {file = "fonttools-4.57.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9d077f909f2343daf4495ba22bb0e23b62886e8ec7c109ee8234bdbd678cf344"}, + {file = "fonttools-4.57.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:46370ac47a1e91895d40e9ad48effbe8e9d9db1a4b80888095bc00e7beaa042f"}, + {file = "fonttools-4.57.0-cp311-cp311-win32.whl", hash = "sha256:ca2aed95855506b7ae94e8f1f6217b7673c929e4f4f1217bcaa236253055cb36"}, + {file = "fonttools-4.57.0-cp311-cp311-win_amd64.whl", hash = "sha256:17168a4670bbe3775f3f3f72d23ee786bd965395381dfbb70111e25e81505b9d"}, + {file = "fonttools-4.57.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:889e45e976c74abc7256d3064aa7c1295aa283c6bb19810b9f8b604dfe5c7f31"}, + {file = "fonttools-4.57.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0425c2e052a5f1516c94e5855dbda706ae5a768631e9fcc34e57d074d1b65b92"}, + {file = "fonttools-4.57.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44c26a311be2ac130f40a96769264809d3b0cb297518669db437d1cc82974888"}, + {file = "fonttools-4.57.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84c41ba992df5b8d680b89fd84c6a1f2aca2b9f1ae8a67400c8930cd4ea115f6"}, + {file = "fonttools-4.57.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ea1e9e43ca56b0c12440a7c689b1350066595bebcaa83baad05b8b2675129d98"}, + {file = "fonttools-4.57.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:84fd56c78d431606332a0627c16e2a63d243d0d8b05521257d77c6529abe14d8"}, + {file = "fonttools-4.57.0-cp312-cp312-win32.whl", hash = "sha256:f4376819c1c778d59e0a31db5dc6ede854e9edf28bbfa5b756604727f7f800ac"}, + {file = "fonttools-4.57.0-cp312-cp312-win_amd64.whl", hash = "sha256:57e30241524879ea10cdf79c737037221f77cc126a8cdc8ff2c94d4a522504b9"}, + {file = "fonttools-4.57.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:408ce299696012d503b714778d89aa476f032414ae57e57b42e4b92363e0b8ef"}, + {file = "fonttools-4.57.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bbceffc80aa02d9e8b99f2a7491ed8c4a783b2fc4020119dc405ca14fb5c758c"}, + {file = "fonttools-4.57.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f022601f3ee9e1f6658ed6d184ce27fa5216cee5b82d279e0f0bde5deebece72"}, + {file = "fonttools-4.57.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4dea5893b58d4637ffa925536462ba626f8a1b9ffbe2f5c272cdf2c6ebadb817"}, + {file = "fonttools-4.57.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:dff02c5c8423a657c550b48231d0a48d7e2b2e131088e55983cfe74ccc2c7cc9"}, + {file = "fonttools-4.57.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:767604f244dc17c68d3e2dbf98e038d11a18abc078f2d0f84b6c24571d9c0b13"}, + {file = "fonttools-4.57.0-cp313-cp313-win32.whl", hash = "sha256:8e2e12d0d862f43d51e5afb8b9751c77e6bec7d2dc00aad80641364e9df5b199"}, + {file = "fonttools-4.57.0-cp313-cp313-win_amd64.whl", hash = "sha256:f1d6bc9c23356908db712d282acb3eebd4ae5ec6d8b696aa40342b1d84f8e9e3"}, + {file = "fonttools-4.57.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:9d57b4e23ebbe985125d3f0cabbf286efa191ab60bbadb9326091050d88e8213"}, + {file = "fonttools-4.57.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:579ba873d7f2a96f78b2e11028f7472146ae181cae0e4d814a37a09e93d5c5cc"}, + {file = "fonttools-4.57.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e3e1ec10c29bae0ea826b61f265ec5c858c5ba2ce2e69a71a62f285cf8e4595"}, + {file = "fonttools-4.57.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1968f2a2003c97c4ce6308dc2498d5fd4364ad309900930aa5a503c9851aec8"}, + {file = "fonttools-4.57.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:aff40f8ac6763d05c2c8f6d240c6dac4bb92640a86d9b0c3f3fff4404f34095c"}, + {file = "fonttools-4.57.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:d07f1b64008e39fceae7aa99e38df8385d7d24a474a8c9872645c4397b674481"}, + {file = "fonttools-4.57.0-cp38-cp38-win32.whl", hash = "sha256:51d8482e96b28fb28aa8e50b5706f3cee06de85cbe2dce80dbd1917ae22ec5a6"}, + {file = "fonttools-4.57.0-cp38-cp38-win_amd64.whl", hash = "sha256:03290e818782e7edb159474144fca11e36a8ed6663d1fcbd5268eb550594fd8e"}, + {file = "fonttools-4.57.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7339e6a3283e4b0ade99cade51e97cde3d54cd6d1c3744459e886b66d630c8b3"}, + {file = "fonttools-4.57.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:05efceb2cb5f6ec92a4180fcb7a64aa8d3385fd49cfbbe459350229d1974f0b1"}, + {file = "fonttools-4.57.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a97bb05eb24637714a04dee85bdf0ad1941df64fe3b802ee4ac1c284a5f97b7c"}, + {file = "fonttools-4.57.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:541cb48191a19ceb1a2a4b90c1fcebd22a1ff7491010d3cf840dd3a68aebd654"}, + {file = "fonttools-4.57.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:cdef9a056c222d0479a1fdb721430f9efd68268014c54e8166133d2643cb05d9"}, + {file = "fonttools-4.57.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:3cf97236b192a50a4bf200dc5ba405aa78d4f537a2c6e4c624bb60466d5b03bd"}, + {file = "fonttools-4.57.0-cp39-cp39-win32.whl", hash = "sha256:e952c684274a7714b3160f57ec1d78309f955c6335c04433f07d36c5eb27b1f9"}, + {file = "fonttools-4.57.0-cp39-cp39-win_amd64.whl", hash = "sha256:a2a722c0e4bfd9966a11ff55c895c817158fcce1b2b6700205a376403b546ad9"}, + {file = "fonttools-4.57.0-py3-none-any.whl", hash = "sha256:3122c604a675513c68bd24c6a8f9091f1c2376d18e8f5fe5a101746c81b3e98f"}, + {file = "fonttools-4.57.0.tar.gz", hash = "sha256:727ece10e065be2f9dd239d15dd5d60a66e17eac11aea47d447f9f03fdbc42de"}, +] +markers = {main = "extra == \"all\""} + +[package.extras] +all = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "fs (>=2.2.0,<3)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres ; platform_python_implementation == \"PyPy\"", "pycairo", "scipy ; platform_python_implementation != \"PyPy\"", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0) ; python_version <= \"3.12\"", "xattr ; sys_platform == \"darwin\"", "zopfli (>=0.1.4)"] +graphite = ["lz4 (>=1.7.4.2)"] +interpolatable = ["munkres ; platform_python_implementation == \"PyPy\"", "pycairo", "scipy ; platform_python_implementation != \"PyPy\""] +lxml = ["lxml (>=4.0)"] +pathops = ["skia-pathops (>=0.5.0)"] +plot = ["matplotlib"] +repacker = ["uharfbuzz (>=0.23.0)"] +symfont = ["sympy"] +type1 = ["xattr ; sys_platform == \"darwin\""] +ufo = ["fs (>=2.2.0,<3)"] +unicode = ["unicodedata2 (>=15.1.0) ; python_version <= \"3.12\""] +woff = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "zopfli (>=0.1.4)"] + +[[package]] +name = "freezegun" +version = "1.5.5" +description = "Let your Python tests travel through time" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "freezegun-1.5.5-py3-none-any.whl", hash = "sha256:cd557f4a75cf074e84bc374249b9dd491eaeacd61376b9eb3c423282211619d2"}, + {file = "freezegun-1.5.5.tar.gz", hash = "sha256:ac7742a6cc6c25a2c35e9292dfd554b897b517d2dec26891a2e8debf205cb94a"}, +] + +[package.dependencies] +python-dateutil = ">=2.7" + +[[package]] +name = "ghp-import" +version = "2.1.0" +description = "Copy your docs directly to the gh-pages branch." +optional = false +python-versions = "*" +groups = ["docs"] +files = [ + {file = "ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343"}, + {file = "ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619"}, +] + +[package.dependencies] +python-dateutil = ">=2.8.1" + +[package.extras] +dev = ["flake8", "markdown", "twine", "wheel"] + +[[package]] +name = "griffe" +version = "0.38.0" +description = "Signatures for entire Python programs. Extract the structure, the frame, the skeleton of your project, to generate API documentation or find breaking changes in your API." +optional = false +python-versions = ">=3.8" +groups = ["docs"] +files = [ + {file = "griffe-0.38.0-py3-none-any.whl", hash = "sha256:6a5bc457320e8e199006aa5fbb03e162f5e21abe31aa6221f7a5c37ea0724c71"}, + {file = "griffe-0.38.0.tar.gz", hash = "sha256:9b97487b583042b543d1e28196caee638ecd766c8c4c98135071806cb5333ac2"}, +] + +[package.dependencies] +colorama = ">=0.4" + +[[package]] +name = "grpcio" +version = "1.70.0" +description = "HTTP/2-based RPC framework" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +markers = "python_version < \"3.10\"" +files = [ + {file = "grpcio-1.70.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:95469d1977429f45fe7df441f586521361e235982a0b39e33841549143ae2851"}, + {file = "grpcio-1.70.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:ed9718f17fbdb472e33b869c77a16d0b55e166b100ec57b016dc7de9c8d236bf"}, + {file = "grpcio-1.70.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:374d014f29f9dfdb40510b041792e0e2828a1389281eb590df066e1cc2b404e5"}, + {file = "grpcio-1.70.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2af68a6f5c8f78d56c145161544ad0febbd7479524a59c16b3e25053f39c87f"}, + {file = "grpcio-1.70.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce7df14b2dcd1102a2ec32f621cc9fab6695effef516efbc6b063ad749867295"}, + {file = "grpcio-1.70.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c78b339869f4dbf89881e0b6fbf376313e4f845a42840a7bdf42ee6caed4b11f"}, + {file = "grpcio-1.70.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:58ad9ba575b39edef71f4798fdb5c7b6d02ad36d47949cd381d4392a5c9cbcd3"}, + {file = "grpcio-1.70.0-cp310-cp310-win32.whl", hash = "sha256:2b0d02e4b25a5c1f9b6c7745d4fa06efc9fd6a611af0fb38d3ba956786b95199"}, + {file = "grpcio-1.70.0-cp310-cp310-win_amd64.whl", hash = "sha256:0de706c0a5bb9d841e353f6343a9defc9fc35ec61d6eb6111802f3aa9fef29e1"}, + {file = "grpcio-1.70.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:17325b0be0c068f35770f944124e8839ea3185d6d54862800fc28cc2ffad205a"}, + {file = "grpcio-1.70.0-cp311-cp311-macosx_10_14_universal2.whl", hash = "sha256:dbe41ad140df911e796d4463168e33ef80a24f5d21ef4d1e310553fcd2c4a386"}, + {file = "grpcio-1.70.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:5ea67c72101d687d44d9c56068328da39c9ccba634cabb336075fae2eab0d04b"}, + {file = "grpcio-1.70.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cb5277db254ab7586769e490b7b22f4ddab3876c490da0a1a9d7c695ccf0bf77"}, + {file = "grpcio-1.70.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7831a0fc1beeeb7759f737f5acd9fdcda520e955049512d68fda03d91186eea"}, + {file = "grpcio-1.70.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:27cc75e22c5dba1fbaf5a66c778e36ca9b8ce850bf58a9db887754593080d839"}, + {file = "grpcio-1.70.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d63764963412e22f0491d0d32833d71087288f4e24cbcddbae82476bfa1d81fd"}, + {file = "grpcio-1.70.0-cp311-cp311-win32.whl", hash = "sha256:bb491125103c800ec209d84c9b51f1c60ea456038e4734688004f377cfacc113"}, + {file = "grpcio-1.70.0-cp311-cp311-win_amd64.whl", hash = "sha256:d24035d49e026353eb042bf7b058fb831db3e06d52bee75c5f2f3ab453e71aca"}, + {file = "grpcio-1.70.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:ef4c14508299b1406c32bdbb9fb7b47612ab979b04cf2b27686ea31882387cff"}, + {file = "grpcio-1.70.0-cp312-cp312-macosx_10_14_universal2.whl", hash = "sha256:aa47688a65643afd8b166928a1da6247d3f46a2784d301e48ca1cc394d2ffb40"}, + {file = "grpcio-1.70.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:880bfb43b1bb8905701b926274eafce5c70a105bc6b99e25f62e98ad59cb278e"}, + {file = "grpcio-1.70.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e654c4b17d07eab259d392e12b149c3a134ec52b11ecdc6a515b39aceeec898"}, + {file = "grpcio-1.70.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2394e3381071045a706ee2eeb6e08962dd87e8999b90ac15c55f56fa5a8c9597"}, + {file = "grpcio-1.70.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:b3c76701428d2df01964bc6479422f20e62fcbc0a37d82ebd58050b86926ef8c"}, + {file = "grpcio-1.70.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ac073fe1c4cd856ebcf49e9ed6240f4f84d7a4e6ee95baa5d66ea05d3dd0df7f"}, + {file = "grpcio-1.70.0-cp312-cp312-win32.whl", hash = "sha256:cd24d2d9d380fbbee7a5ac86afe9787813f285e684b0271599f95a51bce33528"}, + {file = "grpcio-1.70.0-cp312-cp312-win_amd64.whl", hash = "sha256:0495c86a55a04a874c7627fd33e5beaee771917d92c0e6d9d797628ac40e7655"}, + {file = "grpcio-1.70.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:aa573896aeb7d7ce10b1fa425ba263e8dddd83d71530d1322fd3a16f31257b4a"}, + {file = "grpcio-1.70.0-cp313-cp313-macosx_10_14_universal2.whl", hash = "sha256:d405b005018fd516c9ac529f4b4122342f60ec1cee181788249372524e6db429"}, + {file = "grpcio-1.70.0-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:f32090238b720eb585248654db8e3afc87b48d26ac423c8dde8334a232ff53c9"}, + {file = "grpcio-1.70.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfa089a734f24ee5f6880c83d043e4f46bf812fcea5181dcb3a572db1e79e01c"}, + {file = "grpcio-1.70.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f19375f0300b96c0117aca118d400e76fede6db6e91f3c34b7b035822e06c35f"}, + {file = "grpcio-1.70.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:7c73c42102e4a5ec76608d9b60227d917cea46dff4d11d372f64cbeb56d259d0"}, + {file = "grpcio-1.70.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:0a5c78d5198a1f0aa60006cd6eb1c912b4a1520b6a3968e677dbcba215fabb40"}, + {file = "grpcio-1.70.0-cp313-cp313-win32.whl", hash = "sha256:fe9dbd916df3b60e865258a8c72ac98f3ac9e2a9542dcb72b7a34d236242a5ce"}, + {file = "grpcio-1.70.0-cp313-cp313-win_amd64.whl", hash = "sha256:4119fed8abb7ff6c32e3d2255301e59c316c22d31ab812b3fbcbaf3d0d87cc68"}, + {file = "grpcio-1.70.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:8058667a755f97407fca257c844018b80004ae8035565ebc2812cc550110718d"}, + {file = "grpcio-1.70.0-cp38-cp38-macosx_10_14_universal2.whl", hash = "sha256:879a61bf52ff8ccacbedf534665bb5478ec8e86ad483e76fe4f729aaef867cab"}, + {file = "grpcio-1.70.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:0ba0a173f4feacf90ee618fbc1a27956bfd21260cd31ced9bc707ef551ff7dc7"}, + {file = "grpcio-1.70.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:558c386ecb0148f4f99b1a65160f9d4b790ed3163e8610d11db47838d452512d"}, + {file = "grpcio-1.70.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:412faabcc787bbc826f51be261ae5fa996b21263de5368a55dc2cf824dc5090e"}, + {file = "grpcio-1.70.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3b0f01f6ed9994d7a0b27eeddea43ceac1b7e6f3f9d86aeec0f0064b8cf50fdb"}, + {file = "grpcio-1.70.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7385b1cb064734005204bc8994eed7dcb801ed6c2eda283f613ad8c6c75cf873"}, + {file = "grpcio-1.70.0-cp38-cp38-win32.whl", hash = "sha256:07269ff4940f6fb6710951116a04cd70284da86d0a4368fd5a3b552744511f5a"}, + {file = "grpcio-1.70.0-cp38-cp38-win_amd64.whl", hash = "sha256:aba19419aef9b254e15011b230a180e26e0f6864c90406fdbc255f01d83bc83c"}, + {file = "grpcio-1.70.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:4f1937f47c77392ccd555728f564a49128b6a197a05a5cd527b796d36f3387d0"}, + {file = "grpcio-1.70.0-cp39-cp39-macosx_10_14_universal2.whl", hash = "sha256:0cd430b9215a15c10b0e7d78f51e8a39d6cf2ea819fd635a7214fae600b1da27"}, + {file = "grpcio-1.70.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:e27585831aa6b57b9250abaf147003e126cd3a6c6ca0c531a01996f31709bed1"}, + {file = "grpcio-1.70.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c1af8e15b0f0fe0eac75195992a63df17579553b0c4af9f8362cc7cc99ccddf4"}, + {file = "grpcio-1.70.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cbce24409beaee911c574a3d75d12ffb8c3e3dd1b813321b1d7a96bbcac46bf4"}, + {file = "grpcio-1.70.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ff4a8112a79464919bb21c18e956c54add43ec9a4850e3949da54f61c241a4a6"}, + {file = "grpcio-1.70.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5413549fdf0b14046c545e19cfc4eb1e37e9e1ebba0ca390a8d4e9963cab44d2"}, + {file = "grpcio-1.70.0-cp39-cp39-win32.whl", hash = "sha256:b745d2c41b27650095e81dea7091668c040457483c9bdb5d0d9de8f8eb25e59f"}, + {file = "grpcio-1.70.0-cp39-cp39-win_amd64.whl", hash = "sha256:a31d7e3b529c94e930a117b2175b2efd179d96eb3c7a21ccb0289a8ab05b645c"}, + {file = "grpcio-1.70.0.tar.gz", hash = "sha256:8d1584a68d5922330025881e63a6c1b54cc8117291d382e4fa69339b6d914c56"}, +] + +[package.extras] +protobuf = ["grpcio-tools (>=1.70.0)"] + +[[package]] +name = "grpcio" +version = "1.78.0" +description = "HTTP/2-based RPC framework" +optional = false +python-versions = ">=3.9" +groups = ["main", "dev"] +markers = "python_version >= \"3.10\"" +files = [ + {file = "grpcio-1.78.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:7cc47943d524ee0096f973e1081cb8f4f17a4615f2116882a5f1416e4cfe92b5"}, + {file = "grpcio-1.78.0-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:c3f293fdc675ccba4db5a561048cca627b5e7bd1c8a6973ffedabe7d116e22e2"}, + {file = "grpcio-1.78.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:10a9a644b5dd5aec3b82b5b0b90d41c0fa94c85ef42cb42cf78a23291ddb5e7d"}, + {file = "grpcio-1.78.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:4c5533d03a6cbd7f56acfc9cfb44ea64f63d29091e40e44010d34178d392d7eb"}, + {file = "grpcio-1.78.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ff870aebe9a93a85283837801d35cd5f8814fe2ad01e606861a7fb47c762a2b7"}, + {file = "grpcio-1.78.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:391e93548644e6b2726f1bb84ed60048d4bcc424ce5e4af0843d28ca0b754fec"}, + {file = "grpcio-1.78.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:df2c8f3141f7cbd112a6ebbd760290b5849cda01884554f7c67acc14e7b1758a"}, + {file = "grpcio-1.78.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bd8cb8026e5f5b50498a3c4f196f57f9db344dad829ffae16b82e4fdbaea2813"}, + {file = "grpcio-1.78.0-cp310-cp310-win32.whl", hash = "sha256:f8dff3d9777e5d2703a962ee5c286c239bf0ba173877cc68dc02c17d042e29de"}, + {file = "grpcio-1.78.0-cp310-cp310-win_amd64.whl", hash = "sha256:94f95cf5d532d0e717eed4fc1810e8e6eded04621342ec54c89a7c2f14b581bf"}, + {file = "grpcio-1.78.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:2777b783f6c13b92bd7b716667452c329eefd646bfb3f2e9dabea2e05dbd34f6"}, + {file = "grpcio-1.78.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:9dca934f24c732750389ce49d638069c3892ad065df86cb465b3fa3012b70c9e"}, + {file = "grpcio-1.78.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:459ab414b35f4496138d0ecd735fed26f1318af5e52cb1efbc82a09f0d5aa911"}, + {file = "grpcio-1.78.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:082653eecbdf290e6e3e2c276ab2c54b9e7c299e07f4221872380312d8cf395e"}, + {file = "grpcio-1.78.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:85f93781028ec63f383f6bc90db785a016319c561cc11151fbb7b34e0d012303"}, + {file = "grpcio-1.78.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f12857d24d98441af6a1d5c87442d624411db486f7ba12550b07788f74b67b04"}, + {file = "grpcio-1.78.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5397fff416b79e4b284959642a4e95ac4b0f1ece82c9993658e0e477d40551ec"}, + {file = "grpcio-1.78.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:fbe6e89c7ffb48518384068321621b2a69cab509f58e40e4399fdd378fa6d074"}, + {file = "grpcio-1.78.0-cp311-cp311-win32.whl", hash = "sha256:6092beabe1966a3229f599d7088b38dfc8ffa1608b5b5cdda31e591e6500f856"}, + {file = "grpcio-1.78.0-cp311-cp311-win_amd64.whl", hash = "sha256:1afa62af6e23f88629f2b29ec9e52ec7c65a7176c1e0a83292b93c76ca882558"}, + {file = "grpcio-1.78.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:f9ab915a267fc47c7e88c387a3a28325b58c898e23d4995f765728f4e3dedb97"}, + {file = "grpcio-1.78.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3f8904a8165ab21e07e58bf3e30a73f4dffc7a1e0dbc32d51c61b5360d26f43e"}, + {file = "grpcio-1.78.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:859b13906ce098c0b493af92142ad051bf64c7870fa58a123911c88606714996"}, + {file = "grpcio-1.78.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:b2342d87af32790f934a79c3112641e7b27d63c261b8b4395350dad43eff1dc7"}, + {file = "grpcio-1.78.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:12a771591ae40bc65ba67048fa52ef4f0e6db8279e595fd349f9dfddeef571f9"}, + {file = "grpcio-1.78.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:185dea0d5260cbb2d224c507bf2a5444d5abbb1fa3594c1ed7e4c709d5eb8383"}, + {file = "grpcio-1.78.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:51b13f9aed9d59ee389ad666b8c2214cc87b5de258fa712f9ab05f922e3896c6"}, + {file = "grpcio-1.78.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fd5f135b1bd58ab088930b3c613455796dfa0393626a6972663ccdda5b4ac6ce"}, + {file = "grpcio-1.78.0-cp312-cp312-win32.whl", hash = "sha256:94309f498bcc07e5a7d16089ab984d42ad96af1d94b5a4eb966a266d9fcabf68"}, + {file = "grpcio-1.78.0-cp312-cp312-win_amd64.whl", hash = "sha256:9566fe4ababbb2610c39190791e5b829869351d14369603702e890ef3ad2d06e"}, + {file = "grpcio-1.78.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:ce3a90455492bf8bfa38e56fbbe1dbd4f872a3d8eeaf7337dc3b1c8aa28c271b"}, + {file = "grpcio-1.78.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:2bf5e2e163b356978b23652c4818ce4759d40f4712ee9ec5a83c4be6f8c23a3a"}, + {file = "grpcio-1.78.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8f2ac84905d12918e4e55a16da17939eb63e433dc11b677267c35568aa63fc84"}, + {file = "grpcio-1.78.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:b58f37edab4a3881bc6c9bca52670610e0c9ca14e2ea3cf9debf185b870457fb"}, + {file = "grpcio-1.78.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:735e38e176a88ce41840c21bb49098ab66177c64c82426e24e0082500cc68af5"}, + {file = "grpcio-1.78.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2045397e63a7a0ee7957c25f7dbb36ddc110e0cfb418403d110c0a7a68a844e9"}, + {file = "grpcio-1.78.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:a9f136fbafe7ccf4ac7e8e0c28b31066e810be52d6e344ef954a3a70234e1702"}, + {file = "grpcio-1.78.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:748b6138585379c737adc08aeffd21222abbda1a86a0dca2a39682feb9196c20"}, + {file = "grpcio-1.78.0-cp313-cp313-win32.whl", hash = "sha256:271c73e6e5676afe4fc52907686670c7cea22ab2310b76a59b678403ed40d670"}, + {file = "grpcio-1.78.0-cp313-cp313-win_amd64.whl", hash = "sha256:f2d4e43ee362adfc05994ed479334d5a451ab7bc3f3fee1b796b8ca66895acb4"}, + {file = "grpcio-1.78.0-cp314-cp314-linux_armv7l.whl", hash = "sha256:e87cbc002b6f440482b3519e36e1313eb5443e9e9e73d6a52d43bd2004fcfd8e"}, + {file = "grpcio-1.78.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:c41bc64626db62e72afec66b0c8a0da76491510015417c127bfc53b2fe6d7f7f"}, + {file = "grpcio-1.78.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8dfffba826efcf366b1e3ccc37e67afe676f290e13a3b48d31a46739f80a8724"}, + {file = "grpcio-1.78.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:74be1268d1439eaaf552c698cdb11cd594f0c49295ae6bb72c34ee31abbe611b"}, + {file = "grpcio-1.78.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:be63c88b32e6c0f1429f1398ca5c09bc64b0d80950c8bb7807d7d7fb36fb84c7"}, + {file = "grpcio-1.78.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:3c586ac70e855c721bda8f548d38c3ca66ac791dc49b66a8281a1f99db85e452"}, + {file = "grpcio-1.78.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:35eb275bf1751d2ffbd8f57cdbc46058e857cf3971041521b78b7db94bdaf127"}, + {file = "grpcio-1.78.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:207db540302c884b8848036b80db352a832b99dfdf41db1eb554c2c2c7800f65"}, + {file = "grpcio-1.78.0-cp314-cp314-win32.whl", hash = "sha256:57bab6deef2f4f1ca76cc04565df38dc5713ae6c17de690721bdf30cb1e0545c"}, + {file = "grpcio-1.78.0-cp314-cp314-win_amd64.whl", hash = "sha256:dce09d6116df20a96acfdbf85e4866258c3758180e8c49845d6ba8248b6d0bbb"}, + {file = "grpcio-1.78.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:86f85dd7c947baa707078a236288a289044836d4b640962018ceb9cd1f899af5"}, + {file = "grpcio-1.78.0-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:de8cb00d1483a412a06394b8303feec5dcb3b55f81d83aa216dbb6a0b86a94f5"}, + {file = "grpcio-1.78.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e888474dee2f59ff68130f8a397792d8cb8e17e6b3434339657ba4ee90845a8c"}, + {file = "grpcio-1.78.0-cp39-cp39-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:86ce2371bfd7f212cf60d8517e5e854475c2c43ce14aa910e136ace72c6db6c1"}, + {file = "grpcio-1.78.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b0c689c02947d636bc7fab3e30cc3a3445cca99c834dfb77cd4a6cabfc1c5597"}, + {file = "grpcio-1.78.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ce7599575eeb25c0f4dc1be59cada6219f3b56176f799627f44088b21381a28a"}, + {file = "grpcio-1.78.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:684083fd383e9dc04c794adb838d4faea08b291ce81f64ecd08e4577c7398adf"}, + {file = "grpcio-1.78.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ab399ef5e3cd2a721b1038a0f3021001f19c5ab279f145e1146bb0b9f1b2b12c"}, + {file = "grpcio-1.78.0-cp39-cp39-win32.whl", hash = "sha256:f3d6379493e18ad4d39537a82371c5281e153e963cecb13f953ebac155756525"}, + {file = "grpcio-1.78.0-cp39-cp39-win_amd64.whl", hash = "sha256:5361a0630a7fdb58a6a97638ab70e1dae2893c4d08d7aba64ded28bb9e7a29df"}, + {file = "grpcio-1.78.0.tar.gz", hash = "sha256:7382b95189546f375c174f53a5fa873cef91c4b8005faa05cc5b3beea9c4f1c5"}, +] + +[package.dependencies] +typing-extensions = ">=4.12,<5.0" + +[package.extras] +protobuf = ["grpcio-tools (>=1.78.0)"] + +[[package]] +name = "grpcio-tools" +version = "1.62.3" +description = "Protobuf code generator for gRPC" +optional = false +python-versions = ">=3.7" +groups = ["dev"] +markers = "python_version <= \"3.10\"" +files = [ + {file = "grpcio-tools-1.62.3.tar.gz", hash = "sha256:7c7136015c3d62c3eef493efabaf9e3380e3e66d24ee8e94c01cb71377f57833"}, + {file = "grpcio_tools-1.62.3-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:2f968b049c2849540751ec2100ab05e8086c24bead769ca734fdab58698408c1"}, + {file = "grpcio_tools-1.62.3-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:0a8c0c4724ae9c2181b7dbc9b186df46e4f62cb18dc184e46d06c0ebeccf569e"}, + {file = "grpcio_tools-1.62.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5782883a27d3fae8c425b29a9d3dcf5f47d992848a1b76970da3b5a28d424b26"}, + {file = "grpcio_tools-1.62.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3d812daffd0c2d2794756bd45a353f89e55dc8f91eb2fc840c51b9f6be62667"}, + {file = "grpcio_tools-1.62.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b47d0dda1bdb0a0ba7a9a6de88e5a1ed61f07fad613964879954961e36d49193"}, + {file = "grpcio_tools-1.62.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ca246dffeca0498be9b4e1ee169b62e64694b0f92e6d0be2573e65522f39eea9"}, + {file = "grpcio_tools-1.62.3-cp310-cp310-win32.whl", hash = "sha256:6a56d344b0bab30bf342a67e33d386b0b3c4e65868ffe93c341c51e1a8853ca5"}, + {file = "grpcio_tools-1.62.3-cp310-cp310-win_amd64.whl", hash = "sha256:710fecf6a171dcbfa263a0a3e7070e0df65ba73158d4c539cec50978f11dad5d"}, + {file = "grpcio_tools-1.62.3-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:703f46e0012af83a36082b5f30341113474ed0d91e36640da713355cd0ea5d23"}, + {file = "grpcio_tools-1.62.3-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:7cc83023acd8bc72cf74c2edbe85b52098501d5b74d8377bfa06f3e929803492"}, + {file = "grpcio_tools-1.62.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ff7d58a45b75df67d25f8f144936a3e44aabd91afec833ee06826bd02b7fbe7"}, + {file = "grpcio_tools-1.62.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f2483ea232bd72d98a6dc6d7aefd97e5bc80b15cd909b9e356d6f3e326b6e43"}, + {file = "grpcio_tools-1.62.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:962c84b4da0f3b14b3cdb10bc3837ebc5f136b67d919aea8d7bb3fd3df39528a"}, + {file = "grpcio_tools-1.62.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8ad0473af5544f89fc5a1ece8676dd03bdf160fb3230f967e05d0f4bf89620e3"}, + {file = "grpcio_tools-1.62.3-cp311-cp311-win32.whl", hash = "sha256:db3bc9fa39afc5e4e2767da4459df82b095ef0cab2f257707be06c44a1c2c3e5"}, + {file = "grpcio_tools-1.62.3-cp311-cp311-win_amd64.whl", hash = "sha256:e0898d412a434e768a0c7e365acabe13ff1558b767e400936e26b5b6ed1ee51f"}, + {file = "grpcio_tools-1.62.3-cp312-cp312-macosx_10_10_universal2.whl", hash = "sha256:d102b9b21c4e1e40af9a2ab3c6d41afba6bd29c0aa50ca013bf85c99cdc44ac5"}, + {file = "grpcio_tools-1.62.3-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:0a52cc9444df978438b8d2332c0ca99000521895229934a59f94f37ed896b133"}, + {file = "grpcio_tools-1.62.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:141d028bf5762d4a97f981c501da873589df3f7e02f4c1260e1921e565b376fa"}, + {file = "grpcio_tools-1.62.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47a5c093ab256dec5714a7a345f8cc89315cb57c298b276fa244f37a0ba507f0"}, + {file = "grpcio_tools-1.62.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:f6831fdec2b853c9daa3358535c55eed3694325889aa714070528cf8f92d7d6d"}, + {file = "grpcio_tools-1.62.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e02d7c1a02e3814c94ba0cfe43d93e872c758bd8fd5c2797f894d0c49b4a1dfc"}, + {file = "grpcio_tools-1.62.3-cp312-cp312-win32.whl", hash = "sha256:b881fd9505a84457e9f7e99362eeedd86497b659030cf57c6f0070df6d9c2b9b"}, + {file = "grpcio_tools-1.62.3-cp312-cp312-win_amd64.whl", hash = "sha256:11c625eebefd1fd40a228fc8bae385e448c7e32a6ae134e43cf13bbc23f902b7"}, + {file = "grpcio_tools-1.62.3-cp37-cp37m-macosx_10_10_universal2.whl", hash = "sha256:ec6fbded0c61afe6f84e3c2a43e6d656791d95747d6d28b73eff1af64108c434"}, + {file = "grpcio_tools-1.62.3-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:bfda6ee8990997a9df95c5606f3096dae65f09af7ca03a1e9ca28f088caca5cf"}, + {file = "grpcio_tools-1.62.3-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b77f9f9cee87cd798f0fe26b7024344d1b03a7cd2d2cba7035f8433b13986325"}, + {file = "grpcio_tools-1.62.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e02d3b96f2d0e4bab9ceaa30f37d4f75571e40c6272e95364bff3125a64d184"}, + {file = "grpcio_tools-1.62.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1da38070738da53556a4b35ab67c1b9884a5dd48fa2f243db35dc14079ea3d0c"}, + {file = "grpcio_tools-1.62.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ace43b26d88a58dcff16c20d23ff72b04d0a415f64d2820f4ff06b1166f50557"}, + {file = "grpcio_tools-1.62.3-cp37-cp37m-win_amd64.whl", hash = "sha256:350a80485e302daaa95d335a931f97b693e170e02d43767ab06552c708808950"}, + {file = "grpcio_tools-1.62.3-cp38-cp38-macosx_10_10_universal2.whl", hash = "sha256:c3a1ac9d394f8e229eb28eec2e04b9a6f5433fa19c9d32f1cb6066e3c5114a1d"}, + {file = "grpcio_tools-1.62.3-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:11f363570dea661dde99e04a51bd108a5807b5df32a6f8bdf4860e34e94a4dbf"}, + {file = "grpcio_tools-1.62.3-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9ad9950119d8ae27634e68b7663cc8d340ae535a0f80d85a55e56a6973ab1f"}, + {file = "grpcio_tools-1.62.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c5d22b252dcef11dd1e0fbbe5bbfb9b4ae048e8880d33338215e8ccbdb03edc"}, + {file = "grpcio_tools-1.62.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:27cd9ef5c5d68d5ed104b6dcb96fe9c66b82050e546c9e255716903c3d8f0373"}, + {file = "grpcio_tools-1.62.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f4b1615adf67bd8bb71f3464146a6f9949972d06d21a4f5e87e73f6464d97f57"}, + {file = "grpcio_tools-1.62.3-cp38-cp38-win32.whl", hash = "sha256:e18e15287c31baf574fcdf8251fb7f997d64e96c6ecf467906e576da0a079af6"}, + {file = "grpcio_tools-1.62.3-cp38-cp38-win_amd64.whl", hash = "sha256:6c3064610826f50bd69410c63101954676edc703e03f9e8f978a135f1aaf97c1"}, + {file = "grpcio_tools-1.62.3-cp39-cp39-macosx_10_10_universal2.whl", hash = "sha256:8e62cc7164b0b7c5128e637e394eb2ef3db0e61fc798e80c301de3b2379203ed"}, + {file = "grpcio_tools-1.62.3-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:c8ad5cce554e2fcaf8842dee5d9462583b601a3a78f8b76a153c38c963f58c10"}, + {file = "grpcio_tools-1.62.3-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec279dcf3518201fc592c65002754f58a6b542798cd7f3ecd4af086422f33f29"}, + {file = "grpcio_tools-1.62.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c989246c2aebc13253f08be32538a4039a64e12d9c18f6d662d7aee641dc8b5"}, + {file = "grpcio_tools-1.62.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ca4f5eeadbb57cf03317d6a2857823239a63a59cc935f5bd6cf6e8b7af7a7ecc"}, + {file = "grpcio_tools-1.62.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0cb3a3436ac119cbd37a7d3331d9bdf85dad21a6ac233a3411dff716dcbf401e"}, + {file = "grpcio_tools-1.62.3-cp39-cp39-win32.whl", hash = "sha256:3eae6ea76d62fcac091e1f15c2dcedf1dc3f114f8df1a972a8a0745e89f4cf61"}, + {file = "grpcio_tools-1.62.3-cp39-cp39-win_amd64.whl", hash = "sha256:eec73a005443061f4759b71a056f745e3b000dc0dc125c9f20560232dfbcbd14"}, +] + +[package.dependencies] +grpcio = ">=1.62.3" +protobuf = ">=4.21.6,<5.0.dev0" +setuptools = "*" + +[[package]] +name = "grpcio-tools" +version = "1.78.0" +description = "Protobuf code generator for gRPC" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +markers = "python_version >= \"3.11\"" +files = [ + {file = "grpcio_tools-1.78.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:ea64e38d1caa2b8468b08cb193f5a091d169b6dbfe1c7dac37d746651ab9d84e"}, + {file = "grpcio_tools-1.78.0-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:4003fcd5cbb5d578b06176fd45883a72a8f9203152149b7c680ce28653ad9e3a"}, + {file = "grpcio_tools-1.78.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fe6b0081775394c61ec633c9ff5dbc18337100eabb2e946b5c83967fe43b2748"}, + {file = "grpcio_tools-1.78.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:7e989ad2cd93db52d7f1a643ecaa156ac55bf0484f1007b485979ce8aef62022"}, + {file = "grpcio_tools-1.78.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b874991797e96c41a37e563236c3317ed41b915eff25b292b202d6277d30da85"}, + {file = "grpcio_tools-1.78.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:daa8c288b728228377aaf758925692fc6068939d9fa32f92ca13dedcbeb41f33"}, + {file = "grpcio_tools-1.78.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:87e648759b06133199f4bc0c0053e3819f4ec3b900dc399e1097b6065db998b5"}, + {file = "grpcio_tools-1.78.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f3d3ced52bfe39eba3d24f5a8fab4e12d071959384861b41f0c52ca5399d6920"}, + {file = "grpcio_tools-1.78.0-cp310-cp310-win32.whl", hash = "sha256:4bb6ed690d417b821808796221bde079377dff98fdc850ac157ad2f26cda7a36"}, + {file = "grpcio_tools-1.78.0-cp310-cp310-win_amd64.whl", hash = "sha256:0c676d8342fd53bd85a5d5f0d070cd785f93bc040510014708ede6fcb32fada1"}, + {file = "grpcio_tools-1.78.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:6a8b8b7b49f319d29dbcf507f62984fa382d1d10437d75c3f26db5f09c4ac0af"}, + {file = "grpcio_tools-1.78.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:d62cf3b68372b0c6d722a6165db41b976869811abeabc19c8522182978d8db10"}, + {file = "grpcio_tools-1.78.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fa9056742efeaf89d5fe14198af71e5cbc4fbf155d547b89507e19d6025906c6"}, + {file = "grpcio_tools-1.78.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:e3191af125dcb705aa6bc3856ba81ba99b94121c1b6ebee152e66ea084672831"}, + {file = "grpcio_tools-1.78.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:283239ddbb67ae83fac111c61b25d8527a1dbd355b377cbc8383b79f1329944d"}, + {file = "grpcio_tools-1.78.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ac977508c0db15301ef36d6c79769ec1a6cc4e3bc75735afca7fe7e360cead3a"}, + {file = "grpcio_tools-1.78.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4ff605e25652a0bd13aa8a73a09bc48669c68170902f5d2bf1468a57d5e78771"}, + {file = "grpcio_tools-1.78.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0197d7b561c79be78ab93d0fe2836c8def470683df594bae3ac89dd8e5c821b2"}, + {file = "grpcio_tools-1.78.0-cp311-cp311-win32.whl", hash = "sha256:28f71f591f7f39555863ced84fcc209cbf4454e85ef957232f43271ee99af577"}, + {file = "grpcio_tools-1.78.0-cp311-cp311-win_amd64.whl", hash = "sha256:5a6de495dabf86a3b40b9a7492994e1232b077af9d63080811838b781abbe4e8"}, + {file = "grpcio_tools-1.78.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:9eb122da57d4cad7d339fc75483116f0113af99e8d2c67f3ef9cae7501d806e4"}, + {file = "grpcio_tools-1.78.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:d0c501b8249940b886420e6935045c44cb818fa6f265f4c2b97d5cff9cb5e796"}, + {file = "grpcio_tools-1.78.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:77e5aa2d2a7268d55b1b113f958264681ef1994c970f69d48db7d4683d040f57"}, + {file = "grpcio_tools-1.78.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:8e3c0b0e6ba5275322ba29a97bf890565a55f129f99a21b121145e9e93a22525"}, + {file = "grpcio_tools-1.78.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:975d4cb48694e20ebd78e1643e5f1cd94cdb6a3d38e677a8e84ae43665aa4790"}, + {file = "grpcio_tools-1.78.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:553ff18c5d52807dedecf25045ae70bad7a3dbba0b27a9a3cdd9bcf0a1b7baec"}, + {file = "grpcio_tools-1.78.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:8c7f5e4af5a84d2e96c862b1a65e958a538237e268d5f8203a3a784340975b51"}, + {file = "grpcio_tools-1.78.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:96183e2b44afc3f9a761e9d0f985c3b44e03e8bb98e626241a6cbfb3b6f7e88f"}, + {file = "grpcio_tools-1.78.0-cp312-cp312-win32.whl", hash = "sha256:2250e8424c565a88573f7dc10659a0b92802e68c2a1d57e41872c9b88ccea7a6"}, + {file = "grpcio_tools-1.78.0-cp312-cp312-win_amd64.whl", hash = "sha256:217d1fa29de14d9c567d616ead7cb0fef33cde36010edff5a9390b00d52e5094"}, + {file = "grpcio_tools-1.78.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:2d6de1cc23bdc1baafc23e201b1e48c617b8c1418b4d8e34cebf72141676e5fb"}, + {file = "grpcio_tools-1.78.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:2afeaad88040894c76656202ff832cb151bceb05c0e6907e539d129188b1e456"}, + {file = "grpcio_tools-1.78.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:33cc593735c93c03d63efe7a8ba25f3c66f16c52f0651910712490244facad72"}, + {file = "grpcio_tools-1.78.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:2921d7989c4d83b71f03130ab415fa4d66e6693b8b8a1fcbb7a1c67cff19b812"}, + {file = "grpcio_tools-1.78.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e6a0df438e82c804c7b95e3f311c97c2f876dcc36376488d5b736b7bcf5a9b45"}, + {file = "grpcio_tools-1.78.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e9c6070a9500798225191ef25d0055a15d2c01c9c8f2ee7b681fffa99c98c822"}, + {file = "grpcio_tools-1.78.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:394e8b57d85370a62e5b0a4d64c96fcf7568345c345d8590c821814d227ecf1d"}, + {file = "grpcio_tools-1.78.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a3ef700293ab375e111a2909d87434ed0a0b086adf0ce67a8d9cf12ea7765e63"}, + {file = "grpcio_tools-1.78.0-cp313-cp313-win32.whl", hash = "sha256:6993b960fec43a8d840ee5dc20247ef206c1a19587ea49fe5e6cc3d2a09c1585"}, + {file = "grpcio_tools-1.78.0-cp313-cp313-win_amd64.whl", hash = "sha256:275ce3c2978842a8cf9dd88dce954e836e590cf7029649ad5d1145b779039ed5"}, + {file = "grpcio_tools-1.78.0-cp314-cp314-linux_armv7l.whl", hash = "sha256:8b080d0d072e6032708a3a91731b808074d7ab02ca8fb9847b6a011fdce64cd9"}, + {file = "grpcio_tools-1.78.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:8c0ad8f8f133145cd7008b49cb611a5c6a9d89ab276c28afa17050516e801f79"}, + {file = "grpcio_tools-1.78.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2f8ea092a7de74c6359335d36f0674d939a3c7e1a550f4c2c9e80e0226de8fe4"}, + {file = "grpcio_tools-1.78.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:da422985e0cac822b41822f43429c19ecb27c81ffe3126d0b74e77edec452608"}, + {file = "grpcio_tools-1.78.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4fab1faa3fbcb246263e68da7a8177d73772283f9db063fb8008517480888d26"}, + {file = "grpcio_tools-1.78.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:dd9c094f73f734becae3f20f27d4944d3cd8fb68db7338ee6c58e62fc5c3d99f"}, + {file = "grpcio_tools-1.78.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:2ed51ce6b833068f6c580b73193fc2ec16468e6bc18354bc2f83a58721195a58"}, + {file = "grpcio_tools-1.78.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:05803a5cdafe77c8bdf36aa660ad7a6a1d9e49bc59ce45c1bade2a4698826599"}, + {file = "grpcio_tools-1.78.0-cp314-cp314-win32.whl", hash = "sha256:f7c722e9ce6f11149ac5bddd5056e70aaccfd8168e74e9d34d8b8b588c3f5c7c"}, + {file = "grpcio_tools-1.78.0-cp314-cp314-win_amd64.whl", hash = "sha256:7d58ade518b546120ec8f0a8e006fc8076ae5df151250ebd7e82e9b5e152c229"}, + {file = "grpcio_tools-1.78.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:30b1eef2afb6f2c3deb94525d60aedfea807d4937b5e23ad72600e3f8cd1c768"}, + {file = "grpcio_tools-1.78.0-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:c70b07b2610db3743d831700301eb17a9e1de2818d1f36ad53cb5b8b593a5749"}, + {file = "grpcio_tools-1.78.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f6d53392eb0f758eaa9ecfa6f9aab1e1f3c9db117a4242c802a30363fdc404d2"}, + {file = "grpcio_tools-1.78.0-cp39-cp39-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:638fa11b4731dce2c662f685c3be0489246e8d2306654eb26ebd71e6a24c4b70"}, + {file = "grpcio_tools-1.78.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:21b31c87cef35af124f1cfb105614725b462656d2684f59d05a6210266b17b9e"}, + {file = "grpcio_tools-1.78.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:b81b4cf356272512172a604d4467af9b373de69cd69e1ac163fb41f7dac33099"}, + {file = "grpcio_tools-1.78.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:5c8ceb32cd818e40739529b3c3143a30c899c247db22a6275c4798dece9a4ae7"}, + {file = "grpcio_tools-1.78.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1872d01f984c85ee49ce581fcaffbcc9c792692b4b5ebf9bba4358fc895c316a"}, + {file = "grpcio_tools-1.78.0-cp39-cp39-win32.whl", hash = "sha256:4eff49de5f8f320ed2a69bbb6bfe512175b1762d736cfce28aca0129939f7252"}, + {file = "grpcio_tools-1.78.0-cp39-cp39-win_amd64.whl", hash = "sha256:6ddf7e7a7d069e7287b9cb68937102efe1686e63117a162d01578ac2839b4acd"}, + {file = "grpcio_tools-1.78.0.tar.gz", hash = "sha256:4b0dd86560274316e155d925158276f8564508193088bc43e20d3f5dff956b2b"}, +] + +[package.dependencies] +grpcio = ">=1.78.0" +protobuf = ">=6.31.1,<7.0.0" +setuptools = ">=77.0.1" + +[[package]] +name = "idna" +version = "3.11" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.8" +groups = ["dev", "docs"] +files = [ + {file = "idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea"}, + {file = "idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902"}, +] + +[package.extras] +all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] + +[[package]] +name = "importlib-metadata" +version = "8.5.0" +description = "Read metadata from Python packages" +optional = false +python-versions = ">=3.8" +groups = ["docs"] +markers = "python_version < \"3.10\"" +files = [ + {file = "importlib_metadata-8.5.0-py3-none-any.whl", hash = "sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b"}, + {file = "importlib_metadata-8.5.0.tar.gz", hash = "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7"}, +] + +[package.dependencies] +zipp = ">=3.20" + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +perf = ["ipython"] +test = ["flufl.flake8", "importlib-resources (>=1.3) ; python_version < \"3.9\"", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] +type = ["pytest-mypy"] + +[[package]] +name = "importlib-resources" +version = "6.4.5" +description = "Read resources from Python packages" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +files = [ + {file = "importlib_resources-6.4.5-py3-none-any.whl", hash = "sha256:ac29d5f956f01d5e4bb63102a5a19957f1b9175e45649977264a1416783bb717"}, + {file = "importlib_resources-6.4.5.tar.gz", hash = "sha256:980862a1d16c9e147a59603677fa2aa5fd82b87f223b6cb870695bcfce830065"}, +] +markers = {main = "python_version < \"3.10\" and extra == \"all\"", dev = "python_version < \"3.10\""} + +[package.dependencies] +zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["jaraco.test (>=5.4)", "pytest (>=6,!=8.1.*)", "zipp (>=3.17)"] +type = ["pytest-mypy"] + +[[package]] +name = "iniconfig" +version = "2.1.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760"}, + {file = "iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"}, +] + +[[package]] +name = "ipython" +version = "8.12.3" +description = "IPython: Productive Interactive Computing" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "ipython-8.12.3-py3-none-any.whl", hash = "sha256:b0340d46a933d27c657b211a329d0be23793c36595acf9e6ef4164bc01a1804c"}, + {file = "ipython-8.12.3.tar.gz", hash = "sha256:3910c4b54543c2ad73d06579aa771041b7d5707b033bd488669b4cf544e3b363"}, +] + +[package.dependencies] +appnope = {version = "*", markers = "sys_platform == \"darwin\""} +backcall = "*" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +decorator = "*" +jedi = ">=0.16" +matplotlib-inline = "*" +pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} +pickleshare = "*" +prompt-toolkit = ">=3.0.30,<3.0.37 || >3.0.37,<3.1.0" +pygments = ">=2.4.0" +stack-data = "*" +traitlets = ">=5" +typing-extensions = {version = "*", markers = "python_version < \"3.10\""} + +[package.extras] +all = ["black", "curio", "docrepr", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.21)", "pandas", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] +black = ["black"] +doc = ["docrepr", "ipykernel", "matplotlib", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] +kernel = ["ipykernel"] +nbconvert = ["nbconvert"] +nbformat = ["nbformat"] +notebook = ["ipywidgets", "notebook"] +parallel = ["ipyparallel"] +qtconsole = ["qtconsole"] +test = ["pytest (<7.1)", "pytest-asyncio", "testpath"] +test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pandas", "pytest (<7.1)", "pytest-asyncio", "testpath", "trio"] + +[[package]] +name = "isort" +version = "5.13.2" +description = "A Python utility / library to sort Python imports." +optional = false +python-versions = ">=3.8.0" +groups = ["dev"] +files = [ + {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, + {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, +] + +[package.extras] +colors = ["colorama (>=0.4.6)"] + +[[package]] +name = "jedi" +version = "0.19.2" +description = "An autocompletion tool for Python that can be used for text editors." +optional = false +python-versions = ">=3.6" +groups = ["dev"] +files = [ + {file = "jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9"}, + {file = "jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0"}, +] + +[package.dependencies] +parso = ">=0.8.4,<0.9.0" + +[package.extras] +docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] +qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] +testing = ["Django", "attrs", "colorama", "docopt", "pytest (<9.0.0)"] + +[[package]] +name = "jinja2" +version = "3.1.6" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +groups = ["docs"] +files = [ + {file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"}, + {file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "kiwisolver" +version = "1.4.7" +description = "A fast implementation of the Cassowary constraint solver" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +markers = "python_version < \"3.10\"" +files = [ + {file = "kiwisolver-1.4.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8a9c83f75223d5e48b0bc9cb1bf2776cf01563e00ade8775ffe13b0b6e1af3a6"}, + {file = "kiwisolver-1.4.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:58370b1ffbd35407444d57057b57da5d6549d2d854fa30249771775c63b5fe17"}, + {file = "kiwisolver-1.4.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:aa0abdf853e09aff551db11fce173e2177d00786c688203f52c87ad7fcd91ef9"}, + {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8d53103597a252fb3ab8b5845af04c7a26d5e7ea8122303dd7a021176a87e8b9"}, + {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:88f17c5ffa8e9462fb79f62746428dd57b46eb931698e42e990ad63103f35e6c"}, + {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88a9ca9c710d598fd75ee5de59d5bda2684d9db36a9f50b6125eaea3969c2599"}, + {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f4d742cb7af1c28303a51b7a27aaee540e71bb8e24f68c736f6f2ffc82f2bf05"}, + {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e28c7fea2196bf4c2f8d46a0415c77a1c480cc0724722f23d7410ffe9842c407"}, + {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e968b84db54f9d42046cf154e02911e39c0435c9801681e3fc9ce8a3c4130278"}, + {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0c18ec74c0472de033e1bebb2911c3c310eef5649133dd0bedf2a169a1b269e5"}, + {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8f0ea6da6d393d8b2e187e6a5e3fb81f5862010a40c3945e2c6d12ae45cfb2ad"}, + {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:f106407dda69ae456dd1227966bf445b157ccc80ba0dff3802bb63f30b74e895"}, + {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:84ec80df401cfee1457063732d90022f93951944b5b58975d34ab56bb150dfb3"}, + {file = "kiwisolver-1.4.7-cp310-cp310-win32.whl", hash = "sha256:71bb308552200fb2c195e35ef05de12f0c878c07fc91c270eb3d6e41698c3bcc"}, + {file = "kiwisolver-1.4.7-cp310-cp310-win_amd64.whl", hash = "sha256:44756f9fd339de0fb6ee4f8c1696cfd19b2422e0d70b4cefc1cc7f1f64045a8c"}, + {file = "kiwisolver-1.4.7-cp310-cp310-win_arm64.whl", hash = "sha256:78a42513018c41c2ffd262eb676442315cbfe3c44eed82385c2ed043bc63210a"}, + {file = "kiwisolver-1.4.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d2b0e12a42fb4e72d509fc994713d099cbb15ebf1103545e8a45f14da2dfca54"}, + {file = "kiwisolver-1.4.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2a8781ac3edc42ea4b90bc23e7d37b665d89423818e26eb6df90698aa2287c95"}, + {file = "kiwisolver-1.4.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:46707a10836894b559e04b0fd143e343945c97fd170d69a2d26d640b4e297935"}, + {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef97b8df011141c9b0f6caf23b29379f87dd13183c978a30a3c546d2c47314cb"}, + {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ab58c12a2cd0fc769089e6d38466c46d7f76aced0a1f54c77652446733d2d02"}, + {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:803b8e1459341c1bb56d1c5c010406d5edec8a0713a0945851290a7930679b51"}, + {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f9a9e8a507420fe35992ee9ecb302dab68550dedc0da9e2880dd88071c5fb052"}, + {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18077b53dc3bb490e330669a99920c5e6a496889ae8c63b58fbc57c3d7f33a18"}, + {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6af936f79086a89b3680a280c47ea90b4df7047b5bdf3aa5c524bbedddb9e545"}, + {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:3abc5b19d24af4b77d1598a585b8a719beb8569a71568b66f4ebe1fb0449460b"}, + {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:933d4de052939d90afbe6e9d5273ae05fb836cc86c15b686edd4b3560cc0ee36"}, + {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:65e720d2ab2b53f1f72fb5da5fb477455905ce2c88aaa671ff0a447c2c80e8e3"}, + {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3bf1ed55088f214ba6427484c59553123fdd9b218a42bbc8c6496d6754b1e523"}, + {file = "kiwisolver-1.4.7-cp311-cp311-win32.whl", hash = "sha256:4c00336b9dd5ad96d0a558fd18a8b6f711b7449acce4c157e7343ba92dd0cf3d"}, + {file = "kiwisolver-1.4.7-cp311-cp311-win_amd64.whl", hash = "sha256:929e294c1ac1e9f615c62a4e4313ca1823ba37326c164ec720a803287c4c499b"}, + {file = "kiwisolver-1.4.7-cp311-cp311-win_arm64.whl", hash = "sha256:e33e8fbd440c917106b237ef1a2f1449dfbb9b6f6e1ce17c94cd6a1e0d438376"}, + {file = "kiwisolver-1.4.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:5360cc32706dab3931f738d3079652d20982511f7c0ac5711483e6eab08efff2"}, + {file = "kiwisolver-1.4.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:942216596dc64ddb25adb215c3c783215b23626f8d84e8eff8d6d45c3f29f75a"}, + {file = "kiwisolver-1.4.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:48b571ecd8bae15702e4f22d3ff6a0f13e54d3d00cd25216d5e7f658242065ee"}, + {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ad42ba922c67c5f219097b28fae965e10045ddf145d2928bfac2eb2e17673640"}, + {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:612a10bdae23404a72941a0fc8fa2660c6ea1217c4ce0dbcab8a8f6543ea9e7f"}, + {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9e838bba3a3bac0fe06d849d29772eb1afb9745a59710762e4ba3f4cb8424483"}, + {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:22f499f6157236c19f4bbbd472fa55b063db77a16cd74d49afe28992dff8c258"}, + {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:693902d433cf585133699972b6d7c42a8b9f8f826ebcaf0132ff55200afc599e"}, + {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4e77f2126c3e0b0d055f44513ed349038ac180371ed9b52fe96a32aa071a5107"}, + {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:657a05857bda581c3656bfc3b20e353c232e9193eb167766ad2dc58b56504948"}, + {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4bfa75a048c056a411f9705856abfc872558e33c055d80af6a380e3658766038"}, + {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:34ea1de54beef1c104422d210c47c7d2a4999bdecf42c7b5718fbe59a4cac383"}, + {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:90da3b5f694b85231cf93586dad5e90e2d71b9428f9aad96952c99055582f520"}, + {file = "kiwisolver-1.4.7-cp312-cp312-win32.whl", hash = "sha256:18e0cca3e008e17fe9b164b55735a325140a5a35faad8de92dd80265cd5eb80b"}, + {file = "kiwisolver-1.4.7-cp312-cp312-win_amd64.whl", hash = "sha256:58cb20602b18f86f83a5c87d3ee1c766a79c0d452f8def86d925e6c60fbf7bfb"}, + {file = "kiwisolver-1.4.7-cp312-cp312-win_arm64.whl", hash = "sha256:f5a8b53bdc0b3961f8b6125e198617c40aeed638b387913bf1ce78afb1b0be2a"}, + {file = "kiwisolver-1.4.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2e6039dcbe79a8e0f044f1c39db1986a1b8071051efba3ee4d74f5b365f5226e"}, + {file = "kiwisolver-1.4.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a1ecf0ac1c518487d9d23b1cd7139a6a65bc460cd101ab01f1be82ecf09794b6"}, + {file = "kiwisolver-1.4.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7ab9ccab2b5bd5702ab0803676a580fffa2aa178c2badc5557a84cc943fcf750"}, + {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f816dd2277f8d63d79f9c8473a79fe54047bc0467754962840782c575522224d"}, + {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf8bcc23ceb5a1b624572a1623b9f79d2c3b337c8c455405ef231933a10da379"}, + {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dea0bf229319828467d7fca8c7c189780aa9ff679c94539eed7532ebe33ed37c"}, + {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c06a4c7cf15ec739ce0e5971b26c93638730090add60e183530d70848ebdd34"}, + {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:913983ad2deb14e66d83c28b632fd35ba2b825031f2fa4ca29675e665dfecbe1"}, + {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5337ec7809bcd0f424c6b705ecf97941c46279cf5ed92311782c7c9c2026f07f"}, + {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4c26ed10c4f6fa6ddb329a5120ba3b6db349ca192ae211e882970bfc9d91420b"}, + {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c619b101e6de2222c1fcb0531e1b17bbffbe54294bfba43ea0d411d428618c27"}, + {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:073a36c8273647592ea332e816e75ef8da5c303236ec0167196793eb1e34657a"}, + {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3ce6b2b0231bda412463e152fc18335ba32faf4e8c23a754ad50ffa70e4091ee"}, + {file = "kiwisolver-1.4.7-cp313-cp313-win32.whl", hash = "sha256:f4c9aee212bc89d4e13f58be11a56cc8036cabad119259d12ace14b34476fd07"}, + {file = "kiwisolver-1.4.7-cp313-cp313-win_amd64.whl", hash = "sha256:8a3ec5aa8e38fc4c8af308917ce12c536f1c88452ce554027e55b22cbbfbff76"}, + {file = "kiwisolver-1.4.7-cp313-cp313-win_arm64.whl", hash = "sha256:76c8094ac20ec259471ac53e774623eb62e6e1f56cd8690c67ce6ce4fcb05650"}, + {file = "kiwisolver-1.4.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5d5abf8f8ec1f4e22882273c423e16cae834c36856cac348cfbfa68e01c40f3a"}, + {file = "kiwisolver-1.4.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:aeb3531b196ef6f11776c21674dba836aeea9d5bd1cf630f869e3d90b16cfade"}, + {file = "kiwisolver-1.4.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b7d755065e4e866a8086c9bdada157133ff466476a2ad7861828e17b6026e22c"}, + {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08471d4d86cbaec61f86b217dd938a83d85e03785f51121e791a6e6689a3be95"}, + {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7bbfcb7165ce3d54a3dfbe731e470f65739c4c1f85bb1018ee912bae139e263b"}, + {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d34eb8494bea691a1a450141ebb5385e4b69d38bb8403b5146ad279f4b30fa3"}, + {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9242795d174daa40105c1d86aba618e8eab7bf96ba8c3ee614da8302a9f95503"}, + {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a0f64a48bb81af7450e641e3fe0b0394d7381e342805479178b3d335d60ca7cf"}, + {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8e045731a5416357638d1700927529e2b8ab304811671f665b225f8bf8d8f933"}, + {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:4322872d5772cae7369f8351da1edf255a604ea7087fe295411397d0cfd9655e"}, + {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:e1631290ee9271dffe3062d2634c3ecac02c83890ada077d225e081aca8aab89"}, + {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:edcfc407e4eb17e037bca59be0e85a2031a2ac87e4fed26d3e9df88b4165f92d"}, + {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:4d05d81ecb47d11e7f8932bd8b61b720bf0b41199358f3f5e36d38e28f0532c5"}, + {file = "kiwisolver-1.4.7-cp38-cp38-win32.whl", hash = "sha256:b38ac83d5f04b15e515fd86f312479d950d05ce2368d5413d46c088dda7de90a"}, + {file = "kiwisolver-1.4.7-cp38-cp38-win_amd64.whl", hash = "sha256:d83db7cde68459fc803052a55ace60bea2bae361fc3b7a6d5da07e11954e4b09"}, + {file = "kiwisolver-1.4.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3f9362ecfca44c863569d3d3c033dbe8ba452ff8eed6f6b5806382741a1334bd"}, + {file = "kiwisolver-1.4.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e8df2eb9b2bac43ef8b082e06f750350fbbaf2887534a5be97f6cf07b19d9583"}, + {file = "kiwisolver-1.4.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f32d6edbc638cde7652bd690c3e728b25332acbadd7cad670cc4a02558d9c417"}, + {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e2e6c39bd7b9372b0be21456caab138e8e69cc0fc1190a9dfa92bd45a1e6e904"}, + {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dda56c24d869b1193fcc763f1284b9126550eaf84b88bbc7256e15028f19188a"}, + {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79849239c39b5e1fd906556c474d9b0439ea6792b637511f3fe3a41158d89ca8"}, + {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5e3bc157fed2a4c02ec468de4ecd12a6e22818d4f09cde2c31ee3226ffbefab2"}, + {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3da53da805b71e41053dc670f9a820d1157aae77b6b944e08024d17bcd51ef88"}, + {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8705f17dfeb43139a692298cb6637ee2e59c0194538153e83e9ee0c75c2eddde"}, + {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:82a5c2f4b87c26bb1a0ef3d16b5c4753434633b83d365cc0ddf2770c93829e3c"}, + {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ce8be0466f4c0d585cdb6c1e2ed07232221df101a4c6f28821d2aa754ca2d9e2"}, + {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:409afdfe1e2e90e6ee7fc896f3df9a7fec8e793e58bfa0d052c8a82f99c37abb"}, + {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5b9c3f4ee0b9a439d2415012bd1b1cc2df59e4d6a9939f4d669241d30b414327"}, + {file = "kiwisolver-1.4.7-cp39-cp39-win32.whl", hash = "sha256:a79ae34384df2b615eefca647a2873842ac3b596418032bef9a7283675962644"}, + {file = "kiwisolver-1.4.7-cp39-cp39-win_amd64.whl", hash = "sha256:cf0438b42121a66a3a667de17e779330fc0f20b0d97d59d2f2121e182b0505e4"}, + {file = "kiwisolver-1.4.7-cp39-cp39-win_arm64.whl", hash = "sha256:764202cc7e70f767dab49e8df52c7455e8de0df5d858fa801a11aa0d882ccf3f"}, + {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:94252291e3fe68001b1dd747b4c0b3be12582839b95ad4d1b641924d68fd4643"}, + {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5b7dfa3b546da08a9f622bb6becdb14b3e24aaa30adba66749d38f3cc7ea9706"}, + {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd3de6481f4ed8b734da5df134cd5a6a64fe32124fe83dde1e5b5f29fe30b1e6"}, + {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a91b5f9f1205845d488c928e8570dcb62b893372f63b8b6e98b863ebd2368ff2"}, + {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40fa14dbd66b8b8f470d5fc79c089a66185619d31645f9b0773b88b19f7223c4"}, + {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:eb542fe7933aa09d8d8f9d9097ef37532a7df6497819d16efe4359890a2f417a"}, + {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:bfa1acfa0c54932d5607e19a2c24646fb4c1ae2694437789129cf099789a3b00"}, + {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:eee3ea935c3d227d49b4eb85660ff631556841f6e567f0f7bda972df6c2c9935"}, + {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f3160309af4396e0ed04db259c3ccbfdc3621b5559b5453075e5de555e1f3a1b"}, + {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a17f6a29cf8935e587cc8a4dbfc8368c55edc645283db0ce9801016f83526c2d"}, + {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:10849fb2c1ecbfae45a693c070e0320a91b35dd4bcf58172c023b994283a124d"}, + {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:ac542bf38a8a4be2dc6b15248d36315ccc65f0743f7b1a76688ffb6b5129a5c2"}, + {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:8b01aac285f91ca889c800042c35ad3b239e704b150cfd3382adfc9dcc780e39"}, + {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:48be928f59a1f5c8207154f935334d374e79f2b5d212826307d072595ad76a2e"}, + {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f37cfe618a117e50d8c240555331160d73d0411422b59b5ee217843d7b693608"}, + {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:599b5c873c63a1f6ed7eead644a8a380cfbdf5db91dcb6f85707aaab213b1674"}, + {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:801fa7802e5cfabe3ab0c81a34c323a319b097dfb5004be950482d882f3d7225"}, + {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:0c6c43471bc764fad4bc99c5c2d6d16a676b1abf844ca7c8702bdae92df01ee0"}, + {file = "kiwisolver-1.4.7.tar.gz", hash = "sha256:9893ff81bd7107f7b685d3017cc6583daadb4fc26e4a888350df530e41980a60"}, +] + +[[package]] +name = "kiwisolver" +version = "1.5.0" +description = "A fast implementation of the Cassowary constraint solver" +optional = false +python-versions = ">=3.10" +groups = ["main", "dev"] +markers = "python_version >= \"3.10\"" +files = [ + {file = "kiwisolver-1.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:32cc0a5365239a6ea0c6ed461e8838d053b57e397443c0ca894dcc8e388d4374"}, + {file = "kiwisolver-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cc0b66c1eec9021353a4b4483afb12dfd50e3669ffbb9152d6842eb34c7e29fd"}, + {file = "kiwisolver-1.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:86e0287879f75621ae85197b0877ed2f8b7aa57b511c7331dce2eb6f4de7d476"}, + {file = "kiwisolver-1.5.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:62f59da443c4f4849f73a51a193b1d9d258dcad0c41bc4d1b8fb2bcc04bfeb22"}, + {file = "kiwisolver-1.5.0-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9190426b7aa26c5229501fa297b8d0653cfd3f5a36f7990c264e157cbf886b3b"}, + {file = "kiwisolver-1.5.0-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c8277104ded0a51e699c8c3aff63ce2c56d4ed5519a5f73e0fd7057f959a2b9e"}, + {file = "kiwisolver-1.5.0-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8f9baf6f0a6e7571c45c8863010b45e837c3ee1c2c77fcd6ef423be91b21fedb"}, + {file = "kiwisolver-1.5.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cff8e5383db4989311f99e814feeb90c4723eb4edca425b9d5d9c3fefcdd9537"}, + {file = "kiwisolver-1.5.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ebae99ed6764f2b5771c522477b311be313e8841d2e0376db2b10922daebbba4"}, + {file = "kiwisolver-1.5.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:d5cd5189fc2b6a538b75ae45433140c4823463918f7b1617c31e68b085c0022c"}, + {file = "kiwisolver-1.5.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f42c23db5d1521218a3276bb08666dcb662896a0be7347cba864eca45ff64ede"}, + {file = "kiwisolver-1.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:94eff26096eb5395136634622515b234ecb6c9979824c1f5004c6e3c3c85ccd2"}, + {file = "kiwisolver-1.5.0-cp310-cp310-win_arm64.whl", hash = "sha256:dd952e03bfbb096cfe2dd35cd9e00f269969b67536cb4370994afc20ff2d0875"}, + {file = "kiwisolver-1.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9eed0f7edbb274413b6ee781cca50541c8c0facd3d6fd289779e494340a2b85c"}, + {file = "kiwisolver-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c4923e404d6bcd91b6779c009542e5647fef32e4a5d75e115e3bbac6f2335eb"}, + {file = "kiwisolver-1.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0df54df7e686afa55e6f21fb86195224a6d9beb71d637e8d7920c95cf0f89aac"}, + {file = "kiwisolver-1.5.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2517e24d7315eb51c10664cdb865195df38ab74456c677df67bb47f12d088a27"}, + {file = "kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff710414307fefa903e0d9bdf300972f892c23477829f49504e59834f4195398"}, + {file = "kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6176c1811d9d5a04fa391c490cc44f451e240697a16977f11c6f722efb9041db"}, + {file = "kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:50847dca5d197fcbd389c805aa1a1cf32f25d2e7273dc47ab181a517666b68cc"}, + {file = "kiwisolver-1.5.0-cp311-cp311-manylinux_2_39_riscv64.whl", hash = "sha256:01808c6d15f4c3e8559595d6d1fe6411c68e4a3822b4b9972b44473b24f4e679"}, + {file = "kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f1f9f4121ec58628c96baa3de1a55a4e3a333c5102c8e94b64e23bf7b2083309"}, + {file = "kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b7d335370ae48a780c6e6a6bbfa97342f563744c39c35562f3f367665f5c1de2"}, + {file = "kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:800ee55980c18545af444d93fdd60c56b580db5cc54867d8cbf8a1dc0829938c"}, + {file = "kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c438f6ca858697c9ab67eb28246c92508af972e114cac34e57a6d4ba17a3ac08"}, + {file = "kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8c63c91f95173f9c2a67c7c526b2cea976828a0e7fced9cdcead2802dc10f8a4"}, + {file = "kiwisolver-1.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:beb7f344487cdcb9e1efe4b7a29681b74d34c08f0043a327a74da852a6749e7b"}, + {file = "kiwisolver-1.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:ad4ae4ffd1ee9cd11357b4c66b612da9888f4f4daf2f36995eda64bd45370cac"}, + {file = "kiwisolver-1.5.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:4e9750bc21b886308024f8a54ccb9a2cc38ac9fa813bf4348434e3d54f337ff9"}, + {file = "kiwisolver-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:72ec46b7eba5b395e0a7b63025490d3214c11013f4aacb4f5e8d6c3041829588"}, + {file = "kiwisolver-1.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ed3a984b31da7481b103f68776f7128a89ef26ed40f4dc41a2223cda7fb24819"}, + {file = "kiwisolver-1.5.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bb5136fb5352d3f422df33f0c879a1b0c204004324150cc3b5e3c4f310c9049f"}, + {file = "kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b2af221f268f5af85e776a73d62b0845fc8baf8ef0abfae79d29c77d0e776aaf"}, + {file = "kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b0f172dc8ffaccb8522d7c5d899de00133f2f1ca7b0a49b7da98e901de87bf2d"}, + {file = "kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6ab8ba9152203feec73758dad83af9a0bbe05001eb4639e547207c40cfb52083"}, + {file = "kiwisolver-1.5.0-cp312-cp312-manylinux_2_39_riscv64.whl", hash = "sha256:cdee07c4d7f6d72008d3f73b9bf027f4e11550224c7c50d8df1ae4a37c1402a6"}, + {file = "kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7c60d3c9b06fb23bd9c6139281ccbdc384297579ae037f08ae90c69f6845c0b1"}, + {file = "kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e315e5ec90d88e140f57696ff85b484ff68bb311e36f2c414aa4286293e6dee0"}, + {file = "kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:1465387ac63576c3e125e5337a6892b9e99e0627d52317f3ca79e6930d889d15"}, + {file = "kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:530a3fd64c87cffa844d4b6b9768774763d9caa299e9b75d8eca6a4423b31314"}, + {file = "kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1d9daea4ea6b9be74fe2f01f7fbade8d6ffab263e781274cffca0dba9be9eec9"}, + {file = "kiwisolver-1.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:f18c2d9782259a6dc132fdc7a63c168cbc74b35284b6d75c673958982a378384"}, + {file = "kiwisolver-1.5.0-cp312-cp312-win_arm64.whl", hash = "sha256:f7c7553b13f69c1b29a5bde08ddc6d9d0c8bfb84f9ed01c30db25944aeb852a7"}, + {file = "kiwisolver-1.5.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:fd40bb9cd0891c4c3cb1ddf83f8bbfa15731a248fdc8162669405451e2724b09"}, + {file = "kiwisolver-1.5.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c0e1403fd7c26d77c1f03e096dc58a5c726503fa0db0456678b8668f76f521e3"}, + {file = "kiwisolver-1.5.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dda366d548e89a90d88a86c692377d18d8bd64b39c1fb2b92cb31370e2896bbd"}, + {file = "kiwisolver-1.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:332b4f0145c30b5f5ad9374881133e5aa64320428a57c2c2b61e9d891a51c2f3"}, + {file = "kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c50b89ffd3e1a911c69a1dd3de7173c0cd10b130f56222e57898683841e4f96"}, + {file = "kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4db576bb8c3ef9365f8b40fe0f671644de6736ae2c27a2c62d7d8a1b4329f099"}, + {file = "kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0b85aad90cea8ac6797a53b5d5f2e967334fa4d1149f031c4537569972596cb8"}, + {file = "kiwisolver-1.5.0-cp313-cp313-manylinux_2_39_riscv64.whl", hash = "sha256:d36ca54cb4c6c4686f7cbb7b817f66f5911c12ddb519450bbe86707155028f87"}, + {file = "kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:38f4a703656f493b0ad185211ccfca7f0386120f022066b018eb5296d8613e23"}, + {file = "kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3ac2360e93cb41be81121755c6462cff3beaa9967188c866e5fce5cf13170859"}, + {file = "kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c95cab08d1965db3d84a121f1c7ce7479bdd4072c9b3dafd8fecce48a2e6b902"}, + {file = "kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fc20894c3d21194d8041a28b65622d5b86db786da6e3cfe73f0c762951a61167"}, + {file = "kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7a32f72973f0f950c1920475d5c5ea3d971b81b6f0ec53b8d0a956cc965f22e0"}, + {file = "kiwisolver-1.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bf3acf1419fa93064a4c2189ac0b58e3be7872bf6ee6177b0d4c63dc4cea276"}, + {file = "kiwisolver-1.5.0-cp313-cp313-win_arm64.whl", hash = "sha256:fa8eb9ecdb7efb0b226acec134e0d709e87a909fa4971a54c0c4f6e88635484c"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:db485b3847d182b908b483b2ed133c66d88d49cacf98fd278fadafe11b4478d1"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:be12f931839a3bdfe28b584db0e640a65a8bcbc24560ae3fdb025a449b3d754e"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:16b85d37c2cbb3253226d26e64663f755d88a03439a9c47df6246b35defbdfb7"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4432b835675f0ea7414aab3d37d119f7226d24869b7a829caeab49ebda407b0c"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b0feb50971481a2cc44d94e88bdb02cdd497618252ae226b8eb1201b957e368"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:56fa888f10d0f367155e76ce849fa1166fc9730d13bd2d65a2aa13b6f5424489"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:940dda65d5e764406b9fb92761cbf462e4e63f712ab60ed98f70552e496f3bf1"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-manylinux_2_39_riscv64.whl", hash = "sha256:89fc958c702ee9a745e4700378f5d23fddbc46ff89e8fdbf5395c24d5c1452a3"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9027d773c4ff81487181a925945743413f6069634d0b122d0b37684ccf4f1e18"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:5b233ea3e165e43e35dba1d2b8ecc21cf070b45b65ae17dd2747d2713d942021"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:ce9bf03dad3b46408c08649c6fbd6ca28a9fce0eb32fdfffa6775a13103b5310"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:fc4d3f1fb9ca0ae9f97b095963bc6326f1dbfd3779d6679a1e016b9baaa153d3"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f443b4825c50a51ee68585522ab4a1d1257fac65896f282b4c6763337ac9f5d2"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-win_arm64.whl", hash = "sha256:893ff3a711d1b515ba9da14ee090519bad4610ed1962fbe298a434e8c5f8db53"}, + {file = "kiwisolver-1.5.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8df31fe574b8b3993cc61764f40941111b25c2d9fea13d3ce24a49907cd2d615"}, + {file = "kiwisolver-1.5.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:1d49a49ac4cbfb7c1375301cd1ec90169dfeae55ff84710d782260ce77a75a02"}, + {file = "kiwisolver-1.5.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0cbe94b69b819209a62cb27bdfa5dc2a8977d8de2f89dfd97ba4f53ed3af754e"}, + {file = "kiwisolver-1.5.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:80aa065ffd378ff784822a6d7c3212f2d5f5e9c3589614b5c228b311fd3063ac"}, + {file = "kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e7f886f47ab881692f278ae901039a234e4025a68e6dfab514263a0b1c4ae05"}, + {file = "kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5060731cc3ed12ca3a8b57acd4aeca5bbc2f49216dd0bec1650a1acd89486bcd"}, + {file = "kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7a4aa69609f40fce3cbc3f87b2061f042eee32f94b8f11db707b66a26461591a"}, + {file = "kiwisolver-1.5.0-cp314-cp314-manylinux_2_39_riscv64.whl", hash = "sha256:d168fda2dbff7b9b5f38e693182d792a938c31db4dac3a80a4888de603c99554"}, + {file = "kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:413b820229730d358efd838ecbab79902fe97094565fdc80ddb6b0a18c18a581"}, + {file = "kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:5124d1ea754509b09e53738ec185584cc609aae4a3b510aaf4ed6aa047ef9303"}, + {file = "kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e4415a8db000bf49a6dd1c478bf70062eaacff0f462b92b0ba68791a905861f9"}, + {file = "kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d618fd27420381a4f6044faa71f46d8bfd911bd077c555f7138ed88729bfbe79"}, + {file = "kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5092eb5b1172947f57d6ea7d89b2f29650414e4293c47707eb499ec07a0ac796"}, + {file = "kiwisolver-1.5.0-cp314-cp314-win_amd64.whl", hash = "sha256:d76e2d8c75051d58177e762164d2e9ab92886534e3a12e795f103524f221dd8e"}, + {file = "kiwisolver-1.5.0-cp314-cp314-win_arm64.whl", hash = "sha256:fa6248cd194edff41d7ea9425ced8ca3a6f838bfb295f6f1d6e6bb694a8518df"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:d1ffeb80b5676463d7a7d56acbe8e37a20ce725570e09549fe738e02ca6b7e1e"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:bc4d8e252f532ab46a1de9349e2d27b91fce46736a9eedaa37beaca66f574ed4"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6783e069732715ad0c3ce96dbf21dbc2235ab0593f2baf6338101f70371f4028"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e7c4c09a490dc4d4a7f8cbee56c606a320f9dc28cf92a7157a39d1ce7676a657"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2a075bd7bd19c70cf67c8badfa36cf7c5d8de3c9ddb8420c51e10d9c50e94920"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bdd3e53429ff02aa319ba59dfe4ceeec345bf46cf180ec2cf6fd5b942e7975e9"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cdcb35dc9d807259c981a85531048ede628eabcffb3239adf3d17463518992d"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-manylinux_2_39_riscv64.whl", hash = "sha256:70d593af6a6ca332d1df73d519fddb5148edb15cd90d5f0155e3746a6d4fcc65"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:377815a8616074cabbf3f53354e1d040c35815a134e01d7614b7692e4bf8acfa"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0255a027391d52944eae1dbb5d4cc5903f57092f3674e8e544cdd2622826b3f0"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:012b1eb16e28718fa782b5e61dc6f2da1f0792ca73bd05d54de6cb9561665fc9"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0e3aafb33aed7479377e5e9a82e9d4bf87063741fc99fc7ae48b0f16e32bdd6f"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e7a116ae737f0000343218c4edf5bd45893bfeaff0993c0b215d7124c9f77646"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:1dd9b0b119a350976a6d781e7278ec7aca0b201e1a9e2d23d9804afecb6ca681"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-win_arm64.whl", hash = "sha256:58f812017cd2985c21fbffb4864d59174d4903dd66fa23815e74bbc7a0e2dd57"}, + {file = "kiwisolver-1.5.0-graalpy312-graalpy250_312_native-macosx_10_13_x86_64.whl", hash = "sha256:5ae8e62c147495b01a0f4765c878e9bfdf843412446a247e28df59936e99e797"}, + {file = "kiwisolver-1.5.0-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:f6764a4ccab3078db14a632420930f6186058750df066b8ea2a7106df91d3203"}, + {file = "kiwisolver-1.5.0-graalpy312-graalpy250_312_native-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c31c13da98624f957b0fb1b5bae5383b2333c2c3f6793d9825dd5ce79b525cb7"}, + {file = "kiwisolver-1.5.0-graalpy312-graalpy250_312_native-win_amd64.whl", hash = "sha256:1f1489f769582498610e015a8ef2d36f28f505ab3096d0e16b4858a9ec214f57"}, + {file = "kiwisolver-1.5.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:295d9ffe712caa9f8a3081de8d32fc60191b4b51c76f02f951fd8407253528f4"}, + {file = "kiwisolver-1.5.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:51e8c4084897de9f05898c2c2a39af6318044ae969d46ff7a34ed3f96274adca"}, + {file = "kiwisolver-1.5.0-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b83af57bdddef03c01a9138034c6ff03181a3028d9a1003b301eb1a55e161a3f"}, + {file = "kiwisolver-1.5.0-pp310-pypy310_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf4679a3d71012a7c2bf360e5cd878fbd5e4fcac0896b56393dec239d81529ed"}, + {file = "kiwisolver-1.5.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:41024ed50e44ab1a60d3fe0a9d15a4ccc9f5f2b1d814ff283c8d01134d5b81bc"}, + {file = "kiwisolver-1.5.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ec4c85dc4b687c7f7f15f553ff26a98bfe8c58f5f7f0ac8905f0ba4c7be60232"}, + {file = "kiwisolver-1.5.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:12e91c215a96e39f57989c8912ae761286ac5a9584d04030ceb3368a357f017a"}, + {file = "kiwisolver-1.5.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:be4a51a55833dc29ab5d7503e7bcb3b3af3402d266018137127450005cdfe737"}, + {file = "kiwisolver-1.5.0-pp311-pypy311_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:daae526907e262de627d8f70058a0f64acc9e2641c164c99c8f594b34a799a16"}, + {file = "kiwisolver-1.5.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:59cd8683f575d96df5bb48f6add94afc055012c29e28124fcae2b63661b9efb1"}, + {file = "kiwisolver-1.5.0.tar.gz", hash = "sha256:d4193f3d9dc3f6f79aaed0e5637f45d98850ebf01f7ca20e69457f3e8946b66a"}, +] + +[[package]] +name = "markdown" +version = "3.7" +description = "Python implementation of John Gruber's Markdown." +optional = false +python-versions = ">=3.8" +groups = ["docs"] +files = [ + {file = "Markdown-3.7-py3-none-any.whl", hash = "sha256:7eb6df5690b81a1d7942992c97fad2938e956e79df20cbc6186e9c3a77b1c803"}, + {file = "markdown-3.7.tar.gz", hash = "sha256:2ae2471477cfd02dbbf038d5d9bc226d40def84b4fe2986e49b59b6b472bbed2"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} + +[package.extras] +docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.5)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"] +testing = ["coverage", "pyyaml"] + +[[package]] +name = "markupsafe" +version = "2.1.5" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.7" +groups = ["docs"] +files = [ + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, + {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, +] + +[[package]] +name = "matplotlib" +version = "3.7.5" +description = "Python plotting package" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +files = [ + {file = "matplotlib-3.7.5-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:4a87b69cb1cb20943010f63feb0b2901c17a3b435f75349fd9865713bfa63925"}, + {file = "matplotlib-3.7.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:d3ce45010fefb028359accebb852ca0c21bd77ec0f281952831d235228f15810"}, + {file = "matplotlib-3.7.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fbea1e762b28400393d71be1a02144aa16692a3c4c676ba0178ce83fc2928fdd"}, + {file = "matplotlib-3.7.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec0e1adc0ad70ba8227e957551e25a9d2995e319c29f94a97575bb90fa1d4469"}, + {file = "matplotlib-3.7.5-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6738c89a635ced486c8a20e20111d33f6398a9cbebce1ced59c211e12cd61455"}, + {file = "matplotlib-3.7.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1210b7919b4ed94b5573870f316bca26de3e3b07ffdb563e79327dc0e6bba515"}, + {file = "matplotlib-3.7.5-cp310-cp310-win32.whl", hash = "sha256:068ebcc59c072781d9dcdb82f0d3f1458271c2de7ca9c78f5bd672141091e9e1"}, + {file = "matplotlib-3.7.5-cp310-cp310-win_amd64.whl", hash = "sha256:f098ffbaab9df1e3ef04e5a5586a1e6b1791380698e84938d8640961c79b1fc0"}, + {file = "matplotlib-3.7.5-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:f65342c147572673f02a4abec2d5a23ad9c3898167df9b47c149f32ce61ca078"}, + {file = "matplotlib-3.7.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4ddf7fc0e0dc553891a117aa083039088d8a07686d4c93fb8a810adca68810af"}, + {file = "matplotlib-3.7.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0ccb830fc29442360d91be48527809f23a5dcaee8da5f4d9b2d5b867c1b087b8"}, + {file = "matplotlib-3.7.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efc6bb28178e844d1f408dd4d6341ee8a2e906fc9e0fa3dae497da4e0cab775d"}, + {file = "matplotlib-3.7.5-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b15c4c2d374f249f324f46e883340d494c01768dd5287f8bc00b65b625ab56c"}, + {file = "matplotlib-3.7.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d028555421912307845e59e3de328260b26d055c5dac9b182cc9783854e98fb"}, + {file = "matplotlib-3.7.5-cp311-cp311-win32.whl", hash = "sha256:fe184b4625b4052fa88ef350b815559dd90cc6cc8e97b62f966e1ca84074aafa"}, + {file = "matplotlib-3.7.5-cp311-cp311-win_amd64.whl", hash = "sha256:084f1f0f2f1010868c6f1f50b4e1c6f2fb201c58475494f1e5b66fed66093647"}, + {file = "matplotlib-3.7.5-cp312-cp312-macosx_10_12_universal2.whl", hash = "sha256:34bceb9d8ddb142055ff27cd7135f539f2f01be2ce0bafbace4117abe58f8fe4"}, + {file = "matplotlib-3.7.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:c5a2134162273eb8cdfd320ae907bf84d171de948e62180fa372a3ca7cf0f433"}, + {file = "matplotlib-3.7.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:039ad54683a814002ff37bf7981aa1faa40b91f4ff84149beb53d1eb64617980"}, + {file = "matplotlib-3.7.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d742ccd1b09e863b4ca58291728db645b51dab343eebb08d5d4b31b308296ce"}, + {file = "matplotlib-3.7.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:743b1c488ca6a2bc7f56079d282e44d236bf375968bfd1b7ba701fd4d0fa32d6"}, + {file = "matplotlib-3.7.5-cp312-cp312-win_amd64.whl", hash = "sha256:fbf730fca3e1f23713bc1fae0a57db386e39dc81ea57dc305c67f628c1d7a342"}, + {file = "matplotlib-3.7.5-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:cfff9b838531698ee40e40ea1a8a9dc2c01edb400b27d38de6ba44c1f9a8e3d2"}, + {file = "matplotlib-3.7.5-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:1dbcca4508bca7847fe2d64a05b237a3dcaec1f959aedb756d5b1c67b770c5ee"}, + {file = "matplotlib-3.7.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4cdf4ef46c2a1609a50411b66940b31778db1e4b73d4ecc2eaa40bd588979b13"}, + {file = "matplotlib-3.7.5-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:167200ccfefd1674b60e957186dfd9baf58b324562ad1a28e5d0a6b3bea77905"}, + {file = "matplotlib-3.7.5-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:53e64522934df6e1818b25fd48cf3b645b11740d78e6ef765fbb5fa5ce080d02"}, + {file = "matplotlib-3.7.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3e3bc79b2d7d615067bd010caff9243ead1fc95cf735c16e4b2583173f717eb"}, + {file = "matplotlib-3.7.5-cp38-cp38-win32.whl", hash = "sha256:6b641b48c6819726ed47c55835cdd330e53747d4efff574109fd79b2d8a13748"}, + {file = "matplotlib-3.7.5-cp38-cp38-win_amd64.whl", hash = "sha256:f0b60993ed3488b4532ec6b697059897891927cbfc2b8d458a891b60ec03d9d7"}, + {file = "matplotlib-3.7.5-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:090964d0afaff9c90e4d8de7836757e72ecfb252fb02884016d809239f715651"}, + {file = "matplotlib-3.7.5-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:9fc6fcfbc55cd719bc0bfa60bde248eb68cf43876d4c22864603bdd23962ba25"}, + {file = "matplotlib-3.7.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7cc3078b019bb863752b8b60e8b269423000f1603cb2299608231996bd9d54"}, + {file = "matplotlib-3.7.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e4e9a868e8163abaaa8259842d85f949a919e1ead17644fb77a60427c90473c"}, + {file = "matplotlib-3.7.5-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fa7ebc995a7d747dacf0a717d0eb3aa0f0c6a0e9ea88b0194d3a3cd241a1500f"}, + {file = "matplotlib-3.7.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3785bfd83b05fc0e0c2ae4c4a90034fe693ef96c679634756c50fe6efcc09856"}, + {file = "matplotlib-3.7.5-cp39-cp39-win32.whl", hash = "sha256:29b058738c104d0ca8806395f1c9089dfe4d4f0f78ea765c6c704469f3fffc81"}, + {file = "matplotlib-3.7.5-cp39-cp39-win_amd64.whl", hash = "sha256:fd4028d570fa4b31b7b165d4a685942ae9cdc669f33741e388c01857d9723eab"}, + {file = "matplotlib-3.7.5-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2a9a3f4d6a7f88a62a6a18c7e6a84aedcaf4faf0708b4ca46d87b19f1b526f88"}, + {file = "matplotlib-3.7.5-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b9b3fd853d4a7f008a938df909b96db0b454225f935d3917520305b90680579c"}, + {file = "matplotlib-3.7.5-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0ad550da9f160737d7890217c5eeed4337d07e83ca1b2ca6535078f354e7675"}, + {file = "matplotlib-3.7.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:20da7924a08306a861b3f2d1da0d1aa9a6678e480cf8eacffe18b565af2813e7"}, + {file = "matplotlib-3.7.5-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b45c9798ea6bb920cb77eb7306409756a7fab9db9b463e462618e0559aecb30e"}, + {file = "matplotlib-3.7.5-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a99866267da1e561c7776fe12bf4442174b79aac1a47bd7e627c7e4d077ebd83"}, + {file = "matplotlib-3.7.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b6aa62adb6c268fc87d80f963aca39c64615c31830b02697743c95590ce3fbb"}, + {file = "matplotlib-3.7.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:e530ab6a0afd082d2e9c17eb1eb064a63c5b09bb607b2b74fa41adbe3e162286"}, + {file = "matplotlib-3.7.5.tar.gz", hash = "sha256:1e5c971558ebc811aa07f54c7b7c677d78aa518ef4c390e14673a09e0860184a"}, +] +markers = {main = "python_version < \"3.10\" and extra == \"all\"", dev = "python_version < \"3.10\""} + +[package.dependencies] +contourpy = ">=1.0.1" +cycler = ">=0.10" +fonttools = ">=4.22.0" +importlib-resources = {version = ">=3.2.0", markers = "python_version < \"3.10\""} +kiwisolver = ">=1.0.1" +numpy = ">=1.20,<2" +packaging = ">=20.0" +pillow = ">=6.2.0" +pyparsing = ">=2.3.1" +python-dateutil = ">=2.7" + +[[package]] +name = "matplotlib" +version = "3.10.8" +description = "Python plotting package" +optional = false +python-versions = ">=3.10" +groups = ["main", "dev"] +files = [ + {file = "matplotlib-3.10.8-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:00270d217d6b20d14b584c521f810d60c5c78406dc289859776550df837dcda7"}, + {file = "matplotlib-3.10.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:37b3c1cc42aa184b3f738cfa18c1c1d72fd496d85467a6cf7b807936d39aa656"}, + {file = "matplotlib-3.10.8-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ee40c27c795bda6a5292e9cff9890189d32f7e3a0bf04e0e3c9430c4a00c37df"}, + {file = "matplotlib-3.10.8-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a48f2b74020919552ea25d222d5cc6af9ca3f4eb43a93e14d068457f545c2a17"}, + {file = "matplotlib-3.10.8-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f254d118d14a7f99d616271d6c3c27922c092dac11112670b157798b89bf4933"}, + {file = "matplotlib-3.10.8-cp310-cp310-win_amd64.whl", hash = "sha256:f9b587c9c7274c1613a30afabf65a272114cd6cdbe67b3406f818c79d7ab2e2a"}, + {file = "matplotlib-3.10.8-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6be43b667360fef5c754dda5d25a32e6307a03c204f3c0fc5468b78fa87b4160"}, + {file = "matplotlib-3.10.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2b336e2d91a3d7006864e0990c83b216fcdca64b5a6484912902cef87313d78"}, + {file = "matplotlib-3.10.8-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:efb30e3baaea72ce5928e32bab719ab4770099079d66726a62b11b1ef7273be4"}, + {file = "matplotlib-3.10.8-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d56a1efd5bfd61486c8bc968fa18734464556f0fb8e51690f4ac25d85cbbbbc2"}, + {file = "matplotlib-3.10.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:238b7ce5717600615c895050239ec955d91f321c209dd110db988500558e70d6"}, + {file = "matplotlib-3.10.8-cp311-cp311-win_amd64.whl", hash = "sha256:18821ace09c763ec93aef5eeff087ee493a24051936d7b9ebcad9662f66501f9"}, + {file = "matplotlib-3.10.8-cp311-cp311-win_arm64.whl", hash = "sha256:bab485bcf8b1c7d2060b4fcb6fc368a9e6f4cd754c9c2fea281f4be21df394a2"}, + {file = "matplotlib-3.10.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:64fcc24778ca0404ce0cb7b6b77ae1f4c7231cdd60e6778f999ee05cbd581b9a"}, + {file = "matplotlib-3.10.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b9a5ca4ac220a0cdd1ba6bcba3608547117d30468fefce49bb26f55c1a3d5c58"}, + {file = "matplotlib-3.10.8-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3ab4aabc72de4ff77b3ec33a6d78a68227bf1123465887f9905ba79184a1cc04"}, + {file = "matplotlib-3.10.8-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:24d50994d8c5816ddc35411e50a86ab05f575e2530c02752e02538122613371f"}, + {file = "matplotlib-3.10.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:99eefd13c0dc3b3c1b4d561c1169e65fe47aab7b8158754d7c084088e2329466"}, + {file = "matplotlib-3.10.8-cp312-cp312-win_amd64.whl", hash = "sha256:dd80ecb295460a5d9d260df63c43f4afbdd832d725a531f008dad1664f458adf"}, + {file = "matplotlib-3.10.8-cp312-cp312-win_arm64.whl", hash = "sha256:3c624e43ed56313651bc18a47f838b60d7b8032ed348911c54906b130b20071b"}, + {file = "matplotlib-3.10.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3f2e409836d7f5ac2f1c013110a4d50b9f7edc26328c108915f9075d7d7a91b6"}, + {file = "matplotlib-3.10.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:56271f3dac49a88d7fca5060f004d9d22b865f743a12a23b1e937a0be4818ee1"}, + {file = "matplotlib-3.10.8-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a0a7f52498f72f13d4a25ea70f35f4cb60642b466cbb0a9be951b5bc3f45a486"}, + {file = "matplotlib-3.10.8-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:646d95230efb9ca614a7a594d4fcacde0ac61d25e37dd51710b36477594963ce"}, + {file = "matplotlib-3.10.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f89c151aab2e2e23cb3fe0acad1e8b82841fd265379c4cecd0f3fcb34c15e0f6"}, + {file = "matplotlib-3.10.8-cp313-cp313-win_amd64.whl", hash = "sha256:e8ea3e2d4066083e264e75c829078f9e149fa119d27e19acd503de65e0b13149"}, + {file = "matplotlib-3.10.8-cp313-cp313-win_arm64.whl", hash = "sha256:c108a1d6fa78a50646029cb6d49808ff0fc1330fda87fa6f6250c6b5369b6645"}, + {file = "matplotlib-3.10.8-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:ad3d9833a64cf48cc4300f2b406c3d0f4f4724a91c0bd5640678a6ba7c102077"}, + {file = "matplotlib-3.10.8-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:eb3823f11823deade26ce3b9f40dcb4a213da7a670013929f31d5f5ed1055b22"}, + {file = "matplotlib-3.10.8-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d9050fee89a89ed57b4fb2c1bfac9a3d0c57a0d55aed95949eedbc42070fea39"}, + {file = "matplotlib-3.10.8-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b44d07310e404ba95f8c25aa5536f154c0a8ec473303535949e52eb71d0a1565"}, + {file = "matplotlib-3.10.8-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:0a33deb84c15ede243aead39f77e990469fff93ad1521163305095b77b72ce4a"}, + {file = "matplotlib-3.10.8-cp313-cp313t-win_amd64.whl", hash = "sha256:3a48a78d2786784cc2413e57397981fb45c79e968d99656706018d6e62e57958"}, + {file = "matplotlib-3.10.8-cp313-cp313t-win_arm64.whl", hash = "sha256:15d30132718972c2c074cd14638c7f4592bd98719e2308bccea40e0538bc0cb5"}, + {file = "matplotlib-3.10.8-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b53285e65d4fa4c86399979e956235deb900be5baa7fc1218ea67fbfaeaadd6f"}, + {file = "matplotlib-3.10.8-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:32f8dce744be5569bebe789e46727946041199030db8aeb2954d26013a0eb26b"}, + {file = "matplotlib-3.10.8-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4cf267add95b1c88300d96ca837833d4112756045364f5c734a2276038dae27d"}, + {file = "matplotlib-3.10.8-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2cf5bd12cecf46908f286d7838b2abc6c91cda506c0445b8223a7c19a00df008"}, + {file = "matplotlib-3.10.8-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:41703cc95688f2516b480f7f339d8851a6035f18e100ee6a32bc0b8536a12a9c"}, + {file = "matplotlib-3.10.8-cp314-cp314-win_amd64.whl", hash = "sha256:83d282364ea9f3e52363da262ce32a09dfe241e4080dcedda3c0db059d3c1f11"}, + {file = "matplotlib-3.10.8-cp314-cp314-win_arm64.whl", hash = "sha256:2c1998e92cd5999e295a731bcb2911c75f597d937341f3030cc24ef2733d78a8"}, + {file = "matplotlib-3.10.8-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:b5a2b97dbdc7d4f353ebf343744f1d1f1cca8aa8bfddb4262fcf4306c3761d50"}, + {file = "matplotlib-3.10.8-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3f5c3e4da343bba819f0234186b9004faba952cc420fbc522dc4e103c1985908"}, + {file = "matplotlib-3.10.8-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f62550b9a30afde8c1c3ae450e5eb547d579dd69b25c2fc7a1c67f934c1717a"}, + {file = "matplotlib-3.10.8-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:495672de149445ec1b772ff2c9ede9b769e3cb4f0d0aa7fa730d7f59e2d4e1c1"}, + {file = "matplotlib-3.10.8-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:595ba4d8fe983b88f0eec8c26a241e16d6376fe1979086232f481f8f3f67494c"}, + {file = "matplotlib-3.10.8-cp314-cp314t-win_amd64.whl", hash = "sha256:25d380fe8b1dc32cf8f0b1b448470a77afb195438bafdf1d858bfb876f3edf7b"}, + {file = "matplotlib-3.10.8-cp314-cp314t-win_arm64.whl", hash = "sha256:113bb52413ea508ce954a02c10ffd0d565f9c3bc7f2eddc27dfe1731e71c7b5f"}, + {file = "matplotlib-3.10.8-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f97aeb209c3d2511443f8797e3e5a569aebb040d4f8bc79aa3ee78a8fb9e3dd8"}, + {file = "matplotlib-3.10.8-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fb061f596dad3a0f52b60dc6a5dec4a0c300dec41e058a7efe09256188d170b7"}, + {file = "matplotlib-3.10.8-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:12d90df9183093fcd479f4172ac26b322b1248b15729cb57f42f71f24c7e37a3"}, + {file = "matplotlib-3.10.8-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:6da7c2ce169267d0d066adcf63758f0604aa6c3eebf67458930f9d9b79ad1db1"}, + {file = "matplotlib-3.10.8-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9153c3292705be9f9c64498a8872118540c3f4123d1a1c840172edf262c8be4a"}, + {file = "matplotlib-3.10.8-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1ae029229a57cd1e8fe542485f27e7ca7b23aa9e8944ddb4985d0bc444f1eca2"}, + {file = "matplotlib-3.10.8.tar.gz", hash = "sha256:2299372c19d56bcd35cf05a2738308758d32b9eaed2371898d8f5bd33f084aa3"}, +] +markers = {main = "python_version >= \"3.10\" and extra == \"all\"", dev = "python_version >= \"3.10\""} + +[package.dependencies] +contourpy = ">=1.0.1" +cycler = ">=0.10" +fonttools = ">=4.22.0" +kiwisolver = ">=1.3.1" +numpy = ">=1.23" +packaging = ">=20.0" +pillow = ">=8" +pyparsing = ">=3" +python-dateutil = ">=2.7" + +[package.extras] +dev = ["meson-python (>=0.13.1,<0.17.0)", "pybind11 (>=2.13.2,!=2.13.3)", "setuptools (>=64)", "setuptools_scm (>=7)"] + +[[package]] +name = "matplotlib-inline" +version = "0.1.7" +description = "Inline Matplotlib backend for Jupyter" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca"}, + {file = "matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90"}, +] + +[package.dependencies] +traitlets = "*" + +[[package]] +name = "mergedeep" +version = "1.3.4" +description = "A deep merge function for 🐍." +optional = false +python-versions = ">=3.6" +groups = ["docs"] +files = [ + {file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"}, + {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, +] + +[[package]] +name = "mkdocs" +version = "1.6.0" +description = "Project documentation with Markdown." +optional = false +python-versions = ">=3.8" +groups = ["docs"] +files = [ + {file = "mkdocs-1.6.0-py3-none-any.whl", hash = "sha256:1eb5cb7676b7d89323e62b56235010216319217d4af5ddc543a91beb8d125ea7"}, + {file = "mkdocs-1.6.0.tar.gz", hash = "sha256:a73f735824ef83a4f3bcb7a231dcab23f5a838f88b7efc54a0eef5fbdbc3c512"}, +] + +[package.dependencies] +click = ">=7.0" +colorama = {version = ">=0.4", markers = "platform_system == \"Windows\""} +ghp-import = ">=1.0" +importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} +jinja2 = ">=2.11.1" +markdown = ">=3.3.6" +markupsafe = ">=2.0.1" +mergedeep = ">=1.3.4" +mkdocs-get-deps = ">=0.2.0" +packaging = ">=20.5" +pathspec = ">=0.11.1" +pyyaml = ">=5.1" +pyyaml-env-tag = ">=0.1" +watchdog = ">=2.0" + +[package.extras] +i18n = ["babel (>=2.9.0)"] +min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4) ; platform_system == \"Windows\"", "ghp-import (==1.0)", "importlib-metadata (==4.4) ; python_version < \"3.10\"", "jinja2 (==2.11.1)", "markdown (==3.3.6)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "mkdocs-get-deps (==0.2.0)", "packaging (==20.5)", "pathspec (==0.11.1)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "watchdog (==2.0)"] + +[[package]] +name = "mkdocs-autorefs" +version = "1.2.0" +description = "Automatically link across pages in MkDocs." +optional = false +python-versions = ">=3.8" +groups = ["docs"] +files = [ + {file = "mkdocs_autorefs-1.2.0-py3-none-any.whl", hash = "sha256:d588754ae89bd0ced0c70c06f58566a4ee43471eeeee5202427da7de9ef85a2f"}, + {file = "mkdocs_autorefs-1.2.0.tar.gz", hash = "sha256:a86b93abff653521bda71cf3fc5596342b7a23982093915cb74273f67522190f"}, +] + +[package.dependencies] +Markdown = ">=3.3" +markupsafe = ">=2.0.1" +mkdocs = ">=1.1" + +[[package]] +name = "mkdocs-get-deps" +version = "0.2.0" +description = "MkDocs extension that lists all dependencies according to a mkdocs.yml file" +optional = false +python-versions = ">=3.8" +groups = ["docs"] +markers = "python_version < \"3.10\"" +files = [ + {file = "mkdocs_get_deps-0.2.0-py3-none-any.whl", hash = "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134"}, + {file = "mkdocs_get_deps-0.2.0.tar.gz", hash = "sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=4.3", markers = "python_version < \"3.10\""} +mergedeep = ">=1.3.4" +platformdirs = ">=2.2.0" +pyyaml = ">=5.1" + +[[package]] +name = "mkdocs-get-deps" +version = "0.2.2" +description = "An extra command for MkDocs that infers required PyPI packages from `plugins` in mkdocs.yml" +optional = false +python-versions = ">=3.9" +groups = ["docs"] +markers = "python_version >= \"3.10\"" +files = [ + {file = "mkdocs_get_deps-0.2.2-py3-none-any.whl", hash = "sha256:e7878cbeac04860b8b5e0ca31d3abad3df9411a75a32cde82f8e44b6c16ff650"}, + {file = "mkdocs_get_deps-0.2.2.tar.gz", hash = "sha256:8ee8d5f316cdbbb2834bc1df6e69c08fe769a83e040060de26d3c19fad3599a1"}, +] + +[package.dependencies] +mergedeep = ">=1.3.4" +platformdirs = ">=2.2.0" +pyyaml = ">=5.1" + +[[package]] +name = "mkdocs-include-markdown-plugin" +version = "6.2.2" +description = "Mkdocs Markdown includer plugin." +optional = false +python-versions = ">=3.8" +groups = ["docs"] +files = [ + {file = "mkdocs_include_markdown_plugin-6.2.2-py3-none-any.whl", hash = "sha256:d293950f6499d2944291ca7b9bc4a60e652bbfd3e3a42b564f6cceee268694e7"}, + {file = "mkdocs_include_markdown_plugin-6.2.2.tar.gz", hash = "sha256:f2bd5026650492a581d2fd44be6c22f90391910d76582b96a34c264f2d17875d"}, +] + +[package.dependencies] +mkdocs = ">=1.4" +wcmatch = "*" + +[package.extras] +cache = ["platformdirs"] + +[[package]] +name = "mkdocs-material" +version = "9.7.6" +description = "Documentation that simply works" +optional = false +python-versions = ">=3.8" +groups = ["docs"] +files = [ + {file = "mkdocs_material-9.7.6-py3-none-any.whl", hash = "sha256:71b84353921b8ea1ba84fe11c50912cc512da8fe0881038fcc9a0761c0e635ba"}, + {file = "mkdocs_material-9.7.6.tar.gz", hash = "sha256:00bdde50574f776d328b1862fe65daeaf581ec309bd150f7bff345a098c64a69"}, +] + +[package.dependencies] +babel = ">=2.10" +backrefs = ">=5.7.post1" +colorama = ">=0.4" +jinja2 = ">=3.1" +markdown = ">=3.2" +mkdocs = ">=1.6,<2" +mkdocs-material-extensions = ">=1.3" +paginate = ">=0.5" +pygments = ">=2.16" +pymdown-extensions = ">=10.2" +requests = ">=2.30" + +[package.extras] +git = ["mkdocs-git-committers-plugin-2 (>=1.1)", "mkdocs-git-revision-date-localized-plugin (>=1.2.4)"] +imaging = ["cairosvg (>=2.6)", "pillow (>=10.2)"] +recommended = ["mkdocs-minify-plugin (>=0.7)", "mkdocs-redirects (>=1.2)", "mkdocs-rss-plugin (>=1.6)"] + +[[package]] +name = "mkdocs-material-extensions" +version = "1.3.1" +description = "Extension pack for Python Markdown and MkDocs Material." +optional = false +python-versions = ">=3.8" +groups = ["docs"] +files = [ + {file = "mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31"}, + {file = "mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443"}, +] + +[[package]] +name = "mkdocstrings" +version = "0.24.0" +description = "Automatic documentation from sources, for MkDocs." +optional = false +python-versions = ">=3.8" +groups = ["docs"] +files = [ + {file = "mkdocstrings-0.24.0-py3-none-any.whl", hash = "sha256:f4908560c10f587326d8f5165d1908817b2e280bbf707607f601c996366a2264"}, + {file = "mkdocstrings-0.24.0.tar.gz", hash = "sha256:222b1165be41257b494a9d29b14135d2b7ca43f38161d5b10caae03b87bd4f7e"}, +] + +[package.dependencies] +click = ">=7.0" +importlib-metadata = {version = ">=4.6", markers = "python_version < \"3.10\""} +Jinja2 = ">=2.11.1" +Markdown = ">=3.3" +MarkupSafe = ">=1.1" +mkdocs = ">=1.4" +mkdocs-autorefs = ">=0.3.1" +mkdocstrings-python = {version = ">=0.5.2", optional = true, markers = "extra == \"python\""} +platformdirs = ">=2.2.0" +pymdown-extensions = ">=6.3" +typing-extensions = {version = ">=4.1", markers = "python_version < \"3.10\""} + +[package.extras] +crystal = ["mkdocstrings-crystal (>=0.3.4)"] +python = ["mkdocstrings-python (>=0.5.2)"] +python-legacy = ["mkdocstrings-python-legacy (>=0.2.1)"] + +[[package]] +name = "mkdocstrings-python" +version = "1.8.0" +description = "A Python handler for mkdocstrings." +optional = false +python-versions = ">=3.8" +groups = ["docs"] +files = [ + {file = "mkdocstrings_python-1.8.0-py3-none-any.whl", hash = "sha256:4209970cc90bec194568682a535848a8d8489516c6ed4adbe58bbc67b699ca9d"}, + {file = "mkdocstrings_python-1.8.0.tar.gz", hash = "sha256:1488bddf50ee42c07d9a488dddc197f8e8999c2899687043ec5dd1643d057192"}, +] + +[package.dependencies] +griffe = ">=0.37" +mkdocstrings = ">=0.20" + +[[package]] +name = "mplfinance" +version = "0.12.10b0" +description = "Utilities for the visualization, and visual analysis, of financial data" +optional = false +python-versions = "*" +groups = ["main", "dev"] +files = [ + {file = "mplfinance-0.12.10b0-py3-none-any.whl", hash = "sha256:76d3b095f05ff35de730751649de063bea4064d0c49b21b6182c82997a7f52bb"}, + {file = "mplfinance-0.12.10b0.tar.gz", hash = "sha256:7da150b5851aa5119ad6e06b55e48338b619bb6773f1b85df5de67a5ffd917bf"}, +] +markers = {main = "extra == \"all\""} + +[package.dependencies] +matplotlib = "*" +pandas = "*" + +[[package]] +name = "mypy" +version = "1.14.1" +description = "Optional static typing for Python" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "mypy-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:52686e37cf13d559f668aa398dd7ddf1f92c5d613e4f8cb262be2fb4fedb0fcb"}, + {file = "mypy-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1fb545ca340537d4b45d3eecdb3def05e913299ca72c290326be19b3804b39c0"}, + {file = "mypy-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90716d8b2d1f4cd503309788e51366f07c56635a3309b0f6a32547eaaa36a64d"}, + {file = "mypy-1.14.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ae753f5c9fef278bcf12e1a564351764f2a6da579d4a81347e1d5a15819997b"}, + {file = "mypy-1.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e0fe0f5feaafcb04505bcf439e991c6d8f1bf8b15f12b05feeed96e9e7bf1427"}, + {file = "mypy-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:7d54bd85b925e501c555a3227f3ec0cfc54ee8b6930bd6141ec872d1c572f81f"}, + {file = "mypy-1.14.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f995e511de847791c3b11ed90084a7a0aafdc074ab88c5a9711622fe4751138c"}, + {file = "mypy-1.14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d64169ec3b8461311f8ce2fd2eb5d33e2d0f2c7b49116259c51d0d96edee48d1"}, + {file = "mypy-1.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba24549de7b89b6381b91fbc068d798192b1b5201987070319889e93038967a8"}, + {file = "mypy-1.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:183cf0a45457d28ff9d758730cd0210419ac27d4d3f285beda038c9083363b1f"}, + {file = "mypy-1.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f2a0ecc86378f45347f586e4163d1769dd81c5a223d577fe351f26b179e148b1"}, + {file = "mypy-1.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:ad3301ebebec9e8ee7135d8e3109ca76c23752bac1e717bc84cd3836b4bf3eae"}, + {file = "mypy-1.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:30ff5ef8519bbc2e18b3b54521ec319513a26f1bba19a7582e7b1f58a6e69f14"}, + {file = "mypy-1.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cb9f255c18052343c70234907e2e532bc7e55a62565d64536dbc7706a20b78b9"}, + {file = "mypy-1.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b4e3413e0bddea671012b063e27591b953d653209e7a4fa5e48759cda77ca11"}, + {file = "mypy-1.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:553c293b1fbdebb6c3c4030589dab9fafb6dfa768995a453d8a5d3b23784af2e"}, + {file = "mypy-1.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fad79bfe3b65fe6a1efaed97b445c3d37f7be9fdc348bdb2d7cac75579607c89"}, + {file = "mypy-1.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:8fa2220e54d2946e94ab6dbb3ba0a992795bd68b16dc852db33028df2b00191b"}, + {file = "mypy-1.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:92c3ed5afb06c3a8e188cb5da4984cab9ec9a77ba956ee419c68a388b4595255"}, + {file = "mypy-1.14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dbec574648b3e25f43d23577309b16534431db4ddc09fda50841f1e34e64ed34"}, + {file = "mypy-1.14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8c6d94b16d62eb3e947281aa7347d78236688e21081f11de976376cf010eb31a"}, + {file = "mypy-1.14.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d4b19b03fdf54f3c5b2fa474c56b4c13c9dbfb9a2db4370ede7ec11a2c5927d9"}, + {file = "mypy-1.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0c911fde686394753fff899c409fd4e16e9b294c24bfd5e1ea4675deae1ac6fd"}, + {file = "mypy-1.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:8b21525cb51671219f5307be85f7e646a153e5acc656e5cebf64bfa076c50107"}, + {file = "mypy-1.14.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7084fb8f1128c76cd9cf68fe5971b37072598e7c31b2f9f95586b65c741a9d31"}, + {file = "mypy-1.14.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8f845a00b4f420f693f870eaee5f3e2692fa84cc8514496114649cfa8fd5e2c6"}, + {file = "mypy-1.14.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44bf464499f0e3a2d14d58b54674dee25c031703b2ffc35064bd0df2e0fac319"}, + {file = "mypy-1.14.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c99f27732c0b7dc847adb21c9d47ce57eb48fa33a17bc6d7d5c5e9f9e7ae5bac"}, + {file = "mypy-1.14.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:bce23c7377b43602baa0bd22ea3265c49b9ff0b76eb315d6c34721af4cdf1d9b"}, + {file = "mypy-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:8edc07eeade7ebc771ff9cf6b211b9a7d93687ff892150cb5692e4f4272b0837"}, + {file = "mypy-1.14.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3888a1816d69f7ab92092f785a462944b3ca16d7c470d564165fe703b0970c35"}, + {file = "mypy-1.14.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:46c756a444117c43ee984bd055db99e498bc613a70bbbc120272bd13ca579fbc"}, + {file = "mypy-1.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:27fc248022907e72abfd8e22ab1f10e903915ff69961174784a3900a8cba9ad9"}, + {file = "mypy-1.14.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:499d6a72fb7e5de92218db961f1a66d5f11783f9ae549d214617edab5d4dbdbb"}, + {file = "mypy-1.14.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:57961db9795eb566dc1d1b4e9139ebc4c6b0cb6e7254ecde69d1552bf7613f60"}, + {file = "mypy-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:07ba89fdcc9451f2ebb02853deb6aaaa3d2239a236669a63ab3801bbf923ef5c"}, + {file = "mypy-1.14.1-py3-none-any.whl", hash = "sha256:b66a60cc4073aeb8ae00057f9c1f64d49e90f918fbcef9a977eb121da8b8f1d1"}, + {file = "mypy-1.14.1.tar.gz", hash = "sha256:7ec88144fe9b510e8475ec2f5f251992690fcf89ccb4500b214b4226abcd32d6"}, +] + +[package.dependencies] +mypy_extensions = ">=1.0.0" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing_extensions = ">=4.6.0" + +[package.extras] +dmypy = ["psutil (>=4.0)"] +faster-cache = ["orjson"] +install-types = ["pip"] +mypyc = ["setuptools (>=50)"] +reports = ["lxml"] + +[[package]] +name = "mypy-extensions" +version = "1.1.0" +description = "Type system extensions for programs checked with the mypy type checker." +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505"}, + {file = "mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558"}, +] + +[[package]] +name = "mypy-protobuf" +version = "3.7.0" +description = "Generate mypy stub files from protobuf specs" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "mypy_protobuf-3.7.0-py3-none-any.whl", hash = "sha256:85256e9d4da935722ce8fbaa8d19397e1a2989aa8075c96577987de9fe7cea4d"}, + {file = "mypy_protobuf-3.7.0.tar.gz", hash = "sha256:912fb281f7c7b3e3a7c9b8695712618a716fddbab70f6ad63eaf68eda80c5efe"}, +] + +[package.dependencies] +protobuf = ">=4.25.3" +types-protobuf = ">=4.24" + +[[package]] +name = "numpy" +version = "1.24.4" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +markers = "python_version < \"3.10\"" +files = [ + {file = "numpy-1.24.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c0bfb52d2169d58c1cdb8cc1f16989101639b34c7d3ce60ed70b19c63eba0b64"}, + {file = "numpy-1.24.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ed094d4f0c177b1b8e7aa9cba7d6ceed51c0e569a5318ac0ca9a090680a6a1b1"}, + {file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79fc682a374c4a8ed08b331bef9c5f582585d1048fa6d80bc6c35bc384eee9b4"}, + {file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ffe43c74893dbf38c2b0a1f5428760a1a9c98285553c89e12d70a96a7f3a4d6"}, + {file = "numpy-1.24.4-cp310-cp310-win32.whl", hash = "sha256:4c21decb6ea94057331e111a5bed9a79d335658c27ce2adb580fb4d54f2ad9bc"}, + {file = "numpy-1.24.4-cp310-cp310-win_amd64.whl", hash = "sha256:b4bea75e47d9586d31e892a7401f76e909712a0fd510f58f5337bea9572c571e"}, + {file = "numpy-1.24.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f136bab9c2cfd8da131132c2cf6cc27331dd6fae65f95f69dcd4ae3c3639c810"}, + {file = "numpy-1.24.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2926dac25b313635e4d6cf4dc4e51c8c0ebfed60b801c799ffc4c32bf3d1254"}, + {file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:222e40d0e2548690405b0b3c7b21d1169117391c2e82c378467ef9ab4c8f0da7"}, + {file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7215847ce88a85ce39baf9e89070cb860c98fdddacbaa6c0da3ffb31b3350bd5"}, + {file = "numpy-1.24.4-cp311-cp311-win32.whl", hash = "sha256:4979217d7de511a8d57f4b4b5b2b965f707768440c17cb70fbf254c4b225238d"}, + {file = "numpy-1.24.4-cp311-cp311-win_amd64.whl", hash = "sha256:b7b1fc9864d7d39e28f41d089bfd6353cb5f27ecd9905348c24187a768c79694"}, + {file = "numpy-1.24.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1452241c290f3e2a312c137a9999cdbf63f78864d63c79039bda65ee86943f61"}, + {file = "numpy-1.24.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:04640dab83f7c6c85abf9cd729c5b65f1ebd0ccf9de90b270cd61935eef0197f"}, + {file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5425b114831d1e77e4b5d812b69d11d962e104095a5b9c3b641a218abcc050e"}, + {file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd80e219fd4c71fc3699fc1dadac5dcf4fd882bfc6f7ec53d30fa197b8ee22dc"}, + {file = "numpy-1.24.4-cp38-cp38-win32.whl", hash = "sha256:4602244f345453db537be5314d3983dbf5834a9701b7723ec28923e2889e0bb2"}, + {file = "numpy-1.24.4-cp38-cp38-win_amd64.whl", hash = "sha256:692f2e0f55794943c5bfff12b3f56f99af76f902fc47487bdfe97856de51a706"}, + {file = "numpy-1.24.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2541312fbf09977f3b3ad449c4e5f4bb55d0dbf79226d7724211acc905049400"}, + {file = "numpy-1.24.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9667575fb6d13c95f1b36aca12c5ee3356bf001b714fc354eb5465ce1609e62f"}, + {file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3a86ed21e4f87050382c7bc96571755193c4c1392490744ac73d660e8f564a9"}, + {file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d11efb4dbecbdf22508d55e48d9c8384db795e1b7b51ea735289ff96613ff74d"}, + {file = "numpy-1.24.4-cp39-cp39-win32.whl", hash = "sha256:6620c0acd41dbcb368610bb2f4d83145674040025e5536954782467100aa8835"}, + {file = "numpy-1.24.4-cp39-cp39-win_amd64.whl", hash = "sha256:befe2bf740fd8373cf56149a5c23a0f601e82869598d41f8e188a0e9869926f8"}, + {file = "numpy-1.24.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:31f13e25b4e304632a4619d0e0777662c2ffea99fcae2029556b17d8ff958aef"}, + {file = "numpy-1.24.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95f7ac6540e95bc440ad77f56e520da5bf877f87dca58bd095288dce8940532a"}, + {file = "numpy-1.24.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e98f220aa76ca2a977fe435f5b04d7b3470c0a2e6312907b37ba6068f26787f2"}, + {file = "numpy-1.24.4.tar.gz", hash = "sha256:80f5e3a4e498641401868df4208b74581206afbee7cf7b8329daae82676d9463"}, +] + +[[package]] +name = "numpy" +version = "1.26.4" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.9" +groups = ["main", "dev"] +markers = "python_version == \"3.10\"" +files = [ + {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, + {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, + {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, + {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}, + {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}, + {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}, + {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}, + {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"}, + {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"}, + {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"}, + {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, +] + +[[package]] +name = "numpy" +version = "2.4.3" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.11" +groups = ["main", "dev"] +markers = "python_version >= \"3.11\"" +files = [ + {file = "numpy-2.4.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:33b3bf58ee84b172c067f56aeadc7ee9ab6de69c5e800ab5b10295d54c581adb"}, + {file = "numpy-2.4.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8ba7b51e71c05aa1f9bc3641463cd82308eab40ce0d5c7e1fd4038cbf9938147"}, + {file = "numpy-2.4.3-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:a1988292870c7cb9d0ebb4cc96b4d447513a9644801de54606dc7aabf2b7d920"}, + {file = "numpy-2.4.3-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:23b46bb6d8ecb68b58c09944483c135ae5f0e9b8d8858ece5e4ead783771d2a9"}, + {file = "numpy-2.4.3-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a016db5c5dba78fa8fe9f5d80d6708f9c42ab087a739803c0ac83a43d686a470"}, + {file = "numpy-2.4.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:715de7f82e192e8cae5a507a347d97ad17598f8e026152ca97233e3666daaa71"}, + {file = "numpy-2.4.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2ddb7919366ee468342b91dea2352824c25b55814a987847b6c52003a7c97f15"}, + {file = "numpy-2.4.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a315e5234d88067f2d97e1f2ef670a7569df445d55400f1e33d117418d008d52"}, + {file = "numpy-2.4.3-cp311-cp311-win32.whl", hash = "sha256:2b3f8d2c4589b1a2028d2a770b0fc4d1f332fb5e01521f4de3199a896d158ddd"}, + {file = "numpy-2.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:77e76d932c49a75617c6d13464e41203cd410956614d0a0e999b25e9e8d27eec"}, + {file = "numpy-2.4.3-cp311-cp311-win_arm64.whl", hash = "sha256:eb610595dd91560905c132c709412b512135a60f1851ccbd2c959e136431ff67"}, + {file = "numpy-2.4.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:61b0cbabbb6126c8df63b9a3a0c4b1f44ebca5e12ff6997b80fcf267fb3150ef"}, + {file = "numpy-2.4.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7395e69ff32526710748f92cd8c9849b361830968ea3e24a676f272653e8983e"}, + {file = "numpy-2.4.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:abdce0f71dcb4a00e4e77f3faf05e4616ceccfe72ccaa07f47ee79cda3b7b0f4"}, + {file = "numpy-2.4.3-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:48da3a4ee1336454b07497ff7ec83903efa5505792c4e6d9bf83d99dc07a1e18"}, + {file = "numpy-2.4.3-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:32e3bef222ad6b052280311d1d60db8e259e4947052c3ae7dd6817451fc8a4c5"}, + {file = "numpy-2.4.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e7dd01a46700b1967487141a66ac1a3cf0dd8ebf1f08db37d46389401512ca97"}, + {file = "numpy-2.4.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:76f0f283506c28b12bba319c0fab98217e9f9b54e6160e9c79e9f7348ba32e9c"}, + {file = "numpy-2.4.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:737f630a337364665aba3b5a77e56a68cc42d350edd010c345d65a3efa3addcc"}, + {file = "numpy-2.4.3-cp312-cp312-win32.whl", hash = "sha256:26952e18d82a1dbbc2f008d402021baa8d6fc8e84347a2072a25e08b46d698b9"}, + {file = "numpy-2.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:65f3c2455188f09678355f5cae1f959a06b778bc66d535da07bf2ef20cd319d5"}, + {file = "numpy-2.4.3-cp312-cp312-win_arm64.whl", hash = "sha256:2abad5c7fef172b3377502bde47892439bae394a71bc329f31df0fd829b41a9e"}, + {file = "numpy-2.4.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b346845443716c8e542d54112966383b448f4a3ba5c66409771b8c0889485dd3"}, + {file = "numpy-2.4.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2629289168f4897a3c4e23dc98d6f1731f0fc0fe52fb9db19f974041e4cc12b9"}, + {file = "numpy-2.4.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:bb2e3cf95854233799013779216c57e153c1ee67a0bf92138acca0e429aefaee"}, + {file = "numpy-2.4.3-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:7f3408ff897f8ab07a07fbe2823d7aee6ff644c097cc1f90382511fe982f647f"}, + {file = "numpy-2.4.3-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:decb0eb8a53c3b009b0962378065589685d66b23467ef5dac16cbe818afde27f"}, + {file = "numpy-2.4.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5f51900414fc9204a0e0da158ba2ac52b75656e7dce7e77fb9f84bfa343b4cc"}, + {file = "numpy-2.4.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6bd06731541f89cdc01b261ba2c9e037f1543df7472517836b78dfb15bd6e476"}, + {file = "numpy-2.4.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:22654fe6be0e5206f553a9250762c653d3698e46686eee53b399ab90da59bd92"}, + {file = "numpy-2.4.3-cp313-cp313-win32.whl", hash = "sha256:d71e379452a2f670ccb689ec801b1218cd3983e253105d6e83780967e899d687"}, + {file = "numpy-2.4.3-cp313-cp313-win_amd64.whl", hash = "sha256:0a60e17a14d640f49146cb38e3f105f571318db7826d9b6fef7e4dce758faecd"}, + {file = "numpy-2.4.3-cp313-cp313-win_arm64.whl", hash = "sha256:c9619741e9da2059cd9c3f206110b97583c7152c1dc9f8aafd4beb450ac1c89d"}, + {file = "numpy-2.4.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:7aa4e54f6469300ebca1d9eb80acd5253cdfa36f2c03d79a35883687da430875"}, + {file = "numpy-2.4.3-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d1b90d840b25874cf5cd20c219af10bac3667db3876d9a495609273ebe679070"}, + {file = "numpy-2.4.3-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:a749547700de0a20a6718293396ec237bb38218049cfce788e08fcb716e8cf73"}, + {file = "numpy-2.4.3-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:94f3c4a151a2e529adf49c1d54f0f57ff8f9b233ee4d44af623a81553ab86368"}, + {file = "numpy-2.4.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22c31dc07025123aedf7f2db9e91783df13f1776dc52c6b22c620870dc0fab22"}, + {file = "numpy-2.4.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:148d59127ac95979d6f07e4d460f934ebdd6eed641db9c0db6c73026f2b2101a"}, + {file = "numpy-2.4.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a97cbf7e905c435865c2d939af3d93f99d18eaaa3cabe4256f4304fb51604349"}, + {file = "numpy-2.4.3-cp313-cp313t-win32.whl", hash = "sha256:be3b8487d725a77acccc9924f65fd8bce9af7fac8c9820df1049424a2115af6c"}, + {file = "numpy-2.4.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1ec84fd7c8e652b0f4aaaf2e6e9cc8eaa9b1b80a537e06b2e3a2fb176eedcb26"}, + {file = "numpy-2.4.3-cp313-cp313t-win_arm64.whl", hash = "sha256:120df8c0a81ebbf5b9020c91439fccd85f5e018a927a39f624845be194a2be02"}, + {file = "numpy-2.4.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:5884ce5c7acfae1e4e1b6fde43797d10aa506074d25b531b4f54bde33c0c31d4"}, + {file = "numpy-2.4.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:297837823f5bc572c5f9379b0c9f3a3365f08492cbdc33bcc3af174372ebb168"}, + {file = "numpy-2.4.3-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:a111698b4a3f8dcbe54c64a7708f049355abd603e619013c346553c1fd4ca90b"}, + {file = "numpy-2.4.3-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:4bd4741a6a676770e0e97fe9ab2e51de01183df3dcbcec591d26d331a40de950"}, + {file = "numpy-2.4.3-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:54f29b877279d51e210e0c80709ee14ccbbad647810e8f3d375561c45ef613dd"}, + {file = "numpy-2.4.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:679f2a834bae9020f81534671c56fd0cc76dd7e5182f57131478e23d0dc59e24"}, + {file = "numpy-2.4.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d84f0f881cb2225c2dfd7f78a10a5645d487a496c6668d6cc39f0f114164f3d0"}, + {file = "numpy-2.4.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d213c7e6e8d211888cc359bab7199670a00f5b82c0978b9d1c75baf1eddbeac0"}, + {file = "numpy-2.4.3-cp314-cp314-win32.whl", hash = "sha256:52077feedeff7c76ed7c9f1a0428558e50825347b7545bbb8523da2cd55c547a"}, + {file = "numpy-2.4.3-cp314-cp314-win_amd64.whl", hash = "sha256:0448e7f9caefb34b4b7dd2b77f21e8906e5d6f0365ad525f9f4f530b13df2afc"}, + {file = "numpy-2.4.3-cp314-cp314-win_arm64.whl", hash = "sha256:b44fd60341c4d9783039598efadd03617fa28d041fc37d22b62d08f2027fa0e7"}, + {file = "numpy-2.4.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0a195f4216be9305a73c0e91c9b026a35f2161237cf1c6de9b681637772ea657"}, + {file = "numpy-2.4.3-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:cd32fbacb9fd1bf041bf8e89e4576b6f00b895f06d00914820ae06a616bdfef7"}, + {file = "numpy-2.4.3-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:2e03c05abaee1f672e9d67bc858f300b5ccba1c21397211e8d77d98350972093"}, + {file = "numpy-2.4.3-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d1ce23cce91fcea443320a9d0ece9b9305d4368875bab09538f7a5b4131938a"}, + {file = "numpy-2.4.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c59020932feb24ed49ffd03704fbab89f22aa9c0d4b180ff45542fe8918f5611"}, + {file = "numpy-2.4.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:9684823a78a6cd6ad7511fc5e25b07947d1d5b5e2812c93fe99d7d4195130720"}, + {file = "numpy-2.4.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0200b25c687033316fb39f0ff4e3e690e8957a2c3c8d22499891ec58c37a3eb5"}, + {file = "numpy-2.4.3-cp314-cp314t-win32.whl", hash = "sha256:5e10da9e93247e554bb1d22f8edc51847ddd7dde52d85ce31024c1b4312bfba0"}, + {file = "numpy-2.4.3-cp314-cp314t-win_amd64.whl", hash = "sha256:45f003dbdffb997a03da2d1d0cb41fbd24a87507fb41605c0420a3db5bd4667b"}, + {file = "numpy-2.4.3-cp314-cp314t-win_arm64.whl", hash = "sha256:4d382735cecd7bcf090172489a525cd7d4087bc331f7df9f60ddc9a296cf208e"}, + {file = "numpy-2.4.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c6b124bfcafb9e8d3ed09130dbee44848c20b3e758b6bbf006e641778927c028"}, + {file = "numpy-2.4.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:76dbb9d4e43c16cf9aa711fcd8de1e2eeb27539dcefb60a1d5e9f12fae1d1ed8"}, + {file = "numpy-2.4.3-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:29363fbfa6f8ee855d7569c96ce524845e3d726d6c19b29eceec7dd555dab152"}, + {file = "numpy-2.4.3-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:bc71942c789ef415a37f0d4eab90341425a00d538cd0642445d30b41023d3395"}, + {file = "numpy-2.4.3-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7e58765ad74dcebd3ef0208a5078fba32dc8ec3578fe84a604432950cd043d79"}, + {file = "numpy-2.4.3-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e236dbda4e1d319d681afcbb136c0c4a8e0f1a5c58ceec2adebb547357fe857"}, + {file = "numpy-2.4.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:4b42639cdde6d24e732ff823a3fa5b701d8acad89c4142bc1d0bd6dc85200ba5"}, + {file = "numpy-2.4.3.tar.gz", hash = "sha256:483a201202b73495f00dbc83796c6ae63137a9bdade074f7648b3e32613412dd"}, +] + +[[package]] +name = "packaging" +version = "25.0" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev", "docs"] +files = [ + {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, + {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, +] + +[[package]] +name = "paginate" +version = "0.5.7" +description = "Divides large result sets into pages for easier browsing" +optional = false +python-versions = "*" +groups = ["docs"] +files = [ + {file = "paginate-0.5.7-py2.py3-none-any.whl", hash = "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591"}, + {file = "paginate-0.5.7.tar.gz", hash = "sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945"}, +] + +[package.extras] +dev = ["pytest", "tox"] +lint = ["black"] + +[[package]] +name = "pandas" +version = "1.5.3" +description = "Powerful data structures for data analysis, time series, and statistics" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +files = [ + {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3749077d86e3a2f0ed51367f30bf5b82e131cc0f14260c4d3e499186fccc4406"}, + {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:972d8a45395f2a2d26733eb8d0f629b2f90bebe8e8eddbb8829b180c09639572"}, + {file = "pandas-1.5.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:50869a35cbb0f2e0cd5ec04b191e7b12ed688874bd05dd777c19b28cbea90996"}, + {file = "pandas-1.5.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3ac844a0fe00bfaeb2c9b51ab1424e5c8744f89860b138434a363b1f620f354"}, + {file = "pandas-1.5.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a0a56cef15fd1586726dace5616db75ebcfec9179a3a55e78f72c5639fa2a23"}, + {file = "pandas-1.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:478ff646ca42b20376e4ed3fa2e8d7341e8a63105586efe54fa2508ee087f328"}, + {file = "pandas-1.5.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6973549c01ca91ec96199e940495219c887ea815b2083722821f1d7abfa2b4dc"}, + {file = "pandas-1.5.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c39a8da13cede5adcd3be1182883aea1c925476f4e84b2807a46e2775306305d"}, + {file = "pandas-1.5.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f76d097d12c82a535fda9dfe5e8dd4127952b45fea9b0276cb30cca5ea313fbc"}, + {file = "pandas-1.5.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e474390e60ed609cec869b0da796ad94f420bb057d86784191eefc62b65819ae"}, + {file = "pandas-1.5.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f2b952406a1588ad4cad5b3f55f520e82e902388a6d5a4a91baa8d38d23c7f6"}, + {file = "pandas-1.5.3-cp311-cp311-win_amd64.whl", hash = "sha256:bc4c368f42b551bf72fac35c5128963a171b40dce866fb066540eeaf46faa003"}, + {file = "pandas-1.5.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:14e45300521902689a81f3f41386dc86f19b8ba8dd5ac5a3c7010ef8d2932813"}, + {file = "pandas-1.5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9842b6f4b8479e41968eced654487258ed81df7d1c9b7b870ceea24ed9459b31"}, + {file = "pandas-1.5.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:26d9c71772c7afb9d5046e6e9cf42d83dd147b5cf5bcb9d97252077118543792"}, + {file = "pandas-1.5.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5fbcb19d6fceb9e946b3e23258757c7b225ba450990d9ed63ccceeb8cae609f7"}, + {file = "pandas-1.5.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:565fa34a5434d38e9d250af3c12ff931abaf88050551d9fbcdfafca50d62babf"}, + {file = "pandas-1.5.3-cp38-cp38-win32.whl", hash = "sha256:87bd9c03da1ac870a6d2c8902a0e1fd4267ca00f13bc494c9e5a9020920e1d51"}, + {file = "pandas-1.5.3-cp38-cp38-win_amd64.whl", hash = "sha256:41179ce559943d83a9b4bbacb736b04c928b095b5f25dd2b7389eda08f46f373"}, + {file = "pandas-1.5.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c74a62747864ed568f5a82a49a23a8d7fe171d0c69038b38cedf0976831296fa"}, + {file = "pandas-1.5.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c4c00e0b0597c8e4f59e8d461f797e5d70b4d025880516a8261b2817c47759ee"}, + {file = "pandas-1.5.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a50d9a4336a9621cab7b8eb3fb11adb82de58f9b91d84c2cd526576b881a0c5a"}, + {file = "pandas-1.5.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd05f7783b3274aa206a1af06f0ceed3f9b412cf665b7247eacd83be41cf7bf0"}, + {file = "pandas-1.5.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f69c4029613de47816b1bb30ff5ac778686688751a5e9c99ad8c7031f6508e5"}, + {file = "pandas-1.5.3-cp39-cp39-win32.whl", hash = "sha256:7cec0bee9f294e5de5bbfc14d0573f65526071029d036b753ee6507d2a21480a"}, + {file = "pandas-1.5.3-cp39-cp39-win_amd64.whl", hash = "sha256:dfd681c5dc216037e0b0a2c821f5ed99ba9f03ebcf119c7dac0e9a7b960b9ec9"}, + {file = "pandas-1.5.3.tar.gz", hash = "sha256:74a3fd7e5a7ec052f183273dc7b0acd3a863edf7520f5d3a1765c04ffdb3b0b1"}, +] +markers = {main = "python_version <= \"3.10\" and extra == \"all\"", dev = "python_version <= \"3.10\""} + +[package.dependencies] +numpy = [ + {version = ">=1.20.3", markers = "python_version < \"3.10\""}, + {version = ">=1.21.0", markers = "python_version >= \"3.10\""}, +] +python-dateutil = ">=2.8.1" +pytz = ">=2020.1" + +[package.extras] +test = ["hypothesis (>=5.5.3)", "pytest (>=6.0)", "pytest-xdist (>=1.31)"] + +[[package]] +name = "pandas" +version = "2.3.3" +description = "Powerful data structures for data analysis, time series, and statistics" +optional = false +python-versions = ">=3.9" +groups = ["main", "dev"] +files = [ + {file = "pandas-2.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:376c6446ae31770764215a6c937f72d917f214b43560603cd60da6408f183b6c"}, + {file = "pandas-2.3.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e19d192383eab2f4ceb30b412b22ea30690c9e618f78870357ae1d682912015a"}, + {file = "pandas-2.3.3-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5caf26f64126b6c7aec964f74266f435afef1c1b13da3b0636c7518a1fa3e2b1"}, + {file = "pandas-2.3.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dd7478f1463441ae4ca7308a70e90b33470fa593429f9d4c578dd00d1fa78838"}, + {file = "pandas-2.3.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4793891684806ae50d1288c9bae9330293ab4e083ccd1c5e383c34549c6e4250"}, + {file = "pandas-2.3.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:28083c648d9a99a5dd035ec125d42439c6c1c525098c58af0fc38dd1a7a1b3d4"}, + {file = "pandas-2.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:503cf027cf9940d2ceaa1a93cfb5f8c8c7e6e90720a2850378f0b3f3b1e06826"}, + {file = "pandas-2.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:602b8615ebcc4a0c1751e71840428ddebeb142ec02c786e8ad6b1ce3c8dec523"}, + {file = "pandas-2.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8fe25fc7b623b0ef6b5009149627e34d2a4657e880948ec3c840e9402e5c1b45"}, + {file = "pandas-2.3.3-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b468d3dad6ff947df92dcb32ede5b7bd41a9b3cceef0a30ed925f6d01fb8fa66"}, + {file = "pandas-2.3.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b98560e98cb334799c0b07ca7967ac361a47326e9b4e5a7dfb5ab2b1c9d35a1b"}, + {file = "pandas-2.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37b5848ba49824e5c30bedb9c830ab9b7751fd049bc7914533e01c65f79791"}, + {file = "pandas-2.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:db4301b2d1f926ae677a751eb2bd0e8c5f5319c9cb3f88b0becbbb0b07b34151"}, + {file = "pandas-2.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:f086f6fe114e19d92014a1966f43a3e62285109afe874f067f5abbdcbb10e59c"}, + {file = "pandas-2.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d21f6d74eb1725c2efaa71a2bfc661a0689579b58e9c0ca58a739ff0b002b53"}, + {file = "pandas-2.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3fd2f887589c7aa868e02632612ba39acb0b8948faf5cc58f0850e165bd46f35"}, + {file = "pandas-2.3.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecaf1e12bdc03c86ad4a7ea848d66c685cb6851d807a26aa245ca3d2017a1908"}, + {file = "pandas-2.3.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b3d11d2fda7eb164ef27ffc14b4fcab16a80e1ce67e9f57e19ec0afaf715ba89"}, + {file = "pandas-2.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a68e15f780eddf2b07d242e17a04aa187a7ee12b40b930bfdd78070556550e98"}, + {file = "pandas-2.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:371a4ab48e950033bcf52b6527eccb564f52dc826c02afd9a1bc0ab731bba084"}, + {file = "pandas-2.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:a16dcec078a01eeef8ee61bf64074b4e524a2a3f4b3be9326420cabe59c4778b"}, + {file = "pandas-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713"}, + {file = "pandas-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8"}, + {file = "pandas-2.3.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e32e7cc9af0f1cc15548288a51a3b681cc2a219faa838e995f7dc53dbab1062d"}, + {file = "pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac"}, + {file = "pandas-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e0a175408804d566144e170d0476b15d78458795bb18f1304fb94160cabf40c"}, + {file = "pandas-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93c2d9ab0fc11822b5eece72ec9587e172f63cff87c00b062f6e37448ced4493"}, + {file = "pandas-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee"}, + {file = "pandas-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:75ea25f9529fdec2d2e93a42c523962261e567d250b0013b16210e1d40d7c2e5"}, + {file = "pandas-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74ecdf1d301e812db96a465a525952f4dde225fdb6d8e5a521d47e1f42041e21"}, + {file = "pandas-2.3.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6435cb949cb34ec11cc9860246ccb2fdc9ecd742c12d3304989017d53f039a78"}, + {file = "pandas-2.3.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110"}, + {file = "pandas-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86"}, + {file = "pandas-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc"}, + {file = "pandas-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ee15f284898e7b246df8087fc82b87b01686f98ee67d85a17b7ab44143a3a9a0"}, + {file = "pandas-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593"}, + {file = "pandas-2.3.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d2cefc361461662ac48810cb14365a365ce864afe85ef1f447ff5a1e99ea81c"}, + {file = "pandas-2.3.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ee67acbbf05014ea6c763beb097e03cd629961c8a632075eeb34247120abcb4b"}, + {file = "pandas-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c46467899aaa4da076d5abc11084634e2d197e9460643dd455ac3db5856b24d6"}, + {file = "pandas-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6253c72c6a1d990a410bc7de641d34053364ef8bcd3126f7e7450125887dffe3"}, + {file = "pandas-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:1b07204a219b3b7350abaae088f451860223a52cfb8a6c53358e7948735158e5"}, + {file = "pandas-2.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2462b1a365b6109d275250baaae7b760fd25c726aaca0054649286bcfbb3e8ec"}, + {file = "pandas-2.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7"}, + {file = "pandas-2.3.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a21d830e78df0a515db2b3d2f5570610f5e6bd2e27749770e8bb7b524b89b450"}, + {file = "pandas-2.3.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5"}, + {file = "pandas-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788"}, + {file = "pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87"}, + {file = "pandas-2.3.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c503ba5216814e295f40711470446bc3fd00f0faea8a086cbc688808e26f92a2"}, + {file = "pandas-2.3.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a637c5cdfa04b6d6e2ecedcb81fc52ffb0fd78ce2ebccc9ea964df9f658de8c8"}, + {file = "pandas-2.3.3-cp39-cp39-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:854d00d556406bffe66a4c0802f334c9ad5a96b4f1f868adf036a21b11ef13ff"}, + {file = "pandas-2.3.3-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bf1f8a81d04ca90e32a0aceb819d34dbd378a98bf923b6398b9a3ec0bf44de29"}, + {file = "pandas-2.3.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:23ebd657a4d38268c7dfbdf089fbc31ea709d82e4923c5ffd4fbd5747133ce73"}, + {file = "pandas-2.3.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5554c929ccc317d41a5e3d1234f3be588248e61f08a74dd17c9eabb535777dc9"}, + {file = "pandas-2.3.3-cp39-cp39-win_amd64.whl", hash = "sha256:d3e28b3e83862ccf4d85ff19cf8c20b2ae7e503881711ff2d534dc8f761131aa"}, + {file = "pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b"}, +] +markers = {main = "python_version >= \"3.11\" and extra == \"all\"", dev = "python_version >= \"3.11\""} + +[package.dependencies] +numpy = [ + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, +] +python-dateutil = ">=2.8.2" +pytz = ">=2020.1" +tzdata = ">=2022.7" + +[package.extras] +all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] +aws = ["s3fs (>=2022.11.0)"] +clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] +compression = ["zstandard (>=0.19.0)"] +computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] +consortium-standard = ["dataframe-api-compat (>=0.1.7)"] +excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] +feather = ["pyarrow (>=10.0.1)"] +fss = ["fsspec (>=2022.11.0)"] +gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] +hdf5 = ["tables (>=3.8.0)"] +html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] +mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] +output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] +parquet = ["pyarrow (>=10.0.1)"] +performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] +plot = ["matplotlib (>=3.6.3)"] +postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] +pyarrow = ["pyarrow (>=10.0.1)"] +spss = ["pyreadstat (>=1.2.0)"] +sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] +test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] +xml = ["lxml (>=4.9.2)"] + +[[package]] +name = "parso" +version = "0.8.5" +description = "A Python Parser" +optional = false +python-versions = ">=3.6" +groups = ["dev"] +files = [ + {file = "parso-0.8.5-py2.py3-none-any.whl", hash = "sha256:646204b5ee239c396d040b90f9e272e9a8017c630092bf59980beb62fd033887"}, + {file = "parso-0.8.5.tar.gz", hash = "sha256:034d7354a9a018bdce352f48b2a8a450f05e9d6ee85db84764e9b6bd96dafe5a"}, +] + +[package.extras] +qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] +testing = ["docopt", "pytest"] + +[[package]] +name = "pathspec" +version = "0.12.1" +description = "Utility library for gitignore style pattern matching of file paths." +optional = false +python-versions = ">=3.8" +groups = ["dev", "docs"] +files = [ + {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, + {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, +] + +[[package]] +name = "pexpect" +version = "4.9.0" +description = "Pexpect allows easy control of interactive console applications." +optional = false +python-versions = "*" +groups = ["dev"] +markers = "sys_platform != \"win32\"" +files = [ + {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, + {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"}, +] + +[package.dependencies] +ptyprocess = ">=0.5" + +[[package]] +name = "pickleshare" +version = "0.7.5" +description = "Tiny 'shelve'-like database with concurrency support" +optional = false +python-versions = "*" +groups = ["dev"] +files = [ + {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, + {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, +] + +[[package]] +name = "pillow" +version = "10.4.0" +description = "Python Imaging Library (Fork)" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +markers = "python_version <= \"3.10\"" +files = [ + {file = "pillow-10.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e"}, + {file = "pillow-10.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc"}, + {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e"}, + {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46"}, + {file = "pillow-10.4.0-cp310-cp310-win32.whl", hash = "sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984"}, + {file = "pillow-10.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141"}, + {file = "pillow-10.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1"}, + {file = "pillow-10.4.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c"}, + {file = "pillow-10.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319"}, + {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d"}, + {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696"}, + {file = "pillow-10.4.0-cp311-cp311-win32.whl", hash = "sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496"}, + {file = "pillow-10.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91"}, + {file = "pillow-10.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22"}, + {file = "pillow-10.4.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94"}, + {file = "pillow-10.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a"}, + {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b"}, + {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9"}, + {file = "pillow-10.4.0-cp312-cp312-win32.whl", hash = "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42"}, + {file = "pillow-10.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a"}, + {file = "pillow-10.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9"}, + {file = "pillow-10.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3"}, + {file = "pillow-10.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc"}, + {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a"}, + {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309"}, + {file = "pillow-10.4.0-cp313-cp313-win32.whl", hash = "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060"}, + {file = "pillow-10.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea"}, + {file = "pillow-10.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d"}, + {file = "pillow-10.4.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8d4d5063501b6dd4024b8ac2f04962d661222d120381272deea52e3fc52d3736"}, + {file = "pillow-10.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c1ee6f42250df403c5f103cbd2768a28fe1a0ea1f0f03fe151c8741e1469c8b"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15e02e9bb4c21e39876698abf233c8c579127986f8207200bc8a8f6bb27acf2"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a8d4bade9952ea9a77d0c3e49cbd8b2890a399422258a77f357b9cc9be8d680"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:43efea75eb06b95d1631cb784aa40156177bf9dd5b4b03ff38979e048258bc6b"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:950be4d8ba92aca4b2bb0741285a46bfae3ca699ef913ec8416c1b78eadd64cd"}, + {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d7480af14364494365e89d6fddc510a13e5a2c3584cb19ef65415ca57252fb84"}, + {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:73664fe514b34c8f02452ffb73b7a92c6774e39a647087f83d67f010eb9a0cf0"}, + {file = "pillow-10.4.0-cp38-cp38-win32.whl", hash = "sha256:e88d5e6ad0d026fba7bdab8c3f225a69f063f116462c49892b0149e21b6c0a0e"}, + {file = "pillow-10.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:5161eef006d335e46895297f642341111945e2c1c899eb406882a6c61a4357ab"}, + {file = "pillow-10.4.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0ae24a547e8b711ccaaf99c9ae3cd975470e1a30caa80a6aaee9a2f19c05701d"}, + {file = "pillow-10.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:298478fe4f77a4408895605f3482b6cc6222c018b2ce565c2b6b9c354ac3229b"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:134ace6dc392116566980ee7436477d844520a26a4b1bd4053f6f47d096997fd"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:930044bb7679ab003b14023138b50181899da3f25de50e9dbee23b61b4de2126"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:c76e5786951e72ed3686e122d14c5d7012f16c8303a674d18cdcd6d89557fc5b"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b2724fdb354a868ddf9a880cb84d102da914e99119211ef7ecbdc613b8c96b3c"}, + {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dbc6ae66518ab3c5847659e9988c3b60dc94ffb48ef9168656e0019a93dbf8a1"}, + {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:06b2f7898047ae93fad74467ec3d28fe84f7831370e3c258afa533f81ef7f3df"}, + {file = "pillow-10.4.0-cp39-cp39-win32.whl", hash = "sha256:7970285ab628a3779aecc35823296a7869f889b8329c16ad5a71e4901a3dc4ef"}, + {file = "pillow-10.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:961a7293b2457b405967af9c77dcaa43cc1a8cd50d23c532e62d48ab6cdd56f5"}, + {file = "pillow-10.4.0-cp39-cp39-win_arm64.whl", hash = "sha256:32cda9e3d601a52baccb2856b8ea1fc213c90b340c542dcef77140dfa3278a9e"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:a02364621fe369e06200d4a16558e056fe2805d3468350df3aef21e00d26214b"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:1b5dea9831a90e9d0721ec417a80d4cbd7022093ac38a568db2dd78363b00908"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b885f89040bb8c4a1573566bbb2f44f5c505ef6e74cec7ab9068c900047f04b"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87dd88ded2e6d74d31e1e0a99a726a6765cda32d00ba72dc37f0651f306daaa8"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:2db98790afc70118bd0255c2eeb465e9767ecf1f3c25f9a1abb8ffc8cfd1fe0a"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cfdd747216947628af7b259d274771d84db2268ca062dd5faf373639d00113a3"}, + {file = "pillow-10.4.0.tar.gz", hash = "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06"}, +] + +[package.extras] +docs = ["furo", "olefile", "sphinx (>=7.3)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] +fpx = ["olefile"] +mic = ["olefile"] +tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] +typing = ["typing-extensions ; python_version < \"3.10\""] +xmp = ["defusedxml"] + +[[package]] +name = "pillow" +version = "12.1.1" +description = "Python Imaging Library (fork)" +optional = false +python-versions = ">=3.10" +groups = ["main", "dev"] +markers = "python_version >= \"3.11\"" +files = [ + {file = "pillow-12.1.1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1f1625b72740fdda5d77b4def688eb8fd6490975d06b909fd19f13f391e077e0"}, + {file = "pillow-12.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:178aa072084bd88ec759052feca8e56cbb14a60b39322b99a049e58090479713"}, + {file = "pillow-12.1.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b66e95d05ba806247aaa1561f080abc7975daf715c30780ff92a20e4ec546e1b"}, + {file = "pillow-12.1.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:89c7e895002bbe49cdc5426150377cbbc04767d7547ed145473f496dfa40408b"}, + {file = "pillow-12.1.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a5cbdcddad0af3da87cb16b60d23648bc3b51967eb07223e9fed77a82b457c4"}, + {file = "pillow-12.1.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9f51079765661884a486727f0729d29054242f74b46186026582b4e4769918e4"}, + {file = "pillow-12.1.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:99c1506ea77c11531d75e3a412832a13a71c7ebc8192ab9e4b2e355555920e3e"}, + {file = "pillow-12.1.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:36341d06738a9f66c8287cf8b876d24b18db9bd8740fa0672c74e259ad408cff"}, + {file = "pillow-12.1.1-cp310-cp310-win32.whl", hash = "sha256:6c52f062424c523d6c4db85518774cc3d50f5539dd6eed32b8f6229b26f24d40"}, + {file = "pillow-12.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:c6008de247150668a705a6338156efb92334113421ceecf7438a12c9a12dab23"}, + {file = "pillow-12.1.1-cp310-cp310-win_arm64.whl", hash = "sha256:1a9b0ee305220b392e1124a764ee4265bd063e54a751a6b62eff69992f457fa9"}, + {file = "pillow-12.1.1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:e879bb6cd5c73848ef3b2b48b8af9ff08c5b71ecda8048b7dd22d8a33f60be32"}, + {file = "pillow-12.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:365b10bb9417dd4498c0e3b128018c4a624dc11c7b97d8cc54effe3b096f4c38"}, + {file = "pillow-12.1.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d4ce8e329c93845720cd2014659ca67eac35f6433fd3050393d85f3ecef0dad5"}, + {file = "pillow-12.1.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc354a04072b765eccf2204f588a7a532c9511e8b9c7f900e1b64e3e33487090"}, + {file = "pillow-12.1.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7e7976bf1910a8116b523b9f9f58bf410f3e8aa330cd9a2bb2953f9266ab49af"}, + {file = "pillow-12.1.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:597bd9c8419bc7c6af5604e55847789b69123bbe25d65cc6ad3012b4f3c98d8b"}, + {file = "pillow-12.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2c1fc0f2ca5f96a3c8407e41cca26a16e46b21060fe6d5b099d2cb01412222f5"}, + {file = "pillow-12.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:578510d88c6229d735855e1f278aa305270438d36a05031dfaae5067cc8eb04d"}, + {file = "pillow-12.1.1-cp311-cp311-win32.whl", hash = "sha256:7311c0a0dcadb89b36b7025dfd8326ecfa36964e29913074d47382706e516a7c"}, + {file = "pillow-12.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:fbfa2a7c10cc2623f412753cddf391c7f971c52ca40a3f65dc5039b2939e8563"}, + {file = "pillow-12.1.1-cp311-cp311-win_arm64.whl", hash = "sha256:b81b5e3511211631b3f672a595e3221252c90af017e399056d0faabb9538aa80"}, + {file = "pillow-12.1.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ab323b787d6e18b3d91a72fc99b1a2c28651e4358749842b8f8dfacd28ef2052"}, + {file = "pillow-12.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:adebb5bee0f0af4909c30db0d890c773d1a92ffe83da908e2e9e720f8edf3984"}, + {file = "pillow-12.1.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bb66b7cc26f50977108790e2456b7921e773f23db5630261102233eb355a3b79"}, + {file = "pillow-12.1.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aee2810642b2898bb187ced9b349e95d2a7272930796e022efaf12e99dccd293"}, + {file = "pillow-12.1.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a0b1cd6232e2b618adcc54d9882e4e662a089d5768cd188f7c245b4c8c44a397"}, + {file = "pillow-12.1.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7aac39bcf8d4770d089588a2e1dd111cbaa42df5a94be3114222057d68336bd0"}, + {file = "pillow-12.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ab174cd7d29a62dd139c44bf74b698039328f45cb03b4596c43473a46656b2f3"}, + {file = "pillow-12.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:339ffdcb7cbeaa08221cd401d517d4b1fe7a9ed5d400e4a8039719238620ca35"}, + {file = "pillow-12.1.1-cp312-cp312-win32.whl", hash = "sha256:5d1f9575a12bed9e9eedd9a4972834b08c97a352bd17955ccdebfeca5913fa0a"}, + {file = "pillow-12.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:21329ec8c96c6e979cd0dfd29406c40c1d52521a90544463057d2aaa937d66a6"}, + {file = "pillow-12.1.1-cp312-cp312-win_arm64.whl", hash = "sha256:af9a332e572978f0218686636610555ae3defd1633597be015ed50289a03c523"}, + {file = "pillow-12.1.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:d242e8ac078781f1de88bf823d70c1a9b3c7950a44cdf4b7c012e22ccbcd8e4e"}, + {file = "pillow-12.1.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:02f84dfad02693676692746df05b89cf25597560db2857363a208e393429f5e9"}, + {file = "pillow-12.1.1-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:e65498daf4b583091ccbb2556c7000abf0f3349fcd57ef7adc9a84a394ed29f6"}, + {file = "pillow-12.1.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6c6db3b84c87d48d0088943bf33440e0c42370b99b1c2a7989216f7b42eede60"}, + {file = "pillow-12.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8b7e5304e34942bf62e15184219a7b5ad4ff7f3bb5cca4d984f37df1a0e1aee2"}, + {file = "pillow-12.1.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:18e5bddd742a44b7e6b1e773ab5db102bd7a94c32555ba656e76d319d19c3850"}, + {file = "pillow-12.1.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc44ef1f3de4f45b50ccf9136999d71abb99dca7706bc75d222ed350b9fd2289"}, + {file = "pillow-12.1.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5a8eb7ed8d4198bccbd07058416eeec51686b498e784eda166395a23eb99138e"}, + {file = "pillow-12.1.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:47b94983da0c642de92ced1702c5b6c292a84bd3a8e1d1702ff923f183594717"}, + {file = "pillow-12.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:518a48c2aab7ce596d3bf79d0e275661b846e86e4d0e7dec34712c30fe07f02a"}, + {file = "pillow-12.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a550ae29b95c6dc13cf69e2c9dc5747f814c54eeb2e32d683e5e93af56caa029"}, + {file = "pillow-12.1.1-cp313-cp313-win32.whl", hash = "sha256:a003d7422449f6d1e3a34e3dd4110c22148336918ddbfc6a32581cd54b2e0b2b"}, + {file = "pillow-12.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:344cf1e3dab3be4b1fa08e449323d98a2a3f819ad20f4b22e77a0ede31f0faa1"}, + {file = "pillow-12.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:5c0dd1636633e7e6a0afe7bf6a51a14992b7f8e60de5789018ebbdfae55b040a"}, + {file = "pillow-12.1.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0330d233c1a0ead844fc097a7d16c0abff4c12e856c0b325f231820fee1f39da"}, + {file = "pillow-12.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5dae5f21afb91322f2ff791895ddd8889e5e947ff59f71b46041c8ce6db790bc"}, + {file = "pillow-12.1.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2e0c664be47252947d870ac0d327fea7e63985a08794758aa8af5b6cb6ec0c9c"}, + {file = "pillow-12.1.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:691ab2ac363b8217f7d31b3497108fb1f50faab2f75dfb03284ec2f217e87bf8"}, + {file = "pillow-12.1.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9e8064fb1cc019296958595f6db671fba95209e3ceb0c4734c9baf97de04b20"}, + {file = "pillow-12.1.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:472a8d7ded663e6162dafdf20015c486a7009483ca671cece7a9279b512fcb13"}, + {file = "pillow-12.1.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:89b54027a766529136a06cfebeecb3a04900397a3590fd252160b888479517bf"}, + {file = "pillow-12.1.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:86172b0831b82ce4f7877f280055892b31179e1576aa00d0df3bb1bbf8c3e524"}, + {file = "pillow-12.1.1-cp313-cp313t-win32.whl", hash = "sha256:44ce27545b6efcf0fdbdceb31c9a5bdea9333e664cda58a7e674bb74608b3986"}, + {file = "pillow-12.1.1-cp313-cp313t-win_amd64.whl", hash = "sha256:a285e3eb7a5a45a2ff504e31f4a8d1b12ef62e84e5411c6804a42197c1cf586c"}, + {file = "pillow-12.1.1-cp313-cp313t-win_arm64.whl", hash = "sha256:cc7d296b5ea4d29e6570dabeaed58d31c3fea35a633a69679fb03d7664f43fb3"}, + {file = "pillow-12.1.1-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:417423db963cb4be8bac3fc1204fe61610f6abeed1580a7a2cbb2fbda20f12af"}, + {file = "pillow-12.1.1-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:b957b71c6b2387610f556a7eb0828afbe40b4a98036fc0d2acfa5a44a0c2036f"}, + {file = "pillow-12.1.1-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:097690ba1f2efdeb165a20469d59d8bb03c55fb6621eb2041a060ae8ea3e9642"}, + {file = "pillow-12.1.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2815a87ab27848db0321fb78c7f0b2c8649dee134b7f2b80c6a45c6831d75ccd"}, + {file = "pillow-12.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f7ed2c6543bad5a7d5530eb9e78c53132f93dfa44a28492db88b41cdab885202"}, + {file = "pillow-12.1.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:652a2c9ccfb556235b2b501a3a7cf3742148cd22e04b5625c5fe057ea3e3191f"}, + {file = "pillow-12.1.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d6e4571eedf43af33d0fc233a382a76e849badbccdf1ac438841308652a08e1f"}, + {file = "pillow-12.1.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b574c51cf7d5d62e9be37ba446224b59a2da26dc4c1bb2ecbe936a4fb1a7cb7f"}, + {file = "pillow-12.1.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a37691702ed687799de29a518d63d4682d9016932db66d4e90c345831b02fb4e"}, + {file = "pillow-12.1.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f95c00d5d6700b2b890479664a06e754974848afaae5e21beb4d83c106923fd0"}, + {file = "pillow-12.1.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:559b38da23606e68681337ad74622c4dbba02254fc9cb4488a305dd5975c7eeb"}, + {file = "pillow-12.1.1-cp314-cp314-win32.whl", hash = "sha256:03edcc34d688572014ff223c125a3f77fb08091e4607e7745002fc214070b35f"}, + {file = "pillow-12.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:50480dcd74fa63b8e78235957d302d98d98d82ccbfac4c7e12108ba9ecbdba15"}, + {file = "pillow-12.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:5cb1785d97b0c3d1d1a16bc1d710c4a0049daefc4935f3a8f31f827f4d3d2e7f"}, + {file = "pillow-12.1.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:1f90cff8aa76835cba5769f0b3121a22bd4eb9e6884cfe338216e557a9a548b8"}, + {file = "pillow-12.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1f1be78ce9466a7ee64bfda57bdba0f7cc499d9794d518b854816c41bf0aa4e9"}, + {file = "pillow-12.1.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:42fc1f4677106188ad9a55562bbade416f8b55456f522430fadab3cef7cd4e60"}, + {file = "pillow-12.1.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:98edb152429ab62a1818039744d8fbb3ccab98a7c29fc3d5fcef158f3f1f68b7"}, + {file = "pillow-12.1.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d470ab1178551dd17fdba0fef463359c41aaa613cdcd7ff8373f54be629f9f8f"}, + {file = "pillow-12.1.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6408a7b064595afcab0a49393a413732a35788f2a5092fdc6266952ed67de586"}, + {file = "pillow-12.1.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5d8c41325b382c07799a3682c1c258469ea2ff97103c53717b7893862d0c98ce"}, + {file = "pillow-12.1.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c7697918b5be27424e9ce568193efd13d925c4481dd364e43f5dff72d33e10f8"}, + {file = "pillow-12.1.1-cp314-cp314t-win32.whl", hash = "sha256:d2912fd8114fc5545aa3a4b5576512f64c55a03f3ebcca4c10194d593d43ea36"}, + {file = "pillow-12.1.1-cp314-cp314t-win_amd64.whl", hash = "sha256:4ceb838d4bd9dab43e06c363cab2eebf63846d6a4aeaea283bbdfd8f1a8ed58b"}, + {file = "pillow-12.1.1-cp314-cp314t-win_arm64.whl", hash = "sha256:7b03048319bfc6170e93bd60728a1af51d3dd7704935feb228c4d4faab35d334"}, + {file = "pillow-12.1.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:600fd103672b925fe62ed08e0d874ea34d692474df6f4bf7ebe148b30f89f39f"}, + {file = "pillow-12.1.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:665e1b916b043cef294bc54d47bf02d87e13f769bc4bc5fa225a24b3a6c5aca9"}, + {file = "pillow-12.1.1-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:495c302af3aad1ca67420ddd5c7bd480c8867ad173528767d906428057a11f0e"}, + {file = "pillow-12.1.1-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8fd420ef0c52c88b5a035a0886f367748c72147b2b8f384c9d12656678dfdfa9"}, + {file = "pillow-12.1.1-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f975aa7ef9684ce7e2c18a3aa8f8e2106ce1e46b94ab713d156b2898811651d3"}, + {file = "pillow-12.1.1-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8089c852a56c2966cf18835db62d9b34fef7ba74c726ad943928d494fa7f4735"}, + {file = "pillow-12.1.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:cb9bb857b2d057c6dfc72ac5f3b44836924ba15721882ef103cecb40d002d80e"}, + {file = "pillow-12.1.1.tar.gz", hash = "sha256:9ad8fa5937ab05218e2b6a4cff30295ad35afd2f83ac592e68c0d871bb0fdbc4"}, +] + +[package.extras] +docs = ["furo", "olefile", "sphinx (>=8.2)", "sphinx-autobuild", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] +fpx = ["olefile"] +mic = ["olefile"] +test-arrow = ["arro3-compute", "arro3-core", "nanoarrow", "pyarrow"] +tests = ["check-manifest", "coverage (>=7.4.2)", "defusedxml", "markdown2", "olefile", "packaging", "pyroma (>=5)", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "trove-classifiers (>=2024.10.12)"] +xmp = ["defusedxml"] + +[[package]] +name = "platformdirs" +version = "4.3.6" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." +optional = false +python-versions = ">=3.8" +groups = ["dev", "docs"] +files = [ + {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, + {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, +] + +[package.extras] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.11.2)"] + +[[package]] +name = "pluggy" +version = "1.5.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "prompt-toolkit" +version = "3.0.52" +description = "Library for building powerful interactive command lines in Python" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955"}, + {file = "prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855"}, +] + +[package.dependencies] +wcwidth = "*" + +[[package]] +name = "protobuf" +version = "4.25.8" +description = "" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +markers = "python_version <= \"3.10\"" +files = [ + {file = "protobuf-4.25.8-cp310-abi3-win32.whl", hash = "sha256:504435d831565f7cfac9f0714440028907f1975e4bed228e58e72ecfff58a1e0"}, + {file = "protobuf-4.25.8-cp310-abi3-win_amd64.whl", hash = "sha256:bd551eb1fe1d7e92c1af1d75bdfa572eff1ab0e5bf1736716814cdccdb2360f9"}, + {file = "protobuf-4.25.8-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:ca809b42f4444f144f2115c4c1a747b9a404d590f18f37e9402422033e464e0f"}, + {file = "protobuf-4.25.8-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:9ad7ef62d92baf5a8654fbb88dac7fa5594cfa70fd3440488a5ca3bfc6d795a7"}, + {file = "protobuf-4.25.8-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:83e6e54e93d2b696a92cad6e6efc924f3850f82b52e1563778dfab8b355101b0"}, + {file = "protobuf-4.25.8-cp38-cp38-win32.whl", hash = "sha256:27d498ffd1f21fb81d987a041c32d07857d1d107909f5134ba3350e1ce80a4af"}, + {file = "protobuf-4.25.8-cp38-cp38-win_amd64.whl", hash = "sha256:d552c53d0415449c8d17ced5c341caba0d89dbf433698e1436c8fa0aae7808a3"}, + {file = "protobuf-4.25.8-cp39-cp39-win32.whl", hash = "sha256:077ff8badf2acf8bc474406706ad890466274191a48d0abd3bd6987107c9cde5"}, + {file = "protobuf-4.25.8-cp39-cp39-win_amd64.whl", hash = "sha256:f4510b93a3bec6eba8fd8f1093e9d7fb0d4a24d1a81377c10c0e5bbfe9e4ed24"}, + {file = "protobuf-4.25.8-py3-none-any.whl", hash = "sha256:15a0af558aa3b13efef102ae6e4f3efac06f1eea11afb3a57db2901447d9fb59"}, + {file = "protobuf-4.25.8.tar.gz", hash = "sha256:6135cf8affe1fc6f76cced2641e4ea8d3e59518d1f24ae41ba97bcad82d397cd"}, +] + +[[package]] +name = "protobuf" +version = "6.33.6" +description = "" +optional = false +python-versions = ">=3.9" +groups = ["main", "dev"] +markers = "python_version >= \"3.11\"" +files = [ + {file = "protobuf-6.33.6-cp310-abi3-win32.whl", hash = "sha256:7d29d9b65f8afef196f8334e80d6bc1d5d4adedb449971fefd3723824e6e77d3"}, + {file = "protobuf-6.33.6-cp310-abi3-win_amd64.whl", hash = "sha256:0cd27b587afca21b7cfa59a74dcbd48a50f0a6400cfb59391340ad729d91d326"}, + {file = "protobuf-6.33.6-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:9720e6961b251bde64edfdab7d500725a2af5280f3f4c87e57c0208376aa8c3a"}, + {file = "protobuf-6.33.6-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:e2afbae9b8e1825e3529f88d514754e094278bb95eadc0e199751cdd9a2e82a2"}, + {file = "protobuf-6.33.6-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:c96c37eec15086b79762ed265d59ab204dabc53056e3443e702d2681f4b39ce3"}, + {file = "protobuf-6.33.6-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:e9db7e292e0ab79dd108d7f1a94fe31601ce1ee3f7b79e0692043423020b0593"}, + {file = "protobuf-6.33.6-cp39-cp39-win32.whl", hash = "sha256:bd56799fb262994b2c2faa1799693c95cc2e22c62f56fb43af311cae45d26f0e"}, + {file = "protobuf-6.33.6-cp39-cp39-win_amd64.whl", hash = "sha256:f443a394af5ed23672bc6c486be138628fbe5c651ccbc536873d7da23d1868cf"}, + {file = "protobuf-6.33.6-py3-none-any.whl", hash = "sha256:77179e006c476e69bf8e8ce866640091ec42e1beb80b213c3900006ecfba6901"}, + {file = "protobuf-6.33.6.tar.gz", hash = "sha256:a6768d25248312c297558af96a9f9c929e8c4cee0659cb07e780731095f38135"}, +] + +[[package]] +name = "ptyprocess" +version = "0.7.0" +description = "Run a subprocess in a pseudo terminal" +optional = false +python-versions = "*" +groups = ["dev"] +markers = "sys_platform != \"win32\"" +files = [ + {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, + {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, +] + +[[package]] +name = "pure-eval" +version = "0.2.3" +description = "Safely evaluate AST nodes without side effects" +optional = false +python-versions = "*" +groups = ["dev"] +files = [ + {file = "pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0"}, + {file = "pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42"}, +] + +[package.extras] +tests = ["pytest"] + +[[package]] +name = "pygments" +version = "2.19.2" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.8" +groups = ["dev", "docs"] +files = [ + {file = "pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b"}, + {file = "pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887"}, +] + +[package.extras] +windows-terminal = ["colorama (>=0.4.6)"] + +[[package]] +name = "pymdown-extensions" +version = "10.15" +description = "Extension pack for Python Markdown." +optional = false +python-versions = ">=3.8" +groups = ["docs"] +files = [ + {file = "pymdown_extensions-10.15-py3-none-any.whl", hash = "sha256:46e99bb272612b0de3b7e7caf6da8dd5f4ca5212c0b273feb9304e236c484e5f"}, + {file = "pymdown_extensions-10.15.tar.gz", hash = "sha256:0e5994e32155f4b03504f939e501b981d306daf7ec2aa1cd2eb6bd300784f8f7"}, +] + +[package.dependencies] +markdown = ">=3.6" +pyyaml = "*" + +[package.extras] +extra = ["pygments (>=2.19.1)"] + +[[package]] +name = "pyparsing" +version = "3.1.4" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" +optional = false +python-versions = ">=3.6.8" +groups = ["main", "dev"] +files = [ + {file = "pyparsing-3.1.4-py3-none-any.whl", hash = "sha256:a6a7ee4235a3f944aa1fa2249307708f893fe5717dc603503c6c7969c070fb7c"}, + {file = "pyparsing-3.1.4.tar.gz", hash = "sha256:f86ec8d1a83f11977c9a6ea7598e8c27fc5cddfa5b07ea2241edbbde1d7bc032"}, +] +markers = {main = "extra == \"all\""} + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + +[[package]] +name = "pytest" +version = "7.4.4" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.7" +groups = ["dev"] +files = [ + {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, + {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=0.12,<2.0" +tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} + +[package.extras] +testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "pytest-asyncio" +version = "0.23.8" +description = "Pytest support for asyncio" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "pytest_asyncio-0.23.8-py3-none-any.whl", hash = "sha256:50265d892689a5faefb84df80819d1ecef566eb3549cf915dfb33569359d1ce2"}, + {file = "pytest_asyncio-0.23.8.tar.gz", hash = "sha256:759b10b33a6dc61cce40a8bd5205e302978bbbcc00e279a8b61d9a6a3c82e4d3"}, +] + +[package.dependencies] +pytest = ">=7.0.0,<9" + +[package.extras] +docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] +testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"] + +[[package]] +name = "pytest-cov" +version = "4.1.0" +description = "Pytest plugin for measuring coverage." +optional = false +python-versions = ">=3.7" +groups = ["dev"] +files = [ + {file = "pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6"}, + {file = "pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a"}, +] + +[package.dependencies] +coverage = {version = ">=5.2.1", extras = ["toml"]} +pytest = ">=4.6" + +[package.extras] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] + +[[package]] +name = "pytest-deadfixtures" +version = "2.2.1" +description = "A simple plugin to list unused fixtures in pytest" +optional = false +python-versions = "*" +groups = ["dev"] +files = [ + {file = "pytest-deadfixtures-2.2.1.tar.gz", hash = "sha256:ca15938a4e8330993ccec9c6c847383d88b3cd574729530647dc6b492daa9c1e"}, + {file = "pytest_deadfixtures-2.2.1-py2.py3-none-any.whl", hash = "sha256:db71533f2d9456227084e00a1231e732973e299ccb7c37ab92e95032ab6c083e"}, +] + +[package.dependencies] +pytest = ">=3.0.0" + +[[package]] +name = "pytest-freezegun" +version = "0.4.2" +description = "Wrap tests with fixtures in freeze_time" +optional = false +python-versions = "*" +groups = ["dev"] +files = [ + {file = "pytest-freezegun-0.4.2.zip", hash = "sha256:19c82d5633751bf3ec92caa481fb5cffaac1787bd485f0df6436fd6242176949"}, + {file = "pytest_freezegun-0.4.2-py2.py3-none-any.whl", hash = "sha256:5318a6bfb8ba4b709c8471c94d0033113877b3ee02da5bfcd917c1889cde99a7"}, +] + +[package.dependencies] +freezegun = ">0.3" +pytest = ">=3.0.0" + +[[package]] +name = "pytest-mock" +version = "3.14.1" +description = "Thin-wrapper around the mock package for easier use with pytest" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "pytest_mock-3.14.1-py3-none-any.whl", hash = "sha256:178aefcd11307d874b4cd3100344e7e2d888d9791a6a1d9bfe90fbc1b74fd1d0"}, + {file = "pytest_mock-3.14.1.tar.gz", hash = "sha256:159e9edac4c451ce77a5cdb9fc5d1100708d2dd4ba3c3df572f14097351af80e"}, +] + +[package.dependencies] +pytest = ">=6.2.5" + +[package.extras] +dev = ["pre-commit", "pytest-asyncio", "tox"] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main", "dev", "docs"] +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "pytz" +version = "2025.2" +description = "World timezone definitions, modern and historical" +optional = false +python-versions = "*" +groups = ["main", "dev", "docs"] +files = [ + {file = "pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00"}, + {file = "pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3"}, +] +markers = {main = "extra == \"all\"", docs = "python_version < \"3.9\""} + +[[package]] +name = "pyyaml" +version = "6.0.3" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.8" +groups = ["bump", "docs"] +files = [ + {file = "PyYAML-6.0.3-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:c2514fceb77bc5e7a2f7adfaa1feb2fb311607c9cb518dbc378688ec73d8292f"}, + {file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c57bb8c96f6d1808c030b1687b9b5fb476abaa47f0db9c0101f5e9f394e97f4"}, + {file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:efd7b85f94a6f21e4932043973a7ba2613b059c4a000551892ac9f1d11f5baf3"}, + {file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22ba7cfcad58ef3ecddc7ed1db3409af68d023b7f940da23c6c2a1890976eda6"}, + {file = "PyYAML-6.0.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:6344df0d5755a2c9a276d4473ae6b90647e216ab4757f8426893b5dd2ac3f369"}, + {file = "PyYAML-6.0.3-cp38-cp38-win32.whl", hash = "sha256:3ff07ec89bae51176c0549bc4c63aa6202991da2d9a6129d7aef7f1407d3f295"}, + {file = "PyYAML-6.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:5cf4e27da7e3fbed4d6c3d8e797387aaad68102272f8f9752883bc32d61cb87b"}, + {file = "pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b"}, + {file = "pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956"}, + {file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8"}, + {file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198"}, + {file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b"}, + {file = "pyyaml-6.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0"}, + {file = "pyyaml-6.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69"}, + {file = "pyyaml-6.0.3-cp310-cp310-win32.whl", hash = "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e"}, + {file = "pyyaml-6.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c"}, + {file = "pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e"}, + {file = "pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824"}, + {file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c"}, + {file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00"}, + {file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d"}, + {file = "pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a"}, + {file = "pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4"}, + {file = "pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b"}, + {file = "pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf"}, + {file = "pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196"}, + {file = "pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0"}, + {file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28"}, + {file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c"}, + {file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc"}, + {file = "pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e"}, + {file = "pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea"}, + {file = "pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5"}, + {file = "pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b"}, + {file = "pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd"}, + {file = "pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8"}, + {file = "pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1"}, + {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c"}, + {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5"}, + {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6"}, + {file = "pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6"}, + {file = "pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be"}, + {file = "pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26"}, + {file = "pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c"}, + {file = "pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb"}, + {file = "pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac"}, + {file = "pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310"}, + {file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7"}, + {file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788"}, + {file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5"}, + {file = "pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764"}, + {file = "pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35"}, + {file = "pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac"}, + {file = "pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3"}, + {file = "pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3"}, + {file = "pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba"}, + {file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c"}, + {file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702"}, + {file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c"}, + {file = "pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065"}, + {file = "pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65"}, + {file = "pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9"}, + {file = "pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b"}, + {file = "pyyaml-6.0.3-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da"}, + {file = "pyyaml-6.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917"}, + {file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9"}, + {file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5"}, + {file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a"}, + {file = "pyyaml-6.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926"}, + {file = "pyyaml-6.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7"}, + {file = "pyyaml-6.0.3-cp39-cp39-win32.whl", hash = "sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0"}, + {file = "pyyaml-6.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007"}, + {file = "pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f"}, +] + +[[package]] +name = "pyyaml-env-tag" +version = "0.1" +description = "A custom YAML tag for referencing environment variables in YAML files. " +optional = false +python-versions = ">=3.6" +groups = ["docs"] +files = [ + {file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"}, + {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, +] + +[package.dependencies] +pyyaml = "*" + +[[package]] +name = "requests" +version = "2.32.4" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.8" +groups = ["dev", "docs"] +files = [ + {file = "requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c"}, + {file = "requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset_normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "ruff" +version = "0.1.15" +description = "An extremely fast Python linter and code formatter, written in Rust." +optional = false +python-versions = ">=3.7" +groups = ["dev"] +files = [ + {file = "ruff-0.1.15-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:5fe8d54df166ecc24106db7dd6a68d44852d14eb0729ea4672bb4d96c320b7df"}, + {file = "ruff-0.1.15-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6f0bfbb53c4b4de117ac4d6ddfd33aa5fc31beeaa21d23c45c6dd249faf9126f"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0d432aec35bfc0d800d4f70eba26e23a352386be3a6cf157083d18f6f5881c8"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9405fa9ac0e97f35aaddf185a1be194a589424b8713e3b97b762336ec79ff807"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c66ec24fe36841636e814b8f90f572a8c0cb0e54d8b5c2d0e300d28a0d7bffec"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:6f8ad828f01e8dd32cc58bc28375150171d198491fc901f6f98d2a39ba8e3ff5"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86811954eec63e9ea162af0ffa9f8d09088bab51b7438e8b6488b9401863c25e"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fd4025ac5e87d9b80e1f300207eb2fd099ff8200fa2320d7dc066a3f4622dc6b"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b17b93c02cdb6aeb696effecea1095ac93f3884a49a554a9afa76bb125c114c1"}, + {file = "ruff-0.1.15-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ddb87643be40f034e97e97f5bc2ef7ce39de20e34608f3f829db727a93fb82c5"}, + {file = "ruff-0.1.15-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:abf4822129ed3a5ce54383d5f0e964e7fef74a41e48eb1dfad404151efc130a2"}, + {file = "ruff-0.1.15-py3-none-musllinux_1_2_i686.whl", hash = "sha256:6c629cf64bacfd136c07c78ac10a54578ec9d1bd2a9d395efbee0935868bf852"}, + {file = "ruff-0.1.15-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1bab866aafb53da39c2cadfb8e1c4550ac5340bb40300083eb8967ba25481447"}, + {file = "ruff-0.1.15-py3-none-win32.whl", hash = "sha256:2417e1cb6e2068389b07e6fa74c306b2810fe3ee3476d5b8a96616633f40d14f"}, + {file = "ruff-0.1.15-py3-none-win_amd64.whl", hash = "sha256:3837ac73d869efc4182d9036b1405ef4c73d9b1f88da2413875e34e0d6919587"}, + {file = "ruff-0.1.15-py3-none-win_arm64.whl", hash = "sha256:9a933dfb1c14ec7a33cceb1e49ec4a16b51ce3c20fd42663198746efc0427360"}, + {file = "ruff-0.1.15.tar.gz", hash = "sha256:f6dfa8c1b21c913c326919056c390966648b680966febcb796cc9d1aaab8564e"}, +] + +[[package]] +name = "sentry-sdk" +version = "2.47.0" +description = "Python client for Sentry (https://sentry.io)" +optional = false +python-versions = ">=3.6" +groups = ["main"] +files = [ + {file = "sentry_sdk-2.47.0-py2.py3-none-any.whl", hash = "sha256:d72f8c61025b7d1d9e52510d03a6247b280094a327dd900d987717a4fce93412"}, + {file = "sentry_sdk-2.47.0.tar.gz", hash = "sha256:8218891d5e41b4ea8d61d2aed62ed10c80e39d9f2959d6f939efbf056857e050"}, +] + +[package.dependencies] +certifi = "*" +urllib3 = ">=1.26.11" + +[package.extras] +aiohttp = ["aiohttp (>=3.5)"] +anthropic = ["anthropic (>=0.16)"] +arq = ["arq (>=0.23)"] +asyncpg = ["asyncpg (>=0.23)"] +beam = ["apache-beam (>=2.12)"] +bottle = ["bottle (>=0.12.13)"] +celery = ["celery (>=3)"] +celery-redbeat = ["celery-redbeat (>=2)"] +chalice = ["chalice (>=1.16.0)"] +clickhouse-driver = ["clickhouse-driver (>=0.2.0)"] +django = ["django (>=1.8)"] +falcon = ["falcon (>=1.4)"] +fastapi = ["fastapi (>=0.79.0)"] +flask = ["blinker (>=1.1)", "flask (>=0.11)", "markupsafe"] +google-genai = ["google-genai (>=1.29.0)"] +grpcio = ["grpcio (>=1.21.1)", "protobuf (>=3.8.0)"] +http2 = ["httpcore[http2] (==1.*)"] +httpx = ["httpx (>=0.16.0)"] +huey = ["huey (>=2)"] +huggingface-hub = ["huggingface_hub (>=0.22)"] +langchain = ["langchain (>=0.0.210)"] +langgraph = ["langgraph (>=0.6.6)"] +launchdarkly = ["launchdarkly-server-sdk (>=9.8.0)"] +litellm = ["litellm (>=1.77.5)"] +litestar = ["litestar (>=2.0.0)"] +loguru = ["loguru (>=0.5)"] +mcp = ["mcp (>=1.15.0)"] +openai = ["openai (>=1.0.0)", "tiktoken (>=0.3.0)"] +openfeature = ["openfeature-sdk (>=0.7.1)"] +opentelemetry = ["opentelemetry-distro (>=0.35b0)"] +opentelemetry-experimental = ["opentelemetry-distro"] +opentelemetry-otlp = ["opentelemetry-distro[otlp] (>=0.35b0)"] +pure-eval = ["asttokens", "executing", "pure_eval"] +pydantic-ai = ["pydantic-ai (>=1.0.0)"] +pymongo = ["pymongo (>=3.1)"] +pyspark = ["pyspark (>=2.4.4)"] +quart = ["blinker (>=1.1)", "quart (>=0.16.1)"] +rq = ["rq (>=0.6)"] +sanic = ["sanic (>=0.8)"] +sqlalchemy = ["sqlalchemy (>=1.2)"] +starlette = ["starlette (>=0.19.1)"] +starlite = ["starlite (>=1.48)"] +statsig = ["statsig (>=0.55.3)"] +tornado = ["tornado (>=6)"] +unleash = ["UnleashClient (>=6.0.1)"] + +[[package]] +name = "setuptools" +version = "75.3.2" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +markers = "python_version < \"3.10\"" +files = [ + {file = "setuptools-75.3.2-py3-none-any.whl", hash = "sha256:90ab613b6583fc02d5369cbca13ea26ea0e182d1df2d943ee9cbe81d4c61add9"}, + {file = "setuptools-75.3.2.tar.gz", hash = "sha256:3c1383e1038b68556a382c1e8ded8887cd20141b0eb5708a6c8d277de49364f5"}, +] + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\"", "ruff (>=0.5.2) ; sys_platform != \"cygwin\""] +core = ["importlib-metadata (>=6) ; python_version < \"3.10\"", "importlib-resources (>=5.10.2) ; python_version < \"3.9\"", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1) ; python_version < \"3.11\"", "wheel (>=0.43.0)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21) ; python_version >= \"3.9\" and sys_platform != \"cygwin\"", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf ; sys_platform != \"cygwin\"", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "ruff (<=0.7.1)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib-metadata (>=7.0.2) ; python_version < \"3.10\"", "jaraco.develop (>=7.21) ; sys_platform != \"cygwin\"", "mypy (==1.12.*)", "pytest-mypy"] + +[[package]] +name = "setuptools" +version = "82.0.1" +description = "Most extensible Python build backend with support for C/C++ extension modules" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +markers = "python_version >= \"3.10\"" +files = [ + {file = "setuptools-82.0.1-py3-none-any.whl", hash = "sha256:a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb"}, + {file = "setuptools-82.0.1.tar.gz", hash = "sha256:7d872682c5d01cfde07da7bccc7b65469d3dca203318515ada1de5eda35efbf9"}, +] + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\"", "ruff (>=0.13.0) ; sys_platform != \"cygwin\""] +core = ["importlib_metadata (>=6) ; python_version < \"3.10\"", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging (>=24.2)", "tomli (>=2.0.1) ; python_version < \"3.11\"", "wheel (>=0.43.0)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21) ; python_version >= \"3.9\" and sys_platform != \"cygwin\"", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf ; sys_platform != \"cygwin\"", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2) ; python_version < \"3.10\"", "jaraco.develop (>=7.21) ; sys_platform != \"cygwin\"", "mypy (==1.18.*)", "pytest-mypy"] + +[[package]] +name = "six" +version = "1.17.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main", "dev", "docs"] +files = [ + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, +] + +[[package]] +name = "stack-data" +version = "0.6.3" +description = "Extract data from python stack frames and tracebacks for informative displays" +optional = false +python-versions = "*" +groups = ["dev"] +files = [ + {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}, + {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}, +] + +[package.dependencies] +asttokens = ">=2.1.0" +executing = ">=1.2.0" +pure-eval = "*" + +[package.extras] +tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] + +[[package]] +name = "termynal" +version = "0.11.1" +description = "A lightweight and modern animated terminal window" +optional = false +python-versions = ">=3.8.1,<4.0.0" +groups = ["docs"] +files = [ + {file = "termynal-0.11.1-py3-none-any.whl", hash = "sha256:553fc58b126a0482b71a442263d33a9b47fb69868a7fdd6cc36dc9f006aab7a2"}, + {file = "termynal-0.11.1.tar.gz", hash = "sha256:ce70d264a649d26365bf72b8cfc5aa2bf903adafebc1027347343779a8695ff0"}, +] + +[package.dependencies] +markdown = "*" + +[package.extras] +mkdocs = ["mkdocs (>=1.4,<2.0)"] + +[[package]] +name = "tokenize-rt" +version = "6.0.0" +description = "A wrapper around the stdlib `tokenize` which roundtrips." +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "tokenize_rt-6.0.0-py2.py3-none-any.whl", hash = "sha256:d4ff7ded2873512938b4f8cbb98c9b07118f01d30ac585a30d7a88353ca36d22"}, + {file = "tokenize_rt-6.0.0.tar.gz", hash = "sha256:b9711bdfc51210211137499b5e355d3de5ec88a85d2025c520cbb921b5194367"}, +] + +[[package]] +name = "tomli" +version = "2.3.0" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +markers = "python_version <= \"3.10\"" +files = [ + {file = "tomli-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:88bd15eb972f3664f5ed4b57c1634a97153b4bac4479dcb6a495f41921eb7f45"}, + {file = "tomli-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:883b1c0d6398a6a9d29b508c331fa56adbcdff647f6ace4dfca0f50e90dfd0ba"}, + {file = "tomli-2.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1381caf13ab9f300e30dd8feadb3de072aeb86f1d34a8569453ff32a7dea4bf"}, + {file = "tomli-2.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a0e285d2649b78c0d9027570d4da3425bdb49830a6156121360b3f8511ea3441"}, + {file = "tomli-2.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a154a9ae14bfcf5d8917a59b51ffd5a3ac1fd149b71b47a3a104ca4edcfa845"}, + {file = "tomli-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:74bf8464ff93e413514fefd2be591c3b0b23231a77f901db1eb30d6f712fc42c"}, + {file = "tomli-2.3.0-cp311-cp311-win32.whl", hash = "sha256:00b5f5d95bbfc7d12f91ad8c593a1659b6387b43f054104cda404be6bda62456"}, + {file = "tomli-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:4dc4ce8483a5d429ab602f111a93a6ab1ed425eae3122032db7e9acf449451be"}, + {file = "tomli-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7d86942e56ded512a594786a5ba0a5e521d02529b3826e7761a05138341a2ac"}, + {file = "tomli-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:73ee0b47d4dad1c5e996e3cd33b8a76a50167ae5f96a2607cbe8cc773506ab22"}, + {file = "tomli-2.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:792262b94d5d0a466afb5bc63c7daa9d75520110971ee269152083270998316f"}, + {file = "tomli-2.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f195fe57ecceac95a66a75ac24d9d5fbc98ef0962e09b2eddec5d39375aae52"}, + {file = "tomli-2.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e31d432427dcbf4d86958c184b9bfd1e96b5b71f8eb17e6d02531f434fd335b8"}, + {file = "tomli-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b0882799624980785240ab732537fcfc372601015c00f7fc367c55308c186f6"}, + {file = "tomli-2.3.0-cp312-cp312-win32.whl", hash = "sha256:ff72b71b5d10d22ecb084d345fc26f42b5143c5533db5e2eaba7d2d335358876"}, + {file = "tomli-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:1cb4ed918939151a03f33d4242ccd0aa5f11b3547d0cf30f7c74a408a5b99878"}, + {file = "tomli-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5192f562738228945d7b13d4930baffda67b69425a7f0da96d360b0a3888136b"}, + {file = "tomli-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:be71c93a63d738597996be9528f4abe628d1adf5e6eb11607bc8fe1a510b5dae"}, + {file = "tomli-2.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4665508bcbac83a31ff8ab08f424b665200c0e1e645d2bd9ab3d3e557b6185b"}, + {file = "tomli-2.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4021923f97266babc6ccab9f5068642a0095faa0a51a246a6a02fccbb3514eaf"}, + {file = "tomli-2.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4ea38c40145a357d513bffad0ed869f13c1773716cf71ccaa83b0fa0cc4e42f"}, + {file = "tomli-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ad805ea85eda330dbad64c7ea7a4556259665bdf9d2672f5dccc740eb9d3ca05"}, + {file = "tomli-2.3.0-cp313-cp313-win32.whl", hash = "sha256:97d5eec30149fd3294270e889b4234023f2c69747e555a27bd708828353ab606"}, + {file = "tomli-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0c95ca56fbe89e065c6ead5b593ee64b84a26fca063b5d71a1122bf26e533999"}, + {file = "tomli-2.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:cebc6fe843e0733ee827a282aca4999b596241195f43b4cc371d64fc6639da9e"}, + {file = "tomli-2.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4c2ef0244c75aba9355561272009d934953817c49f47d768070c3c94355c2aa3"}, + {file = "tomli-2.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c22a8bf253bacc0cf11f35ad9808b6cb75ada2631c2d97c971122583b129afbc"}, + {file = "tomli-2.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0eea8cc5c5e9f89c9b90c4896a8deefc74f518db5927d0e0e8d4a80953d774d0"}, + {file = "tomli-2.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b74a0e59ec5d15127acdabd75ea17726ac4c5178ae51b85bfe39c4f8a278e879"}, + {file = "tomli-2.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b5870b50c9db823c595983571d1296a6ff3e1b88f734a4c8f6fc6188397de005"}, + {file = "tomli-2.3.0-cp314-cp314-win32.whl", hash = "sha256:feb0dacc61170ed7ab602d3d972a58f14ee3ee60494292d384649a3dc38ef463"}, + {file = "tomli-2.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:b273fcbd7fc64dc3600c098e39136522650c49bca95df2d11cf3b626422392c8"}, + {file = "tomli-2.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:940d56ee0410fa17ee1f12b817b37a4d4e4dc4d27340863cc67236c74f582e77"}, + {file = "tomli-2.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f85209946d1fe94416debbb88d00eb92ce9cd5266775424ff81bc959e001acaf"}, + {file = "tomli-2.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a56212bdcce682e56b0aaf79e869ba5d15a6163f88d5451cbde388d48b13f530"}, + {file = "tomli-2.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5f3ffd1e098dfc032d4d3af5c0ac64f6d286d98bc148698356847b80fa4de1b"}, + {file = "tomli-2.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e01decd096b1530d97d5d85cb4dff4af2d8347bd35686654a004f8dea20fc67"}, + {file = "tomli-2.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8a35dd0e643bb2610f156cca8db95d213a90015c11fee76c946aa62b7ae7e02f"}, + {file = "tomli-2.3.0-cp314-cp314t-win32.whl", hash = "sha256:a1f7f282fe248311650081faafa5f4732bdbfef5d45fe3f2e702fbc6f2d496e0"}, + {file = "tomli-2.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:70a251f8d4ba2d9ac2542eecf008b3c8a9fc5c3f9f02c56a9d7952612be2fdba"}, + {file = "tomli-2.3.0-py3-none-any.whl", hash = "sha256:e95b1af3c5b07d9e643909b5abbec77cd9f1217e6d0bca72b0234736b9fb1f1b"}, + {file = "tomli-2.3.0.tar.gz", hash = "sha256:64be704a875d2a59753d80ee8a533c3fe183e3f06807ff7dc2232938ccb01549"}, +] + +[[package]] +name = "tomlkit" +version = "0.12.5" +description = "Style preserving TOML library" +optional = false +python-versions = ">=3.7" +groups = ["bump"] +files = [ + {file = "tomlkit-0.12.5-py3-none-any.whl", hash = "sha256:af914f5a9c59ed9d0762c7b64d3b5d5df007448eb9cd2edc8a46b1eafead172f"}, + {file = "tomlkit-0.12.5.tar.gz", hash = "sha256:eef34fba39834d4d6b73c9ba7f3e4d1c417a4e56f89a7e96e090dd0d24b8fb3c"}, +] + +[[package]] +name = "traitlets" +version = "5.14.3" +description = "Traitlets Python configuration system" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f"}, + {file = "traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7"}, +] + +[package.extras] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] +test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<8.2)", "pytest-mock", "pytest-mypy-testing"] + +[[package]] +name = "types-cachetools" +version = "5.5.0.20240820" +description = "Typing stubs for cachetools" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "types-cachetools-5.5.0.20240820.tar.gz", hash = "sha256:b888ab5c1a48116f7799cd5004b18474cd82b5463acb5ffb2db2fc9c7b053bc0"}, + {file = "types_cachetools-5.5.0.20240820-py3-none-any.whl", hash = "sha256:efb2ed8bf27a4b9d3ed70d33849f536362603a90b8090a328acf0cd42fda82e2"}, +] + +[[package]] +name = "types-protobuf" +version = "4.25.0.20240417" +description = "Typing stubs for protobuf" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "types-protobuf-4.25.0.20240417.tar.gz", hash = "sha256:c34eff17b9b3a0adb6830622f0f302484e4c089f533a46e3f147568313544352"}, + {file = "types_protobuf-4.25.0.20240417-py3-none-any.whl", hash = "sha256:e9b613227c2127e3d4881d75d93c93b4d6fd97b5f6a099a0b654a05351c8685d"}, +] + +[[package]] +name = "types-python-dateutil" +version = "2.9.0.20241206" +description = "Typing stubs for python-dateutil" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "types_python_dateutil-2.9.0.20241206-py3-none-any.whl", hash = "sha256:e248a4bc70a486d3e3ec84d0dc30eec3a5f979d6e7ee4123ae043eedbb987f53"}, + {file = "types_python_dateutil-2.9.0.20241206.tar.gz", hash = "sha256:18f493414c26ffba692a72369fea7a154c502646301ebfe3d56a04b3767284cb"}, +] + +[[package]] +name = "types-pyyaml" +version = "6.0.12.20241230" +description = "Typing stubs for PyYAML" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "types_PyYAML-6.0.12.20241230-py3-none-any.whl", hash = "sha256:fa4d32565219b68e6dee5f67534c722e53c00d1cfc09c435ef04d7353e1e96e6"}, + {file = "types_pyyaml-6.0.12.20241230.tar.gz", hash = "sha256:7f07622dbd34bb9c8b264fe860a17e0efcad00d50b5f27e93984909d9363498c"}, +] + +[[package]] +name = "types-requests" +version = "2.32.0.20241016" +description = "Typing stubs for requests" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "types-requests-2.32.0.20241016.tar.gz", hash = "sha256:0d9cad2f27515d0e3e3da7134a1b6f28fb97129d86b867f24d9c726452634d95"}, + {file = "types_requests-2.32.0.20241016-py3-none-any.whl", hash = "sha256:4195d62d6d3e043a4eaaf08ff8a62184584d2e8684e9d2aa178c7915a7da3747"}, +] + +[package.dependencies] +urllib3 = ">=2" + +[[package]] +name = "typing-extensions" +version = "4.13.2" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev", "docs"] +files = [ + {file = "typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c"}, + {file = "typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef"}, +] +markers = {main = "python_version >= \"3.10\"", docs = "python_version < \"3.10\""} + +[[package]] +name = "tzdata" +version = "2025.2" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +groups = ["main", "dev"] +files = [ + {file = "tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8"}, + {file = "tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9"}, +] +markers = {main = "python_version >= \"3.11\" and extra == \"all\"", dev = "python_version >= \"3.11\""} + +[[package]] +name = "urllib3" +version = "2.2.3" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +groups = ["main", "dev", "docs"] +files = [ + {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, + {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "watchdog" +version = "4.0.2" +description = "Filesystem events monitoring" +optional = false +python-versions = ">=3.8" +groups = ["docs"] +files = [ + {file = "watchdog-4.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ede7f010f2239b97cc79e6cb3c249e72962404ae3865860855d5cbe708b0fd22"}, + {file = "watchdog-4.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a2cffa171445b0efa0726c561eca9a27d00a1f2b83846dbd5a4f639c4f8ca8e1"}, + {file = "watchdog-4.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c50f148b31b03fbadd6d0b5980e38b558046b127dc483e5e4505fcef250f9503"}, + {file = "watchdog-4.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7c7d4bf585ad501c5f6c980e7be9c4f15604c7cc150e942d82083b31a7548930"}, + {file = "watchdog-4.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:914285126ad0b6eb2258bbbcb7b288d9dfd655ae88fa28945be05a7b475a800b"}, + {file = "watchdog-4.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:984306dc4720da5498b16fc037b36ac443816125a3705dfde4fd90652d8028ef"}, + {file = "watchdog-4.0.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1cdcfd8142f604630deef34722d695fb455d04ab7cfe9963055df1fc69e6727a"}, + {file = "watchdog-4.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d7ab624ff2f663f98cd03c8b7eedc09375a911794dfea6bf2a359fcc266bff29"}, + {file = "watchdog-4.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:132937547a716027bd5714383dfc40dc66c26769f1ce8a72a859d6a48f371f3a"}, + {file = "watchdog-4.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:cd67c7df93eb58f360c43802acc945fa8da70c675b6fa37a241e17ca698ca49b"}, + {file = "watchdog-4.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bcfd02377be80ef3b6bc4ce481ef3959640458d6feaae0bd43dd90a43da90a7d"}, + {file = "watchdog-4.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:980b71510f59c884d684b3663d46e7a14b457c9611c481e5cef08f4dd022eed7"}, + {file = "watchdog-4.0.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:aa160781cafff2719b663c8a506156e9289d111d80f3387cf3af49cedee1f040"}, + {file = "watchdog-4.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f6ee8dedd255087bc7fe82adf046f0b75479b989185fb0bdf9a98b612170eac7"}, + {file = "watchdog-4.0.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0b4359067d30d5b864e09c8597b112fe0a0a59321a0f331498b013fb097406b4"}, + {file = "watchdog-4.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:770eef5372f146997638d737c9a3c597a3b41037cfbc5c41538fc27c09c3a3f9"}, + {file = "watchdog-4.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:eeea812f38536a0aa859972d50c76e37f4456474b02bd93674d1947cf1e39578"}, + {file = "watchdog-4.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b2c45f6e1e57ebb4687690c05bc3a2c1fb6ab260550c4290b8abb1335e0fd08b"}, + {file = "watchdog-4.0.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:10b6683df70d340ac3279eff0b2766813f00f35a1d37515d2c99959ada8f05fa"}, + {file = "watchdog-4.0.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:f7c739888c20f99824f7aa9d31ac8a97353e22d0c0e54703a547a218f6637eb3"}, + {file = "watchdog-4.0.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c100d09ac72a8a08ddbf0629ddfa0b8ee41740f9051429baa8e31bb903ad7508"}, + {file = "watchdog-4.0.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:f5315a8c8dd6dd9425b974515081fc0aadca1d1d61e078d2246509fd756141ee"}, + {file = "watchdog-4.0.2-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:2d468028a77b42cc685ed694a7a550a8d1771bb05193ba7b24006b8241a571a1"}, + {file = "watchdog-4.0.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:f15edcae3830ff20e55d1f4e743e92970c847bcddc8b7509bcd172aa04de506e"}, + {file = "watchdog-4.0.2-py3-none-manylinux2014_aarch64.whl", hash = "sha256:936acba76d636f70db8f3c66e76aa6cb5136a936fc2a5088b9ce1c7a3508fc83"}, + {file = "watchdog-4.0.2-py3-none-manylinux2014_armv7l.whl", hash = "sha256:e252f8ca942a870f38cf785aef420285431311652d871409a64e2a0a52a2174c"}, + {file = "watchdog-4.0.2-py3-none-manylinux2014_i686.whl", hash = "sha256:0e83619a2d5d436a7e58a1aea957a3c1ccbf9782c43c0b4fed80580e5e4acd1a"}, + {file = "watchdog-4.0.2-py3-none-manylinux2014_ppc64.whl", hash = "sha256:88456d65f207b39f1981bf772e473799fcdc10801062c36fd5ad9f9d1d463a73"}, + {file = "watchdog-4.0.2-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:32be97f3b75693a93c683787a87a0dc8db98bb84701539954eef991fb35f5fbc"}, + {file = "watchdog-4.0.2-py3-none-manylinux2014_s390x.whl", hash = "sha256:c82253cfc9be68e3e49282831afad2c1f6593af80c0daf1287f6a92657986757"}, + {file = "watchdog-4.0.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:c0b14488bd336c5b1845cee83d3e631a1f8b4e9c5091ec539406e4a324f882d8"}, + {file = "watchdog-4.0.2-py3-none-win32.whl", hash = "sha256:0d8a7e523ef03757a5aa29f591437d64d0d894635f8a50f370fe37f913ce4e19"}, + {file = "watchdog-4.0.2-py3-none-win_amd64.whl", hash = "sha256:c344453ef3bf875a535b0488e3ad28e341adbd5a9ffb0f7d62cefacc8824ef2b"}, + {file = "watchdog-4.0.2-py3-none-win_ia64.whl", hash = "sha256:baececaa8edff42cd16558a639a9b0ddf425f93d892e8392a56bf904f5eff22c"}, + {file = "watchdog-4.0.2.tar.gz", hash = "sha256:b4dfbb6c49221be4535623ea4474a4d6ee0a9cef4a80b20c28db4d858b64e270"}, +] + +[package.extras] +watchmedo = ["PyYAML (>=3.10)"] + +[[package]] +name = "wcmatch" +version = "10.0" +description = "Wildcard/glob file name matcher." +optional = false +python-versions = ">=3.8" +groups = ["docs"] +files = [ + {file = "wcmatch-10.0-py3-none-any.whl", hash = "sha256:0dd927072d03c0a6527a20d2e6ad5ba8d0380e60870c383bc533b71744df7b7a"}, + {file = "wcmatch-10.0.tar.gz", hash = "sha256:e72f0de09bba6a04e0de70937b0cf06e55f36f37b3deb422dfaf854b867b840a"}, +] + +[package.dependencies] +bracex = ">=2.1.1" + +[[package]] +name = "wcwidth" +version = "0.2.14" +description = "Measures the displayed width of unicode strings in a terminal" +optional = false +python-versions = ">=3.6" +groups = ["dev"] +files = [ + {file = "wcwidth-0.2.14-py2.py3-none-any.whl", hash = "sha256:a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1"}, + {file = "wcwidth-0.2.14.tar.gz", hash = "sha256:4d478375d31bc5395a3c55c40ccdf3354688364cd61c4f6adacaa9215d0b3605"}, +] + +[[package]] +name = "zipp" +version = "3.20.2" +description = "Backport of pathlib-compatible object wrapper for zip files" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev", "docs"] +files = [ + {file = "zipp-3.20.2-py3-none-any.whl", hash = "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350"}, + {file = "zipp-3.20.2.tar.gz", hash = "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29"}, +] +markers = {main = "python_version < \"3.10\" and extra == \"all\"", dev = "python_version < \"3.10\"", docs = "python_version < \"3.10\""} + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["big-O", "importlib-resources ; python_version < \"3.9\"", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] +type = ["pytest-mypy"] + +[extras] +all = ["matplotlib", "matplotlib", "mplfinance", "numpy", "numpy", "pandas", "pandas"] + +[metadata] +lock-version = "2.1" +python-versions = "^3.8.1" +content-hash = "e472a71694b006f36a22e42d5cb363501cbb0c82538ee9cfb3bb038e8c722f5f" diff --git a/invest-python-master/protos/t_tech/invest/grpc/common.proto b/invest-python-master/protos/t_tech/invest/grpc/common.proto new file mode 100644 index 0000000..f011101 --- /dev/null +++ b/invest-python-master/protos/t_tech/invest/grpc/common.proto @@ -0,0 +1,144 @@ +syntax = "proto3"; + +package tinkoff.public.invest.api.contract.v1; + +option go_package = "./;investapi"; +option java_package = "ru.tinkoff.piapi.contract.v1"; +option java_multiple_files = true; +option csharp_namespace = "Tinkoff.InvestApi.V1"; +option objc_class_prefix = "TIAPI"; +option php_namespace = "Tinkoff\\Invest\\V1"; + +import "google/protobuf/timestamp.proto"; + +//Тип инструмента. +enum InstrumentType { + INSTRUMENT_TYPE_UNSPECIFIED = 0; + INSTRUMENT_TYPE_BOND = 1; //Облигация. + INSTRUMENT_TYPE_SHARE = 2; //Акция. + INSTRUMENT_TYPE_CURRENCY = 3; //Валюта. + INSTRUMENT_TYPE_ETF = 4; //Exchange-traded fund. Фонд. + INSTRUMENT_TYPE_FUTURES = 5; //Фьючерс. + INSTRUMENT_TYPE_SP = 6; //Структурная нота. + INSTRUMENT_TYPE_OPTION = 7; //Опцион. + INSTRUMENT_TYPE_CLEARING_CERTIFICATE = 8; //Clearing certificate. + INSTRUMENT_TYPE_INDEX = 9; //Индекс. + INSTRUMENT_TYPE_COMMODITY = 10; //Товар. + INSTRUMENT_TYPE_DFA = 11; //Цифровой актив. +} + +//Статус запрашиваемых инструментов. +enum InstrumentStatus { + INSTRUMENT_STATUS_UNSPECIFIED = 0; //Значение не определено. + INSTRUMENT_STATUS_BASE = 1; //По умолчанию — базовый список инструментов, которыми можно торговать через T-Invest API. Сейчас списки доступных бумаг в API и других интерфейсах совпадают — кроме внебиржевых бумаг, но в будущем списки могут различаться. + INSTRUMENT_STATUS_ALL = 2; //Список всех инструментов. +} + +//Денежная сумма в определенной валюте. +message MoneyValue { + + // Строковый ISO-код валюты. + string currency = 1; + + // Целая часть суммы, может быть отрицательным числом. + int64 units = 2; + + // Дробная часть суммы, может быть отрицательным числом. + int32 nano = 3; +} + +//Котировка — денежная сумма без указания валюты. +message Quotation { + + // Целая часть суммы, может быть отрицательным числом. + int64 units = 1; + + // Дробная часть суммы, может быть отрицательным числом. + int32 nano = 2; +} + +//Режим торгов инструмента +enum SecurityTradingStatus { + SECURITY_TRADING_STATUS_UNSPECIFIED = 0; //Торговый статус не определен. + SECURITY_TRADING_STATUS_NOT_AVAILABLE_FOR_TRADING = 1; //Недоступен для торгов. + SECURITY_TRADING_STATUS_OPENING_PERIOD = 2; //Период открытия торгов. + SECURITY_TRADING_STATUS_CLOSING_PERIOD = 3; //Период закрытия торгов. + SECURITY_TRADING_STATUS_BREAK_IN_TRADING = 4; //Перерыв в торговле. + SECURITY_TRADING_STATUS_NORMAL_TRADING = 5; //Нормальная торговля. + SECURITY_TRADING_STATUS_CLOSING_AUCTION = 6; //Аукцион закрытия. + SECURITY_TRADING_STATUS_DARK_POOL_AUCTION = 7; //Аукцион крупных пакетов. + SECURITY_TRADING_STATUS_DISCRETE_AUCTION = 8; //Дискретный аукцион. + SECURITY_TRADING_STATUS_OPENING_AUCTION_PERIOD = 9; //Аукцион открытия. + SECURITY_TRADING_STATUS_TRADING_AT_CLOSING_AUCTION_PRICE = 10; //Период торгов по цене аукциона закрытия. + SECURITY_TRADING_STATUS_SESSION_ASSIGNED = 11; //Сессия назначена. + SECURITY_TRADING_STATUS_SESSION_CLOSE = 12; //Сессия закрыта. + SECURITY_TRADING_STATUS_SESSION_OPEN = 13; //Сессия открыта. + SECURITY_TRADING_STATUS_DEALER_NORMAL_TRADING = 14; //Доступна торговля в режиме внутренней ликвидности брокера. + SECURITY_TRADING_STATUS_DEALER_BREAK_IN_TRADING = 15; //Перерыв торговли в режиме внутренней ликвидности брокера. + SECURITY_TRADING_STATUS_DEALER_NOT_AVAILABLE_FOR_TRADING = 16; //Недоступна торговля в режиме внутренней ликвидности брокера. + SECURITY_TRADING_STATUS_STABILIZATION_AUCTION = 17; //Аукцион обновления цен. +} + +message PingRequest { + optional google.protobuf.Timestamp time = 1; //Время формирования запроса. +} + +message PingDelaySettings { + optional int32 ping_delay_ms = 15; //Задержка (пинг) сообщений: 5000–180 000 миллисекунд. Значение по умолчанию — 120 000. +} + +//Проверка активности стрима. +message Ping { + google.protobuf.Timestamp time = 1; //Время проверки. + string stream_id = 2; //Идентификатор соединения. + optional google.protobuf.Timestamp ping_request_time = 4; //Время формирования запроса. +} + +//Тип цены. +enum PriceType { + PRICE_TYPE_UNSPECIFIED = 0; //Значение не определено. + PRICE_TYPE_POINT = 1; //Цена в пунктах (только для фьючерсов и облигаций). + PRICE_TYPE_CURRENCY = 2; //Цена в валюте расчетов по инструменту. +} + +message Page { + int32 limit = 1; //Максимальное число возвращаемых записей. + int32 page_number = 2; //Порядковый номер страницы, начиная с 0. +} + +message PageResponse { + int32 limit = 1; //Максимальное число возвращаемых записей. + int32 page_number = 2; //Порядковый номер страницы, начиная с 0. + int32 total_count = 3; //Общее количество записей. +} + +message ResponseMetadata { + string tracking_id = 42; //Идентификатор трекинга. + google.protobuf.Timestamp server_time = 43; //Серверное время. +} + +message BrandData { + string logo_name = 1; // Логотип инструмента. Имя файла для получения логотипа. + string logo_base_color = 2; // Цвет бренда. + string text_color = 3; // Цвет текста для цвета логотипа бренда. +} + +enum ResultSubscriptionStatus { + RESULT_SUBSCRIPTION_STATUS_UNSPECIFIED = 0; //Статус подписки не определен. + RESULT_SUBSCRIPTION_STATUS_OK = 1; //Подписка успешно установлена. + RESULT_SUBSCRIPTION_STATUS_ERROR = 13; //Ошибка подписки +} + +message ErrorDetail { + string code = 1; //Код ошибки. + string message = 3; //Описание ошибки. +} + +//Реальная площадка исполнения расчетов. +enum RealExchange { + REAL_EXCHANGE_UNSPECIFIED = 0; //Тип не определен. + REAL_EXCHANGE_MOEX = 1; //Московская биржа. + REAL_EXCHANGE_RTS = 2; //Санкт-Петербургская биржа. + REAL_EXCHANGE_OTC = 3; //Внебиржевой инструмент. + REAL_EXCHANGE_DEALER = 4; //Инструмент, торгуемый на площадке брокера. +} diff --git a/invest-python-master/protos/t_tech/invest/grpc/google/api/field_behavior.proto b/invest-python-master/protos/t_tech/invest/grpc/google/api/field_behavior.proto new file mode 100644 index 0000000..1a3a2f2 --- /dev/null +++ b/invest-python-master/protos/t_tech/invest/grpc/google/api/field_behavior.proto @@ -0,0 +1,90 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/protobuf/descriptor.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "FieldBehaviorProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +extend google.protobuf.FieldOptions { + // A designation of a specific field behavior (required, output only, etc.) + // in protobuf messages. + // + // Examples: + // + // string name = 1 [(google.api.field_behavior) = REQUIRED]; + // State state = 1 [(google.api.field_behavior) = OUTPUT_ONLY]; + // google.protobuf.Duration ttl = 1 + // [(google.api.field_behavior) = INPUT_ONLY]; + // google.protobuf.Timestamp expire_time = 1 + // [(google.api.field_behavior) = OUTPUT_ONLY, + // (google.api.field_behavior) = IMMUTABLE]; + repeated google.api.FieldBehavior field_behavior = 1052; +} + +// An indicator of the behavior of a given field (for example, that a field +// is required in requests, or given as output but ignored as input). +// This **does not** change the behavior in protocol buffers itself; it only +// denotes the behavior and may affect how API tooling handles the field. +// +// Note: This enum **may** receive new values in the future. +enum FieldBehavior { + // Conventional default for enums. Do not use this. + FIELD_BEHAVIOR_UNSPECIFIED = 0; + + // Specifically denotes a field as optional. + // While all fields in protocol buffers are optional, this may be specified + // for emphasis if appropriate. + OPTIONAL = 1; + + // Denotes a field as required. + // This indicates that the field **must** be provided as part of the request, + // and failure to do so will cause an error (usually `INVALID_ARGUMENT`). + REQUIRED = 2; + + // Denotes a field as output only. + // This indicates that the field is provided in responses, but including the + // field in a request does nothing (the server *must* ignore it and + // *must not* throw an error as a result of the field's presence). + OUTPUT_ONLY = 3; + + // Denotes a field as input only. + // This indicates that the field is provided in requests, and the + // corresponding field is not included in output. + INPUT_ONLY = 4; + + // Denotes a field as immutable. + // This indicates that the field may be set once in a request to create a + // resource, but may not be changed thereafter. + IMMUTABLE = 5; + + // Denotes that a (repeated) field is an unordered list. + // This indicates that the service may provide the elements of the list + // in any arbitrary order, rather than the order the user originally + // provided. Additionally, the list's order may or may not be stable. + UNORDERED_LIST = 6; + + // Denotes that this field returns a non-empty default value if not set. + // This indicates that if the user provides the empty value in a request, + // a non-empty value will be returned. The user will not be aware of what + // non-empty value to expect. + NON_EMPTY_DEFAULT = 7; +} diff --git a/invest-python-master/protos/t_tech/invest/grpc/instruments.proto b/invest-python-master/protos/t_tech/invest/grpc/instruments.proto new file mode 100644 index 0000000..779942e --- /dev/null +++ b/invest-python-master/protos/t_tech/invest/grpc/instruments.proto @@ -0,0 +1,1698 @@ +syntax = "proto3"; + +package tinkoff.public.invest.api.contract.v1; + +option go_package = "./;investapi"; +option java_package = "ru.tinkoff.piapi.contract.v1"; +option java_multiple_files = true; +option csharp_namespace = "Tinkoff.InvestApi.V1"; +option objc_class_prefix = "TIAPI"; +option php_namespace = "Tinkoff\\Invest\\V1"; + +import "google/protobuf/timestamp.proto"; +import "t_tech/invest/grpc/common.proto"; +import "t_tech/invest/grpc/google/api/field_behavior.proto"; + +service InstrumentsService {/*Методы сервиса предназначены для получения:
1. Информации об инструментах.
2. + Расписания торговых сессий.
3. Календаря выплат купонов по облигациям.
4. + Размера гарантийного обеспечения по фьючерсам.
5. Дивидендов по ценной бумаге.*/ + + //TradingSchedules — расписания торговых площадок + rpc TradingSchedules (TradingSchedulesRequest) returns (TradingSchedulesResponse); + + //BondBy — получить облигацию по ее идентификатору + rpc BondBy (InstrumentRequest) returns (BondResponse); + + //Bonds — список облигаций + rpc Bonds (InstrumentsRequest) returns (BondsResponse); + + //GetBondCoupons — график выплат купонов по облигации + rpc GetBondCoupons (GetBondCouponsRequest) returns (GetBondCouponsResponse); + + //GetBondEvents — события по облигации + rpc GetBondEvents (GetBondEventsRequest) returns (GetBondEventsResponse); + + //CurrencyBy — получить валюту по ее идентификатору + rpc CurrencyBy (InstrumentRequest) returns (CurrencyResponse); + + //Currencies — список валют + rpc Currencies (InstrumentsRequest) returns (CurrenciesResponse); + + //EtfBy — получить инвестиционный фонд по его идентификатору + rpc EtfBy (InstrumentRequest) returns (EtfResponse); + + //Etfs — список инвестиционных фондов + rpc Etfs (InstrumentsRequest) returns (EtfsResponse); + + //FutureBy — получить фьючерс по его идентификатору + rpc FutureBy (InstrumentRequest) returns (FutureResponse); + + //Futures — список фьючерсов + rpc Futures (InstrumentsRequest) returns (FuturesResponse); + + //OptionBy — получить опцион по его идентификатору + rpc OptionBy (InstrumentRequest) returns (OptionResponse); + + //Deprecated Options — список опционов + rpc Options (InstrumentsRequest) returns (OptionsResponse) { + option deprecated = true; + }; + + //OptionsBy — список опционов + rpc OptionsBy (FilterOptionsRequest) returns (OptionsResponse); + + //ShareBy — получить акцию по ее идентификатору + rpc ShareBy (InstrumentRequest) returns (ShareResponse); + + //Shares — список акций + rpc Shares (InstrumentsRequest) returns (SharesResponse); + + //DfaBy — получить цифровой актив по ее идентификатору + rpc DfaBy (InstrumentRequest) returns (DfaResponse); + + //Dfas — список цифровых активов + rpc Dfas (DfasRequest) returns (DfasResponse); + + //Indicatives — индикативные инструменты — индексы, товары и другие + rpc Indicatives(IndicativesRequest) returns (IndicativesResponse); + + //GetAccruedInterests — накопленный купонный доход по облигации + rpc GetAccruedInterests (GetAccruedInterestsRequest) returns (GetAccruedInterestsResponse); + + //GetFuturesMargin — размера гарантийного обеспечения по фьючерсам + rpc GetFuturesMargin (GetFuturesMarginRequest) returns (GetFuturesMarginResponse); + + //GetInstrumentBy — основная информация об инструменте + rpc GetInstrumentBy (InstrumentRequest) returns (InstrumentResponse); + + //GetDividends — события выплаты дивидендов по инструменту + rpc GetDividends (GetDividendsRequest) returns (GetDividendsResponse); + + //GetAssetBy — получить актив по его идентификатору + rpc GetAssetBy (AssetRequest) returns (AssetResponse); + + //GetAssets — список активов + //Метод работает для всех инструментов, кроме срочных — фьючерсов и опционов + rpc GetAssets (AssetsRequest) returns (AssetsResponse); + + //GetFavorites — получить список избранных инструментов + rpc GetFavorites (GetFavoritesRequest) returns (GetFavoritesResponse); + + //EditFavorites — отредактировать список избранных инструментов + rpc EditFavorites (EditFavoritesRequest) returns (EditFavoritesResponse); + + //CreateFavoriteGroup — создать новую группу избранных инструментов + rpc CreateFavoriteGroup (CreateFavoriteGroupRequest) returns (CreateFavoriteGroupResponse); + + //DeleteFavoriteGroup — удалить группу избранных инструментов + rpc DeleteFavoriteGroup (DeleteFavoriteGroupRequest) returns (DeleteFavoriteGroupResponse); + + //GetFavoriteGroups — список групп избранных инструментов + rpc GetFavoriteGroups (GetFavoriteGroupsRequest) returns (GetFavoriteGroupsResponse); + + //GetCountries — список стран + rpc GetCountries (GetCountriesRequest) returns (GetCountriesResponse); + + //FindInstrument — найти инструмент + rpc FindInstrument (FindInstrumentRequest) returns (FindInstrumentResponse); + + //GetBrands — список брендов + rpc GetBrands(GetBrandsRequest) returns (GetBrandsResponse); + + //GetBrandBy — получить бренд по его идентификатору + rpc GetBrandBy(GetBrandRequest) returns (Brand); + + //GetAssetFundamentals — фундаментальные показатели по активу + rpc GetAssetFundamentals(GetAssetFundamentalsRequest) returns (GetAssetFundamentalsResponse); + + //GetAssetReports — расписания выхода отчетностей эмитентов + rpc GetAssetReports(GetAssetReportsRequest) returns (GetAssetReportsResponse); + + //GetConsensusForecasts — мнения аналитиков по инструменту + rpc GetConsensusForecasts(GetConsensusForecastsRequest) returns (GetConsensusForecastsResponse); + + //GetForecastBy — прогнозы инвестдомов по инструменту + rpc GetForecastBy(GetForecastRequest) returns (GetForecastResponse); + + //GetRiskRates — ставки риска по инструменту + rpc GetRiskRates(RiskRatesRequest) returns (RiskRatesResponse); + + //GetInsiderDeals — сделки инсайдеров по инструментам + rpc GetInsiderDeals(GetInsiderDealsRequest) returns (GetInsiderDealsResponse); + + //StructuredNoteBy — получить структурную ноту по ее идентификатору + rpc StructuredNoteBy (InstrumentRequest) returns (StructuredNoteResponse); + + //StructuredNotes — список структурных нот + rpc StructuredNotes(InstrumentsRequest) returns (StructuredNotesResponse); +} + +//Запрос расписания торгов. +message TradingSchedulesRequest { + optional string exchange = 1; //Наименование биржи или расчетного календаря.
Если не передается, возвращается информация по всем доступным торговым площадкам. + optional google.protobuf.Timestamp from = 2; //Начало периода по UTC. + optional google.protobuf.Timestamp to = 3; //Окончание периода по UTC. +} + +//Список торговых площадок. +message TradingSchedulesResponse { + repeated TradingSchedule exchanges = 1; // Список торговых площадок и режимов торгов. +} + +//Данные по торговой площадке. +message TradingSchedule { + string exchange = 1; // Наименование торговой площадки. + repeated TradingDay days = 2; // Массив с торговыми и неторговыми днями. +} + +//Информация о времени торгов. +message TradingDay { + reserved 5, 6; + google.protobuf.Timestamp date = 1; // Дата. + bool is_trading_day = 2; // Признак торгового дня на бирже. + google.protobuf.Timestamp start_time = 3; // Время начала торгов по UTC. + google.protobuf.Timestamp end_time = 4; // Время окончания торгов по UTC. + google.protobuf.Timestamp opening_auction_start_time = 7; // Время начала аукциона открытия по UTC. + google.protobuf.Timestamp closing_auction_end_time = 8; // Время окончания аукциона закрытия по UTC. + google.protobuf.Timestamp evening_opening_auction_start_time = 9; // Время начала аукциона открытия вечерней сессии по UTC. + google.protobuf.Timestamp evening_start_time = 10; // Время начала вечерней сессии по UTC. + google.protobuf.Timestamp evening_end_time = 11; // Время окончания вечерней сессии по UTC. + google.protobuf.Timestamp clearing_start_time = 12; // Время начала основного клиринга по UTC. + google.protobuf.Timestamp clearing_end_time = 13; // Время окончания основного клиринга по UTC. + google.protobuf.Timestamp premarket_start_time = 14; // Время начала премаркета по UTC. + google.protobuf.Timestamp premarket_end_time = 15; // Время окончания премаркета по UTC. + google.protobuf.Timestamp closing_auction_start_time = 16; // Время начала аукциона закрытия по UTC. + google.protobuf.Timestamp opening_auction_end_time = 17; // Время окончания аукциона открытия по UTC. + repeated TradingInterval intervals = 18; // Торговые интервалы. +} + +//Запрос получения инструмента по идентификатору. +message InstrumentRequest { + InstrumentIdType id_type = 1 [(google.api.field_behavior) = REQUIRED]; // Тип идентификатора инструмента. Возможные значения — `figi`, `ticker`. [Подробнее об идентификации инструментов](/invest/intro/intro/faq_identification). + optional string class_code = 2; // Идентификатор `class_code`. Обязательный, если `id_type = ticker`. + string id = 3 [(google.api.field_behavior) = REQUIRED]; // Идентификатор запрашиваемого инструмента. +} + +//Запрос получения инструментов. +message InstrumentsRequest { + optional InstrumentStatus instrument_status = 1; //Статус запрашиваемых инструментов. [Возможные значения](#instrumentstatus). + optional InstrumentExchangeType instrument_exchange = 2; // Тип площадки торговли. [Возможные значения](#instrumentexchangetype). +} +//Параметры фильтрации опционов. +message FilterOptionsRequest { + optional string basic_asset_uid = 1; //Идентификатор базового актива опциона. Обязательный параметр. + optional string basic_asset_position_uid = 2; //Идентификатор позиции базового актива опциона. + optional string basic_instrument_id = 3; //Идентификатор базового инструмента, принимает значение принимает значения figi, instrument_uid или ticker+"_"+classCode. +} + +//Информация об облигации. +message BondResponse { + Bond instrument = 1; // Информация об облигации. +} + +//Список облигаций. +message BondsResponse { + repeated Bond instruments = 1; //Массив облигаций. +} + +//Запрос купонов по облигации. +message GetBondCouponsRequest { + string figi = 1 [deprecated = true]; //FIGI-идентификатор инструмента. + optional google.protobuf.Timestamp from = 2; //Начало запрашиваемого периода по UTC. Фильтрация по `coupon_date` — дата выплаты купона. + optional google.protobuf.Timestamp to = 3; //Окончание запрашиваемого периода по UTC. Фильтрация по `coupon_date` — дата выплаты купона. + string instrument_id = 4 [(google.api.field_behavior) = REQUIRED]; //Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`. +} + +//Купоны по облигации. +message GetBondCouponsResponse { + repeated Coupon events = 1; +} + +//События по облигации. +message GetBondEventsRequest { + optional google.protobuf.Timestamp from = 2; //Начало запрашиваемого периода по UTC. + optional google.protobuf.Timestamp to = 3; //Окончание запрашиваемого периода по UTC. + string instrument_id = 4 [(google.api.field_behavior) = REQUIRED]; //Идентификатор инструмента — `figi` или `instrument_uid`. + EventType type = 5; //Тип события + + enum EventType { + EVENT_TYPE_UNSPECIFIED = 0; //Неопределенное значение. + EVENT_TYPE_CPN = 1; // Купон. + EVENT_TYPE_CALL = 2; // Опцион (оферта). + EVENT_TYPE_MTY = 3;// Погашение. + EVENT_TYPE_CONV = 4; // Конвертация. + } +} + +//Объект передачи информации о событии облигации. +message GetBondEventsResponse { + repeated BondEvent events = 1; + message BondEvent { + string instrument_id = 2; // Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`. + int32 event_number = 3; // Номер события для данного типа события. + google.protobuf.Timestamp event_date = 4; // Дата события. + GetBondEventsRequest.EventType event_type = 5; // Тип события. + Quotation event_total_vol = 6; // Полное количество бумаг, задействованных в событии. + google.protobuf.Timestamp fix_date = 7; // Дата фиксации владельцев для участия в событии. + google.protobuf.Timestamp rate_date = 8; // Дата определения даты или факта события. + google.protobuf.Timestamp default_date = 9; // Дата дефолта, если применимо. + google.protobuf.Timestamp real_pay_date = 10; // Дата реального исполнения обязательства. + google.protobuf.Timestamp pay_date = 11; // Дата выплаты. + MoneyValue pay_one_bond = 12; // Выплата на одну облигацию. + MoneyValue money_flow_val = 13; // Выплаты на все бумаги, задействованные в событии. + string execution = 14; // Признак исполнения. + string operation_type = 15; // Тип операции. + Quotation value = 16; // Стоимость операции — ставка купона, доля номинала, цена выкупа или коэффициент конвертации. + string note = 17; // Примечание. + string convert_to_fin_tool_id = 18; // ID выпуска бумаг, в который произведена конвертация (для конвертаций). + google.protobuf.Timestamp coupon_start_date = 19; // Начало купонного периода. + google.protobuf.Timestamp coupon_end_date = 20; // Окончание купонного периода. + int32 coupon_period = 21; // Купонный период. + Quotation coupon_interest_rate = 22; // Ставка купона, процентов годовых. + } +} + + + +//Объект передачи информации о купоне облигации. +message Coupon { + string figi = 1; //FIGI-идентификатор инструмента. + google.protobuf.Timestamp coupon_date = 2; //Дата выплаты купона. + int64 coupon_number = 3; //Номер купона. + google.protobuf.Timestamp fix_date = 4; //Дата фиксации реестра для выплаты купона — опционально. + MoneyValue pay_one_bond = 5; //Выплата на одну облигацию. + CouponType coupon_type = 6; //Тип купона. + google.protobuf.Timestamp coupon_start_date = 7; //Начало купонного периода. + google.protobuf.Timestamp coupon_end_date = 8; //Окончание купонного периода. + int32 coupon_period = 9; //Купонный период в днях. +} + +//Тип купонов. +enum CouponType { + COUPON_TYPE_UNSPECIFIED = 0; //Неопределенное значение. + COUPON_TYPE_CONSTANT = 1; //Постоянный. + COUPON_TYPE_FLOATING = 2; //Плавающий. + COUPON_TYPE_DISCOUNT = 3; //Дисконт. + COUPON_TYPE_MORTGAGE = 4; //Ипотечный. + COUPON_TYPE_FIX = 5; //Фиксированный. + COUPON_TYPE_VARIABLE = 6; //Переменный. + COUPON_TYPE_OTHER = 7; //Прочее. +} + +//Данные по валюте. +message CurrencyResponse { + Currency instrument = 1; // Информация о валюте. +} + +//Данные по валютам. +message CurrenciesResponse { + repeated Currency instruments = 1; //Массив валют. +} + +//Данные по фонду. +message EtfResponse { + Etf instrument = 1; // Информация о фонде. +} + +//Данные по фондам. +message EtfsResponse { + repeated Etf instruments = 1; //Массив фондов. +} + +//Данные по фьючерсу. +message FutureResponse { + Future instrument = 1; // Информация о фьючерсу. +} + +//Данные по фьючерсам. +message FuturesResponse { + repeated Future instruments = 1; //Массив фьючерсов. +} + +//Данные по опциону. +message OptionResponse { + Option instrument = 1; // Информация по опциону. +} + +//Данные по опционам. +message OptionsResponse { + repeated Option instruments = 1; //Массив данных по опциону. +} + +//Опцион. +message Option { + string uid = 1; //Уникальный идентификатор инструмента. + string position_uid = 2; //Уникальный идентификатор позиции. + string ticker = 3; //Тикер инструмента. + string class_code = 4; //Класс-код. + string basic_asset_position_uid = 5; //Уникальный идентификатор позиции основного инструмента. + + SecurityTradingStatus trading_status = 21; //Текущий режим торгов инструмента. + RealExchange real_exchange = 31; //Реальная площадка исполнения расчетов (биржа). + OptionDirection direction = 41; //Направление опциона. + OptionPaymentType payment_type = 42; //Тип расчетов по опциону. + OptionStyle style = 43; //Стиль опциона. + OptionSettlementType settlement_type = 44; //Способ исполнения опциона. + + string name = 101; //Название инструмента. + string currency = 111; //Валюта. + string settlement_currency = 112; //Валюта, в которой оценивается контракт. + string asset_type = 131; //Тип актива. + string basic_asset = 132; //Основной актив. + string exchange = 141; // Tорговая площадка (секция биржи). + string country_of_risk = 151; //Код страны рисков. + string country_of_risk_name = 152; //Наименование страны рисков. + string sector = 161; //Сектор экономики. + BrandData brand = 162; // Информация о бренде. + + int32 lot = 201; //Количество бумаг в лоте. + Quotation basic_asset_size = 211; //Размер основного актива. + Quotation klong = 221 [deprecated = true]; //Коэффициент ставки риска длинной позиции по клиенту. 2 – клиент со стандартным уровнем риска (КСУР); 1 – клиент с повышенным уровнем риска (КПУР). + Quotation kshort = 222 [deprecated = true]; //Коэффициент ставки риска короткой позиции по клиенту. 2 – клиент со стандартным уровнем риска (КСУР); 1 – клиент с повышенным уровнем риска (КПУР). + Quotation dlong = 223; //Ставка риска начальной маржи для КСУР лонг. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation dshort = 224; //Ставка риска начальной маржи для КСУР шорт. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation dlong_min = 225; //Ставка риска начальной маржи для КПУР лонг. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation dshort_min = 226; //Ставка риска начальной маржи для КПУР шорт. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation min_price_increment = 231; //Минимальный шаг цены. + MoneyValue strike_price = 241; //Цена страйка. + + Quotation dlong_client = 290; //Ставка риска в лонг с учетом текущего уровня риска портфеля клиента. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation dshort_client = 291; //Ставка риска в шорт с учетом текущего уровня риска портфеля клиента. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + + google.protobuf.Timestamp expiration_date = 301; //Дата истечения срока в формате UTC. + google.protobuf.Timestamp first_trade_date = 311; //Дата начала обращения контракта в формате UTC. + google.protobuf.Timestamp last_trade_date = 312; //Дата исполнения в формате UTC. + google.protobuf.Timestamp first_1min_candle_date = 321; //Дата первой минутной свечи в формате UTC. + google.protobuf.Timestamp first_1day_candle_date = 322; //Дата первой дневной свечи в формате UTC. + + bool short_enabled_flag = 401; //Признак доступности для операций шорт. + bool for_iis_flag = 402; //Возможность покупки или продажи на ИИС. + bool otc_flag = 403; //Флаг, используемый ранее для определения внебиржевых инструментов. На данный момент не используется для торгуемых через API инструментов. Может использоваться как фильтр для операций, совершавшихся некоторое время назад на ОТС площадке. + bool buy_available_flag = 404; //Признак доступности для покупки. + bool sell_available_flag = 405; //Признак доступности для продажи. + bool for_qual_investor_flag = 406; //Флаг, отображающий доступность торговли инструментом только для квалифицированных инвесторов. + bool weekend_flag = 407; //Флаг, отображающий доступность торговли инструментом по выходным. + bool blocked_tca_flag = 408; //Флаг заблокированного ТКС. + bool api_trade_available_flag = 409; //Возможность торговать инструментом через API. + repeated string required_tests = 410; //Тесты, которые необходимо пройти клиенту, чтобы совершать сделки по инструменту. +} + +//Тип опциона по направлению сделки. +enum OptionDirection { + OPTION_DIRECTION_UNSPECIFIED = 0; //Тип не определен. + OPTION_DIRECTION_PUT = 1; //Опцион на продажу. + OPTION_DIRECTION_CALL = 2; //Опцион на покупку. +} + +//Тип расчетов по опциону. +enum OptionPaymentType { + OPTION_PAYMENT_TYPE_UNSPECIFIED = 0; //Тип не определен. + OPTION_PAYMENT_TYPE_PREMIUM = 1; //Опционы с использованием премии в расчетах. + OPTION_PAYMENT_TYPE_MARGINAL = 2; //Маржируемые опционы. +} + +//Тип опциона по стилю. +enum OptionStyle { + OPTION_STYLE_UNSPECIFIED = 0; //Тип не определен. + OPTION_STYLE_AMERICAN = 1; //Американский опцион. + OPTION_STYLE_EUROPEAN = 2; //Европейский опцион. +} + +//Тип опциона по способу исполнения. +enum OptionSettlementType { + OPTION_EXECUTION_TYPE_UNSPECIFIED = 0; //Тип не определен. + OPTION_EXECUTION_TYPE_PHYSICAL_DELIVERY = 1; // Поставочный тип опциона. + OPTION_EXECUTION_TYPE_CASH_SETTLEMENT = 2; //Расчетный тип опциона. +} + +//Данные по акции. +message ShareResponse { + Share instrument = 1; // Информация об акции. +} + +//Данные по акциям. +message SharesResponse { + repeated Share instruments = 1; //Массив акций. +} + +//Данные по структурной ноте. +message StructuredNoteResponse { + StructuredNote instrument = 1; // Информация о структурной ноте. +} + +//Данные по структурным нотам. +message StructuredNotesResponse { + repeated StructuredNote instruments = 1; //Массив структурных нот. +} + +//Объект передачи информации об облигации. +message Bond { + string figi = 1; //FIGI-идентификатор инструмента. + string ticker = 2; //Тикер инструмента. + string class_code = 3; //Класс-код (секция торгов). + string isin = 4; //ISIN-идентификатор инструмента. + int32 lot = 5; //Лотность инструмента. Возможно совершение операций только на количества ценной бумаги, кратные параметру `lot`. [Подробнее](./glossary#lot). + string currency = 6; //Валюта расчетов. + + Quotation klong = 7 [deprecated = true]; //Коэффициент ставки риска длинной позиции по клиенту. 2 – клиент со стандартным уровнем риска (КСУР); 1 – клиент с повышенным уровнем риска (КПУР). + Quotation kshort = 8 [deprecated = true]; //Коэффициент ставки риска короткой позиции по клиенту. 2 – клиент со стандартным уровнем риска (КСУР); 1 – клиент с повышенным уровнем риска (КПУР). + Quotation dlong = 9; //Ставка риска начальной маржи для КСУР лонг. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation dshort = 10; //Ставка риска начальной маржи для КСУР шорт. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation dlong_min = 11; // Ставка риска начальной маржи для КПУР лонг. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation dshort_min = 12; //Ставка риска начальной маржи для КПУР шорт. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + bool short_enabled_flag = 13; //Признак доступности для операций в шорт. + string name = 15; //Название инструмента. + string exchange = 16; //Tорговая площадка (секция биржи). + + int32 coupon_quantity_per_year = 17; //Количество выплат по купонам в год. + google.protobuf.Timestamp maturity_date = 18; //Дата погашения облигации по UTC. + MoneyValue nominal = 19; //Номинал облигации. + MoneyValue initial_nominal = 20; //Первоначальный номинал облигации. + + google.protobuf.Timestamp state_reg_date = 21; //Дата выпуска облигации по UTC. + google.protobuf.Timestamp placement_date = 22; //Дата размещения по UTC. + MoneyValue placement_price = 23; //Цена размещения. + MoneyValue aci_value = 24; //Значение НКД (накопленного купонного дохода) на дату. + + string country_of_risk = 25; //Код страны риска — то есть страны, в которой компания ведет основной бизнес. + string country_of_risk_name = 26; //Наименование страны риска — то есть страны, в которой компания ведет основной бизнес. + string sector = 27; //Сектор экономики. + string issue_kind = 28; //Форма выпуска. Возможные значения:
**documentary** — документарная;
**non_documentary** — бездокументарная. + int64 issue_size = 29; //Размер выпуска. + int64 issue_size_plan = 30; //Плановый размер выпуска. + + SecurityTradingStatus trading_status = 31; //Текущий режим торгов инструмента. + bool otc_flag = 32; //Флаг, используемый ранее для определения внебиржевых инструментов. На данный момент не используется для торгуемых через API инструментов. Может использоваться как фильтр для операций, совершавшихся некоторое время назад на ОТС площадке. + bool buy_available_flag = 33; //Признак доступности для покупки. + bool sell_available_flag = 34; //Признак доступности для продажи. + bool floating_coupon_flag = 35; //Признак облигации с плавающим купоном. + bool perpetual_flag = 36; //Признак бессрочной облигации. + bool amortization_flag = 37; //Признак облигации с амортизацией долга. + Quotation min_price_increment = 38; //Шаг цены. + bool api_trade_available_flag = 39; //Параметр указывает на возможность торговать инструментом через API. + + string uid = 40; //Уникальный идентификатор инструмента. + RealExchange real_exchange = 41; //Реальная площадка исполнения расчетов. (биржа) + string position_uid = 42; //Уникальный идентификатор позиции инструмента. + string asset_uid = 43; //Уникальный идентификатор актива. + + repeated string required_tests = 44; //Тесты, которые необходимо пройти клиенту, чтобы совершать сделки по инструменту. + + bool for_iis_flag = 51; //Признак доступности для ИИС. + bool for_qual_investor_flag = 52; //Флаг, отображающий доступность торговли инструментом только для квалифицированных инвесторов. + bool weekend_flag = 53; //Флаг, отображающий доступность торговли инструментом по выходным. + bool blocked_tca_flag = 54; //Флаг заблокированного ТКС. + bool subordinated_flag = 55; //Признак субординированной облигации. + bool liquidity_flag = 56; //Флаг достаточной ликвидности. + google.protobuf.Timestamp first_1min_candle_date = 61; //Дата первой минутной свечи. + google.protobuf.Timestamp first_1day_candle_date = 62; //Дата первой дневной свечи. + RiskLevel risk_level = 63; //Уровень риска. + BrandData brand = 64; // Информация о бренде. + BondType bond_type = 65; // Тип облигации. + google.protobuf.Timestamp call_date = 69; // Дата погашения облигации. + + Quotation dlong_client = 90; //Ставка риска в лонг с учетом текущего уровня риска портфеля клиента. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation dshort_client = 91; //Ставка риска в шорт с учетом текущего уровня риска портфеля клиента. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + +} + +//Объект передачи информации о валюте. +message Currency { + string figi = 1; //FIGI-идентификатор инструмента. + string ticker = 2; //Тикер инструмента. + string class_code = 3; //Класс-код (секция торгов). + string isin = 4; //ISIN-идентификатор инструмента. + int32 lot = 5; //Лотность инструмента. Возможно совершение операций только на количества ценной бумаги, кратные параметру `lot`. [Подробнее](./glossary#lot). + string currency = 6; //Валюта расчетов. + + Quotation klong = 7 [deprecated = true]; //Коэффициент ставки риска длинной позиции по клиенту. 2 – клиент со стандартным уровнем риска (КСУР); 1 – клиент с повышенным уровнем риска (КПУР). + Quotation kshort = 8 [deprecated = true]; //Коэффициент ставки риска короткой позиции по клиенту. 2 – клиент со стандартным уровнем риска (КСУР); 1 – клиент с повышенным уровнем риска (КПУР). + Quotation dlong = 9; //Ставка риска начальной маржи для КСУР лонг. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation dshort = 10; //Ставка риска начальной маржи для КСУР шорт. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation dlong_min = 11; //Ставка риска начальной маржи для КПУР лонг. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation dshort_min = 12; //Ставка риска начальной маржи для КПУР шорт. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + bool short_enabled_flag = 13; //Признак доступности для операций в шорт. + string name = 15; //Название инструмента. + string exchange = 16; //Tорговая площадка (секция биржи). + + MoneyValue nominal = 17; //Номинал. + + string country_of_risk = 18; //Код страны риска — то есть страны, в которой компания ведет основной бизнес. + string country_of_risk_name = 19; //Наименование страны риска — то есть страны, в которой компания ведет основной бизнес. + + SecurityTradingStatus trading_status = 20; //Текущий режим торгов инструмента. + bool otc_flag = 21; //Флаг, используемый ранее для определения внебиржевых инструментов. На данный момент не используется для торгуемых через API инструментов. Может использоваться как фильтр для операций, совершавшихся некоторое время назад на ОТС площадке. + bool buy_available_flag = 22; //Признак доступности для покупки. + bool sell_available_flag = 23; //Признак доступности для продажи. + string iso_currency_name = 24; //Строковый ISO-код валюты. + Quotation min_price_increment = 25; //Шаг цены. + bool api_trade_available_flag = 26; //Параметр указывает на возможность торговать инструментом через API. + + string uid = 27; //Уникальный идентификатор инструмента. + RealExchange real_exchange = 28; //Реальная площадка исполнения расчетов (биржа). + string position_uid = 29; //Уникальный идентификатор позиции инструмента. + + repeated string required_tests = 30; //Тесты, которые необходимо пройти клиенту, чтобы совершать сделки по инструменту. + + string asset_uid = 31; //Уникальный идентификатор актива. + + bool for_iis_flag = 41; //Признак доступности для ИИС. + bool for_qual_investor_flag = 52; //Флаг, отображающий доступность торговли инструментом только для квалифицированных инвесторов. + bool weekend_flag = 53; //Флаг, отображающий доступность торговли инструментом по выходным. + bool blocked_tca_flag = 54; //Флаг заблокированного ТКС. + google.protobuf.Timestamp first_1min_candle_date = 56; //Дата первой минутной свечи. + google.protobuf.Timestamp first_1day_candle_date = 57; //Дата первой дневной свечи. + BrandData brand = 60; // Информация о бренде. + + Quotation dlong_client = 90; //Ставка риска в лонг с учетом текущего уровня риска портфеля клиента. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation dshort_client = 91; //Ставка риска в шорт с учетом текущего уровня риска портфеля клиента. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + +} + +//Объект передачи информации об инвестиционном фонде. +message Etf { + string figi = 1; //FIGI-идентификатор инструмента. + string ticker = 2; //Тикер инструмента. + string class_code = 3; //Класс-код (секция торгов). + string isin = 4; //ISIN-идентификатор инструмента. + int32 lot = 5; //Лотность инструмента. Возможно совершение операций только на количества ценной бумаги, кратные параметру `lot`. [Подробнее](./glossary#lot). + string currency = 6; //Валюта расчетов. + + Quotation klong = 7 [deprecated = true]; //Коэффициент ставки риска длинной позиции по клиенту. 2 – клиент со стандартным уровнем риска (КСУР); 1 – клиент с повышенным уровнем риска (КПУР). + Quotation kshort = 8 [deprecated = true]; //Коэффициент ставки риска короткой позиции по клиенту. 2 – клиент со стандартным уровнем риска (КСУР); 1 – клиент с повышенным уровнем риска (КПУР). + Quotation dlong = 9; //Ставка риска начальной маржи для КСУР лонг. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation dshort = 10; //Ставка риска начальной маржи для КСУР шорт. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation dlong_min = 11; //Ставка риска начальной маржи для КПУР лонг. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation dshort_min = 12; //Ставка риска начальной маржи для КПУР шорт. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + bool short_enabled_flag = 13; //Признак доступности для операций в шорт. + string name = 15; //Название инструмента. + string exchange = 16; //Tорговая площадка (секция биржи). + + Quotation fixed_commission = 17; //Размер фиксированной комиссии фонда. + string focus_type = 18; //Возможные значения:
**equity** — акции;
**fixed_income** — облигации;
**mixed_allocation** — смешанный;
**money_market** — денежный рынок;
**real_estate** — недвижимость;
**commodity** — товары;
**specialty** — специальный;
**private_equity** — private equity;
**alternative_investment** — альтернативные инвестиции. + google.protobuf.Timestamp released_date = 19; //Дата выпуска по UTC. + Quotation num_shares = 20; //Количество паев фонда в обращении. + + string country_of_risk = 21; //Код страны риска — то есть страны, в которой компания ведет основной бизнес. + string country_of_risk_name = 22; //Наименование страны риска — то есть страны, в которой компания ведет основной бизнес. + string sector = 23; //Сектор экономики. + string rebalancing_freq = 24; //Частота ребалансировки. + + SecurityTradingStatus trading_status = 25; //Текущий режим торгов инструмента. + bool otc_flag = 26; //Флаг, используемый ранее для определения внебиржевых инструментов. На данный момент не используется для торгуемых через API инструментов. Может использоваться как фильтр для операций, совершавшихся некоторое время назад на ОТС площадке. + bool buy_available_flag = 27; //Признак доступности для покупки. + bool sell_available_flag = 28; //Признак доступности для продажи. + Quotation min_price_increment = 29; //Шаг цены. + bool api_trade_available_flag = 30; //Параметр указывает на возможность торговать инструментом через API. + + string uid = 31; //Уникальный идентификатор инструмента. + RealExchange real_exchange = 32; //Реальная площадка исполнения расчетов (биржа). + string position_uid = 33; //Уникальный идентификатор позиции инструмента. + string asset_uid = 34; //Уникальный идентификатор актива. + InstrumentExchangeType instrument_exchange = 35; //Тип площадки торговли. + + repeated string required_tests = 36; //Тесты, которые необходимо пройти клиенту, чтобы совершать сделки по инструменту. + + bool for_iis_flag = 41; //Признак доступности для ИИС. + bool for_qual_investor_flag = 42; //Флаг, отображающий доступность торговли инструментом только для квалифицированных инвесторов. + bool weekend_flag = 43; //ФлагФлаг, отображающий доступность торговли инструментом по выходным. + bool blocked_tca_flag = 44; //Флаг заблокированного ТКС. + bool liquidity_flag = 45; //Флаг достаточной ликвидности. + google.protobuf.Timestamp first_1min_candle_date = 56; //Дата первой минутной свечи. + google.protobuf.Timestamp first_1day_candle_date = 57; //Дата первой дневной свечи. + BrandData brand = 60; // Информация о бренде. + + Quotation dlong_client = 90; //Ставка риска в лонг с учетом текущего уровня риска портфеля клиента. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation dshort_client = 91; //Ставка риска в шорт с учетом текущего уровня риска портфеля клиента. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + +} + +//Объект передачи информации о фьючерсе. +message Future { + string figi = 1; //FIGI-идентификатор инструмента. + string ticker = 2; //Тикер инструмента. + string class_code = 3; //Класс-код (секция торгов). + int32 lot = 4; //Лотность инструмента. Возможно совершение операций только на количества ценной бумаги, кратные параметру `lot`. [Подробнее](./glossary#lot). + string currency = 5; //Валюта расчетов. + + Quotation klong = 6 [deprecated = true]; //Коэффициент ставки риска длинной позиции по клиенту. 2 – клиент со стандартным уровнем риска (КСУР); 1 – клиент с повышенным уровнем риска (КПУР). + Quotation kshort = 7 [deprecated = true]; //Коэффициент ставки риска короткой позиции по клиенту. 2 – клиент со стандартным уровнем риска (КСУР); 1 – клиент с повышенным уровнем риска (КПУР). + Quotation dlong = 8; //Ставка риска начальной маржи для КСУР лонг. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation dshort = 9; //Ставка риска начальной маржи для КСУР шорт. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation dlong_min = 10; //Ставка риска начальной маржи для КПУР лонг. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation dshort_min = 11; //Ставка риска начальной маржи для КПУР шорт. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + bool short_enabled_flag = 12; //Признак доступности для операций шорт. + string name = 13; //Название инструмента. + string exchange = 14; //Tорговая площадка (секция биржи). + + google.protobuf.Timestamp first_trade_date = 15; //Дата начала обращения контракта по UTC. + google.protobuf.Timestamp last_trade_date = 16; //Дата по UTC, до которой возможно проведение операций с фьючерсом. + string futures_type = 17; //Тип фьючерса. Возможные значения:
**physical_delivery** — физические поставки;
**cash_settlement** — денежный эквивалент. + string asset_type = 18; //Тип актива. Возможные значения:
**commodity** — товар;
**currency** — валюта;
**security** — ценная бумага;
**index** — индекс. + string basic_asset = 19; //Основной актив. + Quotation basic_asset_size = 20; //Размер основного актива. + + string country_of_risk = 21; //Код страны риска — то есть страны, в которой компания ведет основной бизнес. + string country_of_risk_name = 22; //Наименование страны риска — то есть страны, в которой компания ведет основной бизнес. + string sector = 23; //Сектор экономики. + google.protobuf.Timestamp expiration_date = 24; //Дата истечения срока в часов поясе UTC. + + SecurityTradingStatus trading_status = 25; //Текущий режим торгов инструмента. + bool otc_flag = 26; //Флаг, используемый ранее для определения внебиржевых инструментов. На данный момент не используется для торгуемых через API инструментов. Может использоваться как фильтр для операций, совершавшихся некоторое время назад на ОТС площадке. + bool buy_available_flag = 27; //Признак доступности для покупки. + bool sell_available_flag = 28; //Признак доступности для продажи. + Quotation min_price_increment = 29; //Шаг цены. + bool api_trade_available_flag = 30; //Параметр указывает на возможность торговать инструментом через API. + + string uid = 31; //Уникальный идентификатор инструмента. + RealExchange real_exchange = 32; //Реальная площадка исполнения расчетов (биржа). + string position_uid = 33; //Уникальный идентификатор позиции инструмента. + string basic_asset_position_uid = 34; //Уникальный идентификатор позиции основного инструмента. + + repeated string required_tests = 35; //Тесты, которые необходимо пройти клиенту, чтобы совершать сделки по инструменту. + + bool for_iis_flag = 41; //Признак доступности для ИИС. + bool for_qual_investor_flag = 42; //Флаг, отображающий доступность торговли инструментом только для квалифицированных инвесторов. + bool weekend_flag = 43; //Флаг, отображающий доступность торговли инструментом по выходным. + bool blocked_tca_flag = 44; //Флаг заблокированного ТКС. + google.protobuf.Timestamp first_1min_candle_date = 56; //Дата первой минутной свечи. + google.protobuf.Timestamp first_1day_candle_date = 57; //Дата первой дневной свечи. + + MoneyValue initial_margin_on_buy = 61; //Гарантийное обеспечение при покупке. + MoneyValue initial_margin_on_sell = 62; //Гарантийное обеспечение при продаже. + Quotation min_price_increment_amount = 63; //Стоимость шага цены. + BrandData brand = 64; // Информация о бренде. + + Quotation dlong_client = 90; //Ставка риска в лонг с учетом текущего уровня риска портфеля клиента. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation dshort_client = 91; //Ставка риска в шорт с учетом текущего уровня риска портфеля клиента. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). +} + +//Объект передачи информации об акции. +message Share { + string figi = 1; //FIGI-идентификатор инструмента. + string ticker = 2; //Тикер инструмента. + string class_code = 3; //Класс-код (секция торгов). + string isin = 4; //ISIN-идентификатор инструмента. + int32 lot = 5; //Лотность инструмента. Возможно совершение операций только на количества ценной бумаги, кратные параметру `lot`. [Подробнее](./glossary#lot) + string currency = 6; //Валюта расчетов. + + Quotation klong = 7 [deprecated = true]; //Коэффициент ставки риска длинной позиции по клиенту. 2 – клиент со стандартным уровнем риска (КСУР); 1 – клиент с повышенным уровнем риска (КПУР). + Quotation kshort = 8 [deprecated = true]; //Коэффициент ставки риска короткой позиции по клиенту. 2 – клиент со стандартным уровнем риска (КСУР); 1 – клиент с повышенным уровнем риска (КПУР). + Quotation dlong = 9; //Ставка риска начальной маржи для КСУР лонг. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation dshort = 10; //Ставка риска начальной маржи для КСУР шорт. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation dlong_min = 11; //Ставка риска начальной маржи для КПУР лонг. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation dshort_min = 12; //Ставка риска начальной маржи для КПУР шорт. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + bool short_enabled_flag = 13; //Признак доступности для операций в шорт. + string name = 15; //Название инструмента. + string exchange = 16; //Tорговая площадка (секция биржи). + + google.protobuf.Timestamp ipo_date = 17; //Дата IPO акции по UTC. + int64 issue_size = 18; //Размер выпуска. + + string country_of_risk = 19; //Код страны риска — то есть страны, в которой компания ведет основной бизнес. + string country_of_risk_name = 20; //Наименование страны риска — то есть страны, в которой компания ведет основной бизнес. + string sector = 21; //Сектор экономики. + int64 issue_size_plan = 22; //Плановый размер выпуска. + MoneyValue nominal = 23; //Номинал. + + SecurityTradingStatus trading_status = 25; //Текущий режим торгов инструмента. + bool otc_flag = 26; //Флаг, используемый ранее для определения внебиржевых инструментов. На данный момент не используется для торгуемых через API инструментов. Может использоваться как фильтр для операций, совершавшихся некоторое время назад на ОТС площадке. + bool buy_available_flag = 27; //Признак доступности для покупки. + bool sell_available_flag = 28; //Признак доступности для продажи. + bool div_yield_flag = 29; //Признак наличия дивидендной доходности. + ShareType share_type = 30; //Тип акции. Возможные значения — `[ShareType](./instruments#sharetype)`. + Quotation min_price_increment = 31; //Шаг цены. + bool api_trade_available_flag = 32; //Возможность торговать инструментом через API. + + string uid = 33; //Уникальный идентификатор инструмента. + RealExchange real_exchange = 34; //Реальная площадка исполнения расчетов (биржа). + string position_uid = 35; //Уникальный идентификатор позиции инструмента. + string asset_uid = 36; //Уникальный идентификатор актива. + InstrumentExchangeType instrument_exchange = 37; //Тип площадки торговли. + + repeated string required_tests = 38; //Тесты, которые необходимо пройти клиенту, чтобы совершать сделки по инструменту. + + bool for_iis_flag = 46; //Признак доступности для ИИС. + bool for_qual_investor_flag = 47; //Флаг, отображающий доступность торговли инструментом только для квалифицированных инвесторов. + bool weekend_flag = 48; //Флаг, отображающий доступность торговли инструментом по выходным. + bool blocked_tca_flag = 49; //Флаг заблокированного ТКС. + bool liquidity_flag = 50; //Флаг достаточной ликвидности. + google.protobuf.Timestamp first_1min_candle_date = 56; //Дата первой минутной свечи. + google.protobuf.Timestamp first_1day_candle_date = 57; //Дата первой дневной свечи. + BrandData brand = 60; // Информация о бренде. + + Quotation dlong_client = 90; //Ставка риска в лонг с учетом текущего уровня риска портфеля клиента. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation dshort_client = 91; //Ставка риска в шорт с учетом текущего уровня риска портфеля клиента. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). +} + +//Объект передачи информации о структурной ноте. +message StructuredNote { + string uid = 1; //Уникальный идентификатор инструмента. + string figi = 2; //FIGI-идентификатор инструмента. + string ticker = 3; //Тикер инструмента. + string class_code = 4; //Класс-код (секция торгов). + string isin = 5; //ISIN-идентификатор инструмента. + string name = 6; //Название инструмента. + string asset_uid = 7; //Уникальный идентификатор актива. + string position_uid = 8; //Уникальный идентификатор позиции. + Quotation min_price_increment = 9; //Шаг цены. + int32 lot = 10; //Лотность инструмента. + MoneyValue nominal = 11; //Номинал. + string currency = 12; //Валюта расчетов. + google.protobuf.Timestamp maturity_date = 13; //Дата погашения облигации в формате UTC. + google.protobuf.Timestamp placement_date = 14; //Дата размещения в формате UTC. + string issue_kind = 15; //Форма выпуска. + int32 issue_size = 16; //Размер выпуска. + int32 issue_size_plan = 17; //Плановый размер выпуска. + Quotation dlong_client = 18; //Ставка риска клиента по инструменту лонг. + Quotation dshort_client = 19; //Ставка риска клиента по инструменту шорт. + bool short_enabled_flag = 20; //Признак доступности для операций в шорт. + string exchange = 21; //Торговая площадка (секция биржи). + SecurityTradingStatus trading_status = 22; //Текущий режим торгов инструмента. + bool api_trade_available_flag = 23; //Признак доступности торгов по бумаге через API. + bool buy_available_flag = 24; //Признак доступности для покупки. + bool sell_available_flag = 25; //Признак доступности для продажи. + bool limit_order_available_flag = 26; //Признак доступности выставления лимитной заявки по инструменту. + bool market_order_available_flag = 27; //Признак доступности выставления рыночной заявки по инструменту. + bool bestprice_order_available_flag = 28; //Признак доступности выставления bestprice заявки по инструменту. + bool weekend_flag = 29; //Флаг отображающий доступность торговли инструментом по выходным. + bool liquidity_flag = 30; //Флаг достаточной ликвидности. + bool for_iis_flag = 31; //Возможность покупки/продажи на ИИС. + bool for_qual_investor_flag = 32; //Флаг отображающий доступность торговли инструментом только для квалифицированных инвесторов. + bool pawnshop_list_flag = 33; //Признак ФИ, включенного в ломбардный список. + RealExchange real_exchange = 34; //Реальная площадка исполнения расчётов. + google.protobuf.Timestamp first_1min_candle_date = 35; //Дата первой минутной свечи. + google.protobuf.Timestamp first_1day_candle_date = 36; //Дата первой дневной свечи. + string borrow_name = 37; //Название заемщика. + string type = 38; //Тип структурной ноты. + LogicPortfolio logic_portfolio = 39; //Стратегия портфеля. + AssetType asset_type = 40; //Тип базового актива. + repeated BasicAsset basic_assets = 41; //Базовые активы, входящие в ноту. + Quotation safety_barrier = 42; //Барьер сохранности (в процентах). + string coupon_period_base = 43; //Базис расчета НКД. + ObservationPrinciple observation_principle = 44; //Принцип наблюдений. + string observation_frequency = 45; //Частота наблюдений. + google.protobuf.Timestamp initial_price_fixing_date = 46; //Дата фиксации цен базовых активов. + repeated Yield yield = 47; //Доходность по ноте в годовом выражении. + bool coupon_saving_flag = 48; //Признак сохранения купонов. + string sector = 49; //Сектор экономики. + string country_of_risk = 50; //Код страны рисков. + string country_of_risk_name = 51; //Наименование страны рисков. + string logo_name = 52; //Имя файла логотипа эмитента. + repeated string required_tests = 53; //Тесты, которые необходимо пройти клиенту, чтобы совершать покупки по бумаге. + + //Базовый актив. + message BasicAsset { + string uid = 1; //Уникальный идентификатор базового актива. + AssetType type = 2; //Тип базового актива. + Quotation initial_price = 3; //Начальная цена базового актива. + } + + //Доходность. + message Yield { + YieldType type = 1; //Тип доходности. + Quotation value = 2; //Значение доходности. + } + + //Стратегия портфеля. + enum LogicPortfolio { + LOGIC_PORTFOLIO_UNSPECIFIED = 0; //Стратегия портфеля не определена. + LOGIC_PORTFOLIO_VOLATILITY = 1; //Волатильность. + LOGIC_PORTFOLIO_CORRELATION = 2; //Корреляция. + } + + //Принцип наблюдений. + enum ObservationPrinciple { + OBSERVATION_PRINCIPLE_UNSPECIFIED = 0; //Принцип наблюдений не определен. + OBSERVATION_PRINCIPLE_WORST_BASIC_ASSET = 1; //По худшему базовому активу. + OBSERVATION_PRINCIPLE_BEST_BASIC_ASSET = 2; //По лучшему базовому активу. + OBSERVATION_PRINCIPLE_AVERAGE_OF_BASIC_ASSETS = 3; //Среднее значение по базовым активам. + OBSERVATION_PRINCIPLE_SINGLE_BASIC_ASSET_PERFORMANCE = 4; //Динамика актива (только если у ноты один базовый актив). + } + + //Тип доходности. + enum YieldType { + YIELD_TYPE_UNSPECIFIED = 0; //Тип доходности не определен. + YIELD_TYPE_GUARANTED_COUPON = 1; //Гарантированный купон. + YIELD_TYPE_CONDITIONAL_COUPON = 2; //Условный купон. + YIELD_TYPE_PARTICIPATION = 3; //Участие в росте. + } +} + +//Запрос НКД по облигации. +message GetAccruedInterestsRequest { + string figi = 1 [deprecated = true]; //FIGI-идентификатор инструмента. + google.protobuf.Timestamp from = 2 [(google.api.field_behavior) = REQUIRED]; //Начало запрашиваемого периода по UTC. + google.protobuf.Timestamp to = 3 [(google.api.field_behavior) = REQUIRED]; //Окончание запрашиваемого периода по UTC. + string instrument_id = 4 [(google.api.field_behavior) = REQUIRED]; //Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`. +} + +//НКД облигации. +message GetAccruedInterestsResponse { + repeated AccruedInterest accrued_interests = 1; //Массив операций начисления купонов. +} + +//Операция начисления купонов. +message AccruedInterest { + google.protobuf.Timestamp date = 1; //Дата и время выплаты по UTC. + Quotation value = 2; //Величина выплаты. + Quotation value_percent = 3; //Величина выплаты в процентах от номинала. + Quotation nominal = 4; //Номинал облигации. +} + +//Запрос информации о фьючерсе +message GetFuturesMarginRequest { + string figi = 1 [deprecated = true]; // Идентификатор инструмента. + string instrument_id = 4 [(google.api.field_behavior) = REQUIRED]; //Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`. +} + +//Данные по фьючерсу +message GetFuturesMarginResponse { + MoneyValue initial_margin_on_buy = 1; //Гарантийное обеспечение при покупке. + MoneyValue initial_margin_on_sell = 2; //Гарантийное обеспечение при продаже. + Quotation min_price_increment = 3; //Шаг цены. + Quotation min_price_increment_amount = 4; //Стоимость шага цены. +} + +//Тип идентификатора инструмента. [Подробнее об идентификации инструментов](/invest/intro/intro/faq_identification). +enum InstrumentIdType { + INSTRUMENT_ID_UNSPECIFIED = 0; //Значение не определено. + INSTRUMENT_ID_TYPE_FIGI = 1; //FIGI. + INSTRUMENT_ID_TYPE_TICKER = 2; //Ticker. + INSTRUMENT_ID_TYPE_UID = 3; //Уникальный идентификатор. + INSTRUMENT_ID_TYPE_POSITION_UID = 4; //Идентификатор позиции. + INSTRUMENT_ID_TYPE_ID = 5; //Универсальный тип идентификатора инструмента. +} + +//Данные по инструменту. +message InstrumentResponse { + Instrument instrument = 1; // Основная информация об инструменте. +} + +//Объект передачи основной информации об инструменте. +message Instrument { + string figi = 1; //FIGI-идентификатор инструмента. + string ticker = 2; //Тикер инструмента. + string class_code = 3; //Класс-код инструмента. + string isin = 4; //ISIN-идентификатор инструмента. + int32 lot = 5; //Лотность инструмента. Возможно совершение операций только на количества ценной бумаги, кратные параметру `lot`. [Подробнее](./glossary#lot). + string currency = 6; //Валюта расчетов. + + Quotation klong = 7 [deprecated = true]; //Коэффициент ставки риска длинной позиции по клиенту. 2 – клиент со стандартным уровнем риска (КСУР); 1 – клиент с повышенным уровнем риска (КПУР). + Quotation kshort = 8 [deprecated = true]; //Коэффициент ставки риска короткой позиции по клиенту. 2 – клиент со стандартным уровнем риска (КСУР); 1 – клиент с повышенным уровнем риска (КПУР). + Quotation dlong = 9; //Ставка риска начальной маржи для КСУР лонг. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation dshort = 10; //Ставка риска начальной маржи для КСУР шорт. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation dlong_min = 11; //Ставка риска начальной маржи для КПУР лонг. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation dshort_min = 12; //Ставка риска начальной маржи для КПУР шорт. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + bool short_enabled_flag = 13; //Признак доступности для операций в шорт. + string name = 14; //Название инструмента. + string exchange = 15; //Tорговая площадка (секция биржи). + + string country_of_risk = 16; //Код страны риска — то есть страны, в которой компания ведет основной бизнес. + string country_of_risk_name = 17; //Наименование страны риска — то есть страны, в которой компания ведет основной бизнес. + string instrument_type = 18; //Тип инструмента. + + SecurityTradingStatus trading_status = 19; //Текущий режим торгов инструмента. + bool otc_flag = 20; //Флаг, используемый ранее для определения внебиржевых инструментов. На данный момент не используется для торгуемых через API инструментов. Может использоваться как фильтр для операций, совершавшихся некоторое время назад на ОТС площадке. + bool buy_available_flag = 21; //Признак доступности для покупки. + bool sell_available_flag = 22; //Признак доступности для продажи. + Quotation min_price_increment = 23; //Шаг цены. + bool api_trade_available_flag = 24; //Параметр указывает на возможность торговать инструментом через API. + + string uid = 25; //Уникальный идентификатор инструмента. + RealExchange real_exchange = 26; //Реальная площадка исполнения расчетов (биржа). + string position_uid = 27; //Уникальный идентификатор позиции инструмента. + string asset_uid = 28; //Уникальный идентификатор актива. + + repeated string required_tests = 29; //Тесты, которые необходимо пройти клиенту, чтобы совершать сделки по инструменту. + + bool for_iis_flag = 36; //Признак доступности для ИИС. + bool for_qual_investor_flag = 37; //Флаг, отображающий доступность торговли инструментом только для квалифицированных инвесторов. + bool weekend_flag = 38; //Флаг, отображающий доступность торговли инструментом по выходным. + bool blocked_tca_flag = 39; //Флаг заблокированного ТКС. + InstrumentType instrument_kind = 40; //Тип инструмента. + google.protobuf.Timestamp first_1min_candle_date = 56; //Дата первой минутной свечи. + google.protobuf.Timestamp first_1day_candle_date = 57; //Дата первой дневной свечи. + BrandData brand = 60; // Информация о бренде. + + Quotation dlong_client = 490; //Ставка риска в лонг с учетом текущего уровня риска портфеля клиента. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + Quotation dshort_client = 491; //Ставка риска в шорт с учетом текущего уровня риска портфеля клиента. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5). + +} + +//Запрос дивидендов. +message GetDividendsRequest { + string figi = 1 [deprecated = true]; //FIGI-идентификатор инструмента. + optional google.protobuf.Timestamp from = 2; //Начало запрашиваемого периода по UTC. Фильтрация происходит по параметру `record_date` — дата фиксации реестра. + optional google.protobuf.Timestamp to = 3; //Окончание запрашиваемого периода по UTC. Фильтрация происходит по параметру `record_date` — дата фиксации реестра. + string instrument_id = 4 [(google.api.field_behavior) = REQUIRED]; //Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`. +} + +//Дивиденды. +message GetDividendsResponse { + repeated Dividend dividends = 1; +} + +//Информация о выплате. +message Dividend { + MoneyValue dividend_net = 1; //Величина дивиденда на 1 ценную бумагу (включая валюту). + google.protobuf.Timestamp payment_date = 2; //Дата фактических выплат по UTC. + google.protobuf.Timestamp declared_date = 3; //Дата объявления дивидендов по UTC. + google.protobuf.Timestamp last_buy_date = 4; //Последний день (включительно) покупки для получения выплаты по UTC. + string dividend_type = 5; //Тип выплаты. Возможные значения: `Regular Cash` – регулярные выплаты, `Cancelled` – выплата отменена, `Daily Accrual` – ежедневное начисление, `Return of Capital` – возврат капитала, прочие типы выплат. + google.protobuf.Timestamp record_date = 6; //Дата фиксации реестра по UTC. + string regularity = 7; //Регулярность выплаты. Возможные значения: `Annual` – ежегодная, `Semi-Anl` – каждые полгода, прочие типы выплат. + MoneyValue close_price = 8; //Цена закрытия инструмента на момент `ex_dividend_date`. + Quotation yield_value = 9; //Величина доходности. + google.protobuf.Timestamp created_at = 10; //Дата и время создания записи по UTC. +} + +//Тип акций. +enum ShareType { + SHARE_TYPE_UNSPECIFIED = 0; //Значение не определено. + SHARE_TYPE_COMMON = 1; //Обыкновенная. + SHARE_TYPE_PREFERRED = 2; //Привилегированная. + SHARE_TYPE_ADR = 3; //Американские депозитарные расписки. + SHARE_TYPE_GDR = 4; //Глобальные депозитарные расписки. + SHARE_TYPE_MLP = 5; //Товарищество с ограниченной ответственностью. + SHARE_TYPE_NY_REG_SHRS = 6; //Акции из реестра Нью-Йорка. + SHARE_TYPE_CLOSED_END_FUND = 7; //Закрытый инвестиционный фонд. + SHARE_TYPE_REIT = 8; //Траст недвижимости. +} + +//Запрос актива по идентификатору. +message AssetRequest { + string id = 1 [(google.api.field_behavior) = REQUIRED]; //UID-идентификатор актива. +} + +//Данные по активу. +message AssetResponse { + AssetFull asset = 1; //Актив. +} + +//Запрос списка активов. +message AssetsRequest { + optional InstrumentType instrument_type = 1; + optional InstrumentStatus instrument_status = 2; //Статус запрашиваемых инструментов. [Возможные значения](#instrumentstatus). + +} + +//Список активов. +message AssetsResponse { + repeated Asset assets = 1; //Активы. +} + +message AssetFull { + string uid = 1; //Уникальный идентификатор актива. + AssetType type = 2; //Тип актива. + string name = 3; //Наименование актива. + string name_brief = 4; //Короткое наименование актива. + string description = 5; //Описание актива. + google.protobuf.Timestamp deleted_at = 6; //Дата и время удаления актива. + repeated string required_tests = 7; //Тестирование клиентов. + oneof ext { + AssetCurrency currency = 8; //Валюта. Обязательно и заполняется только для `type = ASSET_TYPE_CURRENCY`. + AssetSecurity security = 9; //Ценная бумага. Обязательно и заполняется только для `type = ASSET_TYPE_SECURITY`. + } + string gos_reg_code = 10; //Номер государственной регистрации. + string cfi = 11; //Код CFI. + string code_nsd = 12; //Код НРД инструмента. + string status = 13; //Статус актива. + Brand brand = 14; //Бренд. + google.protobuf.Timestamp updated_at = 15; //Дата и время последнего обновления записи. + string br_code = 16; //Код типа ц.б. по классификации Банка России. + string br_code_name = 17; //Наименование кода типа ц.б. по классификации Банка России. + repeated AssetInstrument instruments = 18; //Массив идентификаторов инструментов. +} + +//Информация об активе. +message Asset { + string uid = 1; //Уникальный идентификатор актива. + AssetType type = 2; //Тип актива. + string name = 3; //Наименование актива. + repeated AssetInstrument instruments = 4; //Массив идентификаторов инструментов. +} + +//Тип актива. +enum AssetType { + ASSET_TYPE_UNSPECIFIED = 0; //Тип не определен. + ASSET_TYPE_CURRENCY = 1; //Валюта. + ASSET_TYPE_COMMODITY = 2; //Товар. + ASSET_TYPE_INDEX = 3; //Индекс. + ASSET_TYPE_SECURITY = 4; //Ценная бумага. +} + +//Валюта. +message AssetCurrency { + string base_currency = 1; //ISO-код валюты. +} + +//Ценная бумага. +message AssetSecurity { + string isin = 1; //ISIN-идентификатор ценной бумаги. + string type = 2; //Тип ценной бумаги. + InstrumentType instrument_kind = 10; //Тип инструмента. + oneof ext { + AssetShare share = 3; //Акция. Заполняется только для акций — тип актива `asset.type = ASSET_TYPE_SECURITY` и `security.type = share`. + AssetBond bond = 4; //Облигация. Заполняется только для облигаций — тип актива `asset.type = ASSET_TYPE_SECURITY` и `security.type = bond`. + AssetStructuredProduct sp = 5; //Структурная нота. Заполняется только для структурных продуктов — тип актива `asset.type = ASSET_TYPE_SECURITY` и `security.type = sp`. + AssetEtf etf = 6; // Фонд. Заполняется только для фондов — тип актива `asset.type = ASSET_TYPE_SECURITY` и `security.type = etf`. + AssetClearingCertificate clearing_certificate = 7; // Клиринговый сертификат участия. Заполняется только для клиринговых сертификатов — тип актива `asset.type = ASSET_TYPE_SECURITY` и security.type = `clearing_certificate`. + } +} + +//Акция. +message AssetShare { + ShareType type = 1; //Тип акции. + Quotation issue_size = 2; //Объем выпуска (шт.). + Quotation nominal = 3; //Номинал. + string nominal_currency = 4; //Валюта номинала. + string primary_index = 5; //Индекс (Bloomberg). + Quotation dividend_rate = 6; //Ставка дивиденда (для привилегированных акций). + string preferred_share_type = 7; //Тип привилегированных акций. + google.protobuf.Timestamp ipo_date = 8; //Дата IPO. + google.protobuf.Timestamp registry_date = 9; //Дата регистрации. + bool div_yield_flag = 10; //Признак наличия дивидендной доходности. + string issue_kind = 11; //Форма выпуска ФИ. + google.protobuf.Timestamp placement_date = 12; //Дата размещения акции. + string repres_isin = 13; //ISIN базового актива. + Quotation issue_size_plan = 14; //Объявленное количество, шт. + Quotation total_float = 15; //Количество акций в свободном обращении. +} + +//Облигация. +message AssetBond { + Quotation current_nominal = 1; //Текущий номинал. + string borrow_name = 2; //Наименование заемщика. + Quotation issue_size = 3; //Объем эмиссии облигации (стоимость). + Quotation nominal = 4 ; //Номинал облигации. + string nominal_currency = 5; //Валюта номинала. + string issue_kind = 6; //Форма выпуска облигации. + string interest_kind = 7; //Форма дохода облигации. + int32 coupon_quantity_per_year = 8; //Количество выплат в год. + bool indexed_nominal_flag = 9; //Признак облигации с индексируемым номиналом. + bool subordinated_flag = 10; //Признак субординированной облигации. + bool collateral_flag = 11; //Признак обеспеченной облигации. + bool tax_free_flag = 12; //Признак показывает, что купоны облигации не облагаются налогом — для mass market. + bool amortization_flag = 13; //Признак облигации с амортизацией долга. + bool floating_coupon_flag = 14; //Признак облигации с плавающим купоном. + bool perpetual_flag = 15; //Признак бессрочной облигации. + google.protobuf.Timestamp maturity_date = 16; //Дата погашения облигации. + string return_condition = 17; //Описание и условия получения дополнительного дохода. + google.protobuf.Timestamp state_reg_date = 18; //Дата выпуска облигации. + google.protobuf.Timestamp placement_date = 19; //Дата размещения облигации. + Quotation placement_price = 20; //Цена размещения облигации. + Quotation issue_size_plan = 21; //Объявленное количество, шт. +} + +//Структурная нота. +message AssetStructuredProduct { + string borrow_name = 1; //Наименование заемщика. + Quotation nominal = 2; //Номинал. + string nominal_currency = 3; //Валюта номинала. + StructuredProductType type = 4; //Тип структурной ноты. + string logic_portfolio = 5; //Стратегия портфеля. + AssetType asset_type = 6; //Тип базового актива. + string basic_asset = 7; //Вид базового актива в зависимости от типа базового актива. + Quotation safety_barrier = 8; //Барьер сохранности в процентах. + google.protobuf.Timestamp maturity_date = 9; //Дата погашения. + Quotation issue_size_plan = 10; //Объявленное количество, шт. + Quotation issue_size = 11; //Объем размещения. + google.protobuf.Timestamp placement_date = 12; //Дата размещения ноты. + string issue_kind = 13; //Форма выпуска. +} + +//Тип структурной ноты. +enum StructuredProductType { + SP_TYPE_UNSPECIFIED = 0; //Тип не определен. + SP_TYPE_DELIVERABLE = 1; //Поставочный. + SP_TYPE_NON_DELIVERABLE = 2; //Беспоставочный. +} + +//Фонд. +message AssetEtf { + Quotation total_expense = 1; //Суммарные расходы фонда в процентах. + Quotation hurdle_rate = 2; //Барьерная ставка доходности, после которой фонд имеет право на perfomance fee — в процентах. + Quotation performance_fee = 3; //Комиссия за успешные результаты фонда в процентах. + Quotation fixed_commission = 4; //Фиксированная комиссия за управление в процентах. + string payment_type = 5; //Тип распределения доходов от выплат по бумагам. + bool watermark_flag = 6; //Признак необходимости выхода фонда в плюс для получения комиссии. + Quotation buy_premium = 7; //Премия (надбавка к цене) при покупке доли в фонде — в процентах. + Quotation sell_discount = 8; //Ставка дисконта (вычет из цены) при продаже доли в фонде — в процентах. + bool rebalancing_flag = 9; //Признак ребалансируемости портфеля фонда. + string rebalancing_freq = 10; //Периодичность ребалансировки. + string management_type = 11; //Тип управления. + string primary_index = 12; //Индекс, который реплицирует (старается копировать) фонд. + string focus_type = 13; //База ETF. + bool leveraged_flag = 14; //Признак использования заемных активов (плечо). + Quotation num_share = 15; //Количество акций в обращении. + bool ucits_flag = 16; //Признак обязательства по отчетности перед регулятором. + google.protobuf.Timestamp released_date = 17; //Дата выпуска. + string description = 18; //Описание фонда. + string primary_index_description = 19; //Описание индекса, за которым следует фонд. + string primary_index_company = 20; //Основные компании, в которые вкладывается фонд. + Quotation index_recovery_period = 21; //Срок восстановления индекса после просадки. + string inav_code = 22; //IVAV-код. + bool div_yield_flag = 23; //Признак наличия дивидендной доходности. + Quotation expense_commission = 24; //Комиссия на покрытие расходов фонда в процентах. + Quotation primary_index_tracking_error = 25; //Ошибка следования за индексом в процентах. + string rebalancing_plan = 26; //Плановая ребалансировка портфеля. + string tax_rate = 27; //Ставки налогообложения дивидендов и купонов. + repeated google.protobuf.Timestamp rebalancing_dates = 28; //Даты ребалансировок. + string issue_kind = 29; //Форма выпуска. + Quotation nominal = 30; //Номинал. + string nominal_currency = 31; //Валюта номинала. +} + +//Клиринговый сертификат участия. +message AssetClearingCertificate { + Quotation nominal = 1; //Номинал. + string nominal_currency = 2; //Валюта номинала. +} + +//Бренд. +message Brand { + string uid = 1; //UID-идентификатор бренда. + string name = 2; //Наименование бренда. + string description = 3; //Описание. + string info = 4; //Информация о бренде. + string company = 5; //Компания. + string sector = 6; //Сектор. + string country_of_risk = 7; //Код страны риска. + string country_of_risk_name = 8; //Наименование страны риска. +} + +//Идентификаторы инструмента. +message AssetInstrument { + string uid = 1; //UID-идентификатор инструмента. + string figi = 2; //FIGI-идентификатор инструмента. + string instrument_type = 3; //Тип инструмента. + string ticker = 4; //Тикер инструмента. + string class_code = 5; //Класс-код (секция торгов). + repeated InstrumentLink links = 6; //Массив связанных инструментов. + InstrumentType instrument_kind = 10; //Тип инструмента. + string position_uid = 11; //ID позиции. +} + +//Связь с другим инструментом. +message InstrumentLink { + string type = 1; //Тип связи. + string instrument_uid = 2; //UID-идентификатор связанного инструмента. +} + +//Запрос списка избранных инструментов, входные параметры не требуются. +message GetFavoritesRequest { + optional string group_id = 1; //Уникальный идентификатор группы. +} + +//В ответ передается список избранных инструментов в качестве массива. +message GetFavoritesResponse { + repeated FavoriteInstrument favorite_instruments = 1; //Массив инструментов. + optional string group_id = 2; //Уникальный идентификатор группы. +} + +//Массив избранных инструментов. +message FavoriteInstrument { + string figi = 1; //FIGI-идентификатор инструмента. + string ticker = 2; //Тикер инструмента. + string class_code = 3; //Класс-код инструмента. + string isin = 4; //ISIN-идентификатор инструмента. + string instrument_type = 11; //Тип инструмента. + string name = 12; //Название инструмента. + string uid = 13; //Уникальный идентификатор инструмента. + bool otc_flag = 16; //Флаг, используемый ранее для определения внебиржевых инструментов. На данный момент не используется для торгуемых через API инструментов. Может использоваться как фильтр для операций, совершавшихся некоторое время назад на ОТС площадке. + bool api_trade_available_flag = 17; //Возможность торговать инструментом через API. + InstrumentType instrument_kind = 18; //Тип инструмента. +} + +//Запрос редактирования списка избранных инструментов. +message EditFavoritesRequest { + repeated EditFavoritesRequestInstrument instruments = 1 [(google.api.field_behavior) = REQUIRED]; //Массив инструментов. + EditFavoritesActionType action_type = 6 [(google.api.field_behavior) = REQUIRED]; //Тип действия со списком. + optional string group_id = 7; //Уникальный идентификатор группы. +} + +//Массив инструментов для редактирования списка избранных инструментов. +message EditFavoritesRequestInstrument { + optional string figi = 1 [deprecated = true]; //FIGI-идентификатор инструмента. + string instrument_id = 2 [(google.api.field_behavior) = REQUIRED]; //Идентификатор инструмента — `figi` или `instrument_uid`. +} + +//Тип действия со списком избранных инструментов. +enum EditFavoritesActionType { + EDIT_FAVORITES_ACTION_TYPE_UNSPECIFIED = 0; //Тип не определен. + EDIT_FAVORITES_ACTION_TYPE_ADD = 1; //Добавить в список. + EDIT_FAVORITES_ACTION_TYPE_DEL = 2; //Удалить из списка. +} + +//Результат редактирования списка избранных инструментов. +message EditFavoritesResponse { + repeated FavoriteInstrument favorite_instruments = 1; //Массив инструментов. + optional string group_id = 2; //Уникальный идентификатор группы. +} + +//Запрос создания новой группы избранных инструментов. +message CreateFavoriteGroupRequest { + string group_name = 1 [(google.api.field_behavior) = REQUIRED]; //Название группы, не более 255 символов. + string group_color = 2 [(google.api.field_behavior) = REQUIRED]; //Цвет группы. Принимает значения в HEX-формате, от "000000" до "FFFFFF" + optional string note = 3; //Описание +} + +message CreateFavoriteGroupResponse { + string group_id = 1; //Уникальный идентификатор группы. + string group_name = 2; //Название группы. +} + +//Запрос удаления избранной группы +message DeleteFavoriteGroupRequest { + string group_id = 1 [(google.api.field_behavior) = REQUIRED]; //Уникальный идентификатор группы. +} + +message DeleteFavoriteGroupResponse { +} + +//Запрос получения списка избранных групп +message GetFavoriteGroupsRequest { + repeated string instrument_id = 1; //Массив идентификаторов инструментов. Принимает значение `figi` или `instrument_uid`. Если в группе будет хотя бы один из инструментов массива, то в ответе у группы вернется признак `containsInstrument = true`. + repeated string excluded_group_id = 2; //Массив идентификаторов групп, которые необходимо исключить из ответа. +} + +//Избранные группы +message GetFavoriteGroupsResponse { + repeated FavoriteGroup groups = 1; //Массив групп избранных списков инструментов. + + //Избранная группа + message FavoriteGroup { + string group_id = 1 [(google.api.field_behavior) = REQUIRED]; //Уникальный идентификатор группы. + string group_name = 2 [(google.api.field_behavior) = REQUIRED]; //Название группы. + string color = 3 [(google.api.field_behavior) = REQUIRED]; //Цвет группы в HEX-формате. + int32 size = 4 [(google.api.field_behavior) = REQUIRED]; //Количество инструментов в группе. + optional bool contains_instrument = 5; //Признак наличия в группе хотя бы одного инструмента из запроса. + } +} + +//Запрос справочника стран. +message GetCountriesRequest {} + +//Справочник стран. +message GetCountriesResponse { + repeated CountryResponse countries = 1; //Массив стран. +} + +//Запрос справочника индексов и товаров +message IndicativesRequest {} + +//Справочник индексов и товаров +message IndicativesResponse { + repeated IndicativeResponse instruments = 1; // Массив инструментов. +}; + +//Индикатив +message IndicativeResponse { + string figi = 1; // FIGI-идентификатор инструмента. + string ticker = 2; // Тикер инструмента. + string class_code = 3; // Класс-код инструмента. + string currency = 4; // Валюта расчетов. + InstrumentType instrument_kind = 10; //Тип инструмента. + string name = 12; // Название инструмента. + string exchange = 13; // Tорговая площадка (секция биржи). + string uid = 14; // Уникальный идентификатор инструмента. + bool buy_available_flag = 404; // Признак доступности для покупки. + bool sell_available_flag = 405; // Признак доступности для продажи. +} + +//Данные о стране. +message CountryResponse { + string alfa_two = 1; //Двухбуквенный код страны. + string alfa_three = 2; //Трехбуквенный код страны. + string name = 3; //Наименование страны. + string name_brief = 4; //Краткое наименование страны. +} + +//Запрос на поиск инструментов. +message FindInstrumentRequest { + string query = 1 [(google.api.field_behavior) = REQUIRED]; //Строка поиска. + optional InstrumentType instrument_kind = 2; //Фильтр по типу инструмента. + optional bool api_trade_available_flag = 3; //Фильтр для отображения только торговых инструментов. +} + +//Результат поиска инструментов. +message FindInstrumentResponse { + repeated InstrumentShort instruments = 1; //Массив инструментов, удовлетворяющих условиям поиска. +} + +//Краткая информация об инструменте. +message InstrumentShort { + string isin = 1; //ISIN инструмента. + string figi = 2; //FIGI инструмента. + string ticker = 3; //Ticker инструмента. + string class_code = 4; //ClassCode инструмента. + string instrument_type = 5; //Тип инструмента. + string name = 6; //Название инструмента. + string uid = 7; //Уникальный идентификатор инструмента. + string position_uid = 8; //Уникальный идентификатор позиции инструмента. + InstrumentType instrument_kind = 10; //Тип инструмента. + bool api_trade_available_flag = 11; //Возможность торговать инструментом через API. + bool for_iis_flag = 12; //Признак доступности для ИИС. + google.protobuf.Timestamp first_1min_candle_date = 26; //Дата первой минутной свечи. + google.protobuf.Timestamp first_1day_candle_date = 27; //Дата первой дневной свечи. + bool for_qual_investor_flag = 28; //Флаг, отображающий доступность торговли инструментом только для квалифицированных инвесторов. + bool weekend_flag = 29; //Флаг, отображающий доступность торговли инструментом по выходным. + bool blocked_tca_flag = 30; //Флаг заблокированного ТКС. + int32 lot = 31; //Количество бумаг в лоте. +} + +//Запрос списка брендов. +message GetBrandsRequest { + Page paging = 1; //Настройки пагинации. +} + +//Запрос бренда. +message GetBrandRequest { + string id = 1 [(google.api.field_behavior) = REQUIRED]; //UID-идентификатор бренда. +} + +//Список брендов. +message GetBrandsResponse { + repeated Brand brands = 1; //Массив брендов. + PageResponse paging = 2; //Данные по пагинации. +} + +//Запрос фундаментальных показателей +message GetAssetFundamentalsRequest { + repeated string assets = 1 [(google.api.field_behavior) = REQUIRED]; //Массив идентификаторов активов, не более 100 шт. +} + +//Фундаментальные показатели +message GetAssetFundamentalsResponse { + repeated StatisticResponse fundamentals = 1; + + //Фундаментальные показатели по активу + message StatisticResponse { + string asset_uid = 1; //Идентификатор актива. + string currency = 2; //Валюта. + double market_capitalization = 3; //Рыночная капитализация. + double high_price_last_52_weeks = 4; //Максимум за год. + double low_price_last_52_weeks = 5; //Минимум за год. + double average_daily_volume_last_10_days = 6; //Средний объем торгов за 10 дней. + double average_daily_volume_last_4_weeks = 7; //Средний объем торгов за месяц. + double beta = 8; + double free_float = 9; //Доля акций в свободном обращении. + double forward_annual_dividend_yield = 10; //Процент форвардной дивидендной доходности по отношению к цене акций. + double shares_outstanding = 11; //Количество акций в обращении. + double revenue_ttm = 12; //Выручка. + double ebitda_ttm = 13; //EBITDA — прибыль до вычета процентов, налогов, износа и амортизации. + double net_income_ttm = 14; //Чистая прибыль. + double eps_ttm = 15; //EPS — величина чистой прибыли компании, которая приходится на каждую обыкновенную акцию. + double diluted_eps_ttm = 16; //EPS компании с допущением, что все конвертируемые ценные бумаги компании были сконвертированы в обыкновенные акции. + double free_cash_flow_ttm = 17; //Свободный денежный поток. + double five_year_annual_revenue_growth_rate = 18; //Среднегодовой рocт выручки за 5 лет. + double three_year_annual_revenue_growth_rate = 19; //Среднегодовой рocт выручки за 3 года. + double pe_ratio_ttm = 20; //Соотношение рыночной капитализации компании к ее чистой прибыли. + double price_to_sales_ttm = 21; //Соотношение рыночной капитализации компании к ее выручке. + double price_to_book_ttm = 22; //Соотношение рыночной капитализации компании к ее балансовой стоимости. + double price_to_free_cash_flow_ttm = 23; //Соотношение рыночной капитализации компании к ее свободному денежному потоку. + double total_enterprise_value_mrq = 24; //Рыночная стоимость компании. + double ev_to_ebitda_mrq = 25; //Соотношение EV и EBITDA. + double net_margin_mrq = 26; //Маржа чистой прибыли. + double net_interest_margin_mrq = 27; //Рентабельность чистой прибыли. + double roe = 28; //Рентабельность собственного капитала. + double roa = 29; //Рентабельность активов. + double roic = 30; //Рентабельность активов. + double total_debt_mrq = 31; //Сумма краткосрочных и долгосрочных обязательств компании. + double total_debt_to_equity_mrq = 32; //Соотношение долга к собственному капиталу. + double total_debt_to_ebitda_mrq = 33; //Total Debt/EBITDA. + double free_cash_flow_to_price = 34; //Отношение свободногоо кэша к стоимости. + double net_debt_to_ebitda = 35; //Отношение чистого долга к EBITDA. + double current_ratio_mrq = 36; //Коэффициент текущей ликвидности. + double fixed_charge_coverage_ratio_fy = 37; //Коэффициент покрытия фиксированных платежей — FCCR. + double dividend_yield_daily_ttm = 38; //Дивидендная доходность за 12 месяцев. + double dividend_rate_ttm = 39; //Выплаченные дивиденды за 12 месяцев. + double dividends_per_share = 40; //Значение дивидендов на акцию. + double five_years_average_dividend_yield = 41; //Средняя дивидендная доходность за 5 лет. + double five_year_annual_dividend_growth_rate = 42; //Среднегодовой рост дивидендов за 5 лет. + double dividend_payout_ratio_fy = 43; //Процент чистой прибыли, уходящий на выплату дивидендов. + double buy_back_ttm = 44; //Деньги, потраченные на обратный выкуп акций. + double one_year_annual_revenue_growth_rate = 45; //Рост выручки за 1 год. + string domicile_indicator_code = 46; //Код страны. + double adr_to_common_share_ratio = 47; //Соотношение депозитарной расписки к акциям. + double number_of_employees = 48; //Количество сотрудников. + google.protobuf.Timestamp ex_dividend_date = 49; + google.protobuf.Timestamp fiscal_period_start_date = 50; //Начало фискального периода. + google.protobuf.Timestamp fiscal_period_end_date = 51; //Окончание фискального периода. + double revenue_change_five_years = 53; //Изменение общего дохода за 5 лет. + double eps_change_five_years = 54; //Изменение EPS за 5 лет. + double ebitda_change_five_years = 55; //Изменение EBIDTA за 5 лет. + double total_debt_change_five_years = 56; //Изменение общей задолжности за 5 лет. + double ev_to_sales = 57; //Отношение EV к выручке. + } + +} + +//Запрос отчетов эмитентов +message GetAssetReportsRequest { + string instrument_id = 1 [(google.api.field_behavior) = REQUIRED]; //Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`. + optional google.protobuf.Timestamp from = 2; //Начало запрашиваемого периода по UTC. + optional google.protobuf.Timestamp to = 3; //Окончание запрашиваемого периода по UTC. +} + +//Отчеты эмитентов +message GetAssetReportsResponse { + repeated GetAssetReportsEvent events = 1; // Массив событий по облигации. + + //Отчет + message GetAssetReportsEvent { + string instrument_id = 1; // Идентификатор инструмента. + google.protobuf.Timestamp report_date = 2; // Дата публикации отчета. + int32 period_year = 3; // Год периода отчета. + int32 period_num = 4; // Номер периода. + AssetReportPeriodType period_type = 5; // Тип отчета. + google.protobuf.Timestamp created_at = 6; // Дата создания записи. + } + + enum AssetReportPeriodType { + PERIOD_TYPE_UNSPECIFIED = 0; // Не указан. + PERIOD_TYPE_QUARTER = 1; // Квартальный. + PERIOD_TYPE_SEMIANNUAL = 2; // Полугодовой. + PERIOD_TYPE_ANNUAL = 3; // Годовой. + } +} + +//Запрос консенсус-прогнозов +message GetConsensusForecastsRequest { + optional Page paging = 1; //Настройки пагинации. +} + +//Консенсус-прогнозы +message GetConsensusForecastsResponse { + repeated ConsensusForecastsItem items = 1; // Массив прогнозов. + PageResponse page = 2; //Данные по пагинации. + + //Прогноз + message ConsensusForecastsItem { + string uid = 1; // UID-идентификатор. + string asset_uid = 2; // UID-идентификатор актива. + google.protobuf.Timestamp created_at = 3; // Дата и время создания записи. + Quotation best_target_price = 4; // Целевая цена на 12 месяцев. + Quotation best_target_low = 5; // Минимальная прогнозная цена. + Quotation best_target_high = 6; // Максимальная прогнозная цена. + int32 total_buy_recommend = 7; // Количество аналитиков рекомендующих покупать. + int32 total_hold_recommend = 8; // Количество аналитиков рекомендующих держать. + int32 total_sell_recommend = 9; // Количество аналитиков рекомендующих продавать. + string currency = 10; // Валюта прогнозов инструмента. + Recommendation consensus = 11; // Консенсус-прогноз. + google.protobuf.Timestamp prognosis_date = 12; // Дата прогноза. + } + +} + +enum Recommendation { + RECOMMENDATION_UNSPECIFIED = 0; // Не определено. + RECOMMENDATION_BUY = 1; // Покупать. + RECOMMENDATION_HOLD = 2; // Держать. + RECOMMENDATION_SELL = 3; // Продавать. +} + +//Запрос прогнозов инвестдомов. +message GetForecastRequest { + string instrument_id = 1; // Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`. +} + +//Прогнозы инвестдомов по инструменту. +message GetForecastResponse { + repeated TargetItem targets = 1; //Массив прогнозов. + ConsensusItem consensus = 2; // Согласованный прогноз. + + //Прогноз + message TargetItem { + string uid = 1; // Уникальный идентификатор инструмента. + string ticker = 2; // Тикер инструмента. + string company = 3; // Название компании, давшей прогноз. + Recommendation recommendation = 4; // Прогноз. + google.protobuf.Timestamp recommendation_date = 5; //Дата прогноза. + string currency = 6; // Валюта. + Quotation current_price = 7; // Текущая цена. + Quotation target_price = 8; // Прогнозируемая цена. + Quotation price_change = 9; // Изменение цены. + Quotation price_change_rel = 10; // Относительное изменение цены. + string show_name = 11; // Наименование инструмента. + } + + //Консенсус-прогноз. + message ConsensusItem { + string uid = 1; // Уникальный идентификатор инструмента. + string ticker = 2; // Тикер инструмента. + Recommendation recommendation = 3; // Прогноз. + string currency = 4; // Валюта. + Quotation current_price = 5; // Текущая цена. + Quotation consensus = 6; // Прогнозируемая цена. + Quotation min_target = 7; // Минимальная цена прогноза. + Quotation max_target = 8; // Максимальная цена прогноза. + Quotation price_change = 9; // Изменение цены. + Quotation price_change_rel = 10; // Относительное изменение цены. + } +} + + +//Запрос ставок риска +message RiskRatesRequest { + repeated string instrument_id = 1; // Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`. +} + + +//Ставки риска +message RiskRatesResponse { + repeated RiskRateResult instrument_risk_rates = 1; + + message RiskRateResult { + string instrument_uid = 1; + optional RiskRate short_risk_rate = 2; // Ставка риска пользователя в шорт + optional RiskRate long_risk_rate = 3; // Ставка риска пользователя в лонг + repeated RiskRate short_risk_rates = 5; //Доступные ставки риска в шорт + repeated RiskRate long_risk_rates = 6; //Доступные ставки риска в лонг + optional string error = 9; // Ошибка. + } + message RiskRate { + string risk_level_code = 2; // Категория риска. + Quotation value = 5; // Значение ставки риска. + } +} + +message TradingInterval { + string type = 1; //Название интервала. + TimeInterval interval = 2; //Интервал. + + message TimeInterval { + google.protobuf.Timestamp start_ts = 1; // Время начала интервала. + google.protobuf.Timestamp end_ts = 2; // Время окончания интервала. + } +} + + +//Запрос сделок по инсайдерам +message GetInsiderDealsRequest { + string instrument_id = 1; // Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`. + int32 limit = 2; // Количество выводимых записей в ответе, не больше 100. + optional string next_cursor = 3; // Курсор. +} + +//сделки инсайдеров +message GetInsiderDealsResponse { + + repeated InsiderDeal insider_deals = 1; // Массив сделок. + optional string next_cursor = 2; // Курсор для получения следующей страницы. + + message InsiderDeal { + int64 trade_id = 1; // Уникальный идентификатор сделки. + TradeDirection direction = 2; // Направление сделки. + string currency = 3; // Валюта сделки. + google.protobuf.Timestamp date = 4; // Дата сделки. + int64 quantity = 5; // Количество. + Quotation price = 6; // Цена. + string instrument_uid = 7; // Уникальный идентификатор инструмента. + string ticker = 8; // Тикер инструмента. + string investor_name = 9; // Имя инвестора. + string investor_position = 10; // Какое отношение покупатель/продавец имеет к эмитенту + float percentage = 11; // Купленный/проданный объём от общего количества ценных бумаг на рынке + bool is_option_execution = 12; //Признак является ли сделка реализацией опциона + google.protobuf.Timestamp disclosure_date = 13; // Дата раскрытия сделки. + } + + enum TradeDirection { + TRADE_DIRECTION_UNSPECIFIED = 0; // Не определено. + TRADE_DIRECTION_BUY = 1; // Покупка. + TRADE_DIRECTION_SELL = 2; // Продажа. + TRADE_DIRECTION_INCREASE = 3; // Увеличение доли. + TRADE_DIRECTION_DECREASE = 4; // Уменьшение доли. + } +} + +//Запрос цифровых активов +message DfasRequest { + +} + +//Цифровой актив +message DfaResponse { + string uid = 1; // Уникальный идентификатор инструмента. + string ticker = 2; // Тикер инструмента. + string name = 3; // Название инструмента. + string position_uid = 4; // Уникальный идентификатор позиции. + Quotation min_price_increment = 5; // Шаг цены. + int32 lot = 6; // Количество лотов. + MoneyValue nominal = 7; // Номинал. + string currency = 8; // Валюта. + google.protobuf.Timestamp maturity_date = 9; // Дата погашения ЦФА в формате UTC. + bool short_enabled_flag = 10; // Признак доступности для операций шорт. + bool api_trade_available_flag = 11; // Признак доступности торгов по бумаге через API. + bool buy_available_flag = 12; // Признак доступности для покупки. + bool sell_available_flag = 13; // Признак доступности для продажи. + bool limit_order_available_flag = 14; // Признак доступности выставления лимитной заявки по инструменту. + bool market_order_available_flag = 15; // Признак доступности выставления рыночной заявки по инструменту. + bool bestprice_order_available_flag = 16; // Признак доступности выставления bestprice заявки по инструменту. + bool for_iis_flag = 17; // Возможность покупки/продажи на ИИС. + bool for_qual_investor_flag = 18; // Флаг отображающий доступность торговли инструментом только для квалифицированных инвесторов. + string type = 19; // Тип актива. Возможные значения: credit_portfolio_dfa, debt_dfa. + repeated BasicAsset basic_assets = 20; // Базовые активы, входящие в ЦФА. + ForecastYield forecast_yield = 21; // Прогнозная доходность смарт-портфелей, в виде интервала в %. + Quotation yield_to_maturity = 22; // Доходность к погашению в %. + Quotation coupon_value = 23; // Величина купона. + int32 coupon_payment_frequency = 24; // Количество выплат в год. + google.protobuf.Timestamp coupon_payment_date = 25; // Дата выплаты купона. + Quotation aci_value = 26; // Значение НКД (накопленного купонного дохода) на дату. + + // Базовый актив. + message BasicAsset { + string uid = 1; // UID базового актива + } + + // Прогнозная доходность смарт-портфелей. + message ForecastYield { + Quotation min_value = 1; // Минимальное значение прогнозной доходности в % + Quotation max_value = 2; // Максимальное значение прогнозной доходности в % + } +} + + // Цифровые активы +message DfasResponse { + repeated DfaResponse instruments = 1; // Массив инструментов. +} + +//Уровень риска облигации. +enum RiskLevel { + RISK_LEVEL_UNSPECIFIED = 0; //Не указан. + RISK_LEVEL_LOW = 1; //Низкий уровень риска. + RISK_LEVEL_MODERATE = 2; //Средний уровень риска. + RISK_LEVEL_HIGH = 3; //Высокий уровень риска. +} + +enum BondType { + BOND_TYPE_UNSPECIFIED = 0; // Тип облигации не определен. + BOND_TYPE_REPLACED = 1; // Замещающая облигация. +} + +// Площадка торговли. +enum InstrumentExchangeType { + INSTRUMENT_EXCHANGE_UNSPECIFIED = 0; // Площадка торговли не определена. + INSTRUMENT_EXCHANGE_DEALER = 1; // Бумага, торгуемая у дилера. +} diff --git a/invest-python-master/protos/t_tech/invest/grpc/marketdata.proto b/invest-python-master/protos/t_tech/invest/grpc/marketdata.proto new file mode 100644 index 0000000..a92fbde --- /dev/null +++ b/invest-python-master/protos/t_tech/invest/grpc/marketdata.proto @@ -0,0 +1,692 @@ +syntax = "proto3"; + +package tinkoff.public.invest.api.contract.v1; + +option go_package = "./;investapi"; +option java_package = "ru.tinkoff.piapi.contract.v1"; +option java_multiple_files = true; +option csharp_namespace = "Tinkoff.InvestApi.V1"; +option objc_class_prefix = "TIAPI"; +option php_namespace = "Tinkoff\\Invest\\V1"; + +import "google/protobuf/timestamp.proto"; +import "t_tech/invest/grpc/common.proto"; +import "t_tech/invest/grpc/google/api/field_behavior.proto"; + +service MarketDataService {//Сервис для получения биржевой информации:
1. Свечи.
2. Стаканы.
3. Торговые статусы.
4. Лента сделок. + + //GetCandles — исторические свечи по инструменту + rpc GetCandles(GetCandlesRequest) returns (GetCandlesResponse); + + //GetLastPrices — цены последних сделок по инструментам + rpc GetLastPrices(GetLastPricesRequest) returns (GetLastPricesResponse); + + //GetOrderBook — стакан по инструменту + rpc GetOrderBook(GetOrderBookRequest) returns (GetOrderBookResponse); + + //GetTradingStatus — статус торгов по инструменту + rpc GetTradingStatus(GetTradingStatusRequest) returns (GetTradingStatusResponse); + + //GetTradingStatuses — статус торгов по инструментам + rpc GetTradingStatuses(GetTradingStatusesRequest) returns (GetTradingStatusesResponse); + + //GetLastTrades — обезличенные сделки + //Обезличенные сделки по инструменту. Метод гарантирует получение информации за последний час. + rpc GetLastTrades(GetLastTradesRequest) returns (GetLastTradesResponse); + + //GetClosePrices — цены закрытия торговой сессии по инструментам + rpc GetClosePrices(GetClosePricesRequest) returns (GetClosePricesResponse); + + //GetTechAnalysis — технические индикаторы по инструменту + rpc GetTechAnalysis(GetTechAnalysisRequest) returns (GetTechAnalysisResponse); + + //GetMarketValues — рыночные данные по инструментам + rpc GetMarketValues(GetMarketValuesRequest) returns (GetMarketValuesResponse); +} + +service MarketDataStreamService { + //MarketDataStream — bidirectional стрим предоставления биржевой информации + rpc MarketDataStream(stream MarketDataRequest) returns (stream MarketDataResponse); + + //MarketDataServerSideStream — server-side стрим предоставления биржевой информации + rpc MarketDataServerSideStream(MarketDataServerSideStreamRequest) returns (stream MarketDataResponse); +} + +//Запрос подписки или отписки на определенные биржевые данные. +message MarketDataRequest { + oneof payload { + SubscribeCandlesRequest subscribe_candles_request = 1; //Запрос подписки на свечи. + SubscribeOrderBookRequest subscribe_order_book_request = 2; //Запрос подписки на стаканы. + SubscribeTradesRequest subscribe_trades_request = 3; //Запрос подписки на ленту обезличенных сделок. + SubscribeInfoRequest subscribe_info_request = 4; //Запрос подписки на торговые статусы инструментов. + SubscribeLastPriceRequest subscribe_last_price_request = 5; //Запрос подписки на цены последних сделок. + GetMySubscriptions get_my_subscriptions = 6; //Запрос своих подписок. + PingRequest ping = 7; //Запрос проверки активности соединения. + PingDelaySettings ping_settings = 15; //Запрос настройки пинга. + } +} + +message MarketDataServerSideStreamRequest { + SubscribeCandlesRequest subscribe_candles_request = 1; //Запрос подписки на свечи. + SubscribeOrderBookRequest subscribe_order_book_request = 2; //Запрос подписки на стаканы. + SubscribeTradesRequest subscribe_trades_request = 3; //Запрос подписки на ленту обезличенных сделок. + SubscribeInfoRequest subscribe_info_request = 4; //Запрос подписки на торговые статусы инструментов. + SubscribeLastPriceRequest subscribe_last_price_request = 5; //Запрос подписки на цены последних сделок. + PingDelaySettings ping_settings = 15; //Запрос настройки пинга. +} + +//Пакет биржевой информации по подписке. +message MarketDataResponse { + oneof payload { + SubscribeCandlesResponse subscribe_candles_response = 1; //Результат подписки на свечи. + SubscribeOrderBookResponse subscribe_order_book_response = 2; //Результат подписки на стаканы. + SubscribeTradesResponse subscribe_trades_response = 3; //Результат подписки на поток обезличенных сделок. + SubscribeInfoResponse subscribe_info_response = 4; //Результат подписки на торговые статусы инструментов. + Candle candle = 5; //Свеча. + Trade trade = 6; //Сделки. + OrderBook orderbook = 7; //Стакан. + TradingStatus trading_status = 8; //Торговый статус. + Ping ping = 9; //Проверка активности стрима. + SubscribeLastPriceResponse subscribe_last_price_response = 10; //Результат подписки на цены последние сделок по инструментам. + LastPrice last_price = 11; //Цена последней сделки. + OpenInterest open_interest = 12; //Открытый интерес. + } +} + +// subscribeCandles | Изменения статуса подписки на свечи. +message SubscribeCandlesRequest { + SubscriptionAction subscription_action = 1; //Изменение статуса подписки. + repeated CandleInstrument instruments = 2; //Массив инструментов для подписки на свечи. + bool waiting_close = 3; //Флаг ожидания закрытия временного интервала для отправки свечи. + optional GetCandlesRequest.CandleSource candle_source_type = 9; //Источник свечей. +} + +//Тип операции со списком подписок. +enum SubscriptionAction { + SUBSCRIPTION_ACTION_UNSPECIFIED = 0; //Статус подписки не определен. + SUBSCRIPTION_ACTION_SUBSCRIBE = 1; //Подписаться. + SUBSCRIPTION_ACTION_UNSUBSCRIBE = 2; //Отписаться. +} + +//Интервал свечи. +enum SubscriptionInterval { + SUBSCRIPTION_INTERVAL_UNSPECIFIED = 0; //Интервал свечи не определен. + SUBSCRIPTION_INTERVAL_ONE_MINUTE = 1; //Минутные свечи. + SUBSCRIPTION_INTERVAL_FIVE_MINUTES = 2; //Пятиминутные свечи. + SUBSCRIPTION_INTERVAL_FIFTEEN_MINUTES = 3; //Пятнадцатиминутные свечи. + SUBSCRIPTION_INTERVAL_ONE_HOUR = 4; //Часовые свечи. + SUBSCRIPTION_INTERVAL_ONE_DAY = 5; //Дневные свечи. + SUBSCRIPTION_INTERVAL_2_MIN = 6; //Двухминутные свечи. + SUBSCRIPTION_INTERVAL_3_MIN = 7; //Трехминутные свечи. + SUBSCRIPTION_INTERVAL_10_MIN = 8; //Десятиминутные свечи. + SUBSCRIPTION_INTERVAL_30_MIN = 9; //Тридцатиминутные свечи. + SUBSCRIPTION_INTERVAL_2_HOUR = 10; //Двухчасовые свечи. + SUBSCRIPTION_INTERVAL_4_HOUR = 11; //Четырехчасовые свечи. + SUBSCRIPTION_INTERVAL_WEEK = 12; //Недельные свечи. + SUBSCRIPTION_INTERVAL_MONTH = 13; //Месячные свечи. +} + +//Запрос изменения статус подписки на свечи. +message CandleInstrument { + string figi = 1 [deprecated = true]; // Deprecated FIGI-идентификатор инструмента. Используйте `instrument_id`. + SubscriptionInterval interval = 2; //Интервал свечей. Двухчасовые и четырехчасовые свечи в стриме отсчитываются с 0:00 по UTC. + string instrument_id = 3; //Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`. +} + +//Результат изменения статус подписки на свечи. +message SubscribeCandlesResponse { + string tracking_id = 1; //Уникальный идентификатор запроса. [Подробнее](./grpc#tracking-id). + repeated CandleSubscription candles_subscriptions = 2; //Массив статусов подписки на свечи. +} + +//Статус подписки на свечи. +message CandleSubscription { + string figi = 1; //FIGI-идентификатор инструмента. + SubscriptionInterval interval = 2; //Интервал свечей. + SubscriptionStatus subscription_status = 3; //Статус подписки. + string instrument_uid = 4; //UID инструмента. + bool waiting_close = 5; //Флаг ожидания закрытия временного интервала для отправки свечи. + string stream_id = 6; //Идентификатор открытого соединения. + string subscription_id = 7; //Идентификатор подписки в формате `UUID`. + SubscriptionAction subscription_action = 8; //Действие подписки. + optional GetCandlesRequest.CandleSource candle_source_type = 9; //Источник свечей. + string ticker = 10; //Тикер инструмента. + string class_code = 11; //Класс-код (секция торгов). +} + +//Результат подписки. +enum SubscriptionStatus { + SUBSCRIPTION_STATUS_UNSPECIFIED = 0; //Статус подписки не определен. + SUBSCRIPTION_STATUS_SUCCESS = 1; //Успешно. + SUBSCRIPTION_STATUS_INSTRUMENT_NOT_FOUND = 2; //Инструмент не найден. + SUBSCRIPTION_STATUS_SUBSCRIPTION_ACTION_IS_INVALID = 3; //Некорректный статус подписки. [Список возможных значений](./marketdata#subscriptionaction). + SUBSCRIPTION_STATUS_DEPTH_IS_INVALID = 4; //Некорректная глубина стакана. Доступные значения — 1, 10, 20, 30, 40, 50. + SUBSCRIPTION_STATUS_INTERVAL_IS_INVALID = 5; //Некорректный интервал свечей. [Список возможных значений](./marketdata#subscriptioninterval). + SUBSCRIPTION_STATUS_LIMIT_IS_EXCEEDED = 6; //Превышен лимит на общее количество подписок в рамках стрима. [Лимитная политика](./limits/). + SUBSCRIPTION_STATUS_INTERNAL_ERROR = 7; //Внутренняя ошибка сервиса. + SUBSCRIPTION_STATUS_TOO_MANY_REQUESTS = 8; //Превышен лимит на количество запросов на подписки в течение установленного отрезка времени. + SUBSCRIPTION_STATUS_SUBSCRIPTION_NOT_FOUND = 9; // Активная подписка не найдена. Ошибка может возникнуть только при отписке от несуществующей подписки. + SUBSCRIPTION_STATUS_SOURCE_IS_INVALID = 10; //Указан некорректный источник. +} + +//Запрос на изменение статуса подписки на стаканы. +message SubscribeOrderBookRequest { + SubscriptionAction subscription_action = 1; //Изменение статуса подписки. + repeated OrderBookInstrument instruments = 2; //Массив инструментов для подписки на стаканы. +} + +//Запрос подписки на стаканы. +message OrderBookInstrument { + string figi = 1 [deprecated = true]; //Deprecated FIGI-идентификатор инструмента. Используйте `instrument_id`. + int32 depth = 2; //Глубина стакана. + string instrument_id = 3; //Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`. + OrderBookType order_book_type = 4; //Тип стакана. Значение по умолчанию — `ORDERBOOK_TYPE_ALL`, стакан биржевой и дилера. +} + +//Результат изменения статуса подписки на стаканы. +message SubscribeOrderBookResponse { + string tracking_id = 1; //Уникальный идентификатор запроса. [Подробнее](./grpc#tracking-id). + repeated OrderBookSubscription order_book_subscriptions = 2; //Массив статусов подписки на стаканы. +} + +//Статус подписки. +message OrderBookSubscription { + string figi = 1; //FIGI-идентификатор инструмента. + int32 depth = 2; //Глубина стакана. + SubscriptionStatus subscription_status = 3; //Статус подписки. + string instrument_uid = 4; //UID инструмента. + string stream_id = 5; //Идентификатор открытого соединения. + string subscription_id = 6; //Идентификатор подписки в формате `UUID`. + OrderBookType order_book_type = 7; //Тип стакана. + SubscriptionAction subscription_action = 8; //Действие подписки. + string ticker = 9; //Тикер инструмента. + string class_code = 10; //Класс-код (секция торгов). +} + +//Типы источников сделок. +enum TradeSourceType { + TRADE_SOURCE_UNSPECIFIED = 0; //Тип источника сделки не определён. + TRADE_SOURCE_EXCHANGE = 1; // Биржевые сделки. + TRADE_SOURCE_DEALER = 2; // Сделки дилера. + TRADE_SOURCE_ALL = 3; // Все сделки. +} + +//Изменение статуса подписки на поток обезличенных сделок. +message SubscribeTradesRequest { + SubscriptionAction subscription_action = 1; //Изменение статуса подписки. + repeated TradeInstrument instruments = 2; //Массив инструментов для подписки на поток обезличенных сделок. + TradeSourceType trade_source = 3; //Тип источника сделок. Значение по умолчанию — `TRADE_SOURCE_ALL`, все сделки. + bool with_open_interest = 4; //Флаг открытого интереса. **true** - в стриме дополнительно передается информация об открытом интересе для фьючерсов +} + +//Запрос подписки на поток обезличенных сделок. +message TradeInstrument { + string figi = 1 [deprecated = true]; //Deprecated FIGI-идентификатор инструмента. Используйте instrument_id`. + string instrument_id = 2; //Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`. +} + +//Результат изменения статуса подписки на поток обезличенных сделок. +message SubscribeTradesResponse { + string tracking_id = 1; //Уникальный идентификатор запроса. [Подробнее](./grpc#tracking-id). + repeated TradeSubscription trade_subscriptions = 2; //Массив статусов подписки на поток сделок. + TradeSourceType trade_source = 3; //Тип источника сделок. +} + +//Статус подписки. +message TradeSubscription { + string figi = 1; //FIGI-идентификатор инструмента. + SubscriptionStatus subscription_status = 2; //Статус подписки. + string instrument_uid = 3; //UID инструмента. + string stream_id = 4; //Идентификатор открытого соединения. + string subscription_id = 5; //Идентификатор подписки в формате UUID. + bool with_open_interest = 6; //Флаг открытого интереса. **true** - в стриме дополнительно передается информация об открытом интересе для фьючерсов + SubscriptionAction subscription_action = 7; //Действие подписки. + string ticker = 8; //Тикер инструмента. + string class_code = 9; //Класс-код (секция торгов). +} + +//Изменение статуса подписки на торговый статус инструмента. +message SubscribeInfoRequest { + SubscriptionAction subscription_action = 1; //Изменение статуса подписки. + repeated InfoInstrument instruments = 2; //Массив инструментов для подписки на торговый статус. +} + +//Запрос подписки на торговый статус. +message InfoInstrument { + string figi = 1 [deprecated = true]; //Deprecated FIGI-идентификатор инструмента. Используйте instrument_id`. + string instrument_id = 2; //Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`. +} + +//Результат изменения статуса подписки на торговый статус. +message SubscribeInfoResponse { + string tracking_id = 1; //Уникальный идентификатор запроса. [Подробнее](./grpc#tracking-id). + repeated InfoSubscription info_subscriptions = 2; //Массив статусов подписки на торговый статус. +} + +//Статус подписки. +message InfoSubscription { + string figi = 1; //FIGI-идентификатор инструмента. + SubscriptionStatus subscription_status = 2; //Статус подписки. + string instrument_uid = 3; //UID инструмента. + string stream_id = 4; //Идентификатор открытого соединения. + string subscription_id = 5; //Идентификатор подписки в формате UUID. + SubscriptionAction subscription_action = 6; //Действие подписки. + string ticker = 7; //Тикер инструмента. + string class_code = 8; //Класс-код (секция торгов). +} + +//Изменение статуса подписки на цену последней сделки по инструменту. +message SubscribeLastPriceRequest { + SubscriptionAction subscription_action = 1; //Изменение статуса подписки. + repeated LastPriceInstrument instruments = 2; //Массив инструментов для подписки на цену последней сделки. +} + +//Запрос подписки на последнюю цену. +message LastPriceInstrument { + string figi = 1 [deprecated = true]; //Deprecated FIGI-идентификатор инструмента. Используйте instrument_id`. + string instrument_id = 2; //Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`. +} + +//Результат изменения статуса подписки на цену последней сделки. +message SubscribeLastPriceResponse { + string tracking_id = 1; //Уникальный идентификатор запроса. [Подробнее](./grpc#tracking-id). + repeated LastPriceSubscription last_price_subscriptions = 2; //Массив статусов подписки на цену последней сделки. +} + +//Статус подписки на цену последней сделки. +message LastPriceSubscription { + string figi = 1; //FIGI-идентификатор инструмента. + SubscriptionStatus subscription_status = 2; //Статус подписки. + string instrument_uid = 3; //UID инструмента. + string stream_id = 4; //Идентификатор открытого соединения. + string subscription_id = 5; //Идентификатор подписки в формате `UUID`. + SubscriptionAction subscription_action = 6; //Действие подписки. + string ticker = 7; //Тикер инструмента. + string class_code = 8; //Класс-код (секция торгов). +} + +//Пакет свечей в рамках стрима. +message Candle { + string figi = 1; //FIGI-идентификатор инструмента. + SubscriptionInterval interval = 2; //Интервал свечи. + Quotation open = 3; //Цена открытия за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15). + Quotation high = 4; //Максимальная цена за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15). + Quotation low = 5; //Минимальная цена за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15). + Quotation close = 6; //Цена закрытия за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15). + int64 volume = 7; //Объем сделок в лотах. + google.protobuf.Timestamp time = 8; //Время начала интервала свечи по UTC. + google.protobuf.Timestamp last_trade_ts = 9; //Время последней сделки, вошедшей в свечу по UTC. + string instrument_uid = 10; //UID инструмента. + string ticker = 11; //Тикер инструмента. + string class_code = 12; //Класс-код (секция торгов). + int64 volume_buy = 13; //Объем торгов на покупку. + int64 volume_sell = 14; //Объём торгов на продажу. + CandleSource candle_source_type = 19; //Источник свечей. +} + +//Пакет стаканов в рамках стрима. +message OrderBook { + string figi = 1; //FIGI-идентификатор инструмента. + int32 depth = 2; //Глубина стакана. + bool is_consistent = 3; //Флаг консистентности стакана. **false** — не все заявки попали в стакан из-за сетевых задержек или нарушения порядка доставки. + repeated Order bids = 4; //Массив предложений. + repeated Order asks = 5; //Массив спроса. + google.protobuf.Timestamp time = 6; //Время формирования стакана в часовом поясе UTC по времени биржи. + Quotation limit_up = 7; //Верхний лимит цены за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15). + Quotation limit_down = 8; //Нижний лимит цены за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15). + string instrument_uid = 9; //UID инструмента. + OrderBookType order_book_type = 10; //Тип стакана. + string ticker = 11; //Тикер инструмента. + string class_code = 12; //Класс-код (секция торгов). +} + +//Массив предложений/спроса. +message Order { + Quotation price = 1; //Цена за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15). + int64 quantity = 2; //Количество в лотах. +} + +//Информация о сделке. +message Trade { + string figi = 1; //FIGI-идентификатор инструмента. + TradeDirection direction = 2; //Направление сделки. + Quotation price = 3; //Цена за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15). + int64 quantity = 4; //Количество лотов. + google.protobuf.Timestamp time = 5; //Время сделки в часовом поясе UTC по времени биржи. + string instrument_uid = 6; //UID инструмента. + TradeSourceType trade_source = 7; //Тип источника сделки. + string ticker = 8; //Тикер инструмента. + string class_code = 9; //Класс-код (секция торгов). +} + +//Направление сделки. +enum TradeDirection { + TRADE_DIRECTION_UNSPECIFIED = 0; //Направление сделки не определено. + TRADE_DIRECTION_BUY = 1; //Покупка. + TRADE_DIRECTION_SELL = 2; //Продажа. +} + +//Пакет изменения торгового статуса. +message TradingStatus { + string figi = 1; //FIGI-идентификатор инструмента. + SecurityTradingStatus trading_status = 2; //Статус торговли инструментом. + google.protobuf.Timestamp time = 3; //Время изменения торгового статуса по UTC. + bool limit_order_available_flag = 4; //Признак доступности выставления лимитной заявки по инструменту. + bool market_order_available_flag = 5; //Признак доступности выставления рыночной заявки по инструменту. + string instrument_uid = 6; //UID инструмента. + string ticker = 7; //Тикер инструмента. + string class_code = 8; //Класс-код (секция торгов). +} + +//Запрос исторических свечей. +message GetCandlesRequest { + optional string figi = 1 [deprecated = true]; //Deprecated FIGI-идентификатор инструмента. Используйте `instrument_id`. + google.protobuf.Timestamp from = 2 [(google.api.field_behavior) = REQUIRED]; //Начало запрашиваемого периода по UTC. + google.protobuf.Timestamp to = 3 [(google.api.field_behavior) = REQUIRED]; //Окончание запрашиваемого периода по UTC. + CandleInterval interval = 4 [(google.api.field_behavior) = REQUIRED]; //Интервал запрошенных свечей. + optional string instrument_id = 5; //Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`. + optional CandleSource candle_source_type = 7; //Тип источника свечи. + optional int32 limit = 10; //Максимальное количество свечей в ответе. + + enum CandleSource { + CANDLE_SOURCE_UNSPECIFIED = 0; //Все свечи. + CANDLE_SOURCE_EXCHANGE = 1; //Биржевые свечи. + CANDLE_SOURCE_INCLUDE_WEEKEND = 3; //Все свечи с учетом торговли по выходным. + } +} + +//Интервал свечей. Максимальное значение интервала приведено ориентировочно, может отличаться в большую сторону в зависимости от параметров запроса. +enum CandleInterval { + CANDLE_INTERVAL_UNSPECIFIED = 0; //Интервал не определен. + CANDLE_INTERVAL_1_MIN = 1; //От 1 минуты до 1 дня. Максимальное значение `limit` — 2400. + CANDLE_INTERVAL_5_MIN = 2; //От 5 минут до недели. Максимальное значение `limit` — 2400. + CANDLE_INTERVAL_15_MIN = 3; //От 15 минут до 3 недель. Максимальное значение `limit` — 2400. + CANDLE_INTERVAL_HOUR = 4; //От 1 часа до 3 месяцев. Максимальное значение `limit` — 2400. + CANDLE_INTERVAL_DAY = 5; //От 1 дня до 6 лет. Максимальное значение `limit` — 2400. + CANDLE_INTERVAL_2_MIN = 6; //От 2 минут до 1 дня. Максимальное значение `limit` — 1200. + CANDLE_INTERVAL_3_MIN = 7; //От 3 минут до 1 дня. Максимальное значение `limit` — 750. + CANDLE_INTERVAL_10_MIN = 8; //От 10 минут до недели. Максимальное значение `limit` — 1200. + CANDLE_INTERVAL_30_MIN = 9; //От 30 минут до 3 недель. Максимальное значение `limit` — 1200. + CANDLE_INTERVAL_2_HOUR = 10; //От 2 часов до 3 месяцев. Максимальное значение `limit` — 2400. + CANDLE_INTERVAL_4_HOUR = 11; //От 4 часов до 3 месяцев. Максимальное значение `limit` — 700. + CANDLE_INTERVAL_WEEK = 12; //От 1 недели до 5 лет. Максимальное значение `limit` — 300. + CANDLE_INTERVAL_MONTH = 13; //От 1 месяца до 10 лет. Максимальное значение `limit` — 120. + CANDLE_INTERVAL_5_SEC = 14; //От 5 секунд до 200 минут. Максимальное значение `limit` — 2500. + CANDLE_INTERVAL_10_SEC = 15; //От 10 секунд до 200 минут. Максимальное значение `limit` — 1250. + CANDLE_INTERVAL_30_SEC = 16; //От 30 секунд до 20 часов. Максимальное значение `limit` — 2500. +} + +enum CandleSource { + CANDLE_SOURCE_UNSPECIFIED = 0; //Источник свечей не определен. + CANDLE_SOURCE_EXCHANGE = 1; //Биржевые свечи. + CANDLE_SOURCE_DEALER_WEEKEND = 2; //Свечи дилера в результате торговли по выходным. +} + +//Список свечей. +message GetCandlesResponse { + repeated HistoricCandle candles = 1; //Массив свечей. +} + +//Информация о свече. +message HistoricCandle { + Quotation open = 1; //Цена открытия за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15). + Quotation high = 2; //Максимальная цена за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15). + Quotation low = 3; //Минимальная цена за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15). + Quotation close = 4; //Цена закрытия за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15). + int64 volume = 5; //Объем торгов в лотах. + google.protobuf.Timestamp time = 6; //Время свечи в часовом поясе UTC. + bool is_complete = 7; //Признак завершенности свечи. **false** — свеча за текущие интервал еще сформирована не полностью. + CandleSource candle_source = 9; //Тип источника свечи + int64 volume_buy = 10; //Объем торгов на покупку. + int64 volume_sell = 11; //Объём торгов на продажу. +} + +//Запрос получения цен последних сделок. +message GetLastPricesRequest { + repeated string figi = 1 [deprecated = true]; //Deprecated FIGI-идентификатор инструмента. Используйте `instrument_id`. + repeated string instrument_id = 2; //Массив идентификаторов инструмента. Принимает значения `figi`, `instrument_uid` или `ticker + '_' + class_code`. + LastPriceType last_price_type = 3; //Тип запрашиваемой последней цены. + optional InstrumentStatus instrument_status = 9; //Статус запрашиваемых инструментов. [Возможные значения](#instrumentstatus). +} + +//Список цен последних сделок. +message GetLastPricesResponse { + repeated LastPrice last_prices = 1; //Массив цен последних сделок. +} + +//Информация о цене последней сделки. +message LastPrice { + string figi = 1; //FIGI инструмента. + Quotation price = 2; //Цена последней сделки за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15). + google.protobuf.Timestamp time = 3; //Время получения последней цены в часовом поясе UTC по времени биржи. + string ticker = 9; //Тикер инструмента. + string class_code = 10; //Класс-код (секция торгов). + string instrument_uid = 11; //UID инструмента. + LastPriceType last_price_type = 12; //Тип последней цены. +} + +message OpenInterest { + string instrument_uid = 1; //UID инструмента. + google.protobuf.Timestamp time = 2; //Время получения открытого интереса в часовом поясе UTC по времени биржи. + int64 open_interest = 3; //Открытый интерес. + string ticker = 4; //Тикер инструмента. + string class_code = 5; //Класс-код (секция торгов). +} + +//Запрос стакана. +message GetOrderBookRequest { + optional string figi = 1 [deprecated = true]; //Deprecated FIGI-идентификатор инструмента. Используйте `instrument_id`. + int32 depth = 2 [(google.api.field_behavior) = REQUIRED]; //Глубина стакана. + optional string instrument_id = 3; //Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`. +} + +//Информация о стакане. +message GetOrderBookResponse { + string figi = 1; //FIGI-идентификатор инструмента. + int32 depth = 2; //Глубина стакана. + repeated Order bids = 3; //Множество пар значений на покупку. + repeated Order asks = 4; //Множество пар значений на продажу. + Quotation last_price = 5; //Цена последней сделки за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15). + Quotation close_price = 6; //Цена закрытия за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15). + Quotation limit_up = 7; //Верхний лимит цены за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15). + Quotation limit_down = 8; //Нижний лимит цены за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15). + string instrument_uid = 9; //UID инструмента. + string ticker = 10; //Тикер инструмента. + string class_code = 11; //Класс-код (секция торгов). + google.protobuf.Timestamp last_price_ts = 21; //Время получения цены последней сделки. + google.protobuf.Timestamp close_price_ts = 22; //Время получения цены закрытия. + google.protobuf.Timestamp orderbook_ts = 23; //Время формирования стакана на бирже. +} + +//Запрос получения торгового статуса. +message GetTradingStatusRequest { + optional string figi = 1 [deprecated = true]; //Deprecated FIGI-идентификатор инструмента. Используйте `instrument_id`. + optional string instrument_id = 2; //Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code` +} + +//Запрос получения торгового статуса. +message GetTradingStatusesRequest { + repeated string instrument_id = 1; //Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code` +} + +//Информация о торговом статусе. +message GetTradingStatusesResponse { + repeated GetTradingStatusResponse trading_statuses = 1; //Массив информации о торговых статусах. +} + +//Информация о торговом статусе. +message GetTradingStatusResponse { + string figi = 1; //FIGI-идентификатор инструмента. + SecurityTradingStatus trading_status = 2; //Статус торговли инструментом. + bool limit_order_available_flag = 3; //Признак доступности выставления лимитной заявки по инструменту. + bool market_order_available_flag = 4; //Признак доступности выставления рыночной заявки по инструменту. + bool api_trade_available_flag = 5; //Признак доступности торгов через API. + string instrument_uid = 6; //UID инструмента. + bool bestprice_order_available_flag = 8; //Признак доступности завяки по лучшей цене. + bool only_best_price = 9; //Признак доступности только заявки по лучшей цене. + string ticker = 10; //Тикер инструмента. + string class_code = 11; //Класс-код (секция торгов). +} + +//Запрос обезличенных сделок за последний час. +message GetLastTradesRequest { + optional string figi = 1 [deprecated = true]; //Deprecated FIGI-идентификатор инструмента. Используйте `instrument_id`. + google.protobuf.Timestamp from = 2 [(google.api.field_behavior) = REQUIRED]; //Начало запрашиваемого периода по UTC. + google.protobuf.Timestamp to = 3 [(google.api.field_behavior) = REQUIRED]; //Окончание запрашиваемого периода по UTC. + optional string instrument_id = 4; //Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code` + TradeSourceType trade_source = 5; //Тип источника сделок. Значение по умолчанию — `TRADE_SOURCE_ALL`, все сделки. +} + +//Обезличенных сделок за последний час. +message GetLastTradesResponse { + repeated Trade trades = 1; //Массив сделок. +} + +//Запрос активных подписок. Возвращает по одному сообщению на каждый тип активных подписок — `SubscribeLastPriceResponse`, `SubscribeInfoResponse`, `SubscribeTradesResponse`, `SubscribeOrderBookResponse`, `SubscribeCandlesResponse`. +message GetMySubscriptions {} + +//Запрос цен закрытия торговой сессии по инструментам. +message GetClosePricesRequest { + repeated InstrumentClosePriceRequest instruments = 1 [(google.api.field_behavior) = REQUIRED]; //Массив по инструментам. + optional InstrumentStatus instrument_status = 9; //Статус запрашиваемых инструментов. [Возможные значения](#instrumentstatus). +} + +//Запрос цен закрытия торговой сессии по инструменту. +message InstrumentClosePriceRequest { + string instrument_id = 1; //Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code` +} + +//Цены закрытия торговой сессии по инструментам. +message GetClosePricesResponse { + repeated InstrumentClosePriceResponse close_prices = 1; //Массив по инструментам. +} + +//Цена закрытия торговой сессии по инструменту. +message InstrumentClosePriceResponse { + string figi = 1; //FIGI инструмента. + string instrument_uid = 2; //UID инструмента. + string ticker = 3; //Тикер инструмента. + string class_code = 4; //Класс-код (секция торгов). + Quotation price = 11; //Цена закрытия торговой сессии. + Quotation evening_session_price = 12; //Цена последней сделки с вечерней сессии. Цена публикуется биржей по торговым дням и в нерабочие дни не обновляется. + google.protobuf.Timestamp time = 21; //Дата совершения торгов. + google.protobuf.Timestamp evening_session_price_time = 23; //Дата цены закрытия вечерней сессии. +} + +message GetTechAnalysisRequest { + IndicatorType indicator_type = 1 [(google.api.field_behavior) = REQUIRED]; //Тип технического индикатора. + string instrument_uid = 2 [(google.api.field_behavior) = REQUIRED]; //UID инструмента. + google.protobuf.Timestamp from = 3 [(google.api.field_behavior) = REQUIRED]; //Начало запрашиваемого периода по UTC. + google.protobuf.Timestamp to = 4 [(google.api.field_behavior) = REQUIRED]; //Окончание запрашиваемого периода по UTC. + IndicatorInterval interval = 5 [(google.api.field_behavior) = REQUIRED]; //Интервал, за который рассчитывается индикатор. + TypeOfPrice type_of_price = 6 [(google.api.field_behavior) = REQUIRED]; //Тип цены, который используется при расчете индикатора. + int32 length = 7; //Торговый период, за который рассчитывается индикатор. + Deviation deviation = 8; //Параметры отклонения. + Smoothing smoothing = 9; //Параметры сглаживания. + + message Smoothing { + int32 fast_length = 1; //Короткий период сглаживания для первой экспоненциальной скользящей средней (EMA). + int32 slow_length = 2; //Длинный период сглаживания для второй экспоненциальной скользящей средней (EMA). + int32 signal_smoothing = 3; //Период сглаживания для третьей экспоненциальной скользящей средней (EMA) + } + + message Deviation { + Quotation deviation_multiplier = 1; //Количество стандартных отклонений, на которые отступают верхняя и нижняя границы. + } + + //Интервал свечи. + enum IndicatorInterval { + INDICATOR_INTERVAL_UNSPECIFIED = 0; //Интервал не определен. + INDICATOR_INTERVAL_ONE_MINUTE = 1; //1 минута. + INDICATOR_INTERVAL_FIVE_MINUTES = 2; //5 минут. + INDICATOR_INTERVAL_FIFTEEN_MINUTES = 3; //15 минут. + INDICATOR_INTERVAL_ONE_HOUR = 4; //1 час. + INDICATOR_INTERVAL_ONE_DAY = 5; //1 день. + INDICATOR_INTERVAL_2_MIN = 6; //2 минуты. + INDICATOR_INTERVAL_3_MIN = 7; //3 минуты. + INDICATOR_INTERVAL_10_MIN = 8; //10 минут. + INDICATOR_INTERVAL_30_MIN = 9; //30 минут. + INDICATOR_INTERVAL_2_HOUR = 10; //2 часа. + INDICATOR_INTERVAL_4_HOUR = 11; //4 часа. + INDICATOR_INTERVAL_WEEK = 12; //Неделя. + INDICATOR_INTERVAL_MONTH = 13; //Месяц. + } + + enum TypeOfPrice { + TYPE_OF_PRICE_UNSPECIFIED = 0; //Не указано. + TYPE_OF_PRICE_CLOSE = 1; //Цена закрытия. + TYPE_OF_PRICE_OPEN = 2; //Цена открытия. + TYPE_OF_PRICE_HIGH = 3; //Максимальное значение за выбранный интервал. + TYPE_OF_PRICE_LOW = 4; //Минимальное значение за выбранный интервал. + TYPE_OF_PRICE_AVG = 5; //Среднее значение по показателям [ (close + open + high + low) / 4 ]. + } + + enum IndicatorType { + INDICATOR_TYPE_UNSPECIFIED = 0; //Не определен. + INDICATOR_TYPE_BB = 1; //Bollinger Bands — линия Боллинжера. + INDICATOR_TYPE_EMA = 2; //Exponential Moving Average — EMA, экспоненциальная скользящая средняя. + INDICATOR_TYPE_RSI = 3; //Relative Strength Index — индекс относительной силы. + INDICATOR_TYPE_MACD = 4; //Moving Average Convergence/Divergence — схождение/расхождение скользящих средних. + INDICATOR_TYPE_SMA = 5; //Simple Moving Average — простое скользящее среднее. + } +} + +message GetTechAnalysisResponse { + repeated TechAnalysisItem technical_indicators = 1; //Массив значений результатов технического анализа. + + message TechAnalysisItem { + google.protobuf.Timestamp timestamp = 1; //Временная метка по UTC, для которой были рассчитаны значения индикатора. + optional Quotation middle_band = 2; //Значение простого скользящего среднего (средней линии). + optional Quotation upper_band = 3; //Значение верхней линии Боллинджера. + optional Quotation lower_band = 4; //Значение нижней линии Боллинджера. + optional Quotation signal = 5; //Значение сигнальной линии. + optional Quotation macd = 6; //Значение линии MACD. + } +} + +message GetMarketValuesRequest { + repeated string instrument_id = 1; //Массив идентификаторов инструментов. Принимает значения `figi`, `instrument_uid` или `ticker + '_' + class_code`. + repeated MarketValueType values = 2; //Массив запрашиваемых параметров. +} + +message GetMarketValuesResponse { + repeated MarketValueInstrument instruments = 1; //Массив значений параметров. +} + +message MarketValueInstrument { + string instrument_uid = 1; //Идентификатор инструмента. + repeated MarketValue values = 2; //Массив параметров инструмента. + string ticker = 3; //Тикер инструмента. + string class_code = 4; //Класс-код (секция торгов). +} + +message MarketValue { + optional MarketValueType type = 1; //Тип параметра. + optional Quotation value = 2; //Значение. + optional google.protobuf.Timestamp time = 3; //Дата и время. +} + +enum MarketValueType { + INSTRUMENT_VALUE_UNSPECIFIED = 0; //Не определен. + INSTRUMENT_VALUE_LAST_PRICE = 1; //Последняя биржевая цена. + INSTRUMENT_VALUE_LAST_PRICE_DEALER = 2; //Последняя цена дилера. + INSTRUMENT_VALUE_CLOSE_PRICE = 3; //Цена закрытия. + INSTRUMENT_VALUE_EVENING_SESSION_PRICE = 4; //Цена последней сделки с вечерней сессии. + INSTRUMENT_VALUE_OPEN_INTEREST = 5; // Открытый интерес, возвращается только для фьючерсов. + INSTRUMENT_VALUE_THEOR_PRICE = 6; //Теоретическая цена, возвращается только для опционов. + INSTRUMENT_VALUE_YIELD = 7; //Доходность +} + +enum OrderBookType { + ORDERBOOK_TYPE_UNSPECIFIED = 0; //Не определен. + ORDERBOOK_TYPE_EXCHANGE = 1; //Биржевой стакан. + ORDERBOOK_TYPE_DEALER = 2; //Стакан дилера. + ORDERBOOK_TYPE_ALL = 3; //Стакан биржевой и дилера. +} + +//Тип последней цены +enum LastPriceType { + LAST_PRICE_UNSPECIFIED = 0; //Не определен. + LAST_PRICE_EXCHANGE = 1; // Цена биржи. + LAST_PRICE_DEALER = 2; // Цена дилера +} diff --git a/invest-python-master/protos/t_tech/invest/grpc/operations.proto b/invest-python-master/protos/t_tech/invest/grpc/operations.proto new file mode 100644 index 0000000..f972c2b --- /dev/null +++ b/invest-python-master/protos/t_tech/invest/grpc/operations.proto @@ -0,0 +1,646 @@ +syntax = "proto3"; + +package tinkoff.public.invest.api.contract.v1; + +option go_package = "./;investapi"; +option java_package = "ru.tinkoff.piapi.contract.v1"; +option java_multiple_files = true; +option csharp_namespace = "Tinkoff.InvestApi.V1"; +option objc_class_prefix = "TIAPI"; +option php_namespace = "Tinkoff\\Invest\\V1"; + +import "google/protobuf/timestamp.proto"; +import "t_tech/invest/grpc/common.proto"; +import "t_tech/invest/grpc/google/api/field_behavior.proto"; + +service OperationsService {/*С помощью методов сервиса можно получить:

**1**. Список операций по счету.
**2**. + Портфель по счету.
**3**. Позиции ценных бумаг на счете.
**4**. + Доступный остаток для вывода средств.
**5**. Различные отчеты.*/ + //GetOperations — список операций по счету + //При работе с методом учитывайте [особенности взаимодействия](/invest/services/operations/operations_problems). + rpc GetOperations(OperationsRequest) returns (OperationsResponse); + + //GetPortfolio — портфель по счету + rpc GetPortfolio(PortfolioRequest) returns (PortfolioResponse); + + //GetPositions — список позиций по счету + rpc GetPositions(PositionsRequest) returns (PositionsResponse); + + //GetWithdrawLimits — доступный остаток для вывода средств + rpc GetWithdrawLimits(WithdrawLimitsRequest) returns (WithdrawLimitsResponse); + + //GetBrokerReport — брокерский отчет. + rpc GetBrokerReport(BrokerReportRequest) returns (BrokerReportResponse); + + //GetDividendsForeignIssuer — отчет «Справка о доходах за пределами РФ» + rpc GetDividendsForeignIssuer(GetDividendsForeignIssuerRequest) returns (GetDividendsForeignIssuerResponse); + + //GetOperationsByCursor — список операций по счету с пагинацией + //При работе с методом учитывайте [особенности взаимодействия](/invest/services/operations/operations_problems). + rpc GetOperationsByCursor(GetOperationsByCursorRequest) returns (GetOperationsByCursorResponse); +} + +service OperationsStreamService { + //PortfolioStream — стрим обновлений портфеля + rpc PortfolioStream(PortfolioStreamRequest) returns (stream PortfolioStreamResponse); + + //PositionsStream — стрим обновлений информации по изменению позиций портфеля + rpc PositionsStream(PositionsStreamRequest) returns (stream PositionsStreamResponse); + + //OperationsStream — стрим обновлений операций + rpc OperationsStream(OperationsStreamRequest) returns (stream OperationsStreamResponse); +} + +//Запрос получения списка операций по счету. +message OperationsRequest { + string account_id = 1 [(google.api.field_behavior) = REQUIRED]; //Идентификатор счета клиента. + optional google.protobuf.Timestamp from = 2; //Начало периода по UTC. + optional google.protobuf.Timestamp to = 3; //Окончание периода по UTC. + optional OperationState state = 4; //Статус запрашиваемых операций. + optional string figi = 5; //FIGI-идентификатор инструмента для фильтрации. +} + +//Список операций. +message OperationsResponse { + repeated Operation operations = 1; //Массив операций. +} + +//Данные по операции. +message Operation { + string id = 1; //Идентификатор операции. + string parent_operation_id = 2; //Идентификатор родительской операции. + string currency = 3; //Валюта операции. + MoneyValue payment = 4; //Сумма операции. + MoneyValue price = 5; //Цена операции за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. + OperationState state = 6; //Статус операции. + int64 quantity = 7; //Количество единиц инструмента. + int64 quantity_rest = 8; //Неисполненный остаток по сделке. + string figi = 9; //FIGI-идентификатор инструмента, связанного с операцией. + string instrument_type = 10; //Тип инструмента. Возможные значения:

`bond` — облигация;
`share` — акция;
`currency` — валюта;
`etf` — фонд;
`futures` — фьючерс. + google.protobuf.Timestamp date = 11; //Дата и время операции в формате часовом поясе UTC. + string type = 12; //Текстовое описание типа операции. + OperationType operation_type = 13; //Тип операции. + repeated OperationTrade trades = 14; //Массив сделок. + string asset_uid = 16; //Идентификатор актива + string position_uid = 17; //Уникальный идентификатор позиции. + string instrument_uid = 18; //Уникальный идентификатор инструмента. + repeated ChildOperationItem child_operations = 19; //Массив дочерних операций. +} + +//Сделка по операции. +message OperationTrade { + string trade_id = 1; //Идентификатор сделки. + google.protobuf.Timestamp date_time = 2; //Дата и время сделки по UTC. + int64 quantity = 3; //Количество инструментов. + MoneyValue price = 4; //Цена за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. +} + +//Запрос получения текущего портфеля по счету. +message PortfolioRequest { + string account_id = 1 [(google.api.field_behavior) = REQUIRED]; //Идентификатор счета пользователя. + optional CurrencyRequest currency = 2; //Валюта, в которой нужно рассчитать портфель. + enum CurrencyRequest { + RUB = 0; //Рубли + USD = 1; //Доллары + EUR = 2; //Евро + } +} + +//Текущий портфель по счету. +message PortfolioResponse { + MoneyValue total_amount_shares = 1; //Общая стоимость акций в портфеле. + MoneyValue total_amount_bonds = 2; //Общая стоимость облигаций в портфеле. + MoneyValue total_amount_etf = 3; //Общая стоимость фондов в портфеле. + MoneyValue total_amount_currencies = 4; //Общая стоимость валют в портфеле. + MoneyValue total_amount_futures = 5; //Общая стоимость фьючерсов в портфеле. + Quotation expected_yield = 6; //Текущая относительная доходность портфеля в %. + repeated PortfolioPosition positions = 7; //Список позиций портфеля. + string account_id = 8; //Идентификатор счета пользователя. + + MoneyValue total_amount_options = 9; //Общая стоимость опционов в портфеле. + MoneyValue total_amount_sp = 10; //Общая стоимость структурных нот в портфеле. + MoneyValue total_amount_portfolio = 11; //Общая стоимость портфеля. + repeated VirtualPortfolioPosition virtual_positions = 12; //Массив виртуальных позиций портфеля. + MoneyValue daily_yield = 15; // Рассчитанная доходность портфеля за день в рублях. + Quotation daily_yield_relative = 16; //Относительная доходность в день в %. + MoneyValue total_amount_dfa = 17; //Общая стоимость смарт-активов в портфеле в рублях. +} + +//Запрос позиций портфеля по счету. +message PositionsRequest { + string account_id = 1 [(google.api.field_behavior) = REQUIRED]; //Идентификатор счета пользователя. +} + +//Список позиций по счету. +message PositionsResponse { + repeated MoneyValue money = 1; //Массив валютных позиций портфеля. + repeated MoneyValue blocked = 2; //Массив заблокированных валютных позиций портфеля. + repeated PositionsSecurities securities = 3; //Список ценно-бумажных позиций портфеля. + bool limits_loading_in_progress = 4; //Признак идущей выгрузки лимитов в данный момент. + repeated PositionsFutures futures = 5; //Список фьючерсов портфеля. + repeated PositionsOptions options = 6; //Список опционов портфеля. + string account_id = 15; //Идентификатор счёта пользователя. +} + +//Запрос доступного остатка для вывода. +message WithdrawLimitsRequest { + string account_id = 1 [(google.api.field_behavior) = REQUIRED]; //Идентификатор счета пользователя. +} + +//Доступный остаток для вывода. +message WithdrawLimitsResponse { + repeated MoneyValue money = 1; //Массив валютных позиций портфеля. + repeated MoneyValue blocked = 2; //Массив заблокированных валютных позиций портфеля. + repeated MoneyValue blocked_guarantee = 3; //Заблокировано под гарантийное обеспечение фьючерсов. +} + +//Позиции портфеля. +message PortfolioPosition { + string figi = 1; //FIGI-идентификатор инструмента. + string instrument_type = 2; //Тип инструмента. + Quotation quantity = 3; //Количество инструмента в портфеле в штуках. + MoneyValue average_position_price = 4; //Средневзвешенная цена позиции. Для пересчета возможна задержка до одной секунды. + Quotation expected_yield = 5; //Текущая рассчитанная доходность позиции. + MoneyValue current_nkd = 6; // Текущий НКД. + Quotation average_position_price_pt = 7 [ deprecated = true ]; // Deprecated Средняя цена позиции в пунктах (для фьючерсов). Для пересчета возможна задержка до одной секунды. + MoneyValue current_price = 8; //Текущая цена за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. + MoneyValue average_position_price_fifo = 9; //Средняя цена позиции по методу FIFO. Для пересчета возможна задержка до одной секунды. + Quotation quantity_lots = 10 [ deprecated = true ]; //Deprecated Количество лотов в портфеле. + bool blocked = 21; //Заблокировано на бирже. + Quotation blocked_lots = 22; //Количество бумаг, заблокированных выставленными заявками. + string position_uid = 24; //Уникальный идентификатор позиции. + string instrument_uid = 25; //Уникальный идентификатор инструмента. + MoneyValue var_margin = 26; //Вариационная маржа. + Quotation expected_yield_fifo = 27; //Текущая рассчитанная доходность позиции. + MoneyValue daily_yield = 31; // Рассчитанная доходность портфеля за день. + string ticker = 32; //Тикер инструмента. + string class_code = 33; //Класс-код (секция торгов). +} + +message VirtualPortfolioPosition { + string position_uid = 1; //Уникальный идентификатор позиции. + string instrument_uid = 2; //Уникальный идентификатор инструмента. + string figi = 3; //FIGI-идентификатор инструмента. + string instrument_type = 4; //Тип инструмента. + Quotation quantity = 5; //Количество инструмента в портфеле в штуках. + MoneyValue average_position_price = 6; //Средневзвешенная цена позиции. Для пересчета возможна задержка до одной секунды. + Quotation expected_yield = 7; //Текущая рассчитанная доходность позиции. + Quotation expected_yield_fifo = 8; //Текущая рассчитанная доходность позиции. + google.protobuf.Timestamp expire_date = 9; //Дата, до которой нужно продать виртуальные бумаги. После этой даты виртуальная позиция «сгораетт». + MoneyValue current_price = 10; //Текущая цена за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. + MoneyValue average_position_price_fifo = 11; //Средняя цена позиции по методу FIFO. Для пересчета возможна задержка до одной секунды. + MoneyValue daily_yield = 31; // Рассчитанная доходность портфеля за день. + string ticker = 32; //Тикер инструмента. + string class_code = 33; //Класс-код (секция торгов). +} + +//Баланс позиции ценной бумаги. +message PositionsSecurities { + string figi = 1; //FIGI-идентификатор бумаги. + int64 blocked = 2; //Количество бумаг, заблокированных выставленными заявками. + int64 balance = 3; //Текущий незаблокированный баланс. + string position_uid = 4; //Уникальный идентификатор позиции. + string instrument_uid = 5; //Уникальный идентификатор инструмента. + string ticker = 6; //Тикер инструмента. + string class_code = 7; //Класс-код (секция торгов). + bool exchange_blocked = 11; //Заблокировано на бирже. + string instrument_type = 16; //Тип инструмента. +} + +//Баланс фьючерса. +message PositionsFutures { + string figi = 1; //FIGI-идентификатор фьючерса. + int64 blocked = 2; //Количество бумаг, заблокированных выставленными заявками. + int64 balance = 3; //Текущий незаблокированный баланс. + string position_uid = 4; //Уникальный идентификатор позиции. + string instrument_uid = 5; //Уникальный идентификатор инструмента. + string ticker = 6; //Тикер инструмента. + string class_code = 7; //Класс-код (секция торгов). +} + +//Баланс опциона. +message PositionsOptions { + string position_uid = 1; //Уникальный идентификатор позиции опциона. + string instrument_uid = 2; //Уникальный идентификатор инструмента. + string ticker = 3; //Тикер инструмента. + string class_code = 4; //Класс-код (секция торгов). + int64 blocked = 11; //Количество бумаг, заблокированных выставленными заявками. + int64 balance = 21; //Текущий незаблокированный баланс. +} + +message BrokerReportRequest { + oneof payload { + GenerateBrokerReportRequest generate_broker_report_request = 1; + GetBrokerReportRequest get_broker_report_request = 2; + } +} + +message BrokerReportResponse { + oneof payload { + GenerateBrokerReportResponse generate_broker_report_response = 1; + GetBrokerReportResponse get_broker_report_response = 2; + } +} + +message GenerateBrokerReportRequest { + string account_id = 1 [(google.api.field_behavior) = REQUIRED]; //Идентификатор счета клиента. + google.protobuf.Timestamp from = 2 [(google.api.field_behavior) = REQUIRED]; //Начало периода по UTC. + google.protobuf.Timestamp to = 3 [(google.api.field_behavior) = REQUIRED]; //Окончание периода по UTC. +} + +message GenerateBrokerReportResponse { + string task_id = 1; //Идентификатор задачи формирования брокерского отчета. +} + +message GetBrokerReportRequest { + string task_id = 1 [(google.api.field_behavior) = REQUIRED]; //Идентификатор задачи формирования брокерского отчета. + optional int32 page = 2; //Номер страницы отчета, начинается с 1. Значение по умолчанию — 0. +} + +message GetBrokerReportResponse { + repeated BrokerReport broker_report = 1; + int32 itemsCount = 2; //Количество записей в отчете. + int32 pagesCount = 3; //Количество страниц с данными отчета, начинается с 0. + int32 page = 4; //Текущая страница, начинается с 0. + string task_id = 5; //Идентификатор задачи формирования брокерского отчета. +} + +message BrokerReport { + string trade_id = 1;//Номер сделки. + string order_id = 2; //Номер поручения. + string figi = 3; //FIGI-идентификаторинструмента. + string execute_sign = 4; //Признак исполнения. + google.protobuf.Timestamp trade_datetime = 5; //Дата и время заключения по UTC. + string exchange = 6; //Торговая площадка. + string class_code = 7; //Режим торгов. + string direction = 8; //Вид сделки. + string name = 9; //Сокращенное наименование актива. + string ticker = 10; //Код актива. + MoneyValue price = 11; //Цена за единицу. + int64 quantity = 12; //Количество. + MoneyValue order_amount = 13; //Сумма без НКД. + Quotation aci_value = 14; //НКД. + MoneyValue total_order_amount = 15; //Сумма сделки. + MoneyValue broker_commission = 16; //Комиссия брокера. + MoneyValue exchange_commission = 17; //Комиссия биржи. + MoneyValue exchange_clearing_commission = 18; //Комиссия клирингового центра. + Quotation repo_rate = 19; //Ставка РЕПО, %. + string party = 20; //Контрагент или брокерарокер. + google.protobuf.Timestamp clear_value_date = 21; //Дата расчетов по UTC. + google.protobuf.Timestamp sec_value_date = 22; //Дата поставки по UTC. + string broker_status = 23; //Статус брокера. + string separate_agreement_type = 24; //Тип договора. + string separate_agreement_number = 25; //Номер договора. + string separate_agreement_date = 26; //Дата договора. + string delivery_type = 27; //Тип расчета по сделке. +} + +//Статус запрашиваемых операций. +enum OperationState { + OPERATION_STATE_UNSPECIFIED = 0; //Статус операции не определен. + OPERATION_STATE_EXECUTED = 1; //Исполнена частично или полностью. + OPERATION_STATE_CANCELED = 2; //Отменена. + OPERATION_STATE_PROGRESS = 3; //Исполняется. +} + +//Тип операции. +enum OperationType { + OPERATION_TYPE_UNSPECIFIED = 0; //Тип операции не определен. + OPERATION_TYPE_INPUT = 1; //Пополнение брокерского счета. + OPERATION_TYPE_BOND_TAX = 2; //Удержание НДФЛ по купонам. + OPERATION_TYPE_OUTPUT_SECURITIES = 3; //Вывод ЦБ. + OPERATION_TYPE_OVERNIGHT = 4; //Доход по сделке РЕПО овернайт. + OPERATION_TYPE_TAX = 5; //Удержание налога. + OPERATION_TYPE_BOND_REPAYMENT_FULL = 6; //Полное погашение облигаций. + OPERATION_TYPE_SELL_CARD = 7; //Продажа ЦБ с карты. + OPERATION_TYPE_DIVIDEND_TAX = 8; //Удержание налога по дивидендам. + OPERATION_TYPE_OUTPUT = 9; //Вывод денежных средств. + OPERATION_TYPE_BOND_REPAYMENT = 10; //Частичное погашение облигаций. + OPERATION_TYPE_TAX_CORRECTION = 11; //Корректировка налога. + OPERATION_TYPE_SERVICE_FEE = 12; //Удержание комиссии за обслуживание брокерского счета. + OPERATION_TYPE_BENEFIT_TAX = 13; //Удержание налога за материальную выгоду. + OPERATION_TYPE_MARGIN_FEE = 14; //Удержание комиссии за непокрытую позицию. + OPERATION_TYPE_BUY = 15; //Покупка ЦБ. + OPERATION_TYPE_BUY_CARD = 16; //Покупка ЦБ с карты. + OPERATION_TYPE_INPUT_SECURITIES = 17; //Перевод ценных бумаг из другого депозитария. + OPERATION_TYPE_SELL_MARGIN = 18; //Продажа в результате Margin-call. + OPERATION_TYPE_BROKER_FEE = 19; //Удержание комиссии за операцию. + OPERATION_TYPE_BUY_MARGIN = 20; //Покупка в результате Margin-call. + OPERATION_TYPE_DIVIDEND = 21; //Выплата дивидендов. + OPERATION_TYPE_SELL = 22; //Продажа ЦБ. + OPERATION_TYPE_COUPON = 23; //Выплата купонов. + OPERATION_TYPE_SUCCESS_FEE = 24; //Удержание комиссии SuccessFee. + OPERATION_TYPE_DIVIDEND_TRANSFER = 25; //Передача дивидендного дохода. + OPERATION_TYPE_ACCRUING_VARMARGIN = 26; //Зачисление вариационной маржи. + OPERATION_TYPE_WRITING_OFF_VARMARGIN = 27; //Списание вариационной маржи. + OPERATION_TYPE_DELIVERY_BUY = 28; //Покупка в рамках экспирации фьючерсного контракта. + OPERATION_TYPE_DELIVERY_SELL = 29; //Продажа в рамках экспирации фьючерсного контракта. + OPERATION_TYPE_TRACK_MFEE = 30; //Комиссия за управление по счету автоследования. + OPERATION_TYPE_TRACK_PFEE = 31; //Комиссия за результат по счету автоследования. + OPERATION_TYPE_TAX_PROGRESSIVE = 32; //Удержание налога по ставке 15%. + OPERATION_TYPE_BOND_TAX_PROGRESSIVE = 33; //Удержание налога по купонам по ставке 15%. + OPERATION_TYPE_DIVIDEND_TAX_PROGRESSIVE = 34; //Удержание налога по дивидендам по ставке 15%. + OPERATION_TYPE_BENEFIT_TAX_PROGRESSIVE = 35; //Удержание налога за материальную выгоду по ставке 15%. + OPERATION_TYPE_TAX_CORRECTION_PROGRESSIVE = 36; //Корректировка налога по ставке 15%. + OPERATION_TYPE_TAX_REPO_PROGRESSIVE = 37; //Удержание налога за возмещение по сделкам РЕПО по ставке 15%. + OPERATION_TYPE_TAX_REPO = 38; //Удержание налога за возмещение по сделкам РЕПО. + OPERATION_TYPE_TAX_REPO_HOLD = 39; //Удержание налога по сделкам РЕПО. + OPERATION_TYPE_TAX_REPO_REFUND = 40; //Возврат налога по сделкам РЕПО. + OPERATION_TYPE_TAX_REPO_HOLD_PROGRESSIVE = 41; //Удержание налога по сделкам РЕПО по ставке 15%. + OPERATION_TYPE_TAX_REPO_REFUND_PROGRESSIVE = 42; //Возврат налога по сделкам РЕПО по ставке 15%. + OPERATION_TYPE_DIV_EXT = 43; //Выплата дивидендов на карту. + OPERATION_TYPE_TAX_CORRECTION_COUPON = 44; //Корректировка налога по купонам. + OPERATION_TYPE_CASH_FEE = 45; //Комиссия за валютный остаток. + OPERATION_TYPE_OUT_FEE = 46; //Комиссия за вывод валюты с брокерского счета. + OPERATION_TYPE_OUT_STAMP_DUTY = 47; //Гербовый сбор. + OPERATION_TYPE_OUTPUT_SWIFT = 50; // SWIFT-перевод. + OPERATION_TYPE_INPUT_SWIFT = 51; // SWIFT-перевод. + OPERATION_TYPE_OUTPUT_ACQUIRING = 53; // Перевод на карту. + OPERATION_TYPE_INPUT_ACQUIRING = 54; // Перевод с карты. + OPERATION_TYPE_OUTPUT_PENALTY = 55; // Комиссия за вывод средств. + OPERATION_TYPE_ADVICE_FEE = 56; // Списание оплаты за сервис Советов. + OPERATION_TYPE_TRANS_IIS_BS = 57; // Перевод ценных бумаг с ИИС на брокерский счет. + OPERATION_TYPE_TRANS_BS_BS = 58; // Перевод ценных бумаг с одного брокерского счета на другой. + OPERATION_TYPE_OUT_MULTI = 59; // Вывод денежных средств со счета. + OPERATION_TYPE_INP_MULTI = 60; // Пополнение денежных средств со счета. + OPERATION_TYPE_OVER_PLACEMENT = 61; // Размещение биржевого овернайта. + OPERATION_TYPE_OVER_COM = 62; // Списание комиссии. + OPERATION_TYPE_OVER_INCOME = 63; // Доход от оверанайта. + OPERATION_TYPE_OPTION_EXPIRATION = 64; // Экспирация опциона. + OPERATION_TYPE_FUTURE_EXPIRATION = 65; // Экспирация фьючерса. + OPERATION_TYPE_OTHER_FEE = 66; // Прочие комиссии; + OPERATION_TYPE_OTHER = 67; // Операция по счету; + OPERATION_TYPE_DFA_REDEMPTION = 68; // погашение ЦФА-токена; + OPERATION_TYPE_PRIMARY_ORDER =69; // отмена заявки на первичное размещение по ЦФА; +} + +message GetDividendsForeignIssuerRequest { + oneof payload { + GenerateDividendsForeignIssuerReportRequest generate_div_foreign_issuer_report = 1; //Объект запроса формирования отчета. + GetDividendsForeignIssuerReportRequest get_div_foreign_issuer_report = 2; //Объект запроса сформированного отчета. + } +} + +message GetDividendsForeignIssuerResponse { + oneof payload { + GenerateDividendsForeignIssuerReportResponse generate_div_foreign_issuer_report_response = 1; //Объект результата задачи запуска формирования отчета. + GetDividendsForeignIssuerReportResponse div_foreign_issuer_report = 2; //Отчет «Справка о доходах за пределами РФ». + } +} + +//Объект запроса формирования отчета «Справка о доходах за пределами РФ». +message GenerateDividendsForeignIssuerReportRequest { + string account_id = 1 [(google.api.field_behavior) = REQUIRED]; //Идентификатор счета клиента. + google.protobuf.Timestamp from = 2 [(google.api.field_behavior) = REQUIRED]; //Начало периода по UTC. + google.protobuf.Timestamp to = 3 [(google.api.field_behavior) = REQUIRED]; //Окончание периода по UTC. Как правило, можно сформировать отчет по дату на несколько дней меньше текущей. Начало и окончание периода должны быть в рамках одного календарного года. +} + +// Объект запроса сформированного отчета «Справка о доходах за пределами РФ». +message GetDividendsForeignIssuerReportRequest { + string task_id = 1 [(google.api.field_behavior) = REQUIRED]; //Идентификатор задачи формирования отчета. + optional int32 page = 2; //Номер страницы отчета (начинается с 0), значение по умолчанию: 0. +} + +// Объект результата задачи запуска формирования отчета «Справка о доходах за пределами РФ». +message GenerateDividendsForeignIssuerReportResponse { + string task_id = 1; //Идентификатор задачи формирования отчета. +} + +message GetDividendsForeignIssuerReportResponse { + repeated DividendsForeignIssuerReport dividends_foreign_issuer_report = 1; + int32 itemsCount = 2; //Количество записей в отчете. + int32 pagesCount = 3; //Количество страниц с данными отчета, начинается с 0. + int32 page = 4; //Текущая страница, начинается с 0. +} + +// Отчет «Справка о доходах за пределами РФ». +message DividendsForeignIssuerReport { + google.protobuf.Timestamp record_date = 1; //Дата фиксации реестра. + google.protobuf.Timestamp payment_date = 2; //Дата выплаты. + string security_name = 3; //Наименование ценной бумаги. + string isin = 4; //ISIN-идентификатор ценной бумаги. + string issuer_country = 5; //Страна эмитента. Для депозитарных расписок указывается страна эмитента базового актива. + int64 quantity = 6; //Количество ценных бумаг. + Quotation dividend = 7; //Выплаты на одну бумагу + Quotation external_commission = 8; //Комиссия внешних платежных агентов. + Quotation dividend_gross = 9; //Сумма до удержания налога. + Quotation tax = 10; //Сумма налога, удержанного агентом. + Quotation dividend_amount = 11; //Итоговая сумма выплаты. + string currency = 12; //Валюта. +} + +//Запрос установки stream-соединения. +message PortfolioStreamRequest { + repeated string accounts = 1; //Массив идентификаторов счетов пользователя. + PingDelaySettings ping_settings = 15; //Запрос настройки пинга. +} + +//Информация по позициям и доходностям портфелей. +message PortfolioStreamResponse { + oneof payload { + PortfolioSubscriptionResult subscriptions = 1; //Объект результата подписки. + PortfolioResponse portfolio = 2; //Объект стриминга портфеля. + Ping ping = 3; //Проверка активности стрима. + } +} + +//Объект результата подписки. +message PortfolioSubscriptionResult { + repeated AccountSubscriptionStatus accounts = 1; //Массив счетов клиента. + string tracking_id = 7; //Уникальный идентификатор запроса, подробнее: [tracking_id](/invest/intro/developer/protocols/grpc#tracking-id). + string stream_id = 8; //Идентификатор открытого соединения +} + +//Счет клиента. +message AccountSubscriptionStatus { + string account_id = 1; //Идентификатор счета. + PortfolioSubscriptionStatus subscription_status = 6; //Результат подписки. +} + +//Результат подписки. +enum PortfolioSubscriptionStatus { + PORTFOLIO_SUBSCRIPTION_STATUS_UNSPECIFIED = 0; //Тип не определен. + PORTFOLIO_SUBSCRIPTION_STATUS_SUCCESS = 1; //Успешно. + PORTFOLIO_SUBSCRIPTION_STATUS_ACCOUNT_NOT_FOUND = 2; //Счет не найден или недостаточно прав. + PORTFOLIO_SUBSCRIPTION_STATUS_INTERNAL_ERROR = 3; //Произошла ошибка. +} + +//Запрос списка операций по счету с пагинацией. +message GetOperationsByCursorRequest { + string account_id = 1 [(google.api.field_behavior) = REQUIRED]; //Идентификатор счета клиента, обязательный параметр. Остальные параметры опциональны. + optional string instrument_id = 2; //Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`. + optional google.protobuf.Timestamp from = 6; //Начало периода по UTC. + optional google.protobuf.Timestamp to = 7; //Окончание периода по UTC. + optional string cursor = 11; //Идентификатор элемента, с которого начать формировать ответ. + optional int32 limit = 12; //Лимит количества операций. По умолчанию — `100`, максимальное значение — `1000`. + repeated OperationType operation_types = 13; //Тип операции. Принимает значение из списка `OperationType`. + optional OperationState state = 14; //Статус запрашиваемых операций. Возможные значения указаны в `OperationState`. + optional bool without_commissions = 15; //Флаг возврата комиссии. По умолчанию — `false`. + optional bool without_trades = 16; //Флаг получения ответа без массива сделок. + optional bool without_overnights = 17; //Флаг показа overnight операций. +} + +//Список операций по счету с пагинацией. +message GetOperationsByCursorResponse { + bool has_next = 1; //Признак, есть ли следующий элемент. + string next_cursor = 2; //Следующий курсор. + repeated OperationItem items = 6; //Список операций. +} + +//Данные об операции. +message OperationItem { + string cursor = 1; //Курсор. + string broker_account_id = 6; //Номер счета клиента. + string id = 16; //Идентификатор операции, может меняться с течением времени. + string parent_operation_id = 17; //Идентификатор родительской операции. Может измениться, если изменился ID родительской операции. + string name = 18; //Название операции. + google.protobuf.Timestamp date = 21; //Дата поручения. + OperationType type = 22; //Тип операции. + string description = 23; //Описание операции. + OperationState state = 24; //Статус поручения. + string instrument_uid = 31; //Уникальный идентификатор инструмента. + string figi = 32; //FIGI. + string instrument_type = 33; //Тип инструмента. + InstrumentType instrument_kind = 34; //Тип инструмента. + string position_uid = 35; //Уникальный идентификатор позиции. + string ticker = 36; //Тикер инструмента. + string class_code = 37; //Класс-код (секция торгов). + MoneyValue payment = 41; //Сумма операции. + MoneyValue price = 42; //Цена операции за 1 инструмент. + MoneyValue commission = 43; //Комиссия. + MoneyValue yield = 44; //Доходность. + Quotation yield_relative = 45; //Относительная доходность. + MoneyValue accrued_int = 46; //Накопленный купонный доход. + int64 quantity = 51; //Количество единиц инструмента. + int64 quantity_rest = 52; //Неисполненный остаток по сделке. + int64 quantity_done = 53; //Исполненный остаток. + google.protobuf.Timestamp cancel_date_time = 56; //Дата и время снятия заявки. + string cancel_reason = 57; //Причина отмены операции. + OperationItemTrades trades_info = 61; //Массив сделок. + string asset_uid = 64; //Идентификатор актива. + repeated ChildOperationItem child_operations = 65; //Массив дочерних операций. +} + +//Массив с информацией о сделках. +message OperationItemTrades { + repeated OperationItemTrade trades = 6; +} + +//Сделка по операции. +message OperationItemTrade { + string num = 1; //Номер сделки. + google.protobuf.Timestamp date = 6; //Дата сделки. + int64 quantity = 11; //Количество в единицах. + MoneyValue price = 16; //Цена. + MoneyValue yield = 21; //Доходность. + Quotation yield_relative = 22; //Относительная доходность. +} + +//Запрос установки stream-соединения позиций. +message PositionsStreamRequest { + repeated string accounts = 1; //Массив идентификаторов счетов пользователя. + bool with_initial_positions = 3; //Получение состояния позиций на момент подключения. + PingDelaySettings ping_settings = 15; //Запрос настройки пинга. +} + +//Информация по изменению позиций портфеля. +message PositionsStreamResponse { + oneof payload { + PositionsSubscriptionResult subscriptions = 1; //Объект результата подписки. + PositionData position = 2; //Объект стриминга позиций. + Ping ping = 3; //Проверка активности стрима. + PositionsResponse initial_positions = 5; //Текущие позиции. + } +} + +//Объект результата подписки. +message PositionsSubscriptionResult { + repeated PositionsSubscriptionStatus accounts = 1; //Массив счетов клиента. + string tracking_id = 7; //Уникальный идентификатор запроса, подробнее: [tracking_id](/invest/intro/developer/protocols/grpc#tracking-id). + string stream_id = 8; //Идентификатор открытого соединения +} + +//Счет клиента. +message PositionsSubscriptionStatus { + string account_id = 1; //Идентификатор счета. + PositionsAccountSubscriptionStatus subscription_status = 6; //Результат подписки. +} + +//Результат подписки. +enum PositionsAccountSubscriptionStatus { + POSITIONS_SUBSCRIPTION_STATUS_UNSPECIFIED = 0; //Тип не определен. + POSITIONS_SUBSCRIPTION_STATUS_SUCCESS = 1; //Успешно. + POSITIONS_SUBSCRIPTION_STATUS_ACCOUNT_NOT_FOUND = 2; //Счет не найден или недостаточно прав. + POSITIONS_SUBSCRIPTION_STATUS_INTERNAL_ERROR = 3; //Произошла ошибка. +} + +//Данные о позиции портфеля. +message PositionData { + string account_id = 1; //Идентификатор счета. + repeated PositionsMoney money = 2; //Массив валютных позиций портфеля. + repeated PositionsSecurities securities = 3; //Список ценно-бумажных позиций портфеля. + repeated PositionsFutures futures = 4; //Список фьючерсов портфеля. + repeated PositionsOptions options = 5; //Список опционов портфеля. + google.protobuf.Timestamp date = 6; //Дата и время операции в формате UTC. +} + +//Валютная позиция портфеля. +message PositionsMoney { + MoneyValue available_value = 1; //Доступное количество валютный позиций. + MoneyValue blocked_value = 2; //Заблокированное количество валютных позиций. +} + +message ChildOperationItem { + string instrument_uid = 1; //Уникальный идентификатор инструмента. + MoneyValue payment = 2; //Сумма операции. +} + +//Запрос установки stream-соединения операций. +message OperationsStreamRequest { + repeated string accounts = 1; //Массив идентификаторов счетов пользователя. + PingDelaySettings ping_settings = 15; //Запрос настройки пинга. +} + +//Информация по операциям. +message OperationsStreamResponse { + oneof payload { + OperationsSubscriptionResult subscriptions = 1; //Объект результата подписки. + OperationData operation = 2; //Объект стриминга операций. + Ping ping = 3; //Проверка активности стрима. + } +} + +//Объект результата подписки. +message OperationsSubscriptionResult { + repeated string accounts = 1; //Массив счетов клиента. + OperationsAccountSubscriptionStatus subscription_status = 2; //Результат подписки. + string tracking_id = 7; //Уникальный идентификатор запроса, подробнее: [tracking_id](/invest/intro/developer/protocols/grpc#tracking-id). + string stream_id = 8; //Идентификатор открытого соединения +} + +//Результат подписки. +enum OperationsAccountSubscriptionStatus { + OPERATIONS_SUBSCRIPTION_STATUS_UNSPECIFIED = 0; //Тип не определен. + OPERATIONS_SUBSCRIPTION_STATUS_SUCCESS = 1; //Успешно. + OPERATIONS_SUBSCRIPTION_STATUS_ACCOUNT_NOT_FOUND = 2; //Счет не найден или недостаточно прав. + OPERATIONS_SUBSCRIPTION_STATUS_INTERNAL_ERROR = 3; //Произошла ошибка. +} + +//Данные об операции. +message OperationData { + string broker_account_id = 1; //Идентификатор счета. + string id = 2; //Номер поручения. + string parent_operation_id = 3; //Номер родительского поручения. + string name = 4; //Название инструмента. + google.protobuf.Timestamp date = 5; //Дата. + OperationType type = 6; //Тип операции. + OperationState state = 7; //Статус поручения. + string instrument_uid = 8; //Уникальный идентификатор инструмента. + string figi = 9; //FIGI-идентификатор инструмента. + string instrument_type = 10; //Тип инструмента. + InstrumentType instrument_kind = 11; //Тип инструмента. + string position_uid = 12; //Идентификатор позиции. + string ticker = 13; //Тикер инструмента. + string class_code = 14; //Класс-код (секция торгов). + MoneyValue payment = 15; //Сумма операции. +} diff --git a/invest-python-master/protos/t_tech/invest/grpc/orders.proto b/invest-python-master/protos/t_tech/invest/grpc/orders.proto new file mode 100644 index 0000000..c44698c --- /dev/null +++ b/invest-python-master/protos/t_tech/invest/grpc/orders.proto @@ -0,0 +1,417 @@ +syntax = "proto3"; + +package tinkoff.public.invest.api.contract.v1; + +option go_package = "./;investapi"; +option java_package = "ru.tinkoff.piapi.contract.v1"; +option java_multiple_files = true; +option csharp_namespace = "Tinkoff.InvestApi.V1"; +option objc_class_prefix = "TIAPI"; +option php_namespace = "Tinkoff\\Invest\\V1"; + +import "t_tech/invest/grpc/common.proto"; +import "google/protobuf/timestamp.proto"; +import "t_tech/invest/grpc/google/api/field_behavior.proto"; + +service OrdersStreamService { + //TradesStream — стрим сделок пользователя + rpc TradesStream(TradesStreamRequest) returns (stream TradesStreamResponse); + //OrderStateStream — стрим поручений пользователя + //Перед работой прочитайте [статью](/invest/services/orders/orders_state_stream). + rpc OrderStateStream(OrderStateStreamRequest) returns (stream OrderStateStreamResponse); +} + +service OrdersService {/* Сервис предназначен для работы с торговыми поручениями:
**1**. + выставление;
**2**. отмена;
**3**. получение статуса;
**4**. + расчет полной стоимости;
**5**. получение списка заявок.*/ + //PostOrder — выставить заявку + rpc PostOrder(PostOrderRequest) returns (PostOrderResponse); + + //PostOrderAsync — выставить заявку асинхронным методом + //Особенности работы приведены в [статье](/invest/services/orders/async). + rpc PostOrderAsync(PostOrderAsyncRequest) returns (PostOrderAsyncResponse); + + //CancelOrder — отменить заявку + rpc CancelOrder(CancelOrderRequest) returns (CancelOrderResponse); + + //GetOrderState — получить статус торгового поручения + rpc GetOrderState(GetOrderStateRequest) returns (OrderState); + + //GetOrders — получить список активных заявок по счету + rpc GetOrders(GetOrdersRequest) returns (GetOrdersResponse); + + //ReplaceOrder — изменить выставленную заявку + rpc ReplaceOrder(ReplaceOrderRequest) returns (PostOrderResponse); + + //GetMaxLots — расчет количества доступных для покупки/продажи лотов + rpc GetMaxLots(GetMaxLotsRequest) returns (GetMaxLotsResponse); + + //GetOrderPrice — получить предварительную стоимость для лимитной заявки + rpc GetOrderPrice(GetOrderPriceRequest) returns (GetOrderPriceResponse); +} + +//Запрос установки соединения. +message TradesStreamRequest { + repeated string accounts = 1; //Идентификаторы счетов. + optional int32 ping_delay_ms = 15; //Задержка (пинг) сообщений: 5000–180 000 миллисекунд. Значение по умолчанию — 120 000. +} + +//Информация о торговых поручениях. +message TradesStreamResponse { + oneof payload { + OrderTrades order_trades = 1; //Информация об исполнении торгового поручения. + Ping ping = 2; //Проверка активности стрима. + SubscriptionResponse subscription = 3; //Ответ на запрос на подписку. + } +} + +//Информация об исполнении торгового поручения. +message OrderTrades { + string order_id = 1; //Идентификатор торгового поручения. + google.protobuf.Timestamp created_at = 2; //Дата и время создания сообщения в часовом поясе UTC. + OrderDirection direction = 3; //Направление сделки. + string figi = 4; //Figi-идентификатор инструмента. + repeated OrderTrade trades = 5; //Массив сделок. + string account_id = 6; //Идентификатор счета. + string instrument_uid = 7; //UID идентификатор инструмента. +} + +//Информация о сделке. +message OrderTrade { + google.protobuf.Timestamp date_time = 1; //Дата и время совершения сделки в часовом поясе UTC. + Quotation price = 2; //Цена за 1 инструмент, по которой совершена сделка. + int64 quantity = 3; //Количество штук в сделке. + string trade_id = 4; //Идентификатор сделки. +} + +//Запрос выставления торгового поручения. +message PostOrderRequest { + optional string figi = 1 [deprecated = true]; //Deprecated Figi-идентификатор инструмента. Необходимо использовать instrument_id. + int64 quantity = 2 [(google.api.field_behavior) = REQUIRED]; //Количество лотов. + optional Quotation price = 3; //Цена за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента. Игнорируется для рыночных поручений. + OrderDirection direction = 4 [(google.api.field_behavior) = REQUIRED]; //Направление операции. + string account_id = 5 [(google.api.field_behavior) = REQUIRED]; //Номер счета. + OrderType order_type = 6 [(google.api.field_behavior) = REQUIRED]; //Тип заявки. + string order_id = 7 [(google.api.field_behavior) = REQUIRED]; //Идентификатор запроса выставления поручения для целей идемпотентности в формате UID. Максимальная длина 36 символов. + string instrument_id = 8; //Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`. + TimeInForceType time_in_force = 9; //Алгоритм исполнения поручения, применяется только к лимитной заявке. + PriceType price_type = 10; //Тип цены. + bool confirm_margin_trade = 11; // Согласие на выставление заявки, которая может привести к непокрытой позиции, по умолчанию false. +} + +//Прочитайте про ключ идемпотентности [здесь](./head-orders/) + +//Информация о выставлении поручения. +message PostOrderResponse { + string order_id = 1; //Биржевой идентификатор заявки. + OrderExecutionReportStatus execution_report_status = 2; //Текущий статус заявки. + int64 lots_requested = 3; //Запрошено лотов. + int64 lots_executed = 4; //Исполнено лотов. + + MoneyValue initial_order_price = 5; //Начальная цена заявки. Произведение количества запрошенных лотов на цену. + MoneyValue executed_order_price = 6; //Исполненная средняя цена одного инструмента в заявке. + MoneyValue total_order_amount = 7; //Итоговая стоимость заявки, включающая все комиссии. + MoneyValue initial_commission = 8; //Начальная комиссия. Комиссия рассчитанная при выставлении заявки. + MoneyValue executed_commission = 9; //Фактическая комиссия по итогам исполнения заявки. + MoneyValue aci_value = 10; //Значение НКД (накопленного купонного дохода) на дату. Подробнее: [НКД при выставлении торговых поручений](./head-orders#coupon) + + string figi = 11; // Figi-идентификатор инструмента. + OrderDirection direction = 12; //Направление сделки. + MoneyValue initial_security_price = 13; //Начальная цена за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента. + OrderType order_type = 14; //Тип заявки. + string message = 15; //Дополнительные данные об исполнении заявки. + Quotation initial_order_price_pt = 16; //Начальная цена заявки в пунктах (для фьючерсов). + string instrument_uid = 17; //UID идентификатор инструмента. + string ticker = 18; //Тикер инструмента. + string class_code = 19; //Класс-код (секция торгов). + string order_request_id = 20; //Идентификатор ключа идемпотентности, переданный клиентом, в формате UID. Максимальная длина 36 символов. + ResponseMetadata response_metadata = 254; //Метадата +} + +//Запрос выставления асинхронного торгового поручения. +message PostOrderAsyncRequest { + string instrument_id = 1 [(google.api.field_behavior) = REQUIRED]; //Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`. + int64 quantity = 2 [(google.api.field_behavior) = REQUIRED]; //Количество лотов. + optional Quotation price = 3; //Цена за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента. Игнорируется для рыночных поручений. + OrderDirection direction = 4 [(google.api.field_behavior) = REQUIRED]; //Направление операции. + string account_id = 5 [(google.api.field_behavior) = REQUIRED]; //Номер счета. + OrderType order_type = 6 [(google.api.field_behavior) = REQUIRED]; //Тип заявки. + string order_id = 7 [(google.api.field_behavior) = REQUIRED]; //Идентификатор запроса выставления поручения для целей идемпотентности в формате UID. Максимальная длина 36 символов. + optional TimeInForceType time_in_force = 8; //Алгоритм исполнения поручения, применяется только к лимитной заявке. + optional PriceType price_type = 9; //Тип цены. + bool confirm_margin_trade = 10; // Согласие на выставление заявки, которая может привести к непокрытой позиции, по умолчанию false. +} + +//Результат выставления асинхронного торгового поручения. +message PostOrderAsyncResponse { + string order_request_id = 1 [(google.api.field_behavior) = REQUIRED]; //Идентификатор ключа идемпотентности, переданный клиентом, в формате UID. Максимальная длина 36 символов. + OrderExecutionReportStatus execution_report_status = 2 [(google.api.field_behavior) = REQUIRED]; //Текущий статус заявки. + optional string trade_intent_id = 3; //Идентификатор торгового поручения. +} + +//Запрос отмены торгового поручения. +message CancelOrderRequest { + string account_id = 1 [(google.api.field_behavior) = REQUIRED]; //Номер счета. + string order_id = 2 [(google.api.field_behavior) = REQUIRED]; //Идентификатор заявки. + optional OrderIdType order_id_type = 3; //Тип идентификатора заявки. +} + +//Результат отмены торгового поручения. +message CancelOrderResponse { + google.protobuf.Timestamp time = 1; //Дата и время отмены заявки в часовом поясе UTC. + ResponseMetadata response_metadata = 254; //Метадата +} + +//Запрос получения статуса торгового поручения. +message GetOrderStateRequest { + string account_id = 1 [(google.api.field_behavior) = REQUIRED]; //Номер счета. + string order_id = 2 [(google.api.field_behavior) = REQUIRED]; //Идентификатор заявки. + PriceType price_type = 3; //Тип цены. + optional OrderIdType order_id_type = 4; //Тип идентификатора заявки. +} + +//Запрос получения списка активных торговых поручений. +message GetOrdersRequest { + string account_id = 1 [(google.api.field_behavior) = REQUIRED]; //Номер счета. + optional GetOrdersRequestFilters advanced_filters = 2; //Дополнительные фильтры. + + message GetOrdersRequestFilters { + optional google.protobuf.Timestamp from = 1; //Дата и время, начиная с которой нужно получить информацию в часовом поясе UTC. Параметр применим только к ордерам, созданным сегодня. + optional google.protobuf.Timestamp to = 2; //Дата и время, до которой нужно получить информацию в часовом поясе UTC. Параметр применим только к ордерам, созданным сегодня. + repeated OrderExecutionReportStatus execution_status = 3; //Статусы заявок. + } +} + +//Список активных торговых поручений. +message GetOrdersResponse { + repeated OrderState orders = 1; //Массив активных заявок. +} + +//Информация о торговом поручении. +message OrderState { + string order_id = 1; //Биржевой идентификатор заявки. + OrderExecutionReportStatus execution_report_status = 2; //Текущий статус заявки. + int64 lots_requested = 3; //Запрошено лотов. + int64 lots_executed = 4; //Исполнено лотов. + MoneyValue initial_order_price = 5; //Начальная цена заявки. Произведение количества запрошенных лотов на цену. + MoneyValue executed_order_price = 6; //Исполненная цена заявки. Произведение средней цены покупки на количество лотов. + MoneyValue total_order_amount = 7; //Итоговая стоимость заявки, включающая все комиссии. + MoneyValue average_position_price = 8; //Средняя цена позиции по сделке. + MoneyValue initial_commission = 9; //Начальная комиссия. Комиссия, рассчитанная на момент подачи заявки. + MoneyValue executed_commission = 10; //Фактическая комиссия по итогам исполнения заявки. + string figi = 11; //Figi-идентификатор инструмента. + OrderDirection direction = 12; //Направление заявки. + MoneyValue initial_security_price = 13; //Начальная цена за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента. + repeated OrderStage stages = 14; //Стадии выполнения заявки. + MoneyValue service_commission = 15; //Сервисная комиссия. + string currency = 16; //Валюта заявки. + OrderType order_type = 17; //Тип заявки. + google.protobuf.Timestamp order_date = 18; //Дата и время выставления заявки в часовом поясе UTC. + string instrument_uid = 19; //UID идентификатор инструмента. + string order_request_id = 20; //Идентификатор ключа идемпотентности, переданный клиентом, в формате UID. Максимальная длина 36 символов. + string ticker = 21; //Тикер инструмента. + string class_code = 22; //Класс-код (секция торгов). +} + +//Сделки в рамках торгового поручения. +message OrderStage { + MoneyValue price = 1; //Цена за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента. + int64 quantity = 2; //Количество лотов. + string trade_id = 3; //Идентификатор сделки. + google.protobuf.Timestamp execution_time = 5; //Время исполнения сделки +} + +//Запрос изменения выставленной заявки. +message ReplaceOrderRequest { + string account_id = 1 [(google.api.field_behavior) = REQUIRED]; //Номер счета. + optional OrderIdType order_id_type = 5; //Тип идентификатора заявки. + string order_id = 6 [(google.api.field_behavior) = REQUIRED]; //Идентификатор заявки на бирже. + string idempotency_key = 7 [(google.api.field_behavior) = REQUIRED]; //Новый идентификатор запроса выставления поручения для целей идемпотентности. Максимальная длина 36 символов. Перезатирает старый ключ. + int64 quantity = 11 [(google.api.field_behavior) = REQUIRED]; //Количество лотов. + optional Quotation price = 12; //Цена за 1 инструмент. + optional PriceType price_type = 13; //Тип цены. + bool confirm_margin_trade = 14; // Согласие на выставление заявки, которая может привести к непокрытой позиции, по умолчанию false. +} + +//Запрос на расчет количества доступных для покупки/продажи лотов. Если не указывать цену инструмента, то расчет произведется по текущум ценам в стакане: по лучшему предложению для покупки и по лучшему спросу для продажи. +message GetMaxLotsRequest { + string account_id = 1 [(google.api.field_behavior) = REQUIRED]; //Номер счета + string instrument_id = 2 [(google.api.field_behavior) = REQUIRED]; //Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`. + optional Quotation price = 3; //Цена инструмента +} + +//Результат количество доступных для покупки/продажи лотов +message GetMaxLotsResponse { + string currency = 1; //Валюта инструмента + BuyLimitsView buy_limits = 2; //Лимиты для покупок на собственные деньги + BuyLimitsView buy_margin_limits = 3; //Лимиты для покупок с учетом маржинального кредитования + SellLimitsView sell_limits = 4; //Лимиты для продаж по собственной позиции + SellLimitsView sell_margin_limits = 5; //Лимиты для продаж с учетом маржинального кредитования + + message BuyLimitsView { + Quotation buy_money_amount = 1; //Количество доступной валюты для покупки + int64 buy_max_lots = 2; //Максимальное доступное количество лотов для покупки + int64 buy_max_market_lots = 3; //Максимальное доступное количество лотов для покупки для заявки по рыночной цене на текущий момент + } + + message SellLimitsView { + int64 sell_max_lots = 1; //Максимальное доступное количество лотов для продажи + } +} + +//Запрос получения предварительной стоимости заявки +message GetOrderPriceRequest { + string account_id = 1; //Номер счета + string instrument_id = 2; //Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`. + Quotation price = 3; //Цена инструмента + OrderDirection direction = 12; //Направление заявки + int64 quantity = 13; //Количество лотов +} + +//Предварительная стоимость заявки +message GetOrderPriceResponse { + MoneyValue total_order_amount = 1; //Итоговая стоимость заявки + MoneyValue initial_order_amount = 5; //Стоимость заявки без комиссий, НКД, ГО (для фьючерсов — стоимость контрактов) + int64 lots_requested = 3; //Запрошено лотов + MoneyValue executed_commission = 7; //Общая комиссия + MoneyValue executed_commission_rub = 8; //Общая комиссия в рублях + MoneyValue service_commission = 9; //Сервисная комиссия + MoneyValue deal_commission = 10; //Комиссия за проведение сделки + + oneof instrument_extra { + ExtraBond extra_bond = 12; //Дополнительная информация по облигациям + ExtraFuture extra_future = 13; //Дополнительная информация по фьючерсам + } + + message ExtraBond { + MoneyValue aci_value = 2; //Значение НКД (накопленного купонного дохода) на дату + Quotation nominal_conversion_rate = 3; //Курс конвертации для замещающих облигаций + } + + message ExtraFuture { + MoneyValue initial_margin = 2; //Гарантийное обеспечение для фьючерса + } +} + +//Запрос установки стрим-соединения торговых поручений +message OrderStateStreamRequest { + repeated string accounts = 1; //Идентификаторы счетов. + optional int32 ping_delay_millis = 15; //Задержка (пинг) сообщений: 1000-120 000 миллисекунд. Значение по умолчанию — 120 000. +} + +//Информация по подпискам +message SubscriptionResponse { + string tracking_id = 1; //Уникальный идентификатор запроса, подробнее: [tracking_id](./grpc#tracking-id). + ResultSubscriptionStatus status = 2; //Статус подписки. + string stream_id = 4; //Идентификатор открытого соединения + repeated string accounts = 5; //Идентификаторы счетов. + optional ErrorDetail error = 7; +} + +//Информация по заявкам +message OrderStateStreamResponse { + oneof payload { + OrderState order_state = 1; //Информация об исполнении торгового поручения. + Ping ping = 2; //Проверка активности стрима. + SubscriptionResponse subscription = 3; //Ответ на запрос на подписку. + } + + //Заявка + message OrderState { + string order_id = 1; //Биржевой идентификатор заявки. + optional string order_request_id = 2; //Идентификатор ключа идемпотентности, переданный клиентом, в формате UID. Максимальная длина 36 символов. + string client_code = 3; //Код клиента на бирже. + google.protobuf.Timestamp created_at = 4; //Дата создания заявки. + OrderExecutionReportStatus execution_report_status = 5; //Статус заявки. + optional StatusCauseInfo status_info = 6; //Дополнительная информация по статусу. + string ticker = 7; //Тикер инструмента. + string class_code = 8; //Класс-код (секция торгов). + int32 lot_size = 9; //Лотность инструмента заявки. + OrderDirection direction = 10; //Направление заявки. + TimeInForceType time_in_force = 11; //Алгоритм исполнения поручения. + OrderType order_type = 12; //Тип заявки. + string account_id = 13; //Номер счета. + string trade_order_id = 14 [(google.api.field_behavior) = REQUIRED]; //Идентификатор торгового поручения. + MoneyValue initial_order_price = 22; //Начальная цена заявки. + MoneyValue order_price = 23; //Цена выставления заявки. + optional MoneyValue amount = 24; //Предрассчитанная стоимость полной заявки. + MoneyValue executed_order_price = 25; //Исполненная цена заявки. + string currency = 26; //Валюта исполнения. + int64 lots_requested = 27; //Запрошено лотов. + int64 lots_executed = 28; //Исполнено лотов. + int64 lots_left = 29; //Число неисполненных лотов по заявке. + int64 lots_cancelled = 30; //Отмененные лоты. + optional MarkerType marker = 31; //Спецсимвол. + repeated OrderTrade trades = 33; // Список сделок. + google.protobuf.Timestamp completion_time = 35; //Время исполнения заявки. + string exchange = 36; //Код биржи. + string instrument_uid = 41; //UID идентификатор инструмента. + } + + //Маркер + enum MarkerType { + MARKER_UNKNOWN = 0; //не определено + MARKER_BROKER = 1; //сделки брокера + MARKER_CHAT = 2; //исполнение поручение, полученного от клиента через каналы связи + MARKER_PAPER = 3; //исполнение поручение, полученного от клиента в бумажной форме + MARKER_MARGIN = 4; //принудительное закрытие позиций + MARKER_TKBNM = 5; //сделки по управлению ликвидностью + MARKER_SHORT = 6; //сделки РЕПО по привлечению у клиентов бумаг + MARKER_SPECMM = 7; //перенос временно непокрытых позиций + MARKER_PO = 8; + } + + //Дополнительная информация по статусу заявки + enum StatusCauseInfo { + CAUSE_UNSPECIFIED = 0; //Не определено + CAUSE_CANCELLED_BY_CLIENT = 15; //Отменено клиентом + CAUSE_CANCELLED_BY_EXCHANGE = 1; //Отменено биржей + CAUSE_CANCELLED_NOT_ENOUGH_POSITION = 2; //Заявка не выставлена из-за нехватки средств + CAUSE_CANCELLED_BY_CLIENT_BLOCK = 3; //Отменено из-за блокировки клиента + CAUSE_REJECTED_BY_BROKER = 4; //Отклонено брокером + CAUSE_REJECTED_BY_EXCHANGE = 5; //Отклонено биржей + CAUSE_CANCELLED_BY_BROKER = 6; //Отменено брокером + } + + +} + +//Направление операции. +enum OrderDirection { + ORDER_DIRECTION_UNSPECIFIED = 0; //Значение не указано + ORDER_DIRECTION_BUY = 1; //Покупка + ORDER_DIRECTION_SELL = 2; //Продажа +} + +//Тип заявки. +enum OrderType { + ORDER_TYPE_UNSPECIFIED = 0; //Значение не указано + ORDER_TYPE_LIMIT = 1; //Лимитная + ORDER_TYPE_MARKET = 2; //Рыночная + ORDER_TYPE_BESTPRICE = 3; //Лучшая цена +} + +//Текущий статус заявки (поручения) +enum OrderExecutionReportStatus { + EXECUTION_REPORT_STATUS_UNSPECIFIED = 0; + EXECUTION_REPORT_STATUS_FILL = 1; //Исполнена + EXECUTION_REPORT_STATUS_REJECTED = 2; //Отклонена + EXECUTION_REPORT_STATUS_CANCELLED = 3; //Отменена пользователем + EXECUTION_REPORT_STATUS_NEW = 4; //Новая + EXECUTION_REPORT_STATUS_PARTIALLYFILL = 5; //Частично исполнена +} + +//Алгоритм исполнения заявки +enum TimeInForceType { + TIME_IN_FORCE_UNSPECIFIED = 0; //Значение не определено см. TIME_IN_FORCE_DAY + TIME_IN_FORCE_DAY = 1; //Заявка действует до конца торгового дня. Значение по умолчанию + TIME_IN_FORCE_FILL_AND_KILL = 2; //Если в момент выставления возможно исполнение заявки(в т.ч. частичное), заявка будет исполнена или отменена сразу после выставления + TIME_IN_FORCE_FILL_OR_KILL = 3; //Если в момент выставления возможно полное исполнение заявки, заявка будет исполнена или отменена сразу после выставления, недоступно для срочного рынка и торговли по выходным +} + +//Тип идентификатора заявки +enum OrderIdType { + ORDER_ID_TYPE_UNSPECIFIED = 0; //Тип идентификатора не указан. + ORDER_ID_TYPE_EXCHANGE = 1; //Биржевой идентификатор + ORDER_ID_TYPE_REQUEST = 2; //Ключ идемпотентности, переданный клиентом +} diff --git a/invest-python-master/protos/t_tech/invest/grpc/sandbox.proto b/invest-python-master/protos/t_tech/invest/grpc/sandbox.proto new file mode 100644 index 0000000..57aec32 --- /dev/null +++ b/invest-python-master/protos/t_tech/invest/grpc/sandbox.proto @@ -0,0 +1,114 @@ +syntax = "proto3"; + +package tinkoff.public.invest.api.contract.v1; + +option go_package = "./;investapi"; +option java_package = "ru.tinkoff.piapi.contract.v1"; +option java_multiple_files = true; +option csharp_namespace = "Tinkoff.InvestApi.V1"; +option objc_class_prefix = "TIAPI"; +option php_namespace = "Tinkoff\\Invest\\V1"; + +import "t_tech/invest/grpc/common.proto"; +import "t_tech/invest/grpc/orders.proto"; +import "t_tech/invest/grpc/operations.proto"; +import "t_tech/invest/grpc/stoporders.proto"; +import "t_tech/invest/grpc/users.proto"; +import "t_tech/invest/grpc/google/api/field_behavior.proto"; + +service SandboxService { // Методы для работы с песочницей T-Invest API + + //OpenSandboxAccount — зарегистрировать счет + rpc OpenSandboxAccount(OpenSandboxAccountRequest) returns (OpenSandboxAccountResponse); + + //GetSandboxAccounts — счета пользователя + rpc GetSandboxAccounts(GetAccountsRequest) returns (GetAccountsResponse); + + //CloseSandboxAccount — закрыть счет + rpc CloseSandboxAccount(CloseSandboxAccountRequest) returns (CloseSandboxAccountResponse); + + //PostSandboxOrder — выставить заявку + rpc PostSandboxOrder(PostOrderRequest) returns (PostOrderResponse); + + //PostSandboxOrderAsync — выставить заявку асинхронным методом + //Особенности работы приведены в [статье](/invest/services/orders/async). + rpc PostSandboxOrderAsync(PostOrderAsyncRequest) returns (PostOrderAsyncResponse); + + //ReplaceSandboxOrder — изменить выставленную заявку + rpc ReplaceSandboxOrder(ReplaceOrderRequest) returns (PostOrderResponse); + + //GetSandboxOrders — получить список активных заявок по счету + rpc GetSandboxOrders(GetOrdersRequest) returns (GetOrdersResponse); + + //CancelSandboxOrder — отменить заявку + rpc CancelSandboxOrder(CancelOrderRequest) returns (CancelOrderResponse); + + //GetSandboxOrderState — получить статус торгового поручения + rpc GetSandboxOrderState(GetOrderStateRequest) returns (OrderState); + + //GetSandboxOrderPrice — получить предварительную стоимость для лимитной заявки + rpc GetSandboxOrderPrice(GetOrderPriceRequest) returns (GetOrderPriceResponse); + + //GetSandboxPositions — список позиций по счету + rpc GetSandboxPositions(PositionsRequest) returns (PositionsResponse); + + //GetSandboxOperations — список операций по счету + //При работе с методом учитывайте [особенности взаимодействия](/invest/services/operations/operations_problems). + rpc GetSandboxOperations(OperationsRequest) returns (OperationsResponse); + + //GetSandboxOperationsByCursor — список операций по счету с пагинацией + //При работе с методом учитывайте [особенности взаимодействия](/invest/services/operations/operations_problems). + rpc GetSandboxOperationsByCursor(GetOperationsByCursorRequest) returns (GetOperationsByCursorResponse); + + //GetSandboxPortfolio — портфель по счету + rpc GetSandboxPortfolio(PortfolioRequest) returns (PortfolioResponse); + + //SandboxPayIn — пополнить счет. + rpc SandboxPayIn(SandboxPayInRequest) returns (SandboxPayInResponse); + + //GetSandboxWithdrawLimits — доступный остаток для вывода средств + rpc GetSandboxWithdrawLimits(WithdrawLimitsRequest) returns (WithdrawLimitsResponse); + + //GetSandboxMaxLots — расчет количества доступных для покупки/продажи лотов + rpc GetSandboxMaxLots(GetMaxLotsRequest) returns (GetMaxLotsResponse); + + //PostSandboxStopOrder — выставить стоп-заявку + rpc PostSandboxStopOrder(PostStopOrderRequest) returns (PostStopOrderResponse); + + //GetSandboxStopOrders — получить список активных стоп-заявок по счету + rpc GetSandboxStopOrders(GetStopOrdersRequest) returns (GetStopOrdersResponse); + + //CancelSandboxStopOrder — отменить стоп-заявку + rpc CancelSandboxStopOrder(CancelStopOrderRequest) returns (CancelStopOrderResponse); +} + +//Запрос открытия счета в песочнице. +message OpenSandboxAccountRequest { + optional string name = 1; // Название счета +} + +//Номер открытого счета в песочнице. +message OpenSandboxAccountResponse { + string account_id = 1; //Номер счета +} + +//Запрос закрытия счета в песочнице. +message CloseSandboxAccountRequest { + string account_id = 1 [(google.api.field_behavior) = REQUIRED]; //Номер счета +} + +//Результат закрытия счета в песочнице. +message CloseSandboxAccountResponse { + //пустой ответ +} + +//Запрос пополнения счета в песочнице. +message SandboxPayInRequest { + string account_id = 1 [(google.api.field_behavior) = REQUIRED]; //Номер счета + MoneyValue amount = 2 [(google.api.field_behavior) = REQUIRED]; //Сумма пополнения счета в рублях +} + +//Результат пополнения счета, текущий баланс. +message SandboxPayInResponse { + MoneyValue balance = 1; //Текущий баланс счета +} diff --git a/invest-python-master/protos/t_tech/invest/grpc/signals.proto b/invest-python-master/protos/t_tech/invest/grpc/signals.proto new file mode 100644 index 0000000..31440ea --- /dev/null +++ b/invest-python-master/protos/t_tech/invest/grpc/signals.proto @@ -0,0 +1,109 @@ +syntax = "proto3"; + +package tinkoff.public.invest.api.contract.v1; + +option go_package = "./;investapi"; +option java_package = "ru.tinkoff.piapi.contract.v1"; +option java_multiple_files = true; +option csharp_namespace = "Tinkoff.InvestApi.V1"; +option objc_class_prefix = "TIAPI"; +option php_namespace = "Tinkoff\\Invest\\V1"; + +import "google/protobuf/timestamp.proto"; +import "t_tech/invest/grpc/google/api/field_behavior.proto"; +import "t_tech/invest/grpc/common.proto"; + +service SignalService {//Сервис для получения технических сигналов и мнений аналитиков по инструментам. + + //GetStrategies — стратегии + rpc GetStrategies(GetStrategiesRequest) returns (GetStrategiesResponse); + + //GetSignals — сигналы + rpc GetSignals(GetSignalsRequest) returns (GetSignalsResponse); +} + +//Запрос стратегий. +message GetStrategiesRequest { + optional string strategy_id = 1; //Идентификатор стратегии. +} + +//Стратегии +message GetStrategiesResponse { + repeated Strategy strategies = 1; +} + +//Стратегия +message Strategy { + string strategy_id = 1 [(google.api.field_behavior) = REQUIRED]; //Идентификатор стратегии. + string strategy_name = 2 [(google.api.field_behavior) = REQUIRED]; //Название стратегии. + optional string strategy_description = 3; //Описание стратегии. + optional string strategy_url = 4; //Ссылка на страницу с описанием стратегии. + StrategyType strategy_type = 5 [(google.api.field_behavior) = REQUIRED]; //Тип стратегии. + int32 active_signals = 6 [(google.api.field_behavior) = REQUIRED]; //Количество активных сигналов. + int32 total_signals = 7 [(google.api.field_behavior) = REQUIRED]; //Общее количество сигналов. + int64 time_in_position = 8 [(google.api.field_behavior) = REQUIRED]; //Среднее время нахождения сигнала в позиции. + Quotation average_signal_yield = 9 [(google.api.field_behavior) = REQUIRED]; //Средняя доходность сигнала в стратегии. + Quotation average_signal_yield_year = 10 [(google.api.field_behavior) = REQUIRED]; //Средняя доходность сигналов в стратегии за последний год. + Quotation yield = 11 [(google.api.field_behavior) = REQUIRED]; //Доходность стратегии. + Quotation yield_year = 12 [(google.api.field_behavior) = REQUIRED]; //Доходность стратегии за последний год. +} + +//Запрос сигналов. +message GetSignalsRequest { + optional string signal_id = 1; //Идентификатор сигнала. + optional string strategy_id = 2; //Идентификатор стратегии. + optional StrategyType strategy_type = 3; //Тип стратегии. + optional string instrument_uid = 4; // Идентификатор бумаги. + optional google.protobuf.Timestamp from = 5; // Дата начала запрашиваемого интервала по UTC. + optional google.protobuf.Timestamp to = 6; // Дата конца запрашиваемого интервала по UTC. + optional SignalDirection direction = 7; // Направление сигнала. + optional SignalState active = 8; //Состояние сигнала. + optional Page paging = 9; //Настройки пагинации. +} + +//Сигналы. +message GetSignalsResponse { + repeated Signal signals = 1; //Массив сигналов. + PageResponse paging = 2; //Данные по пагинации. +} + +//Сигнал. +message Signal { + string signal_id = 1 [(google.api.field_behavior) = REQUIRED]; //Идентификатор сигнала. + string strategy_id = 2 [(google.api.field_behavior) = REQUIRED]; //Идентификатор стратегии. + string strategy_name = 3 [(google.api.field_behavior) = REQUIRED]; //Название стратегии. + string instrument_uid = 4 [(google.api.field_behavior) = REQUIRED]; //Идентификатор бумаги. + google.protobuf.Timestamp create_dt = 5 [(google.api.field_behavior) = REQUIRED]; //Дата и время создания сигнала по UTC. + SignalDirection direction = 6 [(google.api.field_behavior) = REQUIRED]; //Направление сигнала. + Quotation initial_price = 7 [(google.api.field_behavior) = REQUIRED]; //Цена бумаги на момент формирования сигнала. + optional string info = 8; //Дополнительная информация о сигнале. + string name = 9 [(google.api.field_behavior) = REQUIRED]; //Название сигнала. + Quotation target_price = 10 [(google.api.field_behavior) = REQUIRED]; //Целевая цена. + google.protobuf.Timestamp end_dt = 11 [(google.api.field_behavior) = REQUIRED]; //Дата и время дедлайна сигнала по UTC. + optional int32 probability = 12; //Вероятность сигнала. + optional Quotation stoploss = 13; //Порог закрытия сигнала по стоплосс. + optional Quotation close_price = 14; //Цена закрытия сигнала. + optional google.protobuf.Timestamp close_dt = 15; //Дата и время закрытия сигнала по UTC. +} + +//Тип стратегии. +enum StrategyType { + STRATEGY_TYPE_UNSPECIFIED = 0; //Не определен. + STRATEGY_TYPE_TECHNICAL = 1; //Техническая стратегия. + STRATEGY_TYPE_FUNDAMENTAL = 2; //Фундаментальная стратегия. +} + +//Направление сигнала. +enum SignalDirection { + SIGNAL_DIRECTION_UNSPECIFIED = 0; //Не определен. + SIGNAL_DIRECTION_BUY = 1; //Покупка. + SIGNAL_DIRECTION_SELL = 2; //Продажа. +} + +//Статус сигнала. +enum SignalState { + SIGNAL_STATE_UNSPECIFIED = 0; //Не определен. + SIGNAL_STATE_ACTIVE = 1; //Активный сигнал. + SIGNAL_STATE_CLOSED = 2; //Закрытый сигнал. + SIGNAL_STATE_ALL = 3; //Все состояния. +} diff --git a/invest-python-master/protos/t_tech/invest/grpc/stoporders.proto b/invest-python-master/protos/t_tech/invest/grpc/stoporders.proto new file mode 100644 index 0000000..e39a27b --- /dev/null +++ b/invest-python-master/protos/t_tech/invest/grpc/stoporders.proto @@ -0,0 +1,177 @@ +syntax = "proto3"; + +package tinkoff.public.invest.api.contract.v1; + +option go_package = "./;investapi"; +option java_package = "ru.tinkoff.piapi.contract.v1"; +option java_multiple_files = true; +option csharp_namespace = "Tinkoff.InvestApi.V1"; +option objc_class_prefix = "TIAPI"; +option php_namespace = "Tinkoff\\Invest\\V1"; + +import "google/protobuf/timestamp.proto"; +import "t_tech/invest/grpc/google/api/field_behavior.proto"; +import "t_tech/invest/grpc/common.proto"; + +service StopOrdersService { /* Сервис для работы со стоп-заявками: выставление, отмена, получение списка стоп-заявок.*/ + + //PostStopOrder — выставить стоп-заявку + rpc PostStopOrder(PostStopOrderRequest) returns (PostStopOrderResponse); + + //GetStopOrders — получить список активных стоп-заявок по счету + rpc GetStopOrders(GetStopOrdersRequest) returns (GetStopOrdersResponse); + + //CancelStopOrder — отменить стоп-заявку + rpc CancelStopOrder(CancelStopOrderRequest) returns (CancelStopOrderResponse); +} + +//Запрос выставления стоп-заявки. +message PostStopOrderRequest { + optional string figi = 1 [ deprecated = true ]; //Deprecated FIGI-идентификатор инструмента. Используйте `instrument_id`. + int64 quantity = 2 [(google.api.field_behavior) = REQUIRED]; //Количество лотов. + optional Quotation price = 3; //Цена за 1 инструмент биржевой заявки, которая будет выставлена при срабатывании по достижению `stop_price`. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. + optional Quotation stop_price = 4; //Стоп-цена заявки за 1 инструмент. При достижении стоп-цены происходит активация стоп-заявки, в результате чего выставляется биржевая заявка. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. + StopOrderDirection direction = 5 [(google.api.field_behavior) = REQUIRED]; //Направление операции. + string account_id = 6 [(google.api.field_behavior) = REQUIRED]; //Номер счета. + StopOrderExpirationType expiration_type = 7 [(google.api.field_behavior) = REQUIRED]; //Тип экспирации заявки. + StopOrderType stop_order_type = 8 [(google.api.field_behavior) = REQUIRED]; //Тип заявки. + optional google.protobuf.Timestamp expire_date = 9; //Дата и время окончания действия стоп-заявки по UTC. Для `ExpirationType = GoodTillDate` заполнение обязательно, для `GoodTillCancel` игнорируется. + string instrument_id = 10 [(google.api.field_behavior) = REQUIRED]; //Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`. + ExchangeOrderType exchange_order_type = 11; //Тип дочерней биржевой заявки. + TakeProfitType take_profit_type = 12; //Подтип стоп-заявки — `TakeProfit`. + TrailingData trailing_data = 13; //Массив с параметрами трейлинг-стопа. + PriceType price_type = 14; //Тип цены. + string order_id = 15 [(google.api.field_behavior) = REQUIRED]; //Идентификатор запроса выставления поручения для целей идемпотентности в формате `UID`. Максимальная длина — 36 символов. + bool confirm_margin_trade = 16; //Согласие на выставление заявки, которая может привести к непокрытой позиции, по умолчанию false. + optional bool instant_execution = 17; //Признак необходимости моментальной активации, используется только для трейлинг-стопа. + message TrailingData { + Quotation indent = 1; //Отступ. + TrailingValueType indent_type = 2; //Тип величины отступа. + Quotation spread = 3; //Размер защитного спреда. + TrailingValueType spread_type = 4; //Тип величины защитного спреда. + } +} + +//Результат выставления стоп-заявки. +message PostStopOrderResponse { + string stop_order_id = 1; //Уникальный идентификатор стоп-заявки. + string order_request_id = 2; //Идентификатор ключа идемпотентности, переданный клиентом, в формате `UID`. Максимальная длина 36 — символов. + ResponseMetadata response_metadata = 254; //Метадата. +} + +//Запрос получения списка активных стоп-заявок. +message GetStopOrdersRequest { + string account_id = 1 [(google.api.field_behavior) = REQUIRED]; //Идентификатор счета клиента. + StopOrderStatusOption status = 2; //Статус заявок. + google.protobuf.Timestamp from = 3; //Левая граница. + google.protobuf.Timestamp to = 4; //Правая граница. +} + +//Список активных стоп-заявок. +message GetStopOrdersResponse { + repeated StopOrder stop_orders = 1; //Массив стоп-заявок по счету. +} + +//Запрос отмены выставленной стоп-заявки. +message CancelStopOrderRequest { + string account_id = 1 [(google.api.field_behavior) = REQUIRED]; //Идентификатор счета клиента. + string stop_order_id = 2 [(google.api.field_behavior) = REQUIRED]; //Уникальный идентификатор стоп-заявки. +} + +//Результат отмены выставленной стоп-заявки. +message CancelStopOrderResponse { + google.protobuf.Timestamp time = 1; //Время отмены заявки по UTC. +} + +//Информация о стоп-заявке. +message StopOrder { + string stop_order_id = 1; //Уникальный идентификатор стоп-заявки. + int64 lots_requested = 2; //Запрошено лотов. + string figi = 3; //FIGI-идентификатор инструмента. + StopOrderDirection direction = 4; //Направление операции. + string currency = 5; //Валюта стоп-заявки. + StopOrderType order_type = 6; //Тип стоп-заявки. + google.protobuf.Timestamp create_date = 7; //Дата и время выставления заявки по UTC. + google.protobuf.Timestamp activation_date_time = 8; //Дата и время конвертации стоп-заявки в биржевую по UTC. + google.protobuf.Timestamp expiration_time = 9; //Дата и время снятия заявки по UTC. + MoneyValue price = 10; //Цена заявки за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. + MoneyValue stop_price = 11; //Цена активации стоп-заявки за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. + string instrument_uid = 12; //`instrument_uid`-идентификатор инструмента. + TakeProfitType take_profit_type = 13; //Подтип стоп-заявки — `TakeProfit`. + TrailingData trailing_data = 14; //Параметры трейлинг-стопа. + StopOrderStatusOption status = 15; //Статус заявки. + ExchangeOrderType exchange_order_type = 16; //Тип дочерней биржевой заявки для тейкпрофита. + optional string exchange_order_id = 17; //Идентификатор биржевой заявки. + string ticker = 18; //Тикер инструмента. + string class_code = 19; //Класс-код (секция торгов). + bool instant_execution = 20; //Признак необходимости моментальной активации, используется только для трейлинг-стопа. + message TrailingData { + Quotation indent = 1; //Отступ. + TrailingValueType indent_type = 2; //Тип величины отступа. + Quotation spread = 3; //Размер защитного спреда. + TrailingValueType spread_type = 4; //Тип величины защитного спреда. + TrailingStopStatus status = 5; //Статус трейлинг-стопа. + Quotation price = 7; //Цена исполнения. + Quotation extr = 8; //Локальный экстремум. + } +} + +//Направление сделки стоп-заявки. +enum StopOrderDirection { + STOP_ORDER_DIRECTION_UNSPECIFIED = 0; //Значение не указано. + STOP_ORDER_DIRECTION_BUY = 1; //Покупка. + STOP_ORDER_DIRECTION_SELL = 2; //Продажа. +} + +//Тип экспирации стоп-заявке. +enum StopOrderExpirationType { + STOP_ORDER_EXPIRATION_TYPE_UNSPECIFIED = 0; //Значение не указано. + STOP_ORDER_EXPIRATION_TYPE_GOOD_TILL_CANCEL = 1; //Действительно до отмены. + STOP_ORDER_EXPIRATION_TYPE_GOOD_TILL_DATE = 2; //Действительно до даты снятия. +} + +//Тип стоп-заявки. +enum StopOrderType { + STOP_ORDER_TYPE_UNSPECIFIED = 0; //Значение не указано. + STOP_ORDER_TYPE_TAKE_PROFIT = 1; //`Take-profit`-заявка. + STOP_ORDER_TYPE_STOP_LOSS = 2; //`Stop-loss`-заявка. + STOP_ORDER_TYPE_STOP_LIMIT = 3; //`Stop-limit`-заявка. +} + +//Статус стоп-заяки. +enum StopOrderStatusOption { + STOP_ORDER_STATUS_UNSPECIFIED = 0; //Значение не указано. + STOP_ORDER_STATUS_ALL = 1; //Все заявки. + STOP_ORDER_STATUS_ACTIVE = 2; //Активные заявки. + STOP_ORDER_STATUS_EXECUTED = 3; //Исполненные заявки. + STOP_ORDER_STATUS_CANCELED = 4; //Отмененные заявки. + STOP_ORDER_STATUS_EXPIRED = 5; //Истекшие заявки. +} + +//Тип выставляемой заявки. +enum ExchangeOrderType { + EXCHANGE_ORDER_TYPE_UNSPECIFIED = 0; //Значение не указано. + EXCHANGE_ORDER_TYPE_MARKET = 1; //Заявка по рыночной цене. + EXCHANGE_ORDER_TYPE_LIMIT = 2; //Лимитная заявка. +} + +//Тип TakeProfit-заявки. +enum TakeProfitType { + TAKE_PROFIT_TYPE_UNSPECIFIED = 0; //Значение не указано. + TAKE_PROFIT_TYPE_REGULAR = 1; //Обычная заявка, значение по умолчанию. + TAKE_PROFIT_TYPE_TRAILING = 2; //Трейлинг-стоп. +} + +//Тип параметров значений трейлинг-стопа. +enum TrailingValueType { + TRAILING_VALUE_UNSPECIFIED = 0; //Значение не указано. + TRAILING_VALUE_ABSOLUTE = 1; //Абсолютное значение в единицах цены. + TRAILING_VALUE_RELATIVE = 2; //Относительное значение в процентах. +} + +//Статус трейлинг-стопа. +enum TrailingStopStatus { + TRAILING_STOP_UNSPECIFIED = 0; //Значение не указано. + TRAILING_STOP_ACTIVE = 1; //Активный. + TRAILING_STOP_ACTIVATED = 2; //Активированный. +} diff --git a/invest-python-master/protos/t_tech/invest/grpc/users.proto b/invest-python-master/protos/t_tech/invest/grpc/users.proto new file mode 100644 index 0000000..79cf0cb --- /dev/null +++ b/invest-python-master/protos/t_tech/invest/grpc/users.proto @@ -0,0 +1,249 @@ +syntax = "proto3"; + +package tinkoff.public.invest.api.contract.v1; + +option go_package = "./;investapi"; +option java_package = "ru.tinkoff.piapi.contract.v1"; +option java_multiple_files = true; +option csharp_namespace = "Tinkoff.InvestApi.V1"; +option objc_class_prefix = "TIAPI"; +option php_namespace = "Tinkoff\\Invest\\V1"; + +import "google/protobuf/timestamp.proto"; +import "t_tech/invest/grpc/google/api/field_behavior.proto"; +import "t_tech/invest/grpc/common.proto"; + +service UsersService { /*С помощью сервиса можно получить:
1. + список счетов пользователя;
2. маржинальные показатели по счeту.*/ + + //GetAccounts — счета пользователя + //Получить список счетов. + rpc GetAccounts (GetAccountsRequest) returns (GetAccountsResponse); + + //GetMarginAttributes — маржинальные показатели по счeту + //Метод позволяет получить маржинальные показатели и ликвидность по заданному счeту. + rpc GetMarginAttributes (GetMarginAttributesRequest) returns (GetMarginAttributesResponse); + + //GetUserTariff — тариф пользователя + //Получить информацию о текущих лимитах на подклчение, согласно текущему тарифу пользователя. + rpc GetUserTariff (GetUserTariffRequest) returns (GetUserTariffResponse); + + //GetInfo — информация о пользователе + //Получить информацию о пользователе: тариф, признак квалификации, пройденные тесты и др. + rpc GetInfo (GetInfoRequest) returns (GetInfoResponse); + + //GetBankAccounts — банковские счета пользователя + //Получить список счетов пользователя, в том числе и банковских. + rpc GetBankAccounts(GetBankAccountsRequest) returns (GetBankAccountsResponse); + + //CurrencyTransfer — перевод денежных средств между счетами + //Перевести денежные средства между брокерскими счетами + rpc CurrencyTransfer(CurrencyTransferRequest) returns (CurrencyTransferResponse); + + //PayIn — пополнение брокерского счета + //Пополнить брокерский счёт с банковского + rpc PayIn(PayInRequest) returns (PayInResponse); + + //GetAccountValues — дополнительные показатели счетов + //Метод предназначен для получения дополнительных показателей счетов + rpc GetAccountValues(GetAccountValuesRequest) returns (GetAccountValuesResponse); +} + +//Запрос получения счетов пользователя. +message GetAccountsRequest { + optional AccountStatus status = 1; //Статус счета. +} + +//Список счетов пользователя. +message GetAccountsResponse { + // Массив счетов клиента. + repeated Account accounts = 1; +} + +//Информация о счeте. +message Account { + + // Идентификатор счeта. + string id = 1; + + // Тип счeта. + AccountType type = 2; + + // Название счeта. + string name = 3; + + // Статус счeта. + AccountStatus status = 4; + + // Дата открытия счeта в часовом поясе UTC. + google.protobuf.Timestamp opened_date = 5; + + // Дата закрытия счeта в часовом поясе UTC. + google.protobuf.Timestamp closed_date = 6; + + // Уровень доступа к текущему счeту (определяется токеном). + AccessLevel access_level = 7; +} + +//Тип счeта. +enum AccountType { + ACCOUNT_TYPE_UNSPECIFIED = 0; //Тип аккаунта не определeн. + ACCOUNT_TYPE_TINKOFF = 1; //Брокерский счeт Т-Инвестиций. + ACCOUNT_TYPE_TINKOFF_IIS = 2; //ИИС. + ACCOUNT_TYPE_INVEST_BOX = 3; //Инвесткопилка. + ACCOUNT_TYPE_INVEST_FUND = 4; //Фонд денежного рынка. + ACCOUNT_TYPE_DEBIT = 5; //Дебетовый карточный счeт. + ACCOUNT_TYPE_SAVING = 6; //Накопительный счeт. + ACCOUNT_TYPE_DFA = 7; //Смарт-счет. +} + +//Статус счeта. +enum AccountStatus { + ACCOUNT_STATUS_UNSPECIFIED = 0; //Статус счeта не определeн. + ACCOUNT_STATUS_NEW = 1; //Новый, в процессе открытия. + ACCOUNT_STATUS_OPEN = 2; //Открытый и активный счeт. + ACCOUNT_STATUS_CLOSED = 3; //Закрытый счeт. + ACCOUNT_STATUS_ALL = 4; //Все счета. +} + +//Запрос маржинальных показателей по счeту. +message GetMarginAttributesRequest { + + // Идентификатор счeта пользователя. + string account_id = 1 [(google.api.field_behavior) = REQUIRED]; +} + +//Маржинальные показатели по счeту. +message GetMarginAttributesResponse { + + // Ликвидная стоимость портфеля. [Подробнее про ликвидный портфель](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q4). + MoneyValue liquid_portfolio = 1; + + // Начальная маржа — начальное обеспечение для совершения новой сделки. [Подробнее про начальную и минимальную маржу](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q6). + MoneyValue starting_margin = 2; + + // Минимальная маржа — это минимальное обеспечение для поддержания позиции, которую вы уже открыли. [Подробнее про начальную и минимальную маржу](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q6). + MoneyValue minimal_margin = 3; + + // Уровень достаточности средств. Соотношение стоимости ликвидного портфеля к начальной марже. + Quotation funds_sufficiency_level = 4; + + // Объем недостающих средств. Разница между стартовой маржой и ликвидной стоимости портфеля. + MoneyValue amount_of_missing_funds = 5; + + // Скорректированная маржа. Начальная маржа, в которой плановые позиции рассчитываются с учeтом активных заявок на покупку позиций лонг или продажу позиций шорт. + MoneyValue corrected_margin = 6; + + // Размер гарантийного обеспечения, заблокированного под фьючерсы. + MoneyValue guarantee_for_futures = 7; +} + +//Запрос текущих лимитов пользователя. +message GetUserTariffRequest { +} + +//Текущие лимиты пользователя. +message GetUserTariffResponse { + repeated UnaryLimit unary_limits = 1; //Массив лимитов пользователя по unary-запросам. + repeated StreamLimit stream_limits = 2; //Массив лимитов пользователей для stream-соединений. +} + +//Лимит unary-методов. +message UnaryLimit { + int32 limit_per_minute = 1; //Количество unary-запросов в минуту. + repeated string methods = 2; //Названия методов. + optional int32 limit_per_second = 3; //Количество unary-запросов в секунду. +} + +//Лимит stream-соединений. +message StreamLimit { + int32 limit = 1; //Максимальное количество stream-соединений. + repeated string streams = 2; //Названия stream-методов. + int32 open = 3; //Текущее количество открытых stream-соединений. +} + +//Запрос информации о пользователе. +message GetInfoRequest { +} + +//Информация о пользователе. +message GetInfoResponse { + bool prem_status = 1; //Признак премиум клиента. + bool qual_status = 2; //Признак квалифицированного инвестора. + repeated string qualified_for_work_with = 3; //Набор требующих тестирования инструментов и возможностей, с которыми может работать пользователь. [Подробнее](/invest/services/accounts/faq_users). + string tariff = 4; //Наименование тарифа пользователя. + string user_id = 9; //Идентификатор пользователя. + string risk_level_code = 12; // Категория риска. +} + +//Уровень доступа к счeту. +enum AccessLevel { + ACCOUNT_ACCESS_LEVEL_UNSPECIFIED = 0; //Уровень доступа не определeн. + ACCOUNT_ACCESS_LEVEL_FULL_ACCESS = 1; //Полный доступ к счeту. + ACCOUNT_ACCESS_LEVEL_READ_ONLY = 2; //Доступ с уровнем прав «только чтение». + ACCOUNT_ACCESS_LEVEL_NO_ACCESS = 3; //Доступа нет. +} + +//Запрос списка банковских счетов пользователя. +message GetBankAccountsRequest { +} + +//Список банковских счетов пользователя. +message GetBankAccountsResponse { + repeated BankAccount bank_accounts = 1; //Массив банковских счетов. +} + +//Банковский счeт. +message BankAccount { + string id = 1; //Идентификатор счeта. + string name = 2; //Название счeта. + repeated MoneyValue money = 3; //Список валютных позиций на счeте. + google.protobuf.Timestamp opened_date = 4; //Дата открытия счeта в часовом поясе UTC. + AccountType type = 5; //Тип счeта. +} + +message CurrencyTransferRequest { + string from_account_id = 1 [(google.api.field_behavior) = REQUIRED]; // Номер счета списания. + string to_account_id = 2 [(google.api.field_behavior) = REQUIRED]; // Номер счета зачисления. + MoneyValue amount = 3 [(google.api.field_behavior) = REQUIRED]; // Сумма перевода с указанием валюты. + string transaction_id = 4; // Идентификатор запроса выставления поручения для целей идемпотентности в формате UUID. +} + +message CurrencyTransferResponse { + +} + +message PayInRequest { + string from_account_id = 1 [(google.api.field_behavior) = REQUIRED]; // Номер счета списания. + string to_account_id = 2 [(google.api.field_behavior) = REQUIRED]; // Номер брокерского счета зачисления. + MoneyValue amount = 3 [(google.api.field_behavior) = REQUIRED]; // Сумма перевода с указанием валюты. +} + +message PayInResponse { + +} + +enum AccountValue { + ACCOUNT_VALUE_UNSPECIFIED = 0; // Не определён. + ACCOUNT_VALUE_MARGIN_FEE = 1; // Размер комиссии за маржинальное кредитование. + ACCOUNT_VALUE_AMOUNT_WITHOUT_EXTRA_FEE = 2; // Остаток доступного лимита с текущей комиссией. +} + +message GetAccountValuesRequest { + repeated string accounts = 1; // Массив счетов пользователя. + repeated AccountValue values = 2; // Массив запрашиваемых параметров. +} + +message GetAccountValuesResponse { + repeated AccountValuesWithParameters accounts = 1; // Массив счетов с параметрами. +} + +message AccountValuesWithParameters { + string account_id = 1; // Номер счета. + repeated InstrumentParameter values = 2; // Массив параметров инструмента. +} + +message InstrumentParameter { + AccountValue name = 1; // Тип запрашиваемого параметра. + MoneyValue value = 2; // Значение запрашиваемого параметра. +} \ No newline at end of file diff --git a/invest-python-master/pyproject.toml b/invest-python-master/pyproject.toml new file mode 100644 index 0000000..62f8b1e --- /dev/null +++ b/invest-python-master/pyproject.toml @@ -0,0 +1,182 @@ +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" + +[project] +requires-python = ">=3.8" +name = "t-tech-investments" +version = "0.3.5" +description = "T-Invest Python SDK" +authors = [{name="Invest Public API Team", email="t-tech.python@ya.ru>"}] +license = "Apache-2.0" +readme = "README.md" +repository = "https://opensource.tbank.ru/invest/invest-python" +homepage = "https://developer.tbank.ru/invest/intro/intro" + +[tool.poetry] + +packages = [ + {include = "t_tech"} +] +exclude = ["t_tech/__init__.py"] + +[tool.poetry.dependencies] +python = "^3.8.1" +cachetools = "^5.2.0" +grpcio = [ + {version = "^1.59.3", python = "<3.11"}, + {version = "^1.75.0", python = ">=3.11"} +] +protobuf = [ + {version = "^4.25.1", python = "<3.11"}, + {version = "^6.31.1", python = ">=3.11"} +] +python-dateutil = "^2.8.2" +deprecation = "^2.1.0" +matplotlib = [ + {version = "^3.5.1", python = "<3.11", optional = true }, + {version = "^3.10.0", python = ">=3.11", optional = true } +] +numpy = [ + { version = "^1.22.2", python = "<3.11", optional = true }, + { version = "^2.0.0", python = ">=3.11", optional = true } +] +pandas = [ + { version = "^1.4.0", python = "<3.11", optional = true }, + { version = "^2.3.3", python = ">=3.11", optional = true } +] +mplfinance = {version = "^0.12.8-beta.9", optional = true} +pillow = [ + { version = "^10.4.0", python = "<3.11", optional = true }, + { version = "^12.0.0", python = ">=3.11", optional = true } +] +kiwisolver = [ + { version = "^1.4.7", python = "<3.11", optional = true }, + { version = "^1.5.0", python = ">=3.11", optional = true } +] +contourpy = [ + { version = "^1.1.1", python = "<3.11", optional = true }, + { version = "^1.3.3", python = ">=3.11", optional = true } +] +sentry-sdk = "^2.47.0" + +[tool.poetry.extras] +all = ["pandas", "numpy", "matplotlib", "mplfinance"] + +[tool.poetry.group.bump.dependencies] +PyYAML = "^6.0" +tomlkit = "^0.12.3" + +[tool.poetry.group.dev.dependencies] +black = {extras = ["jupyter"], version = "^23.7.0"} +codecov = "^2.1.12" +grpcio-tools = [ + {version = "^1.59.3", python = "<3.11"}, + {version = "^1.75.0", python = ">=3.11"} +] +ipython = "^8.1.1" +isort = "^5.10.1" +mypy = "^1.7.1" +mypy-protobuf = "^3.5.0" +pytest = "^7.4.3" +pytest-asyncio = "^0.23.2" +pytest-cov = "^4.1.0" +pytest-deadfixtures = "^2.2.1" +pytest-freezegun = "^0.4.2" +pytest-mock = "^3.12.0" +requests = "^2.27.1" +ruff = "^0.1.6" +types-cachetools = "^5.2.1" +types-protobuf = "^4.23.0.4" +types-python-dateutil = "^2.8.12" +types-PyYAML = "^6.0.7" +types-requests = "^2.27.7" +mplfinance = "^0.12.8-beta.9" + +[tool.poetry.group.docs.dependencies] +mkdocs = "1.6.0" +mkdocs-include-markdown-plugin = "^6.0.4" +mkdocs-material = "^9.7.0" +mkdocstrings = {version = "0.24.0", extras = ["python"]} +termynal = "^0.11.1" +griffe = "0.38.0" + +[tool.pytest.ini_options] +testpaths = "tests" +addopts = "--strict-markers --showlocals --verbosity 2" +log_level = "DEBUG" +asyncio_mode = "auto" + +[tool.ruff] +target-version = "py38" +line-length = 88 +select = [ + "D", + "B", + "C", + "E", + "F", + "Q", + "RUF001", + "T", + "W" +] +ignore = [ + "D100", + "D101", + "D102", + "D103", + "D104", + "D105", + "D106", + "D107", + "D203", + "D213", + "B008", + "B905", + "Q000" +] +exclude = [ + "t_tech/invest/grpc", + "examples/*" +] + +[tool.black] +exclude = "t_tech/invest/grpc" +target-version = ["py38", "py39", "py310", "py311", "py312"] + +[tool.coverage.report] +show_missing = true +skip_covered = true +fail_under = 64 +exclude_lines = [ + "raise NotImplementedError", + "def __repr__", + "pragma: no cover" +] +omit = [ + "*/.local/*", + "tests/*", + "**/__main__.py" +] +branch = true +source = "t_tech" + +[tool.isort] +profile = "black" +multi_line_output = 3 +combine_as_imports = true + +[tool.mypy] +ignore_missing_imports = true +no_implicit_optional = true +check_untyped_defs = true +exclude = ['venv', '.venv'] + +[[tool.mypy.overrides]] +module = ["tests.*", "examples.*"] +check_untyped_defs = false + +[[tool.mypy.overrides]] +module = ["t_tech.invest.caching.instruments_cache.*", "t_tech.invest.mock_services.*"] +ignore_errors = true diff --git a/invest-python-master/pytest.ini b/invest-python-master/pytest.ini new file mode 100644 index 0000000..cc0c733 --- /dev/null +++ b/invest-python-master/pytest.ini @@ -0,0 +1,6 @@ +[pytest] +cache_dir = .pytest_cache +asyncio_mode = auto +addopts = --verbosity=2 --showlocals --strict-markers --log-level=DEBUG +markers = + test_sandbox: marks sandbox tests (use option '--test-sandbox' to run) diff --git a/invest-python-master/scripts/__init__.py b/invest-python-master/scripts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/invest-python-master/scripts/download_protos.py b/invest-python-master/scripts/download_protos.py new file mode 100644 index 0000000..358de02 --- /dev/null +++ b/invest-python-master/scripts/download_protos.py @@ -0,0 +1,93 @@ +import os +import shutil +import sys +from http import HTTPStatus +from pathlib import Path +from zipfile import ZipFile + +import requests + +BRANCH = "master" +URL = f"https://opensource.tbank.ru/invest/invest-contracts/-/archive/{BRANCH}/invest-contracts-{BRANCH}.zip?ref_type=heads" +OUTPUT_PATH = "protos/t_tech/invest/grpc" +PROTOS_TMP_ZIP = "protos.zip" +ZIP_PROTOS_ROOT_PATH_BRANCH = BRANCH.replace("/", "-") +ZIP_PROTOS_ROOT_PATH = f"invest-contracts-{ZIP_PROTOS_ROOT_PATH_BRANCH}" +ZIP_PROTOS_PATH = f"{ZIP_PROTOS_ROOT_PATH}/src/docs/contracts" +FILES = [ + "google/api/field_behavior.proto", + "common.proto", + "instruments.proto", + "marketdata.proto", + "operations.proto", + "orders.proto", + "sandbox.proto", + "signals.proto", + "stoporders.proto", + "users.proto", +] + +LINES_TO_REPLACE = [ + (f'import "{file_name}";', f'import "t_tech/invest/grpc/{file_name}";') + for file_name in FILES +] + + +def main() -> int: + _clear_in_start() + _download_protos() + _extract_protos() + _move_protos() + _clear_in_end() + _modify_protos() + return 0 + + +def _clear_in_start(): + shutil.rmtree(OUTPUT_PATH, ignore_errors=True) + + +def _download_protos(): + session = requests.session() + response = session.get(URL, stream=True) + if response.status_code != HTTPStatus.OK: + return + + with open(PROTOS_TMP_ZIP, "wb") as f: + for chunk in response: + f.write(chunk) + + +def _extract_protos(): + with ZipFile(PROTOS_TMP_ZIP) as zf: + for name in FILES: + zf.extract(f"{ZIP_PROTOS_PATH}/{name}", path=".") + + +def _move_protos(): + os.makedirs(OUTPUT_PATH, exist_ok=True) + for name in FILES: + folders = "/".join(name.split("/")[:-1]) + Path(f"{OUTPUT_PATH}/{folders}").mkdir(parents=True, exist_ok=True) + shutil.move(f"{ZIP_PROTOS_PATH}/{name}", f"{OUTPUT_PATH}/{folders}") + + +def _clear_in_end(): + os.remove(PROTOS_TMP_ZIP) + shutil.rmtree(ZIP_PROTOS_ROOT_PATH) + + +def _modify_protos(): + for name in FILES: + with open(f"{OUTPUT_PATH}/{name}", "r", encoding="utf-8") as f: + protofile_text = f.read() + + for str_to_replace, replaced_str in LINES_TO_REPLACE: + protofile_text = protofile_text.replace(str_to_replace, replaced_str) + + with open(f"{OUTPUT_PATH}/{name}", "w+", encoding="utf-8") as f: + f.write(protofile_text) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/invest-python-master/scripts/update_issue_templates.py b/invest-python-master/scripts/update_issue_templates.py new file mode 100644 index 0000000..8968081 --- /dev/null +++ b/invest-python-master/scripts/update_issue_templates.py @@ -0,0 +1,28 @@ +import sys + +import yaml + + +def add_version(version: str, file: str) -> None: + with open(file, "r", encoding="utf-8") as f: + data = yaml.safe_load(f) + for field in data["body"]: + if field.get("id", "") == "package-version": + field["attributes"]["options"] = [ + version, + *field["attributes"]["options"], + ] + with open(file, "w+", encoding="utf-8") as f: + yaml.dump( + data, f, default_flow_style=False, sort_keys=False, allow_unicode=True + ) + + +def main() -> None: + version = sys.argv[1] + add_version(version, ".github/ISSUE_TEMPLATE/bug_report.yaml") + add_version(version, ".github/ISSUE_TEMPLATE/issue.yaml") + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/scripts/update_package_version.py b/invest-python-master/scripts/update_package_version.py new file mode 100644 index 0000000..573f158 --- /dev/null +++ b/invest-python-master/scripts/update_package_version.py @@ -0,0 +1,23 @@ +import re +import sys + + +def set_version(new_value: str, constant_name: str, file_path: str) -> None: + with open(file_path, "r") as file: + file_data = file.read() + + constant_pattern = re.compile(rf'{constant_name}\s*=\s*["\'].*?["\']', re.MULTILINE) + file_data = constant_pattern.sub(f'{constant_name} = "{new_value}"', file_data) + + with open(file_path, "w") as file: + file.write(file_data) + + +def main() -> None: + version = sys.argv[1] + set_version(version, "__version__", "t_tech/invest/__init__.py") + set_version(version, "APP_VERSION", "t_tech/invest/constants.py") + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/scripts/version.py b/invest-python-master/scripts/version.py new file mode 100644 index 0000000..81d29e0 --- /dev/null +++ b/invest-python-master/scripts/version.py @@ -0,0 +1,59 @@ +import re +from typing import Tuple + +from tomlkit import loads + +Version = Tuple[str, str, str, str, str] + + +def main() -> None: + current_version = get_current_version() + print( # noqa:T201,T001 + version_to_str(next_beta_version(parse_version(version=current_version))) + ) + + +def get_current_version(): + with open("pyproject.toml", "r", encoding="utf-8") as f: + pyproject = loads(f.read()) + current_version: str = pyproject["project"]["version"] # type:ignore + return current_version + + +def parse_version(version: str) -> Version: + pattern = re.compile( + r"^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$" # noqa:E501 # pylint:disable=line-too-long + ) + match = pattern.search(version) + if not match: + raise ValueError(f"{version} is not a version") + + return tuple(n and str(n) or "" for n in match.groups(0)) # type:ignore + + +def next_beta_version(version: Version) -> Version: + major, minor, patch, prerelease, buildmetadata = version + if not prerelease: + return major, minor, str(int(patch) + 1), prerelease, buildmetadata + prerelease_n = int(remove_prefix(prerelease, "beta")) + return (major, minor, patch, "beta" + str(prerelease_n + 1), buildmetadata) + + +def version_to_str(version: Version) -> str: + major, minor, patch, prerelease, _ = version + return ( + f"{major}.{minor}.{patch}-{prerelease}" + if prerelease + else f"{major}.{minor}.{patch}" + ) + + +def remove_prefix(text: str, prefix: str) -> str: + if text.startswith(prefix): + prefix_len = len(prefix) + return text[prefix_len:] + return text + + +if __name__ == "__main__": + main() diff --git a/invest-python-master/t_tech/__init__.py b/invest-python-master/t_tech/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/invest-python-master/t_tech/invest/__init__.py b/invest-python-master/t_tech/invest/__init__.py new file mode 100644 index 0000000..f0f4eff --- /dev/null +++ b/invest-python-master/t_tech/invest/__init__.py @@ -0,0 +1,506 @@ +from .clients import AsyncClient, Client +from .exceptions import AioRequestError, InvestError, RequestError +from .logging import get_current_tracking_id +from .schemas import ( + AccessLevel, + Account, + AccountStatus, + AccountSubscriptionStatus, + AccountType, + AccruedInterest, + Asset, + AssetBond, + AssetClearingCertificate, + AssetCurrency, + AssetEtf, + AssetFull, + AssetInstrument, + AssetRequest, + AssetResponse, + AssetSecurity, + AssetShare, + AssetsRequest, + AssetsResponse, + AssetStructuredProduct, + AssetType, + Bond, + BondResponse, + BondsResponse, + Brand, + BrokerReportRequest, + BrokerReportResponse, + BuyLimitsView, + CancelOrderRequest, + CancelOrderResponse, + CancelStopOrderRequest, + CancelStopOrderResponse, + Candle, + CandleInstrument, + CandleInterval, + CandleSubscription, + CloseSandboxAccountRequest, + CloseSandboxAccountResponse, + CountryResponse, + Coupon, + CouponType, + CurrenciesResponse, + Currency, + CurrencyResponse, + Dividend, + DividendsForeignIssuerReport, + EditFavoritesActionType, + EditFavoritesRequest, + EditFavoritesRequestInstrument, + EditFavoritesResponse, + Etf, + EtfResponse, + EtfsResponse, + ExchangeOrderType, + ExtraBond, + ExtraFuture, + FavoriteInstrument, + FilterOptionsRequest, + FindInstrumentRequest, + FindInstrumentResponse, + Future, + FutureResponse, + FuturesResponse, + GenerateBrokerReportRequest, + GenerateDividendsForeignIssuerReportRequest, + GenerateDividendsForeignIssuerReportResponse, + GetAccountsRequest, + GetAccountsResponse, + GetAccruedInterestsRequest, + GetAccruedInterestsResponse, + GetAssetFundamentalsRequest, + GetAssetFundamentalsResponse, + GetBondCouponsRequest, + GetBondCouponsResponse, + GetBrandRequest, + GetBrandsRequest, + GetBrandsResponse, + GetBrokerReportRequest, + GetCandlesRequest, + GetCandlesResponse, + GetClosePricesRequest, + GetClosePricesResponse, + GetCountriesRequest, + GetCountriesResponse, + GetDividendsForeignIssuerReportRequest, + GetDividendsForeignIssuerReportResponse, + GetDividendsForeignIssuerRequest, + GetDividendsForeignIssuerResponse, + GetDividendsRequest, + GetDividendsResponse, + GetFavoritesRequest, + GetFavoritesResponse, + GetFuturesMarginRequest, + GetFuturesMarginResponse, + GetInfoRequest, + GetInfoResponse, + GetLastPricesRequest, + GetLastPricesResponse, + GetLastTradesRequest, + GetLastTradesResponse, + GetMarginAttributesRequest, + GetMarginAttributesResponse, + GetMaxLotsRequest, + GetMaxLotsResponse, + GetMySubscriptions, + GetOperationsByCursorRequest, + GetOperationsByCursorResponse, + GetOrderBookRequest, + GetOrderBookResponse, + GetOrderPriceRequest, + GetOrderPriceResponse, + GetOrdersRequest, + GetOrdersResponse, + GetOrderStateRequest, + GetStopOrdersRequest, + GetStopOrdersResponse, + GetTradingStatusRequest, + GetTradingStatusResponse, + GetUserTariffRequest, + GetUserTariffResponse, + HistoricCandle, + InfoInstrument, + InfoSubscription, + Instrument, + InstrumentClosePriceRequest, + InstrumentClosePriceResponse, + InstrumentIdType, + InstrumentLink, + InstrumentRequest, + InstrumentResponse, + InstrumentShort, + InstrumentsRequest, + InstrumentStatus, + InstrumentType, + LastPrice, + LastPriceInstrument, + LastPriceSubscription, + MarketDataRequest, + MarketDataResponse, + MarketDataServerSideStreamRequest, + MoneyValue, + OpenSandboxAccountRequest, + OpenSandboxAccountResponse, + Operation, + OperationItem, + OperationItemTrade, + OperationItemTrades, + OperationsRequest, + OperationsResponse, + OperationState, + OperationTrade, + OperationType, + Option, + OptionDirection, + OptionPaymentType, + OptionResponse, + OptionSettlementType, + OptionsResponse, + OptionStyle, + Order, + OrderBook, + OrderBookInstrument, + OrderBookSubscription, + OrderDirection, + OrderExecutionReportStatus, + OrderStage, + OrderState, + OrderTrade, + OrderTrades, + OrderType, + Page, + PortfolioPosition, + PortfolioRequest, + PortfolioResponse, + PortfolioStreamRequest, + PortfolioStreamResponse, + PortfolioSubscriptionResult, + PortfolioSubscriptionStatus, + PositionData, + PositionsAccountSubscriptionStatus, + PositionsMoney, + PositionsOptions, + PositionsRequest, + PositionsResponse, + PositionsSecurities, + PositionsStreamRequest, + PositionsStreamResponse, + PositionsSubscriptionResult, + PositionsSubscriptionStatus, + PostOrderRequest, + PostOrderResponse, + PostStopOrderRequest, + PostStopOrderRequestTrailingData, + PostStopOrderResponse, + PriceType, + Quotation, + RealExchange, + ReplaceOrderRequest, + SandboxPayInRequest, + SandboxPayInResponse, + SecurityTradingStatus, + SellLimitsView, + Share, + ShareResponse, + SharesResponse, + ShareType, + StatisticResponse, + StopOrder, + StopOrderDirection, + StopOrderExpirationType, + StopOrderStatusOption, + StopOrderTrailingData, + StopOrderType, + StreamLimit, + StructuredProductType, + SubscribeCandlesRequest, + SubscribeCandlesResponse, + SubscribeInfoRequest, + SubscribeInfoResponse, + SubscribeLastPriceRequest, + SubscribeLastPriceResponse, + SubscribeOrderBookRequest, + SubscribeOrderBookResponse, + SubscribeTradesRequest, + SubscribeTradesResponse, + SubscriptionAction, + SubscriptionInterval, + SubscriptionStatus, + TakeProfitType, + TimeInForceType, + Trade, + TradeDirection, + TradeInstrument, + TradesStreamRequest, + TradesStreamResponse, + TradeSubscription, + TradingDay, + TradingSchedule, + TradingSchedulesRequest, + TradingSchedulesResponse, + TradingStatus, + UnaryLimit, + WithdrawLimitsRequest, + WithdrawLimitsResponse, +) + +__version__ = "0.3.5" + +__all__ = ( + "__version__", + "AccessLevel", + "Account", + "AccountStatus", + "AccountSubscriptionStatus", + "AccountType", + "AccruedInterest", + "AioRequestError", + "Asset", + "AssetBond", + "AssetClearingCertificate", + "AssetCurrency", + "AssetEtf", + "AssetFull", + "AssetInstrument", + "AssetRequest", + "AssetResponse", + "AssetSecurity", + "AssetShare", + "AssetsRequest", + "AssetsResponse", + "AssetStructuredProduct", + "AssetType", + "AsyncClient", + "Bond", + "BondResponse", + "BondsResponse", + "Brand", + "BrokerReportRequest", + "BrokerReportResponse", + "BuyLimitsView", + "CancelOrderRequest", + "CancelOrderResponse", + "CancelStopOrderRequest", + "CancelStopOrderResponse", + "Candle", + "CandleInstrument", + "CandleInterval", + "CandleSubscription", + "Client", + "CloseSandboxAccountRequest", + "CloseSandboxAccountResponse", + "CountryResponse", + "Coupon", + "CouponType", + "CurrenciesResponse", + "Currency", + "CurrencyResponse", + "Dividend", + "DividendsForeignIssuerReport", + "EditFavoritesActionType", + "EditFavoritesRequest", + "EditFavoritesRequestInstrument", + "EditFavoritesResponse", + "Etf", + "EtfResponse", + "EtfsResponse", + "ExchangeOrderType", + "ExtraBond", + "ExtraFuture", + "FavoriteInstrument", + "FilterOptionsRequest", + "FindInstrumentRequest", + "FindInstrumentResponse", + "Future", + "FutureResponse", + "FuturesResponse", + "GenerateBrokerReportRequest", + "GenerateDividendsForeignIssuerReportRequest", + "GenerateDividendsForeignIssuerReportResponse", + "get_current_tracking_id", + "GetAccountsRequest", + "GetAccountsResponse", + "GetAccruedInterestsRequest", + "GetAccruedInterestsResponse", + "GetAssetFundamentalsRequest", + "GetAssetFundamentalsResponse", + "GetBondCouponsRequest", + "GetBondCouponsResponse", + "GetBrandRequest", + "GetBrandsRequest", + "GetBrandsResponse", + "GetBrokerReportRequest", + "GetCandlesRequest", + "GetCandlesResponse", + "GetClosePricesRequest", + "GetClosePricesResponse", + "GetCountriesRequest", + "GetCountriesResponse", + "GetDividendsForeignIssuerReportRequest", + "GetDividendsForeignIssuerReportResponse", + "GetDividendsForeignIssuerRequest", + "GetDividendsForeignIssuerResponse", + "GetDividendsRequest", + "GetDividendsResponse", + "GetFavoritesRequest", + "GetFavoritesResponse", + "GetFuturesMarginRequest", + "GetFuturesMarginResponse", + "GetInfoRequest", + "GetInfoResponse", + "GetLastPricesRequest", + "GetLastPricesResponse", + "GetLastTradesRequest", + "GetLastTradesResponse", + "GetMarginAttributesRequest", + "GetMarginAttributesResponse", + "GetMaxLotsRequest", + "GetMaxLotsResponse", + "GetMySubscriptions", + "GetOperationsByCursorRequest", + "GetOperationsByCursorResponse", + "GetOrderBookRequest", + "GetOrderBookResponse", + "GetOrderPriceRequest", + "GetOrderPriceResponse", + "GetOrdersRequest", + "GetOrdersResponse", + "GetOrderStateRequest", + "GetStopOrdersRequest", + "GetStopOrdersResponse", + "GetTradingStatusRequest", + "GetTradingStatusResponse", + "GetUserTariffRequest", + "GetUserTariffResponse", + "HistoricCandle", + "InfoInstrument", + "InfoSubscription", + "Instrument", + "InstrumentClosePriceRequest", + "InstrumentClosePriceResponse", + "InstrumentIdType", + "InstrumentLink", + "InstrumentRequest", + "InstrumentResponse", + "InstrumentShort", + "InstrumentsRequest", + "InstrumentStatus", + "InstrumentType", + "InvestError", + "LastPrice", + "LastPriceInstrument", + "LastPriceSubscription", + "MarketDataRequest", + "MarketDataResponse", + "MarketDataServerSideStreamRequest", + "MoneyValue", + "OpenSandboxAccountRequest", + "OpenSandboxAccountResponse", + "Operation", + "OperationItem", + "OperationItemTrade", + "OperationItemTrades", + "OperationsRequest", + "OperationsResponse", + "OperationState", + "OperationTrade", + "OperationType", + "Option", + "OptionDirection", + "OptionPaymentType", + "OptionResponse", + "OptionSettlementType", + "OptionsResponse", + "OptionStyle", + "Order", + "OrderBook", + "OrderBookInstrument", + "OrderBookSubscription", + "OrderDirection", + "OrderExecutionReportStatus", + "OrderStage", + "OrderState", + "OrderTrade", + "OrderTrades", + "OrderType", + "Page", + "PortfolioPosition", + "PortfolioRequest", + "PortfolioResponse", + "PortfolioStreamRequest", + "PortfolioStreamResponse", + "PortfolioSubscriptionResult", + "PortfolioSubscriptionStatus", + "PositionData", + "PositionsAccountSubscriptionStatus", + "PositionsMoney", + "PositionsOptions", + "PositionsRequest", + "PositionsResponse", + "PositionsSecurities", + "PositionsStreamRequest", + "PositionsStreamResponse", + "PositionsSubscriptionResult", + "PositionsSubscriptionStatus", + "PostOrderRequest", + "PostOrderResponse", + "PostStopOrderRequest", + "PostStopOrderRequestTrailingData", + "PostStopOrderResponse", + "PriceType", + "PriceType", + "Quotation", + "RealExchange", + "ReplaceOrderRequest", + "RequestError", + "SandboxPayInRequest", + "SandboxPayInResponse", + "SecurityTradingStatus", + "SellLimitsView", + "Share", + "ShareResponse", + "SharesResponse", + "ShareType", + "StatisticResponse", + "StopOrder", + "StopOrderDirection", + "StopOrderExpirationType", + "StopOrderStatusOption", + "StopOrderTrailingData", + "StopOrderType", + "StreamLimit", + "StructuredProductType", + "SubscribeCandlesRequest", + "SubscribeCandlesResponse", + "SubscribeInfoRequest", + "SubscribeInfoResponse", + "SubscribeLastPriceRequest", + "SubscribeLastPriceResponse", + "SubscribeOrderBookRequest", + "SubscribeOrderBookResponse", + "SubscribeTradesRequest", + "SubscribeTradesResponse", + "SubscriptionAction", + "SubscriptionInterval", + "SubscriptionStatus", + "TakeProfitType", + "TimeInForceType", + "Trade", + "TradeDirection", + "TradeInstrument", + "TradesStreamRequest", + "TradesStreamResponse", + "TradeSubscription", + "TradingDay", + "TradingSchedule", + "TradingSchedulesRequest", + "TradingSchedulesResponse", + "TradingStatus", + "UnaryLimit", + "WithdrawLimitsRequest", + "WithdrawLimitsResponse", +) diff --git a/invest-python-master/t_tech/invest/_error_hub.py b/invest-python-master/t_tech/invest/_error_hub.py new file mode 100644 index 0000000..f54bb89 --- /dev/null +++ b/invest-python-master/t_tech/invest/_error_hub.py @@ -0,0 +1,122 @@ +import datetime +import re +from functools import wraps +from typing import Any, Callable, Optional, cast + +import sentry_sdk +from grpc import StatusCode +from sentry_sdk.integrations.excepthook import ExcepthookIntegration +from sentry_sdk.types import Event + +from ._errors import TFunc +from .constants import ERROR_HUB_DSN, PACKAGE_NAME +from .exceptions import AioRequestError, RequestError + +__all__ = ( + "init_error_hub", + "async_init_error_hub", + "handle_error_hub_gen", + "handle_aio_error_hub_gen", +) + +BEARER_PATTERN = re.compile(r"Bearer\s+[a-zA-Z0-9\-_\.]+", re.IGNORECASE) + + +def sanitize_bearer_tokens(event, hint) -> Optional[Event]: + def _sanitize_value(value): + if isinstance(value, str): + return BEARER_PATTERN.sub("[***Filtered***]", value) + elif isinstance(value, dict): + return {k: _sanitize_value(v) for k, v in value.items()} + elif isinstance(value, (list, tuple)): + return [_sanitize_value(item) for item in value] + else: + return value + + if "exc_info" in hint: + exc_type, exc_value, traceback = hint["exc_info"] + if exc_type == RequestError or exc_type == AioRequestError: + status_code = exc_value.code + if status_code == StatusCode.UNAVAILABLE: + return _sanitize_value(event) + + return None + + +def init_error_hub(client): + import sentry_sdk + from sentry_sdk.integrations.modules import ModulesIntegration + + # noinspection PyProtectedMember + sentry_sdk.init( + dsn=ERROR_HUB_DSN, + send_default_pii=False, + integrations=[], + auto_enabling_integrations=False, + disabled_integrations=[ModulesIntegration(), ExcepthookIntegration()], + before_send=sanitize_bearer_tokens, + release=PACKAGE_NAME, + environment=client._target, + add_full_stack=False, + max_stack_frames=3, + max_breadcrumbs=3, + enable_logs=False, + ) + + +async def async_init_error_hub(client): + init_error_hub(client) + + +def handle_error_hub_gen() -> Callable[[TFunc], TFunc]: + def decorator(func: TFunc) -> TFunc: + # noinspection DuplicatedCode + @wraps(func) + def wrapper(*args: Any, **kwargs: Any) -> Any: + with sentry_sdk.new_scope() as scope: + stream_start = datetime.datetime.now() + scope.set_extra("stream_start", stream_start) + try: + for message in func(*args, **kwargs): + scope.set_extra("last_message", message) + yield message + except RequestError as e: + metadata = e.metadata + tracking_id = metadata.tracking_id if metadata else None + scope.set_extra("tracking_id", tracking_id) + scope.set_extra( + "stream_duration", datetime.datetime.now() - stream_start + ) + sentry_sdk.capture_exception(e) + raise + + return cast(TFunc, wrapper) + + return decorator + + +def handle_aio_error_hub_gen() -> Callable[[TFunc], TFunc]: + def decorator(func: TFunc) -> TFunc: + # noinspection DuplicatedCode + @wraps(func) + async def wrapper(*args: Any, **kwargs: Any) -> Any: + with sentry_sdk.new_scope() as scope: + stream_start = datetime.datetime.now() + scope.set_extra("stream_start", stream_start) + try: + async for message in func(*args, **kwargs): + scope.set_extra("last_message", message) + yield message + except AioRequestError as e: + metadata = e.metadata + tracking_id = metadata.tracking_id if metadata else None + scope.set_extra("tracking_id", tracking_id) + scope.set_extra( + "stream_duration", datetime.datetime.now() - stream_start + ) + sentry_sdk.capture_exception(e) + raise + + return cast(TFunc, wrapper) + + return decorator diff --git a/invest-python-master/t_tech/invest/_errors.py b/invest-python-master/t_tech/invest/_errors.py new file mode 100644 index 0000000..0ef4b37 --- /dev/null +++ b/invest-python-master/t_tech/invest/_errors.py @@ -0,0 +1,137 @@ +from functools import wraps +from typing import Any, Callable, TypeVar, cast + +from grpc import Call, RpcError, StatusCode +from grpc.aio import AioRpcError + +from .exceptions import ( + AioRequestError, + AioUnauthenticatedError, + RequestError, + UnauthenticatedError, +) +from .logging import get_metadata_from_aio_error, get_metadata_from_call, log_error + +TFunc = TypeVar("TFunc", bound=Callable[..., Any]) + + +def handle_request_error(name: str) -> Callable[[TFunc], TFunc]: + def decorator(func: TFunc) -> TFunc: + # noinspection DuplicatedCode + @wraps(func) + def wrapper(*args: Any, **kwargs: Any) -> Any: + try: + return func(*args, **kwargs) + except RpcError as e: + if issubclass(type(e), Call): + metadata = get_metadata_from_call(e) + tracking_id = metadata.tracking_id if metadata else None + log_error( + tracking_id, + name, + f"{e.code().name} {e.details()}", # type:ignore + ) + status_code = e.code() # type:ignore + details = e.details() # type:ignore + + if status_code == StatusCode.UNAUTHENTICATED: + raise UnauthenticatedError( + status_code, details, metadata + ) from e + + raise RequestError(status_code, details, metadata) from e + raise + + return cast(TFunc, wrapper) + + return decorator + + +def handle_request_error_gen(name: str) -> Callable[[TFunc], TFunc]: + def decorator(func: TFunc) -> TFunc: + # noinspection DuplicatedCode + @wraps(func) + def wrapper(*args: Any, **kwargs: Any) -> Any: + try: + for message in func(*args, **kwargs): + yield message + except RpcError as e: + if issubclass(type(e), Call): + metadata = get_metadata_from_call(e) + tracking_id = metadata.tracking_id if metadata else None + log_error( + tracking_id, + name, + f"{e.code().name} {e.details()}", # type:ignore + ) + status_code = e.code() # type:ignore + details = e.details() # type:ignore + + if status_code == StatusCode.UNAUTHENTICATED: + raise UnauthenticatedError( + status_code, details, metadata + ) from e + + raise RequestError(status_code, details, metadata) from e + raise + + return cast(TFunc, wrapper) + + return decorator + + +def handle_aio_request_error(name: str) -> Callable[[TFunc], TFunc]: + def decorator(func: TFunc) -> TFunc: + # noinspection DuplicatedCode + @wraps(func) + async def wrapper(*args: Any, **kwargs: Any) -> Any: + try: + return await func(*args, **kwargs) + except AioRpcError as e: + metadata = get_metadata_from_aio_error(e) + tracking_id = metadata.tracking_id if metadata else None + log_error( + tracking_id, + name, + f"{e.code().name} {e.details()}", # type:ignore + ) + status_code = e.code() # type:ignore + details = e.details() # type:ignore + + if status_code == StatusCode.UNAUTHENTICATED: + raise AioUnauthenticatedError(status_code, details, metadata) from e + + raise AioRequestError(status_code, details, metadata) from e + + return cast(TFunc, wrapper) + + return decorator + + +def handle_aio_request_error_gen(name: str) -> Callable[[TFunc], TFunc]: + def decorator(func: TFunc) -> TFunc: + # noinspection DuplicatedCode + @wraps(func) + async def wrapper(*args: Any, **kwargs: Any) -> Any: + try: + async for result in func(*args, **kwargs): + yield result + except AioRpcError as e: + metadata = get_metadata_from_aio_error(e) + tracking_id = metadata.tracking_id if metadata else None + log_error( + tracking_id, + name, + f"{e.code().name} {e.details()}", # type:ignore + ) + status_code = e.code() # type:ignore + details = e.details() # type:ignore + + if status_code == StatusCode.UNAUTHENTICATED: + raise AioUnauthenticatedError(status_code, details, metadata) from e + + raise AioRequestError(status_code, details, metadata) from e + + return cast(TFunc, wrapper) + + return decorator diff --git a/invest-python-master/t_tech/invest/_grpc_helpers.py b/invest-python-master/t_tech/invest/_grpc_helpers.py new file mode 100644 index 0000000..5df35ad --- /dev/null +++ b/invest-python-master/t_tech/invest/_grpc_helpers.py @@ -0,0 +1,500 @@ +# pylint:disable=no-name-in-module +import dataclasses +import enum +import logging +import os +from abc import ABC +from datetime import datetime, timedelta, timezone +from decimal import Decimal +from textwrap import dedent +from typing import ( + Any, + Dict, + Optional, + Tuple, + Type, + TypeVar, + Union, + get_args, + get_origin, + get_type_hints, +) + +from google.protobuf import symbol_database +from google.protobuf.message_factory import GetMessageClass +from google.protobuf.timestamp_pb2 import Timestamp + +_sym_db = symbol_database.Default() +NoneType = type(None) +logger = logging.getLogger(__name__) +T = TypeVar("T") + + +def ts_to_datetime(value: Timestamp) -> datetime: + ts = value.seconds + (value.nanos / 1e9) + return datetime(1970, 1, 1, tzinfo=timezone.utc) + timedelta(seconds=ts) + + +def datetime_to_ts(value: datetime) -> Tuple[int, int]: + seconds = int(value.timestamp()) + nanos = int(value.microsecond * 1e3) + return seconds, nanos + + +# Proto 3 data types +TYPE_ENUM = "enum" +TYPE_BOOL = "bool" +TYPE_INT32 = "int32" +TYPE_INT64 = "int64" +TYPE_UINT32 = "uint32" +TYPE_UINT64 = "uint64" +TYPE_SINT32 = "sint32" +TYPE_SINT64 = "sint64" +TYPE_FLOAT = "float" +TYPE_DOUBLE = "double" +TYPE_FIXED32 = "fixed32" +TYPE_SFIXED32 = "sfixed32" +TYPE_FIXED64 = "fixed64" +TYPE_SFIXED64 = "sfixed64" +TYPE_STRING = "string" +TYPE_BYTES = "bytes" +TYPE_MESSAGE = "message" +TYPE_MAP = "map" + +PLACEHOLDER: Any = object() + + +@dataclasses.dataclass(frozen=True) +class FieldMetadata: + """Stores internal metadata used for parsing & serialization.""" + + # Protobuf field number + number: int + # Protobuf type name + proto_type: str + # Map information if the proto_type is a map + map_types: Optional[Tuple[str, str]] = None + # Groups several "one-of" fields together + group: Optional[str] = None + # Describes the wrapped type (e.g. when using google.protobuf.BoolValue) + wraps: Optional[str] = None + # Is the field optional + optional: Optional[bool] = False + + @staticmethod + def get(field: dataclasses.Field) -> "FieldMetadata": + """Return the field metadata for a dataclass field.""" + return field.metadata["proto"] + + +def dataclass_field( + number: int, + proto_type: str, + *, + map_types: Optional[Tuple[str, str]] = None, + group: Optional[str] = None, + wraps: Optional[str] = None, + optional: bool = False, +) -> dataclasses.Field: + """Create a dataclass field with attached protobuf metadata.""" + return dataclasses.field( + default=None if optional else PLACEHOLDER, # type:ignore + metadata={ + "proto": FieldMetadata( + number, proto_type, map_types, group, wraps, optional + ) + }, + ) + + +def enum_field(number: int, group: Optional[str] = None, optional: bool = False) -> Any: + return dataclass_field(number, TYPE_ENUM, group=group, optional=optional) + + +def bool_field(number: int, group: Optional[str] = None, optional: bool = False) -> Any: + return dataclass_field(number, TYPE_BOOL, group=group, optional=optional) + + +def int32_field( + number: int, group: Optional[str] = None, optional: bool = False +) -> Any: + return dataclass_field(number, TYPE_INT32, group=group, optional=optional) + + +def int64_field( + number: int, group: Optional[str] = None, optional: bool = False +) -> Any: + return dataclass_field(number, TYPE_INT64, group=group, optional=optional) + + +def uint32_field( + number: int, group: Optional[str] = None, optional: bool = False +) -> Any: + return dataclass_field(number, TYPE_UINT32, group=group, optional=optional) + + +def uint64_field( + number: int, group: Optional[str] = None, optional: bool = False +) -> Any: + return dataclass_field(number, TYPE_UINT64, group=group, optional=optional) + + +def sint32_field( + number: int, group: Optional[str] = None, optional: bool = False +) -> Any: + return dataclass_field(number, TYPE_SINT32, group=group, optional=optional) + + +def sint64_field( + number: int, group: Optional[str] = None, optional: bool = False +) -> Any: + return dataclass_field(number, TYPE_SINT64, group=group, optional=optional) + + +def float_field( + number: int, group: Optional[str] = None, optional: bool = False +) -> Any: + return dataclass_field(number, TYPE_FLOAT, group=group, optional=optional) + + +def double_field( + number: int, group: Optional[str] = None, optional: bool = False +) -> Any: + return dataclass_field(number, TYPE_DOUBLE, group=group, optional=optional) + + +def fixed32_field( + number: int, group: Optional[str] = None, optional: bool = False +) -> Any: + return dataclass_field(number, TYPE_FIXED32, group=group, optional=optional) + + +def fixed64_field( + number: int, group: Optional[str] = None, optional: bool = False +) -> Any: + return dataclass_field(number, TYPE_FIXED64, group=group, optional=optional) + + +def sfixed32_field( + number: int, group: Optional[str] = None, optional: bool = False +) -> Any: + return dataclass_field(number, TYPE_SFIXED32, group=group, optional=optional) + + +def sfixed64_field( + number: int, group: Optional[str] = None, optional: bool = False +) -> Any: + return dataclass_field(number, TYPE_SFIXED64, group=group, optional=optional) + + +def string_field( + number: int, group: Optional[str] = None, optional: bool = False +) -> Any: + return dataclass_field(number, TYPE_STRING, group=group, optional=optional) + + +def bytes_field( + number: int, group: Optional[str] = None, optional: bool = False +) -> Any: + return dataclass_field(number, TYPE_BYTES, group=group, optional=optional) + + +def message_field( + number: int, + group: Optional[str] = None, + wraps: Optional[str] = None, + optional: bool = False, +) -> Any: + return dataclass_field( + number, TYPE_MESSAGE, group=group, wraps=wraps, optional=optional + ) + + +def map_field( + number: int, key_type: str, value_type: str, group: Optional[str] = None +) -> Any: + return dataclass_field( + number, TYPE_MAP, map_types=(key_type, value_type), group=group + ) + + +class Enum(enum.IntEnum): + @classmethod + def from_string(cls, name: str) -> "Enum": + try: + return cls._member_map_[name] # type: ignore # pylint:disable=no-member + except KeyError as e: + raise ValueError(f"Unknown value {name} for enum {cls.__name__}") from e + + +class Message: + ... + + +class Service(ABC): + _stub_factory: Any + + def __init__(self, channel, metadata): + self.stub = self._stub_factory(channel) + self.metadata = metadata + + +_UNKNOWN: Any = object() +PRIMITIVE_TYPES = (str, float, bool, int) + + +class UnknownType(TypeError): + pass + + +PYTHON_KEYWORDS = ( + "False", + "None", + "True", + "and", + "as", + "assert", + "async", + "await", + "break", + "class", + "continue", + "def", + "del", + "elif", + "else", + "except", + "finally", + "for", + "from", + "global", + "if", + "import", + "in", + "is", + "lambda", + "nonlocal", + "not", + "or", + "pass", + "raise", + "return", + "try", + "while", + "with", + "yield", +) + + +def to_unsafe_field_name(field_name: str) -> str: + if field_name.endswith("_"): + unsafe_field_name = field_name[:-1] + if unsafe_field_name in PYTHON_KEYWORDS: + return unsafe_field_name + return field_name + + +TEnum = TypeVar("TEnum", bound=Enum) +USE_DEFAULT_ENUM_IF_ERROR_ENV = "USE_DEFAULT_ENUM_IF_ERROR" + + +def _init_enum(enum_class: Type[TEnum], value: Any) -> TEnum: + """Defaults when value is not yet supported. + + Use USE_DEFAULT_ENUM_IF_ERROR to use default enum when value is not yet supported. + """ + use_default_enum_if_error = os.environ.get( + USE_DEFAULT_ENUM_IF_ERROR_ENV, "true" + ) in ( + "true", + "True", + "1", + ) + # todo think about using pydantic settings to parse env vars + + try: + return enum_class(value) + except ValueError as error: + if not use_default_enum_if_error: + raise ValueError( + f"Неизвестное значение '{value}' для enum '{enum_class.__name__}' " + f"доступные значения: {list(enum_class)}. " + f"Возможно сервер стал отдавать новые значения, " + f"в то время как sdk еще не обновлен. " + f"Для игнорирования ошибки установите " + f"переменную окружения {USE_DEFAULT_ENUM_IF_ERROR_ENV}=true" + ) from error + default_enum = enum_class(0) + logger.warning( + dedent( + """\ + Было получено неизвестное значение '%s' для enum '%s' + Доступные значения: %s. + Возможно сервер стал отдавать новые значения, + в то время как sdk еще не обновлен. + Сообщите об этой проблеме разработчикам библиотеки. + Установлено значение по умолчанию %s, ошибка проигнорирована + Для вызова ошибки установите переменную окружения %s=false + """ # noqa: RUF001 + ), + value, + enum_class.__name__, + list(enum_class), + default_enum, + USE_DEFAULT_ENUM_IF_ERROR_ENV, + ) + return default_enum + + +# pylint:disable=too-many-nested-blocks +# pylint:disable=too-many-branches +# pylint:disable=too-many-locals +# pylint:disable=too-many-nested-blocks +# pylint:disable=too-many-statements +def protobuf_to_dataclass(pb_obj: Any, dataclass_type: Type[T]) -> T: # noqa:C901 + dataclass_hints = get_type_hints(dataclass_type) + dataclass_dict: Dict[str, Any] = {} + dataclass_fields = dataclass_type.__dataclass_fields__ # type:ignore + for field_name, field_type in dataclass_hints.items(): + unsafe_field_name = to_unsafe_field_name(field_name) + pb_value = getattr(pb_obj, unsafe_field_name) + field_value = _UNKNOWN + oneof = dataclass_fields[field_name].metadata["proto"].group + if oneof and pb_obj.WhichOneof(oneof) != field_name: + dataclass_dict[field_name] = None + continue + + origin = get_origin(field_type) + if origin is None: + if field_type in PRIMITIVE_TYPES: + field_value = pb_value + if field_type == Decimal: + field_value = Decimal(str(pb_value)) + elif issubclass(field_type, datetime): + field_value = ts_to_datetime(pb_value) + elif dataclasses.is_dataclass(field_type): + field_value = protobuf_to_dataclass( + pb_value, + field_type if isinstance(field_type, type) else type(field_type), + ) + elif issubclass(field_type, Enum): + field_value = _init_enum(enum_class=field_type, value=pb_value) + elif origin == list: + args = get_args(field_type) + first_arg = args[0] + if first_arg in PRIMITIVE_TYPES: + field_value = pb_value + elif dataclasses.is_dataclass(first_arg): + field_value = [ + protobuf_to_dataclass( + item, + first_arg if isinstance(first_arg, type) else type(first_arg), + ) + for item in pb_value + ] + elif first_arg == Decimal: + field_value = [Decimal(str(item)) for item in pb_value] + elif first_arg == datetime: + field_value = [ts_to_datetime(item) for item in pb_value] + elif issubclass(field_type, Enum): + field_value = [ + _init_enum(enum_class=field_type, value=item) for item in pb_value + ] + if origin == Union: + args = get_args(field_type) + if len(args) > 2: + raise NotImplementedError( + "Union of more than 2 args is not supported yet." + ) + first_arg, second_arg = args[0], args[1] + if second_arg == NoneType and str(pb_value) == "": + field_value = None + elif first_arg in PRIMITIVE_TYPES: + field_value = pb_value + elif first_arg == Decimal: + field_value = Decimal(str(pb_value)) + elif issubclass(first_arg, datetime): + field_value = ts_to_datetime(pb_value) + elif dataclasses.is_dataclass(first_arg): + field_value = protobuf_to_dataclass( + pb_value, + first_arg if isinstance(first_arg, type) else type(first_arg), + ) + elif issubclass(first_arg, Enum): + field_value = _init_enum(enum_class=first_arg, value=pb_value) + + if field_value is _UNKNOWN: + raise UnknownType(f'type "{field_type}" unknown') + dataclass_dict[field_name] = field_value + return dataclass_type(**dataclass_dict) + + +def dataclass_to_protobuff(dataclass_obj: Any, protobuff_obj: T) -> T: # noqa:C901 + dataclass_type = type(dataclass_obj) + dataclass_hints = get_type_hints(dataclass_type) + if not dataclass_hints: + protobuff_obj.SetInParent() # type:ignore + return protobuff_obj + for field_name, field_type in dataclass_hints.items(): + field_value = getattr(dataclass_obj, field_name) + if field_value is PLACEHOLDER: + continue + origin = get_origin(field_type) + if origin is None: + _update_field(field_type, protobuff_obj, field_name, field_value) + elif origin == list: + args = get_args(field_type) + first_arg = args[0] + pb_value = getattr(protobuff_obj, field_name) + if first_arg in PRIMITIVE_TYPES: + pb_value.extend(item for item in field_value) + elif dataclasses.is_dataclass(first_arg): + descriptor = protobuff_obj.DESCRIPTOR # type:ignore + field_descriptor = descriptor.fields_by_name[field_name].message_type + type_ = GetMessageClass(field_descriptor) + pb_value.extend( + dataclass_to_protobuff(item, type_()) for item in field_value + ) + elif issubclass(first_arg, Enum): + pb_value.extend(item.value for item in field_value) + else: + raise UnknownType(f"type {field_type} unknown") + elif origin == Union: + args = get_args(field_type) + first_arg = args[0] + second_arg = args[1] + if second_arg != NoneType: + raise UnknownType(f"type {field_type} unknown") + + if field_value is None: + pass # just skip setting the field, since its set to None by default + else: + _update_field(first_arg, protobuff_obj, field_name, field_value) + else: + raise UnknownType(f"type {field_type} unknown") + + return protobuff_obj + + +def _update_field( + field_type: Type[Any], protobuff_obj: Any, field_name: str, field_value: Any +) -> None: + if field_type in PRIMITIVE_TYPES: + setattr(protobuff_obj, field_name, field_value) + elif issubclass(field_type, datetime): + field_name_ = field_name + if field_name == "from_": + field_name_ = "from" + pb_value = getattr(protobuff_obj, field_name_) + seconds, nanos = datetime_to_ts(field_value) + pb_value.seconds = seconds + pb_value.nanos = nanos + elif dataclasses.is_dataclass(field_type): + pb_value = getattr(protobuff_obj, field_name) + dataclass_to_protobuff(field_value, pb_value) + elif issubclass(field_type, Enum): + if isinstance(field_value, int): + field_value = field_type(field_value) + setattr(protobuff_obj, field_name, field_value.value) + else: + raise UnknownType(f"type {field_type} unknown") diff --git a/invest-python-master/t_tech/invest/async_services.py b/invest-python-master/t_tech/invest/async_services.py new file mode 100644 index 0000000..532781b --- /dev/null +++ b/invest-python-master/t_tech/invest/async_services.py @@ -0,0 +1,2447 @@ +# pylint:disable=redefined-builtin,too-many-lines +import asyncio +from datetime import datetime +from typing import AsyncGenerator, AsyncIterable, List, Optional + +import grpc +from deprecation import deprecated + +from . import _grpc_helpers, utils +from ._error_hub import handle_aio_error_hub_gen +from ._errors import handle_aio_request_error, handle_aio_request_error_gen +from .exceptions import RequestError +from .grpc import ( + instruments_pb2, + instruments_pb2_grpc, + marketdata_pb2, + marketdata_pb2_grpc, + operations_pb2, + operations_pb2_grpc, + orders_pb2, + orders_pb2_grpc, + sandbox_pb2, + sandbox_pb2_grpc, + signals_pb2, + signals_pb2_grpc, + stoporders_pb2, + stoporders_pb2_grpc, + users_pb2, + users_pb2_grpc, +) +from .logging import get_tracking_id_from_coro, log_request +from .market_data_stream.async_market_data_stream_manager import ( + AsyncMarketDataStreamManager, +) +from .metadata import get_metadata +from .schemas import ( + AssetRequest, + AssetResponse, + AssetsRequest, + AssetsResponse, + BondResponse, + BondsResponse, + Brand, + BrokerReportRequest, + BrokerReportResponse, + CancelOrderRequest, + CancelOrderResponse, + CancelStopOrderRequest, + CancelStopOrderResponse, + CandleInterval, + CandleSource, + CloseSandboxAccountRequest, + CloseSandboxAccountResponse, + CreateFavoriteGroupRequest, + CreateFavoriteGroupResponse, + CurrenciesResponse, + CurrencyResponse, + CurrencyTransferRequest, + CurrencyTransferResponse, + DeleteFavoriteGroupRequest, + DeleteFavoriteGroupResponse, + DfaResponse, + DfasRequest, + DfasResponse, + EditFavoritesActionType, + EditFavoritesRequest, + EditFavoritesRequestInstrument, + EditFavoritesResponse, + EtfResponse, + EtfsResponse, + ExchangeOrderType, + FilterOptionsRequest, + FindInstrumentRequest, + FindInstrumentResponse, + FutureResponse, + FuturesResponse, + GenerateBrokerReportRequest, + GenerateDividendsForeignIssuerReportRequest, + GetAccountsRequest, + GetAccountsResponse, + GetAccountValuesRequest, + GetAccountValuesResponse, + GetAccruedInterestsRequest, + GetAccruedInterestsResponse, + GetAssetFundamentalsRequest, + GetAssetFundamentalsResponse, + GetAssetReportsRequest, + GetAssetReportsResponse, + GetBankAccountsRequest, + GetBankAccountsResponse, + GetBondCouponsRequest, + GetBondCouponsResponse, + GetBondEventsRequest, + GetBondEventsResponse, + GetBrandRequest, + GetBrandsRequest, + GetBrandsResponse, + GetBrokerReportRequest, + GetCandlesRequest, + GetCandlesResponse, + GetClosePricesRequest, + GetClosePricesResponse, + GetConsensusForecastsRequest, + GetConsensusForecastsResponse, + GetCountriesRequest, + GetCountriesResponse, + GetDividendsForeignIssuerReportRequest, + GetDividendsForeignIssuerRequest, + GetDividendsForeignIssuerResponse, + GetDividendsRequest, + GetDividendsResponse, + GetFavoriteGroupsRequest, + GetFavoriteGroupsResponse, + GetFavoritesRequest, + GetFavoritesResponse, + GetForecastRequest, + GetForecastResponse, + GetFuturesMarginRequest, + GetFuturesMarginResponse, + GetInfoRequest, + GetInfoResponse, + GetInsiderDealsRequest, + GetInsiderDealsResponse, + GetLastPricesRequest, + GetLastPricesResponse, + GetLastTradesRequest, + GetLastTradesResponse, + GetMarginAttributesRequest, + GetMarginAttributesResponse, + GetMarketValuesRequest, + GetMarketValuesResponse, + GetMaxLotsRequest, + GetMaxLotsResponse, + GetOperationsByCursorRequest, + GetOperationsByCursorResponse, + GetOrderBookRequest, + GetOrderBookResponse, + GetOrderPriceRequest, + GetOrderPriceResponse, + GetOrdersRequest, + GetOrdersRequestFilters, + GetOrdersResponse, + GetOrderStateRequest, + GetSignalsRequest, + GetSignalsResponse, + GetStopOrdersRequest, + GetStopOrdersResponse, + GetStrategiesRequest, + GetStrategiesResponse, + GetTechAnalysisRequest, + GetTechAnalysisResponse, + GetTradingStatusesRequest, + GetTradingStatusesResponse, + GetTradingStatusRequest, + GetTradingStatusResponse, + GetUserTariffRequest, + GetUserTariffResponse, + HistoricCandle, + IndicativesRequest, + IndicativesResponse, + InstrumentClosePriceRequest, + InstrumentExchangeType, + InstrumentIdType, + InstrumentRequest, + InstrumentResponse, + InstrumentsRequest, + InstrumentStatus, + InstrumentType, + LastPriceType, + MarketDataRequest, + MarketDataResponse, + MarketDataServerSideStreamRequest, + MoneyValue, + OpenSandboxAccountRequest, + OpenSandboxAccountResponse, + OperationsRequest, + OperationsResponse, + OperationsStreamRequest, + OperationsStreamResponse, + OperationState, + OptionResponse, + OptionsResponse, + OrderDirection, + OrderExecutionReportStatus, + OrderIdType, + OrderState, + OrderStateStreamRequest, + OrderStateStreamResponse, + OrderType, + Page, + PayInRequest, + PayInResponse, + PingDelaySettings, + PortfolioRequest, + PortfolioResponse, + PortfolioStreamRequest, + PortfolioStreamResponse, + PositionsRequest, + PositionsResponse, + PositionsStreamRequest, + PositionsStreamResponse, + PostOrderAsyncRequest, + PostOrderAsyncResponse, + PostOrderRequest, + PostOrderResponse, + PostStopOrderRequest, + PostStopOrderRequestTrailingData, + PostStopOrderResponse, + PriceType, + Quotation, + ReplaceOrderRequest, + RiskRatesRequest, + RiskRatesResponse, + SandboxPayInRequest, + SandboxPayInResponse, + ShareResponse, + SharesResponse, + StopOrderDirection, + StopOrderExpirationType, + StopOrderStatusOption, + StopOrderType, + StructuredNoteResponse, + StructuredNotesResponse, + TakeProfitType, + TimeInForceType, + TradesStreamRequest, + TradesStreamResponse, + TradingSchedulesRequest, + TradingSchedulesResponse, + WithdrawLimitsRequest, + WithdrawLimitsResponse, +) +from .typedefs import AccountId +from .utils import get_intervals, now + +__all__ = ( + "AsyncServices", + "InstrumentsService", + "MarketDataService", + "MarketDataStreamService", + "OperationsService", + "OperationsStreamService", + "OrdersStreamService", + "OrdersService", + "UsersService", + "SandboxService", + "StopOrdersService", + "SignalsService", +) + + +class AsyncServices: + def __init__( + self, + channel: grpc.aio.Channel, + token: str, + sandbox_token: Optional[str] = None, + app_name: Optional[str] = None, + ) -> None: + metadata = get_metadata(token, app_name) + sandbox_metadata = get_metadata(sandbox_token or token, app_name) + self.instruments = InstrumentsService(channel, metadata) + self.market_data = MarketDataService(channel, metadata) + self.market_data_stream = MarketDataStreamService(channel, metadata) + self.operations = OperationsService(channel, metadata) + self.operations_stream = OperationsStreamService(channel, metadata) + self.orders_stream = OrdersStreamService(channel, metadata) + self.orders = OrdersService(channel, metadata) + self.users = UsersService(channel, metadata) + self.sandbox = SandboxService(channel, sandbox_metadata) + self.stop_orders = StopOrdersService(channel, metadata) + self.signals = SignalsService(channel, metadata) + + def create_market_data_stream(self) -> AsyncMarketDataStreamManager: + return AsyncMarketDataStreamManager(market_data_stream=self.market_data_stream) + + async def cancel_all_orders(self, account_id: AccountId) -> None: + orders_service: OrdersService = self.orders + stop_orders_service: StopOrdersService = self.stop_orders + + orders_response = await orders_service.get_orders(account_id=account_id) + await asyncio.gather( + *[ + orders_service.cancel_order( + account_id=account_id, order_id=order.order_id + ) + for order in orders_response.orders + ] + ) + + stop_orders_response = await stop_orders_service.get_stop_orders( + account_id=account_id + ) + await asyncio.gather( + *[ + stop_orders_service.cancel_stop_order( + account_id=account_id, stop_order_id=stop_order.stop_order_id + ) + for stop_order in stop_orders_response.stop_orders + ] + ) + + async def get_all_candles( + self, + *, + from_: datetime, + to: Optional[datetime] = None, + interval: CandleInterval = CandleInterval(0), + figi: str = "", + instrument_id: str = "", + candle_source_type: Optional[CandleSource] = None, + ) -> AsyncGenerator[HistoricCandle, None]: + to = to or now() + + for local_from_, local_to in get_intervals(interval, from_, to): + candles_response = await self.market_data.get_candles( + figi=figi, + interval=interval, + from_=local_from_, + to=local_to, + instrument_id=instrument_id, + candle_source_type=candle_source_type, + ) + for candle in candles_response.candles: + yield candle + + +class InstrumentsService(_grpc_helpers.Service): + _stub_factory = instruments_pb2_grpc.InstrumentsServiceStub + + @handle_aio_request_error("TradingSchedules") + async def trading_schedules( + self, + *, + exchange: str = "", + from_: Optional[datetime] = None, + to: Optional[datetime] = None, + ) -> TradingSchedulesResponse: + request = TradingSchedulesRequest() + request.exchange = exchange + if from_ is not None: + request.from_ = from_ + if to is not None: + request.to = to + response_coro = self.stub.TradingSchedules( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.TradingSchedulesRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "TradingSchedules") + return _grpc_helpers.protobuf_to_dataclass(response, TradingSchedulesResponse) + + # noinspection PyShadowingBuiltins + @handle_aio_request_error("BondBy") + async def bond_by( + self, + *, + id_type: InstrumentIdType = InstrumentIdType(0), + class_code: str = "", + id: str = "", + ) -> BondResponse: + request = InstrumentRequest() + request.id_type = id_type + request.class_code = class_code + request.id = id + response_coro = self.stub.BondBy( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "BondBy") + return _grpc_helpers.protobuf_to_dataclass(response, BondResponse) + + @handle_aio_request_error("Bonds") + async def bonds( + self, + *, + instrument_status: InstrumentStatus = InstrumentStatus(0), + instrument_exchange: InstrumentExchangeType = InstrumentExchangeType(0), + ) -> BondsResponse: + request = InstrumentsRequest() + request.instrument_status = instrument_status + request.instrument_exchange = instrument_exchange + response_coro = self.stub.Bonds( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "Bonds") + return _grpc_helpers.protobuf_to_dataclass(response, BondsResponse) + + # noinspection PyShadowingBuiltins + @handle_aio_request_error("CurrencyBy") + async def currency_by( + self, + *, + id_type: InstrumentIdType = InstrumentIdType(0), + class_code: str = "", + id: str = "", + ) -> CurrencyResponse: + request = InstrumentRequest() + request.id_type = id_type + request.class_code = class_code + request.id = id + response_coro = self.stub.CurrencyBy( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "CurrencyBy") + return _grpc_helpers.protobuf_to_dataclass(response, CurrencyResponse) + + @handle_aio_request_error("Currencies") + async def currencies( + self, + *, + instrument_status: InstrumentStatus = InstrumentStatus(0), + instrument_exchange: InstrumentExchangeType = InstrumentExchangeType(0), + ) -> CurrenciesResponse: + request = InstrumentsRequest() + request.instrument_status = instrument_status + request.instrument_exchange = instrument_exchange + response_coro = self.stub.Currencies( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "Currencies") + return _grpc_helpers.protobuf_to_dataclass(response, CurrenciesResponse) + + # noinspection PyShadowingBuiltins + @handle_aio_request_error("EtfBy") + async def etf_by( + self, + *, + id_type: InstrumentIdType = InstrumentIdType(0), + class_code: str = "", + id: str = "", + ) -> EtfResponse: + request = InstrumentRequest() + request.id_type = id_type + request.class_code = class_code + request.id = id + response_coro = self.stub.EtfBy( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "EtfBy") + return _grpc_helpers.protobuf_to_dataclass(response, EtfResponse) + + @handle_aio_request_error("Etfs") + async def etfs( + self, + *, + instrument_status: InstrumentStatus = InstrumentStatus(0), + instrument_exchange: InstrumentExchangeType = InstrumentExchangeType(0), + ) -> EtfsResponse: + request = InstrumentsRequest() + request.instrument_status = instrument_status + request.instrument_exchange = instrument_exchange + response_coro = self.stub.Etfs( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "Etfs") + return _grpc_helpers.protobuf_to_dataclass(response, EtfsResponse) + + # noinspection PyShadowingBuiltins + @handle_aio_request_error("FutureBy") + async def future_by( + self, + *, + id_type: InstrumentIdType = InstrumentIdType(0), + class_code: str = "", + id: str = "", + ) -> FutureResponse: + request = InstrumentRequest() + request.id_type = id_type + request.class_code = class_code + request.id = id + response_coro = self.stub.FutureBy( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "FutureBy") + return _grpc_helpers.protobuf_to_dataclass(response, FutureResponse) + + @handle_aio_request_error("Futures") + async def futures( + self, + *, + instrument_status: InstrumentStatus = InstrumentStatus(0), + instrument_exchange: InstrumentExchangeType = InstrumentExchangeType(0), + ) -> FuturesResponse: + request = InstrumentsRequest() + request.instrument_status = instrument_status + request.instrument_exchange = instrument_exchange + response_coro = self.stub.Futures( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "Futures") + return _grpc_helpers.protobuf_to_dataclass(response, FuturesResponse) + + # noinspection PyShadowingBuiltins + @handle_aio_request_error("OptionBy") + async def option_by( + self, + *, + id_type: InstrumentIdType = InstrumentIdType(0), + class_code: str = "", + id: str = "", + ) -> OptionResponse: + request = InstrumentRequest() + request.id_type = id_type + request.class_code = class_code + request.id = id + response_coro = self.stub.OptionBy( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "OptionBy") + return _grpc_helpers.protobuf_to_dataclass(response, OptionResponse) + + @deprecated(details="Use `Client.instruments.options_by(...)` method instead") + @handle_aio_request_error("Options") + async def options( + self, *, instrument_status: InstrumentStatus = InstrumentStatus(0) + ) -> OptionsResponse: + request = InstrumentsRequest() + request.instrument_status = instrument_status + response_coro = self.stub.Options( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "Options") + return _grpc_helpers.protobuf_to_dataclass(response, OptionsResponse) + + @handle_aio_request_error("OptionsBy") + async def options_by( + self, *, basic_asset_uid: str = "", basic_asset_position_uid: str = "" + ) -> OptionsResponse: + request = FilterOptionsRequest() + request.basic_asset_uid = basic_asset_uid + request.basic_asset_position_uid = basic_asset_position_uid + response_coro = self.stub.OptionsBy( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.FilterOptionsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "OptionsBy") + return _grpc_helpers.protobuf_to_dataclass(response, OptionsResponse) + + # noinspection PyShadowingBuiltins + @handle_aio_request_error("ShareBy") + async def share_by( + self, + *, + id_type: InstrumentIdType = InstrumentIdType(0), + class_code: str = "", + id: str = "", + ) -> ShareResponse: + request = InstrumentRequest() + request.id_type = id_type + request.class_code = class_code + request.id = id + response_coro = self.stub.ShareBy( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "ShareBy") + return _grpc_helpers.protobuf_to_dataclass(response, ShareResponse) + + @handle_aio_request_error("Shares") + async def shares( + self, + *, + instrument_status: InstrumentStatus = InstrumentStatus(0), + instrument_exchange: InstrumentExchangeType = InstrumentExchangeType(0), + ) -> SharesResponse: + request = InstrumentsRequest() + request.instrument_status = instrument_status + request.instrument_exchange = instrument_exchange + response_coro = self.stub.Shares( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "Shares") + return _grpc_helpers.protobuf_to_dataclass(response, SharesResponse) + + @handle_aio_request_error("Indicatives") + async def indicatives(self, request: IndicativesRequest) -> IndicativesResponse: + response_coro = self.stub.Indicatives( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "Indicatives") + return _grpc_helpers.protobuf_to_dataclass(response, IndicativesResponse) + + @handle_aio_request_error("GetAccruedInterests") + async def get_accrued_interests( + self, + *, + figi: str = "", + from_: Optional[datetime] = None, + to: Optional[datetime] = None, + instrument_id: str = "", + ) -> GetAccruedInterestsResponse: + request = GetAccruedInterestsRequest() + request.figi = figi + request.instrument_id = instrument_id + if from_ is not None: + request.from_ = from_ + if to is not None: + request.to = to + response_coro = self.stub.GetAccruedInterests( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetAccruedInterestsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request( + await get_tracking_id_from_coro(response_coro), "GetAccruedInterests" + ) + return _grpc_helpers.protobuf_to_dataclass( + response, GetAccruedInterestsResponse + ) + + @handle_aio_request_error("GetFuturesMargin") + async def get_futures_margin( + self, *, figi: str = "", instrument_id: str = "" + ) -> GetFuturesMarginResponse: + request = GetFuturesMarginRequest() + request.figi = figi + request.instrument_id = instrument_id + response_coro = self.stub.GetFuturesMargin( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetFuturesMarginRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetFuturesMargin") + return _grpc_helpers.protobuf_to_dataclass(response, GetFuturesMarginResponse) + + # noinspection PyShadowingBuiltins + @handle_aio_request_error("GetInstrumentBy") + async def get_instrument_by( + self, + *, + id_type: InstrumentIdType = InstrumentIdType(0), + class_code: str = "", + id: str = "", + ) -> InstrumentResponse: + request = InstrumentRequest() + request.id_type = id_type + request.class_code = class_code + request.id = id + response_coro = self.stub.GetInstrumentBy( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetInstrumentBy") + return _grpc_helpers.protobuf_to_dataclass(response, InstrumentResponse) + + @handle_aio_request_error("GetDividends") + async def get_dividends( + self, + *, + figi: str = "", + from_: Optional[datetime] = None, + to: Optional[datetime] = None, + instrument_id: str = "", + ) -> GetDividendsResponse: + request = GetDividendsRequest() + request.figi = figi + request.instrument_id = instrument_id + if from_ is not None: + request.from_ = from_ + if to is not None: + request.to = to + response_coro = self.stub.GetDividends( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetDividendsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetDividends") + return _grpc_helpers.protobuf_to_dataclass(response, GetDividendsResponse) + + @handle_aio_request_error("GetBondCoupons") + async def get_bond_coupons( + self, + *, + figi: str = "", + from_: Optional[datetime] = None, + to: Optional[datetime] = None, + instrument_id: str = "", + ) -> GetBondCouponsResponse: + request = GetBondCouponsRequest() + request.figi = figi + request.instrument_id = instrument_id + if from_ is not None: + request.from_ = from_ + if to is not None: + request.to = to + response_coro = self.stub.GetBondCoupons( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetBondCouponsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetBondCoupons") + return _grpc_helpers.protobuf_to_dataclass(response, GetBondCouponsResponse) + + @handle_aio_request_error("GetBondEvents") + async def get_bond_events( + self, request: GetBondEventsRequest + ) -> GetBondEventsResponse: + response_coro = self.stub.GetBondEvents( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetBondEventsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetBondEvents") + return _grpc_helpers.protobuf_to_dataclass(response, GetBondEventsResponse) + + # noinspection PyShadowingBuiltins + @handle_aio_request_error("GetAssetBy") + async def get_asset_by( + self, + *, + id: str = "", + ) -> AssetResponse: + request = AssetRequest() + request.id = id + response_coro = self.stub.GetAssetBy( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.AssetRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetAssetBy") + return _grpc_helpers.protobuf_to_dataclass(response, AssetResponse) + + @handle_aio_request_error("GetAssets") + async def get_assets( + self, + request: AssetsRequest, + ) -> AssetsResponse: + if request is None: + request = AssetsRequest() + response_coro = self.stub.GetAssets( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.AssetsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetAssets") + return _grpc_helpers.protobuf_to_dataclass(response, AssetsResponse) + + @handle_aio_request_error("GetFavorites") + async def get_favorites( + self, + *, + group_id: Optional[str] = None, + ) -> GetFavoritesResponse: + request = GetFavoritesRequest() + if group_id is not None: + request.group_id = group_id + response_coro = self.stub.GetFavorites( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetFavoritesRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetFavorites") + return _grpc_helpers.protobuf_to_dataclass(response, GetFavoritesResponse) + + @handle_aio_request_error("EditFavorites") + async def edit_favorites( + self, + *, + instruments: Optional[List[EditFavoritesRequestInstrument]] = None, + action_type: Optional[EditFavoritesActionType] = None, + group_id: Optional[str] = None, + ) -> EditFavoritesResponse: + request = EditFavoritesRequest() + if action_type is not None: + request.action_type = action_type + if instruments is not None: + request.instruments = instruments + if group_id is not None: + request.group_id = group_id + response_coro = self.stub.EditFavorites( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.EditFavoritesRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "EditFavorites") + return _grpc_helpers.protobuf_to_dataclass(response, EditFavoritesResponse) + + @handle_aio_request_error("CreateFavoriteGroup") + async def create_favorite_group( + self, + request: CreateFavoriteGroupRequest, + ) -> CreateFavoriteGroupResponse: + response_coro = self.stub.CreateFavoriteGroup( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.CreateFavoriteGroupRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request( + await get_tracking_id_from_coro(response_coro), "CreateFavoriteGroup" + ) + return _grpc_helpers.protobuf_to_dataclass( + response, CreateFavoriteGroupResponse + ) + + @handle_aio_request_error("DeleteFavoriteGroup") + async def delete_favorite_group( + self, + request: DeleteFavoriteGroupRequest, + ) -> DeleteFavoriteGroupResponse: + response_coro = self.stub.DeleteFavoriteGroup( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.DeleteFavoriteGroupRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request( + await get_tracking_id_from_coro(response_coro), "DeleteFavoriteGroup" + ) + return _grpc_helpers.protobuf_to_dataclass( + response, DeleteFavoriteGroupResponse + ) + + @handle_aio_request_error("GetFavoriteGroups") + async def get_favorite_groups( + self, + request: GetFavoriteGroupsRequest, + ) -> GetFavoriteGroupsResponse: + response_coro = self.stub.GetFavoriteGroups( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetFavoriteGroupsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetFavoriteGroups") + return _grpc_helpers.protobuf_to_dataclass(response, GetFavoriteGroupsResponse) + + @handle_aio_request_error("GetCountries") + async def get_countries( + self, + ) -> GetCountriesResponse: + request = GetCountriesRequest() + response_coro = self.stub.GetCountries( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetCountriesRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetCountries") + return _grpc_helpers.protobuf_to_dataclass(response, GetCountriesResponse) + + @handle_aio_request_error("FindInstrument") + async def find_instrument( + self, + *, + query: str = "", + instrument_kind: Optional[InstrumentType] = None, + api_trade_available_flag: Optional[bool] = None, + ) -> FindInstrumentResponse: + request = FindInstrumentRequest() + request.query = query + if instrument_kind is not None: + request.instrument_kind = instrument_kind + if api_trade_available_flag is not None: + request.api_trade_available_flag = api_trade_available_flag + response_coro = self.stub.FindInstrument( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.FindInstrumentRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "FindInstrument") + return _grpc_helpers.protobuf_to_dataclass(response, FindInstrumentResponse) + + @handle_aio_request_error("GetBrands") + async def get_brands( + self, + paging: Optional[Page] = None, + ) -> GetBrandsResponse: + request = GetBrandsRequest() + if paging is not None: + request.paging = paging + response_coro = self.stub.GetBrands( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetBrandsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetBrands") + return _grpc_helpers.protobuf_to_dataclass(response, GetBrandsResponse) + + # noinspection PyShadowingBuiltins + @handle_aio_request_error("GetBrandBy") + async def get_brands_by(self, id: str = "") -> Brand: + request = GetBrandRequest() + request.id = id + response_coro = self.stub.GetBrandBy( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetBrandRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetBrandBy") + return _grpc_helpers.protobuf_to_dataclass(response, Brand) + + @handle_aio_request_error("GetAssetFundamentals") + async def get_asset_fundamentals( + self, request: GetAssetFundamentalsRequest + ) -> GetAssetFundamentalsResponse: + response_coro = self.stub.GetAssetFundamentals( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetAssetFundamentalsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request( + await get_tracking_id_from_coro(response_coro), "GetAssetFundamentals" + ) + return _grpc_helpers.protobuf_to_dataclass( + response, GetAssetFundamentalsResponse + ) + + @handle_aio_request_error("GetAssetReports") + async def get_asset_reports( + self, request: GetAssetReportsRequest + ) -> GetAssetReportsResponse: + response_coro = self.stub.GetAssetReports( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetAssetReportsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetAssetReports") + return _grpc_helpers.protobuf_to_dataclass(response, GetAssetReportsResponse) + + @handle_aio_request_error("GetConsensusForecasts") + async def get_consensus_forecasts( + self, request: GetConsensusForecastsRequest + ) -> GetConsensusForecastsResponse: + response_coro = self.stub.GetConsensusForecasts( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetConsensusForecastsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request( + await get_tracking_id_from_coro(response_coro), "GetConsensusForecasts" + ) + return _grpc_helpers.protobuf_to_dataclass( + response, GetConsensusForecastsResponse + ) + + @handle_aio_request_error("GetForecastBy") + async def get_forecast_by(self, request: GetForecastRequest) -> GetForecastResponse: + response_coro = self.stub.GetForecastBy( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetForecastRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetForecastBy") + return _grpc_helpers.protobuf_to_dataclass(response, GetForecastResponse) + + @handle_aio_request_error("GetRiskRates") + async def get_risk_rates(self, request: RiskRatesRequest) -> RiskRatesResponse: + response_coro = self.stub.GetRiskRates( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.RiskRatesRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetRiskRates") + return _grpc_helpers.protobuf_to_dataclass(response, RiskRatesResponse) + + @handle_aio_request_error("GetInsiderDeals") + async def get_insider_deals( + self, request: GetInsiderDealsRequest + ) -> GetInsiderDealsResponse: + response_coro = self.stub.GetInsiderDeals( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetInsiderDealsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetInsiderDeals") + return _grpc_helpers.protobuf_to_dataclass(response, GetInsiderDealsResponse) + + @handle_aio_request_error("StructuredNoteBy") + async def get_structured_note_by( + self, request: InstrumentRequest + ) -> StructuredNoteResponse: + response_coro = self.stub.StructuredNoteBy( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "StructuredNoteBy") + return _grpc_helpers.protobuf_to_dataclass(response, StructuredNoteResponse) + + @handle_aio_request_error("StructuredNotes") + async def get_structured_notes( + self, request: InstrumentsRequest + ) -> StructuredNotesResponse: + response_coro = self.stub.StructuredNotes( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "StructuredNotes") + return _grpc_helpers.protobuf_to_dataclass(response, StructuredNotesResponse) + + @handle_aio_request_error("Dfas") + async def get_dfas(self) -> DfasResponse: + request = DfasRequest() + response_coro = self.stub.Dfas( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.DfasRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "Dfas") + return _grpc_helpers.protobuf_to_dataclass(response, DfasResponse) + + @handle_aio_request_error("DfaBy") + async def get_dfa_by(self, request: InstrumentRequest) -> DfaResponse: + response_coro = self.stub.DfaBy( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "DfaBy") + return _grpc_helpers.protobuf_to_dataclass(response, DfaResponse) + + +class MarketDataService(_grpc_helpers.Service): + _stub_factory = marketdata_pb2_grpc.MarketDataServiceStub + + @handle_aio_request_error("GetCandles") + async def get_candles( + self, + *, + figi: str = "", + from_: Optional[datetime] = None, + to: Optional[datetime] = None, + interval: CandleInterval = CandleInterval(0), + instrument_id: str = "", + candle_source_type: Optional[CandleSource] = None, + limit: Optional[int] = None, + ) -> GetCandlesResponse: + # noinspection DuplicatedCode + request = GetCandlesRequest() + request.figi = figi + request.instrument_id = instrument_id + request.candle_source_type = candle_source_type + if from_ is not None: + request.from_ = from_ + if to is not None: + request.to = to + if limit is not None: + request.limit = limit + request.interval = interval + response_coro = self.stub.GetCandles( + request=_grpc_helpers.dataclass_to_protobuff( + request, marketdata_pb2.GetCandlesRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetCandles") + return _grpc_helpers.protobuf_to_dataclass(response, GetCandlesResponse) + + @handle_aio_request_error("GetLastPrices") + async def get_last_prices( + self, + *, + figi: Optional[List[str]] = None, + instrument_id: Optional[List[str]] = None, + last_price_type: LastPriceType = LastPriceType.LAST_PRICE_UNSPECIFIED, + instrument_status: Optional[InstrumentStatus] = None, + ) -> GetLastPricesResponse: + figi = figi or [] + instrument_id = instrument_id or [] + + request = GetLastPricesRequest() + request.figi = figi + request.instrument_id = instrument_id + request.last_price_type = last_price_type + if instrument_status: + request.instrument_status = instrument_status + response_coro = self.stub.GetLastPrices( + request=_grpc_helpers.dataclass_to_protobuff( + request, marketdata_pb2.GetLastPricesRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetLastPrices") + return _grpc_helpers.protobuf_to_dataclass(response, GetLastPricesResponse) + + @handle_aio_request_error("GetOrderBook") + async def get_order_book( + self, *, figi: str = "", depth: int = 0, instrument_id: str = "" + ) -> GetOrderBookResponse: + request = GetOrderBookRequest() + request.figi = figi + request.instrument_id = instrument_id + request.depth = depth + response_coro = self.stub.GetOrderBook( + request=_grpc_helpers.dataclass_to_protobuff( + request, marketdata_pb2.GetOrderBookRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetOrderBook") + return _grpc_helpers.protobuf_to_dataclass(response, GetOrderBookResponse) + + @handle_aio_request_error("GetTradingStatus") + async def get_trading_status( + self, *, figi: str = "", instrument_id: str = "" + ) -> GetTradingStatusResponse: + request = GetTradingStatusRequest() + request.figi = figi + request.instrument_id = instrument_id + response_coro = self.stub.GetTradingStatus( + request=_grpc_helpers.dataclass_to_protobuff( + request, marketdata_pb2.GetTradingStatusRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetTradingStatus") + return _grpc_helpers.protobuf_to_dataclass(response, GetTradingStatusResponse) + + @handle_aio_request_error("GetTradingStatuses") + async def get_trading_statuses( + self, *, instrument_ids: Optional[List[str]] = None + ) -> GetTradingStatusesResponse: + request = GetTradingStatusesRequest() + if instrument_ids: + request.instrument_id = instrument_ids + response_coro = self.stub.GetTradingStatuses( + request=_grpc_helpers.dataclass_to_protobuff( + request, marketdata_pb2.GetTradingStatusesRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request( + await get_tracking_id_from_coro(response_coro), "GetTradingStatuses" + ) + return _grpc_helpers.protobuf_to_dataclass(response, GetTradingStatusesResponse) + + @handle_aio_request_error("GetLastTrades") + async def get_last_trades( + self, + *, + figi: str = "", + from_: Optional[datetime] = None, + to: Optional[datetime] = None, + instrument_id: str = "", + ) -> GetLastTradesResponse: + request = GetLastTradesRequest() + request.figi = figi + request.instrument_id = instrument_id + if from_ is not None: + request.from_ = from_ + if to is not None: + request.to = to + response_coro = self.stub.GetLastTrades( + request=_grpc_helpers.dataclass_to_protobuff( + request, marketdata_pb2.GetLastTradesRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetLastTrades") + return _grpc_helpers.protobuf_to_dataclass(response, GetLastTradesResponse) + + @handle_aio_request_error("GetClosePrices") + async def get_close_prices( + self, + *, + instruments: Optional[List[InstrumentClosePriceRequest]] = None, + instrument_status: Optional[InstrumentStatus] = None, + ) -> GetClosePricesResponse: + request = GetClosePricesRequest() + if instruments: + request.instruments = instruments + if instrument_status: + request.instrument_status = instrument_status + response_coro = self.stub.GetClosePrices( + request=_grpc_helpers.dataclass_to_protobuff( + request, marketdata_pb2.GetClosePricesRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetClosePrices") + return _grpc_helpers.protobuf_to_dataclass(response, GetClosePricesResponse) + + @handle_aio_request_error("GetTechAnalysis") + async def get_tech_analysis( + self, + *, + request: GetTechAnalysisRequest, + ) -> GetTechAnalysisResponse: + response_coro = self.stub.GetTechAnalysis( + request=_grpc_helpers.dataclass_to_protobuff( + request, marketdata_pb2.GetTechAnalysisRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetTechAnalysis") + return _grpc_helpers.protobuf_to_dataclass(response, GetTechAnalysisResponse) + + @handle_aio_request_error("GetMarketValues") + async def get_market_values( + self, + *, + request: GetMarketValuesRequest, + ) -> GetMarketValuesResponse: + response_coro = self.stub.GetMarketValues( + request=_grpc_helpers.dataclass_to_protobuff( + request, marketdata_pb2.GetMarketValuesRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetMarketValues") + return _grpc_helpers.protobuf_to_dataclass(response, GetMarketValuesResponse) + + +class MarketDataStreamService(_grpc_helpers.Service): + _stub_factory = marketdata_pb2_grpc.MarketDataStreamServiceStub + + @staticmethod + async def _convert_market_data_stream_request( + request_iterator: AsyncIterable[MarketDataRequest], + ) -> AsyncIterable[marketdata_pb2.MarketDataRequest]: + async for request in request_iterator: + yield _grpc_helpers.dataclass_to_protobuff( + request, marketdata_pb2.MarketDataRequest() + ) + + @staticmethod + async def _convert_market_data_server_side_stream_request( + request_iterator: AsyncIterable[MarketDataServerSideStreamRequest], + ) -> AsyncIterable[marketdata_pb2.MarketDataServerSideStreamRequest]: + async for request in request_iterator: + yield _grpc_helpers.dataclass_to_protobuff( + request, marketdata_pb2.MarketDataServerSideStreamRequest() + ) + + @handle_aio_error_hub_gen() + @handle_aio_request_error_gen("MarketDataStream") + async def market_data_stream( + self, + request_iterator: AsyncIterable[MarketDataRequest], + ) -> AsyncIterable[MarketDataResponse]: + async for response in self.stub.MarketDataStream( + request_iterator=self._convert_market_data_stream_request(request_iterator), + metadata=self.metadata, + ): + yield _grpc_helpers.protobuf_to_dataclass(response, MarketDataResponse) + + @handle_aio_error_hub_gen() + @handle_aio_request_error_gen("MarketDataServerSideStream") + async def market_data_server_side_stream( + self, + request_iterator: AsyncIterable[MarketDataServerSideStreamRequest], + ) -> AsyncIterable[MarketDataResponse]: + async for response in self.stub.MarketDataServerSideStream( + request_iterator=self._convert_market_data_server_side_stream_request( + request_iterator + ), + metadata=self.metadata, + ): + yield _grpc_helpers.protobuf_to_dataclass(response, MarketDataResponse) + + +class OperationsService(_grpc_helpers.Service): + _stub_factory = operations_pb2_grpc.OperationsServiceStub + + @handle_aio_request_error("GetOperations") + async def get_operations( + self, + *, + account_id: str = "", + from_: Optional[datetime] = None, + to: Optional[datetime] = None, + state: OperationState = OperationState(0), + figi: str = "", + ) -> OperationsResponse: + request = OperationsRequest() + request.account_id = account_id + if from_ is not None: + request.from_ = from_ + if to is not None: + request.to = to + request.state = state + request.figi = figi + response_coro = self.stub.GetOperations( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.OperationsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetOperations") + return _grpc_helpers.protobuf_to_dataclass(response, OperationsResponse) + + @handle_aio_request_error("GetPortfolio") + async def get_portfolio(self, *, account_id: str = "") -> PortfolioResponse: + request = PortfolioRequest() + request.account_id = account_id + response_coro = self.stub.GetPortfolio( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.PortfolioRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetPortfolio") + return _grpc_helpers.protobuf_to_dataclass(response, PortfolioResponse) + + @handle_aio_request_error("GetPositions") + async def get_positions(self, *, account_id: str = "") -> PositionsResponse: + request = PositionsRequest() + request.account_id = account_id + response_coro = self.stub.GetPositions( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.PositionsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetPositions") + return _grpc_helpers.protobuf_to_dataclass(response, PositionsResponse) + + @handle_aio_request_error("GetWithdrawLimits") + async def get_withdraw_limits( + self, *, account_id: str = "" + ) -> WithdrawLimitsResponse: + request = WithdrawLimitsRequest() + request.account_id = account_id + response_coro = self.stub.GetWithdrawLimits( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.WithdrawLimitsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetWithdrawLimits") + return _grpc_helpers.protobuf_to_dataclass(response, WithdrawLimitsResponse) + + @handle_aio_request_error("GetBrokerReport") + async def get_broker_report( + self, + *, + generate_broker_report_request: Optional[GenerateBrokerReportRequest] = None, + get_broker_report_request: Optional[GetBrokerReportRequest] = None, + ) -> BrokerReportResponse: + request = BrokerReportRequest() + if generate_broker_report_request: + request.generate_broker_report_request = generate_broker_report_request + if get_broker_report_request: + request.get_broker_report_request = get_broker_report_request + response_coro = self.stub.GetBrokerReport( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.BrokerReportRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetBrokerReport") + return _grpc_helpers.protobuf_to_dataclass(response, BrokerReportResponse) + + @handle_aio_request_error("GetDividendsForeignIssuer") + async def get_dividends_foreign_issuer( + self, + *, + generate_div_foreign_issuer_report: Optional[ + GenerateDividendsForeignIssuerReportRequest + ] = None, + get_div_foreign_issuer_report: Optional[ + GetDividendsForeignIssuerReportRequest + ] = None, + ) -> GetDividendsForeignIssuerResponse: + request = GetDividendsForeignIssuerRequest() + if generate_div_foreign_issuer_report is not None: + request.generate_div_foreign_issuer_report = ( + generate_div_foreign_issuer_report + ) + if get_div_foreign_issuer_report is not None: + request.get_div_foreign_issuer_report = get_div_foreign_issuer_report + response_coro = self.stub.GetDividendsForeignIssuer( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.GetDividendsForeignIssuerRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request( + await get_tracking_id_from_coro(response_coro), "GetDividendsForeignIssuer" + ) + return _grpc_helpers.protobuf_to_dataclass( + response, GetDividendsForeignIssuerResponse + ) + + @handle_aio_request_error("GetOperationsByCursor") + async def get_operations_by_cursor( + self, + request: GetOperationsByCursorRequest, + ) -> GetOperationsByCursorResponse: + response_coro = self.stub.GetOperationsByCursor( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.GetOperationsByCursorRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request( + await get_tracking_id_from_coro(response_coro), "GetOperationsByCursor" + ) + return _grpc_helpers.protobuf_to_dataclass( + response, GetOperationsByCursorResponse + ) + + +class OperationsStreamService(_grpc_helpers.Service): + _stub_factory = operations_pb2_grpc.OperationsStreamServiceStub + + @handle_aio_error_hub_gen() + @handle_aio_request_error_gen("PortfolioStream") + async def portfolio_stream( + self, + *, + accounts: Optional[List[str]] = None, + ping_delay_ms: Optional[int] = None, + ) -> AsyncIterable[PortfolioStreamResponse]: + request = PortfolioStreamRequest() + if accounts: + request.accounts = accounts + else: + raise ValueError("accounts can not be empty") + ping_settings = PingDelaySettings() + if ping_delay_ms is not None: + ping_settings.ping_delay_ms = ping_delay_ms + request.ping_settings = ping_settings + async for response in self.stub.PortfolioStream( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.PortfolioStreamRequest() + ), + metadata=self.metadata, + ): + yield _grpc_helpers.protobuf_to_dataclass(response, PortfolioStreamResponse) + + @handle_aio_error_hub_gen() + @handle_aio_request_error_gen("PositionsStream") + async def positions_stream( + self, + *, + accounts: Optional[List[str]] = None, + ping_delay_ms: Optional[int] = None, + with_initial_positions: Optional[bool] = None, + ) -> AsyncIterable[PositionsStreamResponse]: + # noinspection DuplicatedCode + request = PositionsStreamRequest() + if accounts: + request.accounts = accounts + else: + raise ValueError("accounts can not be empty") + ping_settings = PingDelaySettings() + if ping_delay_ms is not None: + ping_settings.ping_delay_ms = ping_delay_ms + request.ping_settings = ping_settings + if with_initial_positions: + request.with_initial_positions = with_initial_positions + async for response in self.stub.PositionsStream( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.PositionsStreamRequest() + ), + metadata=self.metadata, + ): + yield _grpc_helpers.protobuf_to_dataclass(response, PositionsStreamResponse) + + @handle_aio_error_hub_gen() + @handle_aio_request_error_gen("OperationsStream") + async def operations_stream( + self, + request: OperationsStreamRequest, + ) -> AsyncIterable[OperationsStreamResponse]: + async for response in self.stub.OperationsStream( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.OperationsStreamRequest() + ), + metadata=self.metadata, + ): + yield _grpc_helpers.protobuf_to_dataclass( + response, OperationsStreamResponse + ) + + +class OrdersStreamService(_grpc_helpers.Service): + _stub_factory = orders_pb2_grpc.OrdersStreamServiceStub + + @handle_aio_error_hub_gen() + @handle_aio_request_error_gen("TradesStream") + async def trades_stream( + self, *, accounts: Optional[List[str]] = None + ) -> AsyncIterable[TradesStreamResponse]: + request = TradesStreamRequest() + if accounts: + request.accounts = accounts + else: + raise ValueError("accounts can not be empty") + async for response in self.stub.TradesStream( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.TradesStreamRequest() + ), + metadata=self.metadata, + ): + yield _grpc_helpers.protobuf_to_dataclass(response, TradesStreamResponse) + + @handle_aio_error_hub_gen() + @handle_aio_request_error_gen("OrderStateStream") + async def order_state_stream( + self, *, request: OrderStateStreamRequest + ) -> AsyncIterable[OrderStateStreamResponse]: + async for response in self.stub.OrderStateStream( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.OrderStateStreamRequest() + ), + metadata=self.metadata, + ): + yield _grpc_helpers.protobuf_to_dataclass( + response, OrderStateStreamResponse + ) + + +class OrdersService(_grpc_helpers.Service): + _stub_factory = orders_pb2_grpc.OrdersServiceStub + + @handle_aio_request_error("PostOrder") + async def post_order( + self, + *, + figi: str = "", + quantity: int = 0, + price: Optional[Quotation] = None, + direction: OrderDirection = OrderDirection(0), + account_id: str = "", + order_type: OrderType = OrderType(0), + order_id: str = "", + instrument_id: str = "", + time_in_force: TimeInForceType = TimeInForceType(0), + price_type: PriceType = PriceType(0), + confirm_margin_trade: bool = False, + ) -> PostOrderResponse: + # noinspection DuplicatedCode + request = PostOrderRequest() + request.figi = figi + request.instrument_id = instrument_id + request.quantity = quantity + if price is not None: + request.price = price + request.direction = direction + request.account_id = account_id + request.order_type = order_type + if not utils.empty_or_uuid(order_id): + raise RequestError( + grpc.StatusCode.INVALID_ARGUMENT, + "order_id should be empty or uuid", + None, + ) + request.order_id = order_id + request.time_in_force = time_in_force + request.price_type = price_type + if confirm_margin_trade: + request.confirm_margin_trade = confirm_margin_trade + response_coro = self.stub.PostOrder( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.PostOrderRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "PostOrder") + return _grpc_helpers.protobuf_to_dataclass(response, PostOrderResponse) + + @handle_aio_request_error("PostOrderAsync") + async def post_order_async( + self, request: PostOrderAsyncRequest + ) -> PostOrderAsyncResponse: + if not utils.empty_or_uuid(request.order_id): + raise RequestError( + grpc.StatusCode.INVALID_ARGUMENT, + "order_id should be empty or uuid", + None, + ) + response_coro = self.stub.PostOrderAsync( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.PostOrderAsyncRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "PostOrderAsync") + return _grpc_helpers.protobuf_to_dataclass(response, PostOrderAsyncResponse) + + @handle_aio_request_error("CancelOrder") + async def cancel_order( + self, + *, + account_id: str = "", + order_id: str = "", + order_id_type: Optional["OrderIdType"] = None, + ) -> CancelOrderResponse: + request = CancelOrderRequest() + request.account_id = account_id + request.order_id = order_id + request.order_id_type = order_id_type + response_coro = self.stub.CancelOrder( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.CancelOrderRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "CancelOrder") + return _grpc_helpers.protobuf_to_dataclass(response, CancelOrderResponse) + + @handle_aio_request_error("GetOrderState") + async def get_order_state( + self, + *, + account_id: str = "", + order_id: str = "", + price_type: PriceType = PriceType(0), + order_id_type: Optional["OrderIdType"] = None, + ) -> OrderState: + request = GetOrderStateRequest() + request.account_id = account_id + request.order_id = order_id + request.price_type = price_type + request.order_id_type = order_id_type + response_coro = self.stub.GetOrderState( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.GetOrderStateRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetOrderState") + return _grpc_helpers.protobuf_to_dataclass(response, OrderState) + + @handle_aio_request_error("GetOrders") + async def get_orders( + self, + *, + account_id: str = "", + from_: Optional[datetime] = None, + to: Optional[datetime] = None, + execution_status: Optional[List[OrderExecutionReportStatus]] = None, + ) -> GetOrdersResponse: + # noinspection DuplicatedCode + request = GetOrdersRequest() + request.account_id = account_id + request.advanced_filters = GetOrdersRequestFilters() + if from_ is not None: + request.advanced_filters.from_ = from_ + if to is not None: + request.advanced_filters.to = to + if execution_status is not None: + request.advanced_filters.execution_status = execution_status + response_coro = self.stub.GetOrders( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.GetOrdersRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetOrders") + return _grpc_helpers.protobuf_to_dataclass(response, GetOrdersResponse) + + @handle_aio_request_error("ReplaceOrder") + async def replace_order(self, request: ReplaceOrderRequest) -> PostOrderResponse: + response_coro = self.stub.ReplaceOrder( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.ReplaceOrderRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "ReplaceOrder") + return _grpc_helpers.protobuf_to_dataclass(response, PostOrderResponse) + + @handle_aio_request_error("GetMaxLots") + async def get_max_lots(self, request: GetMaxLotsRequest) -> GetMaxLotsResponse: + response_coro = self.stub.GetMaxLots( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.GetMaxLotsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetMaxLots") + return _grpc_helpers.protobuf_to_dataclass(response, GetMaxLotsResponse) + + @handle_aio_request_error("GetOrderPrice") + async def get_order_price( + self, request: GetOrderPriceRequest + ) -> GetOrderPriceResponse: + response_coro = self.stub.GetOrderPrice( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.GetOrderPriceRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetOrderPrice") + return _grpc_helpers.protobuf_to_dataclass(response, GetOrderPriceResponse) + + +class UsersService(_grpc_helpers.Service): + _stub_factory = users_pb2_grpc.UsersServiceStub + + @handle_aio_request_error("GetAccounts") + async def get_accounts(self) -> GetAccountsResponse: + request = GetAccountsRequest() + response_coro = self.stub.GetAccounts( + request=_grpc_helpers.dataclass_to_protobuff( + request, users_pb2.GetAccountsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetAccounts") + return _grpc_helpers.protobuf_to_dataclass(response, GetAccountsResponse) + + @handle_aio_request_error("GetMarginAttributes") + async def get_margin_attributes( + self, *, account_id: str = "" + ) -> GetMarginAttributesResponse: + request = GetMarginAttributesRequest() + request.account_id = account_id + response_coro = self.stub.GetMarginAttributes( + request=_grpc_helpers.dataclass_to_protobuff( + request, users_pb2.GetMarginAttributesRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request( + await get_tracking_id_from_coro(response_coro), "GetMarginAttributes" + ) + return _grpc_helpers.protobuf_to_dataclass( + response, GetMarginAttributesResponse + ) + + @handle_aio_request_error("GetUserTariff") + async def get_user_tariff(self) -> GetUserTariffResponse: + request = GetUserTariffRequest() + response_coro = self.stub.GetUserTariff( + request=_grpc_helpers.dataclass_to_protobuff( + request, users_pb2.GetUserTariffRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetUserTariff") + return _grpc_helpers.protobuf_to_dataclass(response, GetUserTariffResponse) + + @handle_aio_request_error("GetInfo") + async def get_info(self) -> GetInfoResponse: + request = GetInfoRequest() + response_coro = self.stub.GetInfo( + request=_grpc_helpers.dataclass_to_protobuff( + request, users_pb2.GetInfoRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetInfo") + return _grpc_helpers.protobuf_to_dataclass(response, GetInfoResponse) + + @handle_aio_request_error("GetBankAccounts") + async def get_bank_accounts(self) -> GetBankAccountsResponse: + request = GetBankAccountsRequest() + response_coro = self.stub.GetBankAccounts( + request=_grpc_helpers.dataclass_to_protobuff( + request, users_pb2.GetBankAccountsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetBankAccounts") + return _grpc_helpers.protobuf_to_dataclass(response, GetBankAccountsResponse) + + @handle_aio_request_error("CurrencyTransfer") + async def currency_transfer( + self, request: CurrencyTransferRequest + ) -> CurrencyTransferResponse: + response_coro = self.stub.CurrencyTransfer( + request=_grpc_helpers.dataclass_to_protobuff( + request, users_pb2.CurrencyTransferRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "CurrencyTransfer") + return _grpc_helpers.protobuf_to_dataclass(response, CurrencyTransferResponse) + + @handle_aio_request_error("PayIn") + async def pay_in(self, request: PayInRequest) -> PayInResponse: + response_coro = self.stub.PayIn( + request=_grpc_helpers.dataclass_to_protobuff( + request, users_pb2.PayInRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "PayIn") + return _grpc_helpers.protobuf_to_dataclass(response, PayInResponse) + + @handle_aio_request_error("GetAccountValues") + async def get_account_values( + self, request: GetAccountValuesRequest + ) -> GetAccountValuesResponse: + response_coro = self.stub.GetAccountValues( + request=_grpc_helpers.dataclass_to_protobuff( + request, users_pb2.GetAccountValuesRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetAccountValues") + return _grpc_helpers.protobuf_to_dataclass(response, GetAccountValuesResponse) + + +class SandboxService(_grpc_helpers.Service): + _stub_factory = sandbox_pb2_grpc.SandboxServiceStub + + @handle_aio_request_error("OpenSandboxAccount") + async def open_sandbox_account( + self, name: Optional[str] = "" + ) -> OpenSandboxAccountResponse: + request = OpenSandboxAccountRequest() + request.name = name + response_coro = self.stub.OpenSandboxAccount( + request=_grpc_helpers.dataclass_to_protobuff( + request, sandbox_pb2.OpenSandboxAccountRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request( + await get_tracking_id_from_coro(response_coro), "OpenSandboxAccount" + ) + return _grpc_helpers.protobuf_to_dataclass(response, OpenSandboxAccountResponse) + + @handle_aio_request_error("GetSandboxAccounts") + async def get_sandbox_accounts(self) -> GetAccountsResponse: + request = GetAccountsRequest() + response_coro = self.stub.GetSandboxAccounts( + request=_grpc_helpers.dataclass_to_protobuff( + request, users_pb2.GetAccountsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request( + await get_tracking_id_from_coro(response_coro), "GetSandboxAccounts" + ) + return _grpc_helpers.protobuf_to_dataclass(response, GetAccountsResponse) + + @handle_aio_request_error("CloseSandboxAccount") + async def close_sandbox_account( + self, *, account_id: str = "" + ) -> CloseSandboxAccountResponse: + request = CloseSandboxAccountRequest() + request.account_id = account_id + response_coro = self.stub.CloseSandboxAccount( + request=_grpc_helpers.dataclass_to_protobuff( + request, sandbox_pb2.CloseSandboxAccountRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request( + await get_tracking_id_from_coro(response_coro), "CloseSandboxAccount" + ) + return _grpc_helpers.protobuf_to_dataclass( + response, CloseSandboxAccountResponse + ) + + @handle_aio_request_error("PostSandboxOrder") + async def post_sandbox_order( + self, + *, + figi: str = "", + quantity: int = 0, + price: Optional[Quotation] = None, + direction: OrderDirection = OrderDirection(0), + account_id: str = "", + order_type: OrderType = OrderType(0), + order_id: str = "", + instrument_id: str = "", + time_in_force: TimeInForceType = TimeInForceType(0), + price_type: PriceType = PriceType(0), + ) -> PostOrderResponse: + # noinspection DuplicatedCode + request = PostOrderRequest() + request.figi = figi + request.instrument_id = instrument_id + request.quantity = quantity + if price is not None: + request.price = price + request.direction = direction + request.account_id = account_id + request.order_type = order_type + if not utils.empty_or_uuid(order_id): + raise RequestError( + grpc.StatusCode.INVALID_ARGUMENT, + "order_id should be empty or uuid", + None, + ) + request.order_id = order_id + request.time_in_force = time_in_force + request.price_type = price_type + response_coro = self.stub.PostSandboxOrder( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.PostOrderRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "PostSandboxOrder") + return _grpc_helpers.protobuf_to_dataclass(response, PostOrderResponse) + + @handle_aio_request_error("ReplaceSandboxOrder") + async def replace_sandbox_order( + self, + request: "ReplaceOrderRequest", + ) -> PostOrderResponse: + response_coro = self.stub.ReplaceSandboxOrder( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.ReplaceOrderRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request( + await get_tracking_id_from_coro(response_coro), "ReplaceSandboxOrder" + ) + return _grpc_helpers.protobuf_to_dataclass(response, PostOrderResponse) + + @handle_aio_request_error("GetSandboxOrders") + async def get_sandbox_orders(self, *, account_id: str = "") -> GetOrdersResponse: + request = GetOrdersRequest() + request.account_id = account_id + response_coro = self.stub.GetSandboxOrders( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.GetOrdersRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetSandboxOrders") + return _grpc_helpers.protobuf_to_dataclass(response, GetOrdersResponse) + + @handle_aio_request_error("CancelSandboxOrder") + async def cancel_sandbox_order( + self, + *, + account_id: str = "", + order_id: str = "", + order_id_type: Optional["OrderIdType"] = None, + ) -> CancelOrderResponse: + request = CancelOrderRequest() + request.account_id = account_id + request.order_id = order_id + request.order_id_type = order_id_type + response_coro = self.stub.CancelSandboxOrder( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.CancelOrderRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request( + await get_tracking_id_from_coro(response_coro), "CancelSandboxOrder" + ) + return _grpc_helpers.protobuf_to_dataclass(response, CancelOrderResponse) + + @handle_aio_request_error("GetSandboxOrderState") + async def get_sandbox_order_state( + self, + *, + account_id: str = "", + order_id: str = "", + price_type: PriceType = PriceType(0), + order_id_type: Optional["OrderIdType"] = None, + ) -> OrderState: + request = GetOrderStateRequest() + request.account_id = account_id + request.order_id = order_id + request.price_type = price_type + request.order_id_type = order_id_type + response_coro = self.stub.GetSandboxOrderState( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.GetOrderStateRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request( + await get_tracking_id_from_coro(response_coro), "GetSandboxOrderState" + ) + return _grpc_helpers.protobuf_to_dataclass(response, OrderState) + + @handle_aio_request_error("GetSandboxPositions") + async def get_sandbox_positions(self, *, account_id: str = "") -> PositionsResponse: + request = PositionsRequest() + request.account_id = account_id + response_coro = self.stub.GetSandboxPositions( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.PositionsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request( + await get_tracking_id_from_coro(response_coro), "GetSandboxPositions" + ) + return _grpc_helpers.protobuf_to_dataclass(response, PositionsResponse) + + @handle_aio_request_error("GetSandboxOperations") + async def get_sandbox_operations( + self, + *, + account_id: str = "", + from_: Optional[datetime] = None, + to: Optional[datetime] = None, + state: OperationState = OperationState(0), + figi: str = "", + ) -> OperationsResponse: + request = OperationsRequest() + request.account_id = account_id + if from_ is not None: + request.from_ = from_ + if to is not None: + request.to = to + request.state = state + request.figi = figi + response_coro = self.stub.GetSandboxOperations( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.OperationsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request( + await get_tracking_id_from_coro(response_coro), "GetSandboxOperations" + ) + return _grpc_helpers.protobuf_to_dataclass(response, OperationsResponse) + + @handle_aio_request_error("GetSandboxPortfolio") + async def get_sandbox_portfolio(self, *, account_id: str = "") -> PortfolioResponse: + request = PortfolioRequest() + request.account_id = account_id + response_coro = self.stub.GetSandboxPortfolio( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.PortfolioRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request( + await get_tracking_id_from_coro(response_coro), "GetSandboxPortfolio" + ) + return _grpc_helpers.protobuf_to_dataclass(response, PortfolioResponse) + + @handle_aio_request_error("SandboxPayIn") + async def sandbox_pay_in( + self, *, account_id: str = "", amount: Optional[MoneyValue] = None + ) -> SandboxPayInResponse: + request = SandboxPayInRequest() + request.account_id = account_id + if amount is not None: + request.amount = amount + response_coro = self.stub.SandboxPayIn( + request=_grpc_helpers.dataclass_to_protobuff( + request, sandbox_pb2.SandboxPayInRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "SandboxPayIn") + return _grpc_helpers.protobuf_to_dataclass(response, SandboxPayInResponse) + + @handle_aio_request_error("GetSandboxWithdrawLimits") + async def get_sandbox_withdraw_limits( + self, + *, + account_id: str = "", + ) -> WithdrawLimitsResponse: + request = WithdrawLimitsRequest() + request.account_id = account_id + response_coro = self.stub.GetSandboxWithdrawLimits( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.WithdrawLimitsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request( + await get_tracking_id_from_coro(response_coro), "GetSandboxWithdrawLimits" + ) + return _grpc_helpers.protobuf_to_dataclass(response, WithdrawLimitsResponse) + + @handle_aio_request_error("GetSandboxMaxLots") + async def get_sandbox_max_lots( + self, + *, + request: GetMaxLotsRequest, + ) -> GetMaxLotsResponse: + response_coro = self.stub.GetSandboxMaxLots( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.GetMaxLotsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetSandboxMaxLots") + return _grpc_helpers.protobuf_to_dataclass(response, GetMaxLotsResponse) + + @handle_aio_request_error("PostSandboxOrderAsync") + async def post_sandbox_order_async( + self, + *, + request: "PostOrderAsyncRequest", + ) -> PostOrderAsyncResponse: + response_coro = self.stub.PostSandboxOrderAsync( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.PostOrderAsyncRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request( + await get_tracking_id_from_coro(response_coro), "PostSandboxOrderAsync" + ) + return _grpc_helpers.protobuf_to_dataclass(response, PostOrderAsyncResponse) + + @handle_aio_request_error("PostSandboxStopOrder") + async def post_sandbox_stop_order( + self, *, request: "PostStopOrderRequest" + ) -> PostStopOrderResponse: + response_coro = self.stub.PostSandboxStopOrder( + request=_grpc_helpers.dataclass_to_protobuff( + request, stoporders_pb2.PostStopOrderRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request( + await get_tracking_id_from_coro(response_coro), "PostSandboxStopOrder" + ) + return _grpc_helpers.protobuf_to_dataclass(response, PostStopOrderResponse) + + @handle_aio_request_error("GetSandboxStopOrders") + async def get_sandbox_stop_orders( + self, *, request: "GetStopOrdersRequest" + ) -> GetStopOrdersResponse: + response_coro = self.stub.GetSandboxStopOrders( + request=_grpc_helpers.dataclass_to_protobuff( + request, stoporders_pb2.GetStopOrdersRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request( + await get_tracking_id_from_coro(response_coro), "GetSandboxStopOrders" + ) + return _grpc_helpers.protobuf_to_dataclass(response, GetStopOrdersResponse) + + @handle_aio_request_error("CancelSandboxStopOrder") + async def cancel_sandbox_stop_order( + self, *, request: "CancelStopOrderRequest" + ) -> CancelStopOrderResponse: + response_coro = self.stub.CancelSandboxStopOrder( + request=_grpc_helpers.dataclass_to_protobuff( + request, stoporders_pb2.CancelStopOrderRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request( + await get_tracking_id_from_coro(response_coro), "CancelSandboxStopOrder" + ) + return _grpc_helpers.protobuf_to_dataclass(response, CancelStopOrderResponse) + + @handle_aio_request_error("GetSandboxOrderPrice") + async def get_sandbox_order_price( + self, request: GetOrderPriceRequest + ) -> GetOrderPriceResponse: + response_coro = self.stub.GetSandboxOrderPrice( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.GetOrderPriceRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request( + await get_tracking_id_from_coro(response_coro), "GetSandboxOrderPrice" + ) + return _grpc_helpers.protobuf_to_dataclass(response, GetOrderPriceResponse) + + +class StopOrdersService(_grpc_helpers.Service): + _stub_factory = stoporders_pb2_grpc.StopOrdersServiceStub + + @handle_aio_request_error("PostStopOrder") + async def post_stop_order( + self, + *, + figi: str = "", + quantity: int = 0, + price: Optional[Quotation] = None, + stop_price: Optional[Quotation] = None, + direction: StopOrderDirection = StopOrderDirection(0), + account_id: str = "", + expiration_type: StopOrderExpirationType = StopOrderExpirationType(0), + stop_order_type: StopOrderType = StopOrderType(0), + expire_date: Optional[datetime] = None, + instrument_id: str = "", + exchange_order_type: ExchangeOrderType = ExchangeOrderType(0), + take_profit_type: TakeProfitType = TakeProfitType(0), + trailing_data: Optional[PostStopOrderRequestTrailingData] = None, + price_type: PriceType = PriceType(0), + order_id: str = "", + confirm_margin_trade: bool = False, + instant_execution: Optional[bool] = None, + ) -> PostStopOrderResponse: + # noinspection DuplicatedCode + request = PostStopOrderRequest() + request.figi = figi + request.instrument_id = instrument_id + request.quantity = quantity + if price is not None: + request.price = price + if stop_price is not None: + request.stop_price = stop_price + request.direction = direction + request.account_id = account_id + request.expiration_type = expiration_type + request.stop_order_type = stop_order_type + if expire_date is not None: + request.expire_date = expire_date + request.exchange_order_type = exchange_order_type + request.take_profit_type = take_profit_type + if trailing_data is not None: + request.trailing_data = trailing_data + request.price_type = price_type + request.order_id = order_id + if confirm_margin_trade: + request.confirm_margin_trade = confirm_margin_trade + if instant_execution is not None: + request.instant_execution = instant_execution + response_coro = self.stub.PostStopOrder( + request=_grpc_helpers.dataclass_to_protobuff( + request, stoporders_pb2.PostStopOrderRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "PostStopOrder") + return _grpc_helpers.protobuf_to_dataclass(response, PostStopOrderResponse) + + @handle_aio_request_error("GetStopOrders") + async def get_stop_orders( + self, + *, + account_id: str = "", + status: StopOrderStatusOption = StopOrderStatusOption(0), + from_: Optional[datetime] = None, + to: Optional[datetime] = None, + ) -> GetStopOrdersResponse: + request = GetStopOrdersRequest() + request.account_id = account_id + request.status = status + if from_ is not None: + request.from_ = from_ + if to is not None: + request.to = to + response_coro = self.stub.GetStopOrders( + request=_grpc_helpers.dataclass_to_protobuff( + request, stoporders_pb2.GetStopOrdersRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetStopOrders") + return _grpc_helpers.protobuf_to_dataclass(response, GetStopOrdersResponse) + + @handle_aio_request_error("CancelStopOrder") + async def cancel_stop_order( + self, *, account_id: str = "", stop_order_id: str = "" + ) -> CancelStopOrderResponse: + request = CancelStopOrderRequest() + request.account_id = account_id + request.stop_order_id = stop_order_id + response_coro = self.stub.CancelStopOrder( + request=_grpc_helpers.dataclass_to_protobuff( + request, stoporders_pb2.CancelStopOrderRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "CancelStopOrder") + return _grpc_helpers.protobuf_to_dataclass(response, CancelStopOrderResponse) + + +class SignalsService(_grpc_helpers.Service): + _stub_factory = signals_pb2_grpc.SignalServiceStub + + @handle_aio_request_error("GetSignals") + async def get_signals( + self, + *, + request: GetSignalsRequest, + ) -> GetSignalsResponse: + response_coro = self.stub.GetSignals( + request=_grpc_helpers.dataclass_to_protobuff( + request, signals_pb2.GetSignalsRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetSignals") + return _grpc_helpers.protobuf_to_dataclass(response, GetSignalsResponse) + + @handle_aio_request_error("GetStrategies") + async def get_strategies( + self, + *, + request: GetStrategiesRequest, + ) -> GetStrategiesResponse: + response_coro = self.stub.GetStrategies( + request=_grpc_helpers.dataclass_to_protobuff( + request, signals_pb2.GetStrategiesRequest() + ), + metadata=self.metadata, + ) + response = await response_coro + log_request(await get_tracking_id_from_coro(response_coro), "GetStrategies") + return _grpc_helpers.protobuf_to_dataclass(response, GetStrategiesResponse) diff --git a/invest-python-master/t_tech/invest/caching/__init__.py b/invest-python-master/t_tech/invest/caching/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/invest-python-master/t_tech/invest/caching/instruments_cache/__init__.py b/invest-python-master/t_tech/invest/caching/instruments_cache/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/invest-python-master/t_tech/invest/caching/instruments_cache/instrument_storage.py b/invest-python-master/t_tech/invest/caching/instruments_cache/instrument_storage.py new file mode 100644 index 0000000..636b0b7 --- /dev/null +++ b/invest-python-master/t_tech/invest/caching/instruments_cache/instrument_storage.py @@ -0,0 +1,70 @@ +import logging +from dataclasses import replace +from typing import Dict, Generic, Tuple, TypeVar, cast + +from t_tech.invest import InstrumentIdType +from t_tech.invest.caching.instruments_cache.models import ( + InstrumentResponse, + InstrumentsResponse, +) + +logger = logging.getLogger(__name__) + + +TInstrumentResponse = TypeVar("TInstrumentResponse", bound=InstrumentResponse) +TInstrumentsResponse = TypeVar("TInstrumentsResponse", bound=InstrumentsResponse) + + +class InstrumentStorage(Generic[TInstrumentResponse, TInstrumentsResponse]): + def __init__(self, instruments_response: TInstrumentsResponse): + self._instruments_response = instruments_response + + self._instrument_by_class_code_figi: Dict[ + Tuple[str, str], InstrumentResponse + ] = { + (instrument.class_code, instrument.figi): instrument + for instrument in self._instruments_response.instruments + } + self._instrument_by_class_code_ticker: Dict[ + Tuple[str, str], InstrumentResponse + ] = { + (instrument.class_code, instrument.ticker): instrument + for instrument in self._instruments_response.instruments + } + self._instrument_by_class_code_uid: Dict[ + Tuple[str, str], InstrumentResponse + ] = { + (instrument.class_code, instrument.uid): instrument + for instrument in self._instruments_response.instruments + } + + # fmt: off + self._instrument_by_class_code_id_index = { + InstrumentIdType.INSTRUMENT_ID_UNSPECIFIED: + self._instrument_by_class_code_figi, + InstrumentIdType.INSTRUMENT_ID_TYPE_FIGI: + self._instrument_by_class_code_figi, + InstrumentIdType.INSTRUMENT_ID_TYPE_TICKER: + self._instrument_by_class_code_ticker, + InstrumentIdType.INSTRUMENT_ID_TYPE_UID: + self._instrument_by_class_code_uid, + } + # fmt: on + + def get( + self, *, id_type: InstrumentIdType, class_code: str, id: str + ) -> TInstrumentResponse: + logger.debug( + "Cache request id_type=%s, class_code=%s, id=%s", id_type, class_code, id + ) + instrument_by_class_code_id = self._instrument_by_class_code_id_index[id_type] + logger.debug( + "Index for %s found: \n%s", id_type, instrument_by_class_code_id.keys() + ) + key = (class_code, id) + logger.debug("Cache request key=%s", key) + + return cast(TInstrumentResponse, instrument_by_class_code_id[key]) + + def get_instruments_response(self) -> TInstrumentsResponse: + return replace(self._instruments_response, **{}) diff --git a/invest-python-master/t_tech/invest/caching/instruments_cache/instruments_cache.py b/invest-python-master/t_tech/invest/caching/instruments_cache/instruments_cache.py new file mode 100644 index 0000000..1b106fa --- /dev/null +++ b/invest-python-master/t_tech/invest/caching/instruments_cache/instruments_cache.py @@ -0,0 +1,203 @@ +import logging +from typing import cast + +from t_tech.invest import ( + Bond, + BondResponse, + BondsResponse, + CurrenciesResponse, + Currency, + CurrencyResponse, + Etf, + EtfResponse, + EtfsResponse, + Future, + FutureResponse, + FuturesResponse, + InstrumentIdType, + InstrumentStatus, + Share, + ShareResponse, + SharesResponse, +) +from t_tech.invest.caching.instruments_cache.instrument_storage import InstrumentStorage +from t_tech.invest.caching.instruments_cache.interface import IInstrumentsGetter +from t_tech.invest.caching.instruments_cache.models import ( + InstrumentResponse, + InstrumentsResponse, +) +from t_tech.invest.caching.instruments_cache.protocol import InstrumentsResponseCallable +from t_tech.invest.caching.instruments_cache.settings import InstrumentsCacheSettings +from t_tech.invest.caching.overrides import TTLCache +from t_tech.invest.services import InstrumentsService + +logger = logging.getLogger(__name__) + + +class InstrumentsCache(IInstrumentsGetter): + def __init__( + self, + settings: InstrumentsCacheSettings, + instruments_service: InstrumentsService, + ): + self._settings = settings + self._instruments_service = instruments_service + + logger.debug("Initialising instruments cache") + self._instruments_methods = [ + self.shares, + self.futures, + self.etfs, + self.bonds, + self.currencies, + ] + self._cache: TTLCache = TTLCache( + maxsize=len(self._instruments_methods), + ttl=self._settings.ttl.total_seconds(), + ) + self._refresh_cache() + + def _refresh_cache(self): + logger.debug("Refreshing instruments cache") + for instruments_method in self._instruments_methods: + instruments_method() + self._assert_cache() + + def _assert_cache(self): + if self._cache.keys() != {f.__name__ for f in self._instruments_methods}: + raise KeyError(f"Cache does not have all instrument types {self._cache}") + + def _get_instrument_storage( + self, get_instruments_method: InstrumentsResponseCallable + ) -> InstrumentStorage[InstrumentResponse, InstrumentsResponse]: + storage_key = get_instruments_method.__name__ + storage = self._cache.get(storage_key) + if storage is not None: + logger.debug("Got storage for key %s from cache", storage_key) + return storage + logger.debug( + "Storage for key %s not found, creating new storage with ttl=%s", + storage_key, + self._cache.ttl, + ) + instruments_response = get_instruments_method( + instrument_status=InstrumentStatus.INSTRUMENT_STATUS_ALL + ) + storage = InstrumentStorage(instruments_response=instruments_response) + self._cache[storage_key] = storage + return storage # noqa:R504 + + def shares( + self, *, instrument_status: InstrumentStatus = InstrumentStatus(0) + ) -> SharesResponse: + storage = cast( + InstrumentStorage[ShareResponse, SharesResponse], # type: ignore + self._get_instrument_storage(self._instruments_service.shares), + ) + return storage.get_instruments_response() + + def share_by( + self, + *, + id_type: InstrumentIdType = InstrumentIdType(0), + class_code: str = "", + id: str = "", + ) -> ShareResponse: + storage = cast( + InstrumentStorage[Share, SharesResponse], # type: ignore + self._get_instrument_storage(self._instruments_service.shares), + ) + share = storage.get(id_type=id_type, class_code=class_code, id=id) + return ShareResponse(instrument=share) + + def futures( + self, *, instrument_status: InstrumentStatus = InstrumentStatus(0) + ) -> FuturesResponse: + storage = cast( + InstrumentStorage[FutureResponse, FuturesResponse], # type: ignore + self._get_instrument_storage(self._instruments_service.futures), + ) + return storage.get_instruments_response() + + def future_by( + self, + *, + id_type: InstrumentIdType = InstrumentIdType(0), + class_code: str = "", + id: str = "", + ) -> FutureResponse: + storage = cast( + InstrumentStorage[Future, FuturesResponse], # type: ignore + self._get_instrument_storage(self._instruments_service.futures), + ) + future = storage.get(id_type=id_type, class_code=class_code, id=id) + return FutureResponse(instrument=future) + + def etfs( + self, *, instrument_status: InstrumentStatus = InstrumentStatus(0) + ) -> EtfsResponse: + storage = cast( + InstrumentStorage[EtfResponse, EtfsResponse], # type: ignore + self._get_instrument_storage(self._instruments_service.etfs), + ) + return storage.get_instruments_response() + + def etf_by( + self, + *, + id_type: InstrumentIdType = InstrumentIdType(0), + class_code: str = "", + id: str = "", + ) -> EtfResponse: + storage = cast( + InstrumentStorage[Etf, EtfsResponse], # type: ignore + self._get_instrument_storage(self._instruments_service.etfs), + ) + etf = storage.get(id_type=id_type, class_code=class_code, id=id) + return EtfResponse(instrument=etf) + + def bonds( + self, *, instrument_status: InstrumentStatus = InstrumentStatus(0) + ) -> BondsResponse: + storage = cast( + InstrumentStorage[BondResponse, BondsResponse], # type: ignore + self._get_instrument_storage(self._instruments_service.bonds), + ) + return storage.get_instruments_response() + + def bond_by( + self, + *, + id_type: InstrumentIdType = InstrumentIdType(0), + class_code: str = "", + id: str = "", + ) -> BondResponse: + storage = cast( + InstrumentStorage[Bond, BondsResponse], # type: ignore + self._get_instrument_storage(self._instruments_service.bonds), + ) + bond = storage.get(id_type=id_type, class_code=class_code, id=id) + return BondResponse(instrument=bond) + + def currencies( + self, *, instrument_status: InstrumentStatus = InstrumentStatus(0) + ) -> CurrenciesResponse: + storage = cast( + InstrumentStorage[CurrencyResponse, CurrenciesResponse], # type: ignore + self._get_instrument_storage(self._instruments_service.currencies), + ) + return storage.get_instruments_response() + + def currency_by( + self, + *, + id_type: InstrumentIdType = InstrumentIdType(0), + class_code: str = "", + id: str = "", + ) -> CurrencyResponse: + storage = cast( + InstrumentStorage[Currency, CurrenciesResponse], # type: ignore + self._get_instrument_storage(self._instruments_service.currencies), + ) + currency = storage.get(id_type=id_type, class_code=class_code, id=id) + return CurrencyResponse(instrument=currency) diff --git a/invest-python-master/t_tech/invest/caching/instruments_cache/interface.py b/invest-python-master/t_tech/invest/caching/instruments_cache/interface.py new file mode 100644 index 0000000..6ba928b --- /dev/null +++ b/invest-python-master/t_tech/invest/caching/instruments_cache/interface.py @@ -0,0 +1,98 @@ +import abc + +from t_tech.invest import ( + BondResponse, + BondsResponse, + CurrenciesResponse, + CurrencyResponse, + EtfResponse, + EtfsResponse, + FutureResponse, + FuturesResponse, + InstrumentIdType, + InstrumentStatus, + ShareResponse, + SharesResponse, +) + + +class IInstrumentsGetter(abc.ABC): + @abc.abstractmethod + def shares( + self, *, instrument_status: InstrumentStatus = InstrumentStatus(0) + ) -> SharesResponse: + pass + + @abc.abstractmethod + def share_by( + self, + *, + id_type: InstrumentIdType = InstrumentIdType(0), + class_code: str = "", + id: str = "", + ) -> ShareResponse: + pass + + @abc.abstractmethod + def futures( + self, *, instrument_status: InstrumentStatus = InstrumentStatus(0) + ) -> FuturesResponse: + pass + + @abc.abstractmethod + def future_by( + self, + *, + id_type: InstrumentIdType = InstrumentIdType(0), + class_code: str = "", + id: str = "", + ) -> FutureResponse: + pass + + @abc.abstractmethod + def etfs( + self, *, instrument_status: InstrumentStatus = InstrumentStatus(0) + ) -> EtfsResponse: + pass + + @abc.abstractmethod + def etf_by( + self, + *, + id_type: InstrumentIdType = InstrumentIdType(0), + class_code: str = "", + id: str = "", + ) -> EtfResponse: + pass + + @abc.abstractmethod + def bonds( + self, *, instrument_status: InstrumentStatus = InstrumentStatus(0) + ) -> BondsResponse: + pass + + @abc.abstractmethod + def bond_by( + self, + *, + id_type: InstrumentIdType = InstrumentIdType(0), + class_code: str = "", + id: str = "", + ) -> BondResponse: + pass + + @abc.abstractmethod + def currencies( + self, *, instrument_status: InstrumentStatus = InstrumentStatus(0) + ) -> CurrenciesResponse: + pass + + @abc.abstractmethod + def currency_by( + self, + *, + id_type: InstrumentIdType = InstrumentIdType(0), + class_code: str = "", + id: str = "", + ) -> CurrencyResponse: + pass diff --git a/invest-python-master/t_tech/invest/caching/instruments_cache/models.py b/invest-python-master/t_tech/invest/caching/instruments_cache/models.py new file mode 100644 index 0000000..434a8dc --- /dev/null +++ b/invest-python-master/t_tech/invest/caching/instruments_cache/models.py @@ -0,0 +1,13 @@ +from typing import List + + +class InstrumentResponse: + class_code: str + + figi: str + ticker: str + uid: str + + +class InstrumentsResponse: + instruments: List[InstrumentResponse] diff --git a/invest-python-master/t_tech/invest/caching/instruments_cache/protocol.py b/invest-python-master/t_tech/invest/caching/instruments_cache/protocol.py new file mode 100644 index 0000000..a53da15 --- /dev/null +++ b/invest-python-master/t_tech/invest/caching/instruments_cache/protocol.py @@ -0,0 +1,14 @@ +from typing import Protocol + +from t_tech.invest import InstrumentStatus +from t_tech.invest.caching.instruments_cache.models import InstrumentsResponse + + +class InstrumentsResponseCallable(Protocol): + def __call__( + self, *, instrument_status: InstrumentStatus = InstrumentStatus(0) + ) -> InstrumentsResponse: + ... + + def __name__(self) -> str: + ... diff --git a/invest-python-master/t_tech/invest/caching/instruments_cache/settings.py b/invest-python-master/t_tech/invest/caching/instruments_cache/settings.py new file mode 100644 index 0000000..2e94834 --- /dev/null +++ b/invest-python-master/t_tech/invest/caching/instruments_cache/settings.py @@ -0,0 +1,7 @@ +import dataclasses +from datetime import timedelta + + +@dataclasses.dataclass() +class InstrumentsCacheSettings: + ttl: timedelta = timedelta(days=1) diff --git a/invest-python-master/t_tech/invest/caching/market_data_cache/__init__.py b/invest-python-master/t_tech/invest/caching/market_data_cache/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/invest-python-master/t_tech/invest/caching/market_data_cache/cache.py b/invest-python-master/t_tech/invest/caching/market_data_cache/cache.py new file mode 100644 index 0000000..6d846d9 --- /dev/null +++ b/invest-python-master/t_tech/invest/caching/market_data_cache/cache.py @@ -0,0 +1,156 @@ +import logging +from datetime import datetime, timedelta +from typing import Dict, Generator, Iterable, Optional, Tuple + +from t_tech.invest import CandleInterval, HistoricCandle +from t_tech.invest.caching.market_data_cache.cache_settings import ( + MarketDataCacheSettings, +) +from t_tech.invest.caching.market_data_cache.datetime_range import DatetimeRange +from t_tech.invest.caching.market_data_cache.instrument_date_range_market_data import ( + InstrumentDateRangeData, +) +from t_tech.invest.caching.market_data_cache.instrument_market_data_storage import ( + InstrumentMarketDataStorage, +) +from t_tech.invest.schemas import CandleSource +from t_tech.invest.services import Services +from t_tech.invest.utils import ( + candle_interval_to_timedelta, + floor_datetime, + now, + round_datetime_range, + with_filtering_distinct_candles, +) + +logger = logging.getLogger(__name__) + + +class MarketDataCache: + def __init__(self, settings: MarketDataCacheSettings, services: Services): + self._settings = settings + self._settings.base_cache_dir.mkdir(parents=True, exist_ok=True) + self._services = services + self._figi_cache_storages: Dict[ + Tuple[str, CandleInterval], InstrumentMarketDataStorage + ] = {} + + def _get_candles_from_net( + self, + figi: str, + interval: CandleInterval, + from_: datetime, + to: datetime, + instrument_id: str = "", + candle_source_type: Optional[CandleSource] = None, + ) -> Iterable[HistoricCandle]: + yield from self._services.get_all_candles( + figi=figi, + interval=interval, + from_=from_, + to=to, + instrument_id=instrument_id, + candle_source_type=candle_source_type, + ) + + def _with_saving_into_cache( + self, + storage: InstrumentMarketDataStorage, + from_net: Iterable[HistoricCandle], + ) -> Iterable[HistoricCandle]: + candles = list(from_net) + if candles: + complete_candles = list(self._filter_complete_candles(candles)) + complete_candle_times = [candle.time for candle in complete_candles] + complete_net_range = ( + min(complete_candle_times), + max(complete_candle_times), + ) + storage.update( + [ + InstrumentDateRangeData( + date_range=complete_net_range, + historic_candles=complete_candles, + ) + ] + ) + + yield from candles + + def _filter_complete_candles( + self, candles: Iterable[HistoricCandle] + ) -> Iterable[HistoricCandle]: + return filter(lambda candle: candle.is_complete, candles) + + @with_filtering_distinct_candles # type: ignore + def get_all_candles( + self, + *, + from_: datetime, + to: Optional[datetime] = None, + interval: CandleInterval = CandleInterval(0), + figi: str = "", + instrument_id: str = "", + candle_source_type: Optional[CandleSource] = None, + ) -> Generator[HistoricCandle, None, None]: + interval_delta = candle_interval_to_timedelta(interval) + to = to or now() + + processed_time = from_ + figi_cache_storage = self._get_figi_cache_storage(figi=figi, interval=interval) + for cached in figi_cache_storage.get( + request_range=round_datetime_range( + date_range=(from_, to), interval=interval + ) + ): + cached_start, cached_end = cached.date_range + cached_candles = list(cached.historic_candles) + if cached_start > processed_time: + yield from self._with_saving_into_cache( + storage=figi_cache_storage, + from_net=self._get_candles_from_net( + figi=figi, + interval=interval, + from_=processed_time, + to=cached_start, + instrument_id=instrument_id, + candle_source_type=candle_source_type, + ), + ) + + yield from cached_candles + processed_time = cached_end + + if processed_time + interval_delta <= to: + yield from self._with_saving_into_cache( + storage=figi_cache_storage, + from_net=self._get_candles_from_net( + figi=figi, + interval=interval, + from_=processed_time, + to=to, + instrument_id=instrument_id, + ), + ) + + figi_cache_storage.merge() + + def _get_figi_cache_storage( + self, figi: str, interval: CandleInterval + ) -> InstrumentMarketDataStorage: + figi_tuple = (figi, interval) + storage = self._figi_cache_storages.get(figi_tuple) + if storage is None: + storage = InstrumentMarketDataStorage( + figi=figi, interval=interval, settings=self._settings + ) + self._figi_cache_storages[figi_tuple] = storage + return storage # noqa:R504 + + def _round_net_range( + self, net_range: DatetimeRange, interval_delta: timedelta + ) -> DatetimeRange: + start, end = net_range + return floor_datetime(start, interval_delta), floor_datetime( + end, interval_delta + ) diff --git a/invest-python-master/t_tech/invest/caching/market_data_cache/cache_settings.py b/invest-python-master/t_tech/invest/caching/market_data_cache/cache_settings.py new file mode 100644 index 0000000..e775942 --- /dev/null +++ b/invest-python-master/t_tech/invest/caching/market_data_cache/cache_settings.py @@ -0,0 +1,56 @@ +import contextlib +import dataclasses +import enum +import logging +import os +import pickle # noqa:S403 # nosec +from pathlib import Path +from typing import Dict, Generator, Sequence + +from t_tech.invest.caching.market_data_cache.datetime_range import DatetimeRange + +logger = logging.getLogger(__name__) + + +class MarketDataCacheFormat(str, enum.Enum): + CSV = "csv" + + +@dataclasses.dataclass() +class MarketDataCacheSettings: + base_cache_dir: Path = Path(os.getcwd()) / ".market_data_cache" + format_extension: MarketDataCacheFormat = MarketDataCacheFormat.CSV + field_names: Sequence[str] = ( + "time", + "open", + "high", + "low", + "close", + "volume", + "is_complete", + "candle_source", + "volume_buy", + "volume_sell", + ) + meta_extension: str = "meta" + + +@dataclasses.dataclass() +class FileMetaData: + cached_range_in_file: Dict[DatetimeRange, Path] + + +@contextlib.contextmanager +def meta_file_context(meta_file_path: Path) -> Generator[FileMetaData, None, None]: + try: + with open(meta_file_path, "rb") as f: + meta = pickle.load(f) # noqa:S301 # nosec + except FileNotFoundError: + logger.error("File %s was not found. Creating default.", meta_file_path) + + meta = FileMetaData(cached_range_in_file={}) + try: + yield meta + finally: + with open(meta_file_path, "wb") as f: + pickle.dump(meta, f) diff --git a/invest-python-master/t_tech/invest/caching/market_data_cache/datetime_range.py b/invest-python-master/t_tech/invest/caching/market_data_cache/datetime_range.py new file mode 100644 index 0000000..b489438 --- /dev/null +++ b/invest-python-master/t_tech/invest/caching/market_data_cache/datetime_range.py @@ -0,0 +1,4 @@ +from datetime import datetime +from typing import Tuple + +DatetimeRange = Tuple[datetime, datetime] diff --git a/invest-python-master/t_tech/invest/caching/market_data_cache/instrument_date_range_market_data.py b/invest-python-master/t_tech/invest/caching/market_data_cache/instrument_date_range_market_data.py new file mode 100644 index 0000000..04716e8 --- /dev/null +++ b/invest-python-master/t_tech/invest/caching/market_data_cache/instrument_date_range_market_data.py @@ -0,0 +1,11 @@ +import dataclasses +from typing import Iterable + +from t_tech.invest.caching.market_data_cache.datetime_range import DatetimeRange +from t_tech.invest.schemas import HistoricCandle + + +@dataclasses.dataclass() +class InstrumentDateRangeData: + date_range: DatetimeRange + historic_candles: Iterable[HistoricCandle] diff --git a/invest-python-master/t_tech/invest/caching/market_data_cache/instrument_market_data_storage.py b/invest-python-master/t_tech/invest/caching/market_data_cache/instrument_market_data_storage.py new file mode 100644 index 0000000..9f646f4 --- /dev/null +++ b/invest-python-master/t_tech/invest/caching/market_data_cache/instrument_market_data_storage.py @@ -0,0 +1,291 @@ +import csv +import dataclasses +import itertools +import logging +from datetime import datetime +from pathlib import Path +from typing import Dict, Generator, Iterable, Iterator, Optional, Tuple + +import dateutil.parser + +from t_tech.invest.caching.market_data_cache.cache_settings import ( + MarketDataCacheSettings, + meta_file_context, +) +from t_tech.invest.caching.market_data_cache.datetime_range import DatetimeRange +from t_tech.invest.caching.market_data_cache.instrument_date_range_market_data import ( + InstrumentDateRangeData, +) +from t_tech.invest.caching.market_data_cache.interface import ( + IInstrumentMarketDataStorage, +) +from t_tech.invest.caching.market_data_cache.serialization import custom_asdict_factory +from t_tech.invest.schemas import CandleInterval, HistoricCandle +from t_tech.invest.utils import dataclass_from_dict + +logger = logging.getLogger(__name__) + + +class InstrumentMarketDataStorage( + IInstrumentMarketDataStorage[Iterable[InstrumentDateRangeData]] +): + def __init__( + self, figi: str, interval: CandleInterval, settings: MarketDataCacheSettings + ): + self._figi = figi + self._interval = interval + self._settings = settings + self._settings.base_cache_dir.mkdir(parents=True, exist_ok=True) + self._meta_path = self._get_metafile( + file=self._get_base_file_path(figi=self._figi, interval=self._interval) + ) + + def _get_base_file_path(self, figi: str, interval: CandleInterval) -> Path: + instrument_dir = self._get_cache_dir_for_instrument(figi=figi) + instrument_dir.mkdir(parents=True, exist_ok=True) + return self._get_cache_file_for_instrument( + instrument_dir=instrument_dir, interval=interval + ) + + @staticmethod + def _datetime_to_safe_filename(dt: datetime) -> str: + return str(int(dt.timestamp())) + + def _get_file_path(self, date_range: DatetimeRange) -> Path: + start, end = date_range + filepath = self._get_base_file_path(figi=self._figi, interval=self._interval) + start_str = self._datetime_to_safe_filename(start) + end_str = self._datetime_to_safe_filename(end) + filepath = filepath.parent / (filepath.name + f"-{start_str}-{end_str}") + return filepath.with_suffix(f".{self._settings.format_extension.value}") + + def _get_metafile(self, file: Path) -> Path: + return file.with_suffix(f".{self._settings.meta_extension}") + + def _get_cache_file_for_instrument( + self, instrument_dir: Path, interval: CandleInterval + ) -> Path: + return instrument_dir / interval.name + + def _get_cache_dir_for_instrument(self, figi: str) -> Path: + return self._settings.base_cache_dir / figi + + def _get_range_from_file( + self, reader: Iterable[Dict], request_range: DatetimeRange + ) -> Iterable[Dict]: + start, end = request_range + for row in reader: + row_time = dateutil.parser.parse(row["time"]) + if start <= row_time <= end: + yield row + if end < row_time: + return + + def _get_candles_from_cache( + self, + file: Path, + request_range: DatetimeRange, + ) -> Generator[HistoricCandle, None, None]: + with open(file, "r") as infile: # pylint: disable=W1514 + reader = csv.DictReader(infile, fieldnames=self._settings.field_names) + reader_iter = iter(reader) + next(reader_iter) # pylint: disable=R1708 + for row in self._get_range_from_file( + reader_iter, request_range=request_range + ): + yield self._candle_from_row(row) + + def _order_rows( + self, dict_reader1: Iterator[Dict], dict_reader2: Iterator[Dict] + ) -> Iterable[Dict]: + dict_reader_iter1 = iter(dict_reader1) + dict_reader_iter2 = iter(dict_reader2) + + while True: + try: + candle_dict1 = next(dict_reader_iter1) + except StopIteration: + yield from dict_reader_iter2 + break + try: + candle_dict2 = next(dict_reader_iter2) + except StopIteration: + yield from dict_reader_iter1 + break + + candle_dict_time1 = dateutil.parser.parse(candle_dict1["time"]) + candle_dict_time2 = dateutil.parser.parse(candle_dict2["time"]) + if candle_dict_time1 > candle_dict_time2: + dict_reader_iter1 = itertools.chain([candle_dict1], dict_reader_iter1) + yield candle_dict2 + elif candle_dict_time1 < candle_dict_time2: + dict_reader_iter2 = itertools.chain([candle_dict2], dict_reader_iter2) + yield candle_dict1 + else: + yield candle_dict1 + + def _order_candles( + self, + tmp_dict_reader: Iterator[Dict], + historic_candles: Iterable[HistoricCandle], + ) -> Iterable[Dict]: + tmp_iter = iter(tmp_dict_reader) + candle_iter = iter(historic_candles) + + while True: + try: + tmp_candle_dict = next(tmp_iter) + except StopIteration: + yield from [dataclasses.asdict(candle) for candle in candle_iter] + break + try: + candle = next(candle_iter) + except StopIteration: + yield from tmp_iter + break + + tmp_candle_time = dateutil.parser.parse(tmp_candle_dict["time"]) + if tmp_candle_time > candle.time: + tmp_iter = itertools.chain([tmp_candle_dict], tmp_iter) + yield dataclasses.asdict(candle) + elif tmp_candle_time < candle.time: + candle_iter = itertools.chain([candle], candle_iter) + yield tmp_candle_dict + else: + yield tmp_candle_dict + + def _write_candles_file(self, data: InstrumentDateRangeData) -> Path: + file = self._get_file_path(date_range=data.date_range) + with open(file, mode="w") as csv_file: # pylint: disable=W1514 + writer = csv.DictWriter(csv_file, fieldnames=self._settings.field_names) + writer.writeheader() + for candle in data.historic_candles: + writer.writerow( + dataclasses.asdict(candle, dict_factory=custom_asdict_factory) + ) + return file + + def _candle_from_row(self, row: Dict[str, str]) -> HistoricCandle: + return dataclass_from_dict(HistoricCandle, row) + + def _get_intersection( + self, + request_range: DatetimeRange, + cached_range: DatetimeRange, + ) -> Optional[DatetimeRange]: + request_start, request_end = request_range + cached_start, cached_end = cached_range + max_start = max(request_start, cached_start) + min_end = min(request_end, cached_end) + if max_start <= min_end: + return max_start, min_end + return None + + def _merge_intersecting_files( # pylint: disable=R0914 + self, + file1: Path, + range1: DatetimeRange, + file2: Path, + range2: DatetimeRange, + ) -> Tuple[DatetimeRange, Path]: + new_range = (min(min(range1), min(range2)), max(max(range1), max(range2))) + new_file = self._get_file_path(date_range=new_range) + + if new_file == file1: + file2.unlink() + return new_range, new_file + if new_file == file2: + file1.unlink() + return new_range, new_file + + with open(file1, "r") as infile1: # pylint: disable=W1514 + reader1 = csv.DictReader(infile1, fieldnames=self._settings.field_names) + reader_iter1 = iter(reader1) + next(reader_iter1) # skip header + + with open(file2, "r") as infile2: # pylint: disable=W1514 + reader2 = csv.DictReader(infile2, fieldnames=self._settings.field_names) + reader_iter2 = iter(reader2) + next(reader_iter2) # skip header + + with open(new_file, mode="w") as csv_file: # pylint: disable=W1514 + writer = csv.DictWriter( + csv_file, fieldnames=self._settings.field_names + ) + writer.writeheader() + + for candle_dict in self._order_rows( + dict_reader1=reader_iter1, dict_reader2=reader_iter2 + ): + writer.writerow(candle_dict) + + file1.unlink() + file2.unlink() + return new_range, new_file + + def _get_distinct_product( + self, cached_range_in_file: Dict[DatetimeRange, Path] + ) -> Iterable[Tuple[Tuple[DatetimeRange, Path], Tuple[DatetimeRange, Path]]]: + sorted_items = self._get_cached_items_sorted_by_start(cached_range_in_file) + for i, items1 in enumerate(sorted_items): # pylint: disable=R1702 + for j, items2 in enumerate(sorted_items): + if i < j: + yield items1, items2 + + def _try_merge_files( + self, cached_range_in_file: Dict[DatetimeRange, Path] + ) -> Dict[DatetimeRange, Path]: + new_cached_range_in_file = cached_range_in_file.copy() + file_pairs = self._get_distinct_product(new_cached_range_in_file) + for (cached_range, cached_file), (cached_range2, cached_file2) in file_pairs: + intersection_range = self._get_intersection( + request_range=cached_range2, cached_range=cached_range + ) + if intersection_range is not None: + merged_range, merged_file = self._merge_intersecting_files( + file1=cached_file, + range1=cached_range, + file2=cached_file2, + range2=cached_range2, + ) + del new_cached_range_in_file[cached_range] + del new_cached_range_in_file[cached_range2] + new_cached_range_in_file[merged_range] = merged_file + return self._try_merge_files(new_cached_range_in_file) + return new_cached_range_in_file + + def get(self, request_range: DatetimeRange) -> Iterable[InstrumentDateRangeData]: + with meta_file_context(meta_file_path=self._meta_path) as meta_file: + cached_range_in_file = meta_file.cached_range_in_file + + for cached_range, cached_file in self._get_cached_items_sorted_by_start( + cached_range_in_file + ): + intersection = self._get_intersection( + request_range=request_range, cached_range=cached_range + ) + if intersection is not None: + candles = self._get_candles_from_cache( + cached_file, request_range=request_range + ) + yield InstrumentDateRangeData( + date_range=intersection, historic_candles=candles + ) + + def update(self, data_list: Iterable[InstrumentDateRangeData]): + with meta_file_context(meta_file_path=self._meta_path) as meta_file: + for data in data_list: + new_file = self._write_candles_file(data) + meta_file.cached_range_in_file[data.date_range] = new_file + + def merge(self): + with meta_file_context(meta_file_path=self._meta_path) as meta_file: + new_cached_range_in_file = self._try_merge_files( + meta_file.cached_range_in_file + ) + meta_file.cached_range_in_file = new_cached_range_in_file + + def _get_cached_items_sorted_by_start( + self, cached_range_in_file: Dict[DatetimeRange, Path] + ) -> Iterable[Tuple[DatetimeRange, Path]]: + return sorted(cached_range_in_file.items(), key=lambda pair: pair[0][0]) diff --git a/invest-python-master/t_tech/invest/caching/market_data_cache/interface.py b/invest-python-master/t_tech/invest/caching/market_data_cache/interface.py new file mode 100644 index 0000000..c1dfcc0 --- /dev/null +++ b/invest-python-master/t_tech/invest/caching/market_data_cache/interface.py @@ -0,0 +1,13 @@ +from typing import Protocol, TypeVar + +from t_tech.invest.caching.market_data_cache.datetime_range import DatetimeRange + +TInstrumentData = TypeVar("TInstrumentData") + + +class IInstrumentMarketDataStorage(Protocol[TInstrumentData]): + def get(self, request_range: DatetimeRange) -> TInstrumentData: + pass + + def update(self, data_list: TInstrumentData): + pass diff --git a/invest-python-master/t_tech/invest/caching/market_data_cache/serialization.py b/invest-python-master/t_tech/invest/caching/market_data_cache/serialization.py new file mode 100644 index 0000000..a726377 --- /dev/null +++ b/invest-python-master/t_tech/invest/caching/market_data_cache/serialization.py @@ -0,0 +1,10 @@ +from enum import Enum + + +def custom_asdict_factory(data): + def convert_value(obj): + if isinstance(obj, Enum): + return obj.value + return obj + + return {k: convert_value(v) for k, v in data} diff --git a/invest-python-master/t_tech/invest/caching/overrides.py b/invest-python-master/t_tech/invest/caching/overrides.py new file mode 100644 index 0000000..02fdb8c --- /dev/null +++ b/invest-python-master/t_tech/invest/caching/overrides.py @@ -0,0 +1,10 @@ +import time + +from cachetools import TTLCache as TTLCacheBase + + +class TTLCache(TTLCacheBase): + def __init__(self, maxsize, ttl, timer=None, getsizeof=None): + if timer is None: + timer = time.monotonic + super().__init__(maxsize=maxsize, ttl=ttl, timer=timer, getsizeof=getsizeof) diff --git a/invest-python-master/t_tech/invest/candle_getter_protocol.py b/invest-python-master/t_tech/invest/candle_getter_protocol.py new file mode 100644 index 0000000..952adad --- /dev/null +++ b/invest-python-master/t_tech/invest/candle_getter_protocol.py @@ -0,0 +1,16 @@ +from datetime import datetime +from typing import Generator, Optional, Protocol + +from t_tech.invest import CandleInterval, HistoricCandle + + +class CandleGetter(Protocol): + def get_all_candles( # pragma: no cover + self, + *, + from_: datetime, + to: Optional[datetime], + interval: CandleInterval, + figi: str, + ) -> Generator[HistoricCandle, None, None]: + pass diff --git a/invest-python-master/t_tech/invest/channels.py b/invest-python-master/t_tech/invest/channels.py new file mode 100644 index 0000000..65ee23a --- /dev/null +++ b/invest-python-master/t_tech/invest/channels.py @@ -0,0 +1,66 @@ +import itertools +from typing import Any, Optional, Sequence + +import grpc +from grpc.aio import ClientInterceptor + +from .constants import ( + INVEST_GRPC_API, + KEEPALIVE_MAX_PINGS, + KEEPALIVE_TIME_MS, + KEEPALIVE_TIMEOUT_MS, + MAX_RECEIVE_MESSAGE_LENGTH, +) +from .typedefs import ChannelArgumentType + +__all__ = ("create_channel",) + +_required_options: ChannelArgumentType = [ + ("grpc.max_receive_message_length", MAX_RECEIVE_MESSAGE_LENGTH), + ("grpc.keepalive_time_ms", KEEPALIVE_TIME_MS), + ("grpc.keepalive_timeout_ms", KEEPALIVE_TIMEOUT_MS), + ("grpc.http2.max_pings_without_data", KEEPALIVE_MAX_PINGS), +] + + +def create_channel( + *, + target: Optional[str] = None, + options: Optional[ChannelArgumentType] = None, + force_async: bool = False, + compression: Optional[grpc.Compression] = None, + interceptors: Optional[Sequence[ClientInterceptor]] = None, +) -> Any: + creds = grpc.ssl_channel_credentials() + target = target or INVEST_GRPC_API + if options is None: + options = [] + + options = _with_options(options, _required_options) + + args = (target, creds, options, compression) + if force_async: + return grpc.aio.secure_channel(*args, interceptors=interceptors) + return grpc.secure_channel(*args) + + +def _with_options(options: ChannelArgumentType, _required_options: ChannelArgumentType): + for option in _required_options: + options = _with_option(options, option[0], option[1]) + return options + + +def _with_option( + options: ChannelArgumentType, key: str, value: Any +) -> ChannelArgumentType: + if not _contains_option(options, key): + option = (key, value) + return list(itertools.chain(options, [option])) + return options + + +def _contains_option(options: ChannelArgumentType, expected_option_name: str) -> bool: + for option_name, _ in options: + if option_name == expected_option_name: + return True + return False diff --git a/invest-python-master/t_tech/invest/clients.py b/invest-python-master/t_tech/invest/clients.py new file mode 100644 index 0000000..88b3fa1 --- /dev/null +++ b/invest-python-master/t_tech/invest/clients.py @@ -0,0 +1,121 @@ +from typing import List, Optional + +import grpc +from grpc.aio import ClientInterceptor + +from ._error_hub import async_init_error_hub, init_error_hub +from .async_services import AsyncServices +from .channels import create_channel +from .constants import INVEST_GRPC_API +from .services import Services +from .typedefs import ChannelArgumentType + +__all__ = ("Client", "AsyncClient") + + +class Client: + """Sync client. + + ```python + import os + from tinkoff.invest import Client + + TOKEN = os.environ["INVEST_TOKEN"] + + def main(): + with Client(TOKEN) as client: + print(client.users.get_accounts()) + + ``` + """ + + def __init__( + self, + token: str, + *, + target: Optional[str] = None, + sandbox_token: Optional[str] = None, + options: Optional[ChannelArgumentType] = None, + app_name: Optional[str] = None, + interceptors: Optional[List[ClientInterceptor]] = None, + ): + self._token = token + self._sandbox_token = sandbox_token + self._options = options + self._app_name = app_name + self._target = target or INVEST_GRPC_API + self._channel = create_channel(target=target, options=options) + if interceptors is None: + interceptors = [] + for interceptor in interceptors: + self._channel = grpc.intercept_channel(self._channel, interceptor) + + def __enter__(self) -> Services: + init_error_hub(self) + channel = self._channel.__enter__() + return Services( + channel, + token=self._token, + sandbox_token=self._sandbox_token, + app_name=self._app_name, + ) + + def __exit__(self, exc_type, exc_val, exc_tb): + self._channel.__exit__(exc_type, exc_val, exc_tb) + return False + + +class AsyncClient: + """Async client. + + ```python + import asyncio + import os + + from tinkoff.invest import AsyncClient + + TOKEN = os.environ["INVEST_TOKEN"] + + + async def main(): + async with AsyncClient(TOKEN) as client: + print(await client.users.get_accounts()) + + + if __name__ == "__main__": + asyncio.run(main()) + ``` + """ + + def __init__( + self, + token: str, + *, + target: Optional[str] = None, + sandbox_token: Optional[str] = None, + options: Optional[ChannelArgumentType] = None, + app_name: Optional[str] = None, + interceptors: Optional[List[ClientInterceptor]] = None, + ): + self._token = token + self._sandbox_token = sandbox_token + self._options = options + self._app_name = app_name + self._target = target or INVEST_GRPC_API + self._channel = create_channel( + target=target, force_async=True, options=options, interceptors=interceptors + ) + + async def __aenter__(self) -> AsyncServices: + await async_init_error_hub(self) + channel = await self._channel.__aenter__() + return AsyncServices( + channel, + token=self._token, + sandbox_token=self._sandbox_token, + app_name=self._app_name, + ) + + async def __aexit__(self, exc_type, exc_val, exc_tb): + await self._channel.__aexit__(exc_type, exc_val, exc_tb) + return False diff --git a/invest-python-master/t_tech/invest/constants.py b/invest-python-master/t_tech/invest/constants.py new file mode 100644 index 0000000..0b9459e --- /dev/null +++ b/invest-python-master/t_tech/invest/constants.py @@ -0,0 +1,16 @@ +INVEST_GRPC_API = "invest-public-api.tinkoff.ru" +INVEST_GRPC_API_SANDBOX = "sandbox-invest-public-api.tinkoff.ru" +APP_VERSION = "0.3.5" +APP_NAME = f"t-tech.invest-python-{APP_VERSION}" +PACKAGE_NAME = f"t-tech.invest@{APP_VERSION.replace('-beta', '+')}" +X_TRACKING_ID = "x-tracking-id" +X_RATELIMIT_LIMIT = "x-ratelimit-limit" +X_RATELIMIT_REMAINING = "x-ratelimit-remaining" +X_RATELIMIT_RESET = "x-ratelimit-reset" +MESSAGE = "message" +MEGABYTE = 1024 * 1024 +MAX_RECEIVE_MESSAGE_LENGTH = 10 * MEGABYTE +ERROR_HUB_DSN = "https://invest-piapi-errorhub@error-hub.tbank.ru/00000000" +KEEPALIVE_TIME_MS = 1000 +KEEPALIVE_TIMEOUT_MS = 20000 +KEEPALIVE_MAX_PINGS = 120 diff --git a/invest-python-master/t_tech/invest/exceptions.py b/invest-python-master/t_tech/invest/exceptions.py new file mode 100644 index 0000000..98176a2 --- /dev/null +++ b/invest-python-master/t_tech/invest/exceptions.py @@ -0,0 +1,49 @@ +from typing import Any + +from grpc import StatusCode + +__all__ = ( + "InvestError", + "RequestError", + "AioRequestError", + "UnauthenticatedError", + "AioUnauthenticatedError", +) + + +class InvestError(Exception): + pass + + +class RequestError(InvestError): + def __init__( # pylint:disable=super-init-not-called + self, code: StatusCode, details: str, metadata: Any + ) -> None: + self.code = code + self.details = details + self.metadata = metadata + + +class UnauthenticatedError(RequestError): + pass + + +class AioRequestError(InvestError): + def __init__( # pylint:disable=super-init-not-called + self, code: StatusCode, details: str, metadata: Any + ) -> None: + self.code = code + self.details = details + self.metadata = metadata + + +class AioUnauthenticatedError(AioRequestError): + pass + + +class MarketDataStreamError(InvestError): + pass + + +class IsNotSubscribedError(MarketDataStreamError): + pass diff --git a/invest-python-master/t_tech/invest/grpc/__init__.py b/invest-python-master/t_tech/invest/grpc/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/invest-python-master/t_tech/invest/grpc/common_pb2.py b/invest-python-master/t_tech/invest/grpc/common_pb2.py new file mode 100644 index 0000000..92d3327 --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/common_pb2.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: t_tech/invest/grpc/common.proto +# Protobuf Python Version: 4.25.1 +"""Generated protocol buffer code.""" +from google.protobuf import ( + descriptor as _descriptor, + descriptor_pool as _descriptor_pool, + symbol_database as _symbol_database, +) +from google.protobuf.internal import builder as _builder + +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1ft_tech/invest/grpc/common.proto\x12%tinkoff.public.invest.api.contract.v1\x1a\x1fgoogle/protobuf/timestamp.proto\";\n\nMoneyValue\x12\x10\n\x08\x63urrency\x18\x01 \x01(\t\x12\r\n\x05units\x18\x02 \x01(\x03\x12\x0c\n\x04nano\x18\x03 \x01(\x05\"(\n\tQuotation\x12\r\n\x05units\x18\x01 \x01(\x03\x12\x0c\n\x04nano\x18\x02 \x01(\x05\"E\n\x0bPingRequest\x12-\n\x04time\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x00\x88\x01\x01\x42\x07\n\x05_time\"A\n\x11PingDelaySettings\x12\x1a\n\rping_delay_ms\x18\x0f \x01(\x05H\x00\x88\x01\x01\x42\x10\n\x0e_ping_delay_ms\"\x95\x01\n\x04Ping\x12(\n\x04time\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x11\n\tstream_id\x18\x02 \x01(\t\x12:\n\x11ping_request_time\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x00\x88\x01\x01\x42\x14\n\x12_ping_request_time\"*\n\x04Page\x12\r\n\x05limit\x18\x01 \x01(\x05\x12\x13\n\x0bpage_number\x18\x02 \x01(\x05\"G\n\x0cPageResponse\x12\r\n\x05limit\x18\x01 \x01(\x05\x12\x13\n\x0bpage_number\x18\x02 \x01(\x05\x12\x13\n\x0btotal_count\x18\x03 \x01(\x05\"X\n\x10ResponseMetadata\x12\x13\n\x0btracking_id\x18* \x01(\t\x12/\n\x0bserver_time\x18+ \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"K\n\tBrandData\x12\x11\n\tlogo_name\x18\x01 \x01(\t\x12\x17\n\x0flogo_base_color\x18\x02 \x01(\t\x12\x12\n\ntext_color\x18\x03 \x01(\t\",\n\x0b\x45rrorDetail\x12\x0c\n\x04\x63ode\x18\x01 \x01(\t\x12\x0f\n\x07message\x18\x03 \x01(\t*\xeb\x02\n\x0eInstrumentType\x12\x1f\n\x1bINSTRUMENT_TYPE_UNSPECIFIED\x10\x00\x12\x18\n\x14INSTRUMENT_TYPE_BOND\x10\x01\x12\x19\n\x15INSTRUMENT_TYPE_SHARE\x10\x02\x12\x1c\n\x18INSTRUMENT_TYPE_CURRENCY\x10\x03\x12\x17\n\x13INSTRUMENT_TYPE_ETF\x10\x04\x12\x1b\n\x17INSTRUMENT_TYPE_FUTURES\x10\x05\x12\x16\n\x12INSTRUMENT_TYPE_SP\x10\x06\x12\x1a\n\x16INSTRUMENT_TYPE_OPTION\x10\x07\x12(\n$INSTRUMENT_TYPE_CLEARING_CERTIFICATE\x10\x08\x12\x19\n\x15INSTRUMENT_TYPE_INDEX\x10\t\x12\x1d\n\x19INSTRUMENT_TYPE_COMMODITY\x10\n\x12\x17\n\x13INSTRUMENT_TYPE_DFA\x10\x0b*l\n\x10InstrumentStatus\x12!\n\x1dINSTRUMENT_STATUS_UNSPECIFIED\x10\x00\x12\x1a\n\x16INSTRUMENT_STATUS_BASE\x10\x01\x12\x19\n\x15INSTRUMENT_STATUS_ALL\x10\x02*\x81\x07\n\x15SecurityTradingStatus\x12\'\n#SECURITY_TRADING_STATUS_UNSPECIFIED\x10\x00\x12\x35\n1SECURITY_TRADING_STATUS_NOT_AVAILABLE_FOR_TRADING\x10\x01\x12*\n&SECURITY_TRADING_STATUS_OPENING_PERIOD\x10\x02\x12*\n&SECURITY_TRADING_STATUS_CLOSING_PERIOD\x10\x03\x12,\n(SECURITY_TRADING_STATUS_BREAK_IN_TRADING\x10\x04\x12*\n&SECURITY_TRADING_STATUS_NORMAL_TRADING\x10\x05\x12+\n\'SECURITY_TRADING_STATUS_CLOSING_AUCTION\x10\x06\x12-\n)SECURITY_TRADING_STATUS_DARK_POOL_AUCTION\x10\x07\x12,\n(SECURITY_TRADING_STATUS_DISCRETE_AUCTION\x10\x08\x12\x32\n.SECURITY_TRADING_STATUS_OPENING_AUCTION_PERIOD\x10\t\x12<\n8SECURITY_TRADING_STATUS_TRADING_AT_CLOSING_AUCTION_PRICE\x10\n\x12,\n(SECURITY_TRADING_STATUS_SESSION_ASSIGNED\x10\x0b\x12)\n%SECURITY_TRADING_STATUS_SESSION_CLOSE\x10\x0c\x12(\n$SECURITY_TRADING_STATUS_SESSION_OPEN\x10\r\x12\x31\n-SECURITY_TRADING_STATUS_DEALER_NORMAL_TRADING\x10\x0e\x12\x33\n/SECURITY_TRADING_STATUS_DEALER_BREAK_IN_TRADING\x10\x0f\x12<\n8SECURITY_TRADING_STATUS_DEALER_NOT_AVAILABLE_FOR_TRADING\x10\x10\x12\x31\n-SECURITY_TRADING_STATUS_STABILIZATION_AUCTION\x10\x11*V\n\tPriceType\x12\x1a\n\x16PRICE_TYPE_UNSPECIFIED\x10\x00\x12\x14\n\x10PRICE_TYPE_POINT\x10\x01\x12\x17\n\x13PRICE_TYPE_CURRENCY\x10\x02*\x8f\x01\n\x18ResultSubscriptionStatus\x12*\n&RESULT_SUBSCRIPTION_STATUS_UNSPECIFIED\x10\x00\x12!\n\x1dRESULT_SUBSCRIPTION_STATUS_OK\x10\x01\x12$\n RESULT_SUBSCRIPTION_STATUS_ERROR\x10\r*\x8d\x01\n\x0cRealExchange\x12\x1d\n\x19REAL_EXCHANGE_UNSPECIFIED\x10\x00\x12\x16\n\x12REAL_EXCHANGE_MOEX\x10\x01\x12\x15\n\x11REAL_EXCHANGE_RTS\x10\x02\x12\x15\n\x11REAL_EXCHANGE_OTC\x10\x03\x12\x18\n\x14REAL_EXCHANGE_DEALER\x10\x04\x42\x61\n\x1cru.tinkoff.piapi.contract.v1P\x01Z\x0c./;investapi\xa2\x02\x05TIAPI\xaa\x02\x14Tinkoff.InvestApi.V1\xca\x02\x11Tinkoff\\Invest\\V1b\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 't_tech.invest.grpc.common_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\034ru.tinkoff.piapi.contract.v1P\001Z\014./;investapi\242\002\005TIAPI\252\002\024Tinkoff.InvestApi.V1\312\002\021Tinkoff\\Invest\\V1' + _globals['_INSTRUMENTTYPE']._serialized_start=831 + _globals['_INSTRUMENTTYPE']._serialized_end=1194 + _globals['_INSTRUMENTSTATUS']._serialized_start=1196 + _globals['_INSTRUMENTSTATUS']._serialized_end=1304 + _globals['_SECURITYTRADINGSTATUS']._serialized_start=1307 + _globals['_SECURITYTRADINGSTATUS']._serialized_end=2204 + _globals['_PRICETYPE']._serialized_start=2206 + _globals['_PRICETYPE']._serialized_end=2292 + _globals['_RESULTSUBSCRIPTIONSTATUS']._serialized_start=2295 + _globals['_RESULTSUBSCRIPTIONSTATUS']._serialized_end=2438 + _globals['_REALEXCHANGE']._serialized_start=2441 + _globals['_REALEXCHANGE']._serialized_end=2582 + _globals['_MONEYVALUE']._serialized_start=107 + _globals['_MONEYVALUE']._serialized_end=166 + _globals['_QUOTATION']._serialized_start=168 + _globals['_QUOTATION']._serialized_end=208 + _globals['_PINGREQUEST']._serialized_start=210 + _globals['_PINGREQUEST']._serialized_end=279 + _globals['_PINGDELAYSETTINGS']._serialized_start=281 + _globals['_PINGDELAYSETTINGS']._serialized_end=346 + _globals['_PING']._serialized_start=349 + _globals['_PING']._serialized_end=498 + _globals['_PAGE']._serialized_start=500 + _globals['_PAGE']._serialized_end=542 + _globals['_PAGERESPONSE']._serialized_start=544 + _globals['_PAGERESPONSE']._serialized_end=615 + _globals['_RESPONSEMETADATA']._serialized_start=617 + _globals['_RESPONSEMETADATA']._serialized_end=705 + _globals['_BRANDDATA']._serialized_start=707 + _globals['_BRANDDATA']._serialized_end=782 + _globals['_ERRORDETAIL']._serialized_start=784 + _globals['_ERRORDETAIL']._serialized_end=828 +# @@protoc_insertion_point(module_scope) diff --git a/invest-python-master/t_tech/invest/grpc/common_pb2.pyi b/invest-python-master/t_tech/invest/grpc/common_pb2.pyi new file mode 100644 index 0000000..9c86236 --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/common_pb2.pyi @@ -0,0 +1,493 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" + +import builtins +import google.protobuf.descriptor +import google.protobuf.internal.enum_type_wrapper +import google.protobuf.message +import google.protobuf.timestamp_pb2 +import sys +import typing + +if sys.version_info >= (3, 10): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +class _InstrumentType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _InstrumentTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_InstrumentType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + INSTRUMENT_TYPE_UNSPECIFIED: _InstrumentType.ValueType # 0 + INSTRUMENT_TYPE_BOND: _InstrumentType.ValueType # 1 + """Облигация.""" + INSTRUMENT_TYPE_SHARE: _InstrumentType.ValueType # 2 + """Акция.""" + INSTRUMENT_TYPE_CURRENCY: _InstrumentType.ValueType # 3 + """Валюта.""" + INSTRUMENT_TYPE_ETF: _InstrumentType.ValueType # 4 + """Exchange-traded fund. Фонд.""" + INSTRUMENT_TYPE_FUTURES: _InstrumentType.ValueType # 5 + """Фьючерс.""" + INSTRUMENT_TYPE_SP: _InstrumentType.ValueType # 6 + """Структурная нота.""" + INSTRUMENT_TYPE_OPTION: _InstrumentType.ValueType # 7 + """Опцион.""" + INSTRUMENT_TYPE_CLEARING_CERTIFICATE: _InstrumentType.ValueType # 8 + """Clearing certificate.""" + INSTRUMENT_TYPE_INDEX: _InstrumentType.ValueType # 9 + """Индекс.""" + INSTRUMENT_TYPE_COMMODITY: _InstrumentType.ValueType # 10 + """Товар.""" + INSTRUMENT_TYPE_DFA: _InstrumentType.ValueType # 11 + """Цифровой актив.""" + +class InstrumentType(_InstrumentType, metaclass=_InstrumentTypeEnumTypeWrapper): + """Тип инструмента.""" + +INSTRUMENT_TYPE_UNSPECIFIED: InstrumentType.ValueType # 0 +INSTRUMENT_TYPE_BOND: InstrumentType.ValueType # 1 +"""Облигация.""" +INSTRUMENT_TYPE_SHARE: InstrumentType.ValueType # 2 +"""Акция.""" +INSTRUMENT_TYPE_CURRENCY: InstrumentType.ValueType # 3 +"""Валюта.""" +INSTRUMENT_TYPE_ETF: InstrumentType.ValueType # 4 +"""Exchange-traded fund. Фонд.""" +INSTRUMENT_TYPE_FUTURES: InstrumentType.ValueType # 5 +"""Фьючерс.""" +INSTRUMENT_TYPE_SP: InstrumentType.ValueType # 6 +"""Структурная нота.""" +INSTRUMENT_TYPE_OPTION: InstrumentType.ValueType # 7 +"""Опцион.""" +INSTRUMENT_TYPE_CLEARING_CERTIFICATE: InstrumentType.ValueType # 8 +"""Clearing certificate.""" +INSTRUMENT_TYPE_INDEX: InstrumentType.ValueType # 9 +"""Индекс.""" +INSTRUMENT_TYPE_COMMODITY: InstrumentType.ValueType # 10 +"""Товар.""" +INSTRUMENT_TYPE_DFA: InstrumentType.ValueType # 11 +"""Цифровой актив.""" +global___InstrumentType = InstrumentType + +class _InstrumentStatus: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _InstrumentStatusEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_InstrumentStatus.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + INSTRUMENT_STATUS_UNSPECIFIED: _InstrumentStatus.ValueType # 0 + """Значение не определено.""" + INSTRUMENT_STATUS_BASE: _InstrumentStatus.ValueType # 1 + """По умолчанию — базовый список инструментов, которыми можно торговать через T-Invest API. Сейчас списки доступных бумаг в API и других интерфейсах совпадают — кроме внебиржевых бумаг, но в будущем списки могут различаться.""" + INSTRUMENT_STATUS_ALL: _InstrumentStatus.ValueType # 2 + """Список всех инструментов.""" + +class InstrumentStatus(_InstrumentStatus, metaclass=_InstrumentStatusEnumTypeWrapper): + """Статус запрашиваемых инструментов.""" + +INSTRUMENT_STATUS_UNSPECIFIED: InstrumentStatus.ValueType # 0 +"""Значение не определено.""" +INSTRUMENT_STATUS_BASE: InstrumentStatus.ValueType # 1 +"""По умолчанию — базовый список инструментов, которыми можно торговать через T-Invest API. Сейчас списки доступных бумаг в API и других интерфейсах совпадают — кроме внебиржевых бумаг, но в будущем списки могут различаться.""" +INSTRUMENT_STATUS_ALL: InstrumentStatus.ValueType # 2 +"""Список всех инструментов.""" +global___InstrumentStatus = InstrumentStatus + +class _SecurityTradingStatus: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _SecurityTradingStatusEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_SecurityTradingStatus.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + SECURITY_TRADING_STATUS_UNSPECIFIED: _SecurityTradingStatus.ValueType # 0 + """Торговый статус не определен.""" + SECURITY_TRADING_STATUS_NOT_AVAILABLE_FOR_TRADING: _SecurityTradingStatus.ValueType # 1 + """Недоступен для торгов.""" + SECURITY_TRADING_STATUS_OPENING_PERIOD: _SecurityTradingStatus.ValueType # 2 + """Период открытия торгов.""" + SECURITY_TRADING_STATUS_CLOSING_PERIOD: _SecurityTradingStatus.ValueType # 3 + """Период закрытия торгов.""" + SECURITY_TRADING_STATUS_BREAK_IN_TRADING: _SecurityTradingStatus.ValueType # 4 + """Перерыв в торговле.""" + SECURITY_TRADING_STATUS_NORMAL_TRADING: _SecurityTradingStatus.ValueType # 5 + """Нормальная торговля.""" + SECURITY_TRADING_STATUS_CLOSING_AUCTION: _SecurityTradingStatus.ValueType # 6 + """Аукцион закрытия.""" + SECURITY_TRADING_STATUS_DARK_POOL_AUCTION: _SecurityTradingStatus.ValueType # 7 + """Аукцион крупных пакетов.""" + SECURITY_TRADING_STATUS_DISCRETE_AUCTION: _SecurityTradingStatus.ValueType # 8 + """Дискретный аукцион.""" + SECURITY_TRADING_STATUS_OPENING_AUCTION_PERIOD: _SecurityTradingStatus.ValueType # 9 + """Аукцион открытия.""" + SECURITY_TRADING_STATUS_TRADING_AT_CLOSING_AUCTION_PRICE: _SecurityTradingStatus.ValueType # 10 + """Период торгов по цене аукциона закрытия.""" + SECURITY_TRADING_STATUS_SESSION_ASSIGNED: _SecurityTradingStatus.ValueType # 11 + """Сессия назначена.""" + SECURITY_TRADING_STATUS_SESSION_CLOSE: _SecurityTradingStatus.ValueType # 12 + """Сессия закрыта.""" + SECURITY_TRADING_STATUS_SESSION_OPEN: _SecurityTradingStatus.ValueType # 13 + """Сессия открыта.""" + SECURITY_TRADING_STATUS_DEALER_NORMAL_TRADING: _SecurityTradingStatus.ValueType # 14 + """Доступна торговля в режиме внутренней ликвидности брокера.""" + SECURITY_TRADING_STATUS_DEALER_BREAK_IN_TRADING: _SecurityTradingStatus.ValueType # 15 + """Перерыв торговли в режиме внутренней ликвидности брокера.""" + SECURITY_TRADING_STATUS_DEALER_NOT_AVAILABLE_FOR_TRADING: _SecurityTradingStatus.ValueType # 16 + """Недоступна торговля в режиме внутренней ликвидности брокера.""" + SECURITY_TRADING_STATUS_STABILIZATION_AUCTION: _SecurityTradingStatus.ValueType # 17 + """Аукцион обновления цен.""" + +class SecurityTradingStatus(_SecurityTradingStatus, metaclass=_SecurityTradingStatusEnumTypeWrapper): + """Режим торгов инструмента""" + +SECURITY_TRADING_STATUS_UNSPECIFIED: SecurityTradingStatus.ValueType # 0 +"""Торговый статус не определен.""" +SECURITY_TRADING_STATUS_NOT_AVAILABLE_FOR_TRADING: SecurityTradingStatus.ValueType # 1 +"""Недоступен для торгов.""" +SECURITY_TRADING_STATUS_OPENING_PERIOD: SecurityTradingStatus.ValueType # 2 +"""Период открытия торгов.""" +SECURITY_TRADING_STATUS_CLOSING_PERIOD: SecurityTradingStatus.ValueType # 3 +"""Период закрытия торгов.""" +SECURITY_TRADING_STATUS_BREAK_IN_TRADING: SecurityTradingStatus.ValueType # 4 +"""Перерыв в торговле.""" +SECURITY_TRADING_STATUS_NORMAL_TRADING: SecurityTradingStatus.ValueType # 5 +"""Нормальная торговля.""" +SECURITY_TRADING_STATUS_CLOSING_AUCTION: SecurityTradingStatus.ValueType # 6 +"""Аукцион закрытия.""" +SECURITY_TRADING_STATUS_DARK_POOL_AUCTION: SecurityTradingStatus.ValueType # 7 +"""Аукцион крупных пакетов.""" +SECURITY_TRADING_STATUS_DISCRETE_AUCTION: SecurityTradingStatus.ValueType # 8 +"""Дискретный аукцион.""" +SECURITY_TRADING_STATUS_OPENING_AUCTION_PERIOD: SecurityTradingStatus.ValueType # 9 +"""Аукцион открытия.""" +SECURITY_TRADING_STATUS_TRADING_AT_CLOSING_AUCTION_PRICE: SecurityTradingStatus.ValueType # 10 +"""Период торгов по цене аукциона закрытия.""" +SECURITY_TRADING_STATUS_SESSION_ASSIGNED: SecurityTradingStatus.ValueType # 11 +"""Сессия назначена.""" +SECURITY_TRADING_STATUS_SESSION_CLOSE: SecurityTradingStatus.ValueType # 12 +"""Сессия закрыта.""" +SECURITY_TRADING_STATUS_SESSION_OPEN: SecurityTradingStatus.ValueType # 13 +"""Сессия открыта.""" +SECURITY_TRADING_STATUS_DEALER_NORMAL_TRADING: SecurityTradingStatus.ValueType # 14 +"""Доступна торговля в режиме внутренней ликвидности брокера.""" +SECURITY_TRADING_STATUS_DEALER_BREAK_IN_TRADING: SecurityTradingStatus.ValueType # 15 +"""Перерыв торговли в режиме внутренней ликвидности брокера.""" +SECURITY_TRADING_STATUS_DEALER_NOT_AVAILABLE_FOR_TRADING: SecurityTradingStatus.ValueType # 16 +"""Недоступна торговля в режиме внутренней ликвидности брокера.""" +SECURITY_TRADING_STATUS_STABILIZATION_AUCTION: SecurityTradingStatus.ValueType # 17 +"""Аукцион обновления цен.""" +global___SecurityTradingStatus = SecurityTradingStatus + +class _PriceType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _PriceTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_PriceType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + PRICE_TYPE_UNSPECIFIED: _PriceType.ValueType # 0 + """Значение не определено.""" + PRICE_TYPE_POINT: _PriceType.ValueType # 1 + """Цена в пунктах (только для фьючерсов и облигаций).""" + PRICE_TYPE_CURRENCY: _PriceType.ValueType # 2 + """Цена в валюте расчетов по инструменту.""" + +class PriceType(_PriceType, metaclass=_PriceTypeEnumTypeWrapper): + """Тип цены.""" + +PRICE_TYPE_UNSPECIFIED: PriceType.ValueType # 0 +"""Значение не определено.""" +PRICE_TYPE_POINT: PriceType.ValueType # 1 +"""Цена в пунктах (только для фьючерсов и облигаций).""" +PRICE_TYPE_CURRENCY: PriceType.ValueType # 2 +"""Цена в валюте расчетов по инструменту.""" +global___PriceType = PriceType + +class _ResultSubscriptionStatus: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _ResultSubscriptionStatusEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_ResultSubscriptionStatus.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + RESULT_SUBSCRIPTION_STATUS_UNSPECIFIED: _ResultSubscriptionStatus.ValueType # 0 + """Статус подписки не определен.""" + RESULT_SUBSCRIPTION_STATUS_OK: _ResultSubscriptionStatus.ValueType # 1 + """Подписка успешно установлена.""" + RESULT_SUBSCRIPTION_STATUS_ERROR: _ResultSubscriptionStatus.ValueType # 13 + """Ошибка подписки""" + +class ResultSubscriptionStatus(_ResultSubscriptionStatus, metaclass=_ResultSubscriptionStatusEnumTypeWrapper): ... + +RESULT_SUBSCRIPTION_STATUS_UNSPECIFIED: ResultSubscriptionStatus.ValueType # 0 +"""Статус подписки не определен.""" +RESULT_SUBSCRIPTION_STATUS_OK: ResultSubscriptionStatus.ValueType # 1 +"""Подписка успешно установлена.""" +RESULT_SUBSCRIPTION_STATUS_ERROR: ResultSubscriptionStatus.ValueType # 13 +"""Ошибка подписки""" +global___ResultSubscriptionStatus = ResultSubscriptionStatus + +class _RealExchange: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _RealExchangeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_RealExchange.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + REAL_EXCHANGE_UNSPECIFIED: _RealExchange.ValueType # 0 + """Тип не определен.""" + REAL_EXCHANGE_MOEX: _RealExchange.ValueType # 1 + """Московская биржа.""" + REAL_EXCHANGE_RTS: _RealExchange.ValueType # 2 + """Санкт-Петербургская биржа.""" + REAL_EXCHANGE_OTC: _RealExchange.ValueType # 3 + """Внебиржевой инструмент.""" + REAL_EXCHANGE_DEALER: _RealExchange.ValueType # 4 + """Инструмент, торгуемый на площадке брокера.""" + +class RealExchange(_RealExchange, metaclass=_RealExchangeEnumTypeWrapper): + """Реальная площадка исполнения расчетов.""" + +REAL_EXCHANGE_UNSPECIFIED: RealExchange.ValueType # 0 +"""Тип не определен.""" +REAL_EXCHANGE_MOEX: RealExchange.ValueType # 1 +"""Московская биржа.""" +REAL_EXCHANGE_RTS: RealExchange.ValueType # 2 +"""Санкт-Петербургская биржа.""" +REAL_EXCHANGE_OTC: RealExchange.ValueType # 3 +"""Внебиржевой инструмент.""" +REAL_EXCHANGE_DEALER: RealExchange.ValueType # 4 +"""Инструмент, торгуемый на площадке брокера.""" +global___RealExchange = RealExchange + +@typing.final +class MoneyValue(google.protobuf.message.Message): + """Денежная сумма в определенной валюте.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + CURRENCY_FIELD_NUMBER: builtins.int + UNITS_FIELD_NUMBER: builtins.int + NANO_FIELD_NUMBER: builtins.int + currency: builtins.str + """Строковый ISO-код валюты.""" + units: builtins.int + """Целая часть суммы, может быть отрицательным числом.""" + nano: builtins.int + """Дробная часть суммы, может быть отрицательным числом.""" + def __init__( + self, + *, + currency: builtins.str = ..., + units: builtins.int = ..., + nano: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["currency", b"currency", "nano", b"nano", "units", b"units"]) -> None: ... + +global___MoneyValue = MoneyValue + +@typing.final +class Quotation(google.protobuf.message.Message): + """Котировка — денежная сумма без указания валюты.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + UNITS_FIELD_NUMBER: builtins.int + NANO_FIELD_NUMBER: builtins.int + units: builtins.int + """Целая часть суммы, может быть отрицательным числом.""" + nano: builtins.int + """Дробная часть суммы, может быть отрицательным числом.""" + def __init__( + self, + *, + units: builtins.int = ..., + nano: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["nano", b"nano", "units", b"units"]) -> None: ... + +global___Quotation = Quotation + +@typing.final +class PingRequest(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TIME_FIELD_NUMBER: builtins.int + @property + def time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время формирования запроса.""" + + def __init__( + self, + *, + time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_time", b"_time", "time", b"time"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_time", b"_time", "time", b"time"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_time", b"_time"]) -> typing.Literal["time"] | None: ... + +global___PingRequest = PingRequest + +@typing.final +class PingDelaySettings(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PING_DELAY_MS_FIELD_NUMBER: builtins.int + ping_delay_ms: builtins.int + """Задержка (пинг) сообщений: 5000–180 000 миллисекунд. Значение по умолчанию — 120 000.""" + def __init__( + self, + *, + ping_delay_ms: builtins.int | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_ping_delay_ms", b"_ping_delay_ms", "ping_delay_ms", b"ping_delay_ms"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_ping_delay_ms", b"_ping_delay_ms", "ping_delay_ms", b"ping_delay_ms"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_ping_delay_ms", b"_ping_delay_ms"]) -> typing.Literal["ping_delay_ms"] | None: ... + +global___PingDelaySettings = PingDelaySettings + +@typing.final +class Ping(google.protobuf.message.Message): + """Проверка активности стрима.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TIME_FIELD_NUMBER: builtins.int + STREAM_ID_FIELD_NUMBER: builtins.int + PING_REQUEST_TIME_FIELD_NUMBER: builtins.int + stream_id: builtins.str + """Идентификатор соединения.""" + @property + def time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время проверки.""" + + @property + def ping_request_time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время формирования запроса.""" + + def __init__( + self, + *, + time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + stream_id: builtins.str = ..., + ping_request_time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_ping_request_time", b"_ping_request_time", "ping_request_time", b"ping_request_time", "time", b"time"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_ping_request_time", b"_ping_request_time", "ping_request_time", b"ping_request_time", "stream_id", b"stream_id", "time", b"time"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_ping_request_time", b"_ping_request_time"]) -> typing.Literal["ping_request_time"] | None: ... + +global___Ping = Ping + +@typing.final +class Page(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + LIMIT_FIELD_NUMBER: builtins.int + PAGE_NUMBER_FIELD_NUMBER: builtins.int + limit: builtins.int + """Максимальное число возвращаемых записей.""" + page_number: builtins.int + """Порядковый номер страницы, начиная с 0.""" + def __init__( + self, + *, + limit: builtins.int = ..., + page_number: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["limit", b"limit", "page_number", b"page_number"]) -> None: ... + +global___Page = Page + +@typing.final +class PageResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + LIMIT_FIELD_NUMBER: builtins.int + PAGE_NUMBER_FIELD_NUMBER: builtins.int + TOTAL_COUNT_FIELD_NUMBER: builtins.int + limit: builtins.int + """Максимальное число возвращаемых записей.""" + page_number: builtins.int + """Порядковый номер страницы, начиная с 0.""" + total_count: builtins.int + """Общее количество записей.""" + def __init__( + self, + *, + limit: builtins.int = ..., + page_number: builtins.int = ..., + total_count: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["limit", b"limit", "page_number", b"page_number", "total_count", b"total_count"]) -> None: ... + +global___PageResponse = PageResponse + +@typing.final +class ResponseMetadata(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TRACKING_ID_FIELD_NUMBER: builtins.int + SERVER_TIME_FIELD_NUMBER: builtins.int + tracking_id: builtins.str + """Идентификатор трекинга.""" + @property + def server_time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Серверное время.""" + + def __init__( + self, + *, + tracking_id: builtins.str = ..., + server_time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["server_time", b"server_time"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["server_time", b"server_time", "tracking_id", b"tracking_id"]) -> None: ... + +global___ResponseMetadata = ResponseMetadata + +@typing.final +class BrandData(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + LOGO_NAME_FIELD_NUMBER: builtins.int + LOGO_BASE_COLOR_FIELD_NUMBER: builtins.int + TEXT_COLOR_FIELD_NUMBER: builtins.int + logo_name: builtins.str + """Логотип инструмента. Имя файла для получения логотипа.""" + logo_base_color: builtins.str + """ Цвет бренда.""" + text_color: builtins.str + """Цвет текста для цвета логотипа бренда.""" + def __init__( + self, + *, + logo_name: builtins.str = ..., + logo_base_color: builtins.str = ..., + text_color: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["logo_base_color", b"logo_base_color", "logo_name", b"logo_name", "text_color", b"text_color"]) -> None: ... + +global___BrandData = BrandData + +@typing.final +class ErrorDetail(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + CODE_FIELD_NUMBER: builtins.int + MESSAGE_FIELD_NUMBER: builtins.int + code: builtins.str + """Код ошибки.""" + message: builtins.str + """Описание ошибки.""" + def __init__( + self, + *, + code: builtins.str = ..., + message: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["code", b"code", "message", b"message"]) -> None: ... + +global___ErrorDetail = ErrorDetail diff --git a/invest-python-master/t_tech/invest/grpc/common_pb2_grpc.py b/invest-python-master/t_tech/invest/grpc/common_pb2_grpc.py new file mode 100644 index 0000000..2daafff --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/common_pb2_grpc.py @@ -0,0 +1,4 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + diff --git a/invest-python-master/t_tech/invest/grpc/google/api/field_behavior_pb2.py b/invest-python-master/t_tech/invest/grpc/google/api/field_behavior_pb2.py new file mode 100644 index 0000000..af9aa9c --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/google/api/field_behavior_pb2.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: t_tech/invest/grpc/google/api/field_behavior.proto +# Protobuf Python Version: 4.25.1 +"""Generated protocol buffer code.""" +from google.protobuf import ( + descriptor as _descriptor, + descriptor_pool as _descriptor_pool, + symbol_database as _symbol_database, +) +from google.protobuf.internal import builder as _builder + +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n2t_tech/invest/grpc/google/api/field_behavior.proto\x12\ngoogle.api\x1a google/protobuf/descriptor.proto*\xa6\x01\n\rFieldBehavior\x12\x1e\n\x1a\x46IELD_BEHAVIOR_UNSPECIFIED\x10\x00\x12\x0c\n\x08OPTIONAL\x10\x01\x12\x0c\n\x08REQUIRED\x10\x02\x12\x0f\n\x0bOUTPUT_ONLY\x10\x03\x12\x0e\n\nINPUT_ONLY\x10\x04\x12\r\n\tIMMUTABLE\x10\x05\x12\x12\n\x0eUNORDERED_LIST\x10\x06\x12\x15\n\x11NON_EMPTY_DEFAULT\x10\x07:Q\n\x0e\x66ield_behavior\x12\x1d.google.protobuf.FieldOptions\x18\x9c\x08 \x03(\x0e\x32\x19.google.api.FieldBehaviorBp\n\x0e\x63om.google.apiB\x12\x46ieldBehaviorProtoP\x01ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\xa2\x02\x04GAPIb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 't_tech.invest.grpc.google.api.field_behavior_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\016com.google.apiB\022FieldBehaviorProtoP\001ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\242\002\004GAPI' + _globals['_FIELDBEHAVIOR']._serialized_start=101 + _globals['_FIELDBEHAVIOR']._serialized_end=267 +# @@protoc_insertion_point(module_scope) diff --git a/invest-python-master/t_tech/invest/grpc/google/api/field_behavior_pb2.pyi b/invest-python-master/t_tech/invest/grpc/google/api/field_behavior_pb2.pyi new file mode 100644 index 0000000..932962b --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/google/api/field_behavior_pb2.pyi @@ -0,0 +1,147 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +Copyright 2023 Google LLC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + +import builtins +import google.protobuf.descriptor +import google.protobuf.descriptor_pb2 +import google.protobuf.internal.containers +import google.protobuf.internal.enum_type_wrapper +import google.protobuf.internal.extension_dict +import sys +import typing + +if sys.version_info >= (3, 10): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +class _FieldBehavior: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _FieldBehaviorEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_FieldBehavior.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + FIELD_BEHAVIOR_UNSPECIFIED: _FieldBehavior.ValueType # 0 + """Conventional default for enums. Do not use this.""" + OPTIONAL: _FieldBehavior.ValueType # 1 + """Specifically denotes a field as optional. + While all fields in protocol buffers are optional, this may be specified + for emphasis if appropriate. + """ + REQUIRED: _FieldBehavior.ValueType # 2 + """Denotes a field as required. + This indicates that the field **must** be provided as part of the request, + and failure to do so will cause an error (usually `INVALID_ARGUMENT`). + """ + OUTPUT_ONLY: _FieldBehavior.ValueType # 3 + """Denotes a field as output only. + This indicates that the field is provided in responses, but including the + field in a request does nothing (the server *must* ignore it and + *must not* throw an error as a result of the field's presence). + """ + INPUT_ONLY: _FieldBehavior.ValueType # 4 + """Denotes a field as input only. + This indicates that the field is provided in requests, and the + corresponding field is not included in output. + """ + IMMUTABLE: _FieldBehavior.ValueType # 5 + """Denotes a field as immutable. + This indicates that the field may be set once in a request to create a + resource, but may not be changed thereafter. + """ + UNORDERED_LIST: _FieldBehavior.ValueType # 6 + """Denotes that a (repeated) field is an unordered list. + This indicates that the service may provide the elements of the list + in any arbitrary order, rather than the order the user originally + provided. Additionally, the list's order may or may not be stable. + """ + NON_EMPTY_DEFAULT: _FieldBehavior.ValueType # 7 + """Denotes that this field returns a non-empty default value if not set. + This indicates that if the user provides the empty value in a request, + a non-empty value will be returned. The user will not be aware of what + non-empty value to expect. + """ + +class FieldBehavior(_FieldBehavior, metaclass=_FieldBehaviorEnumTypeWrapper): + """An indicator of the behavior of a given field (for example, that a field + is required in requests, or given as output but ignored as input). + This **does not** change the behavior in protocol buffers itself; it only + denotes the behavior and may affect how API tooling handles the field. + + Note: This enum **may** receive new values in the future. + """ + +FIELD_BEHAVIOR_UNSPECIFIED: FieldBehavior.ValueType # 0 +"""Conventional default for enums. Do not use this.""" +OPTIONAL: FieldBehavior.ValueType # 1 +"""Specifically denotes a field as optional. +While all fields in protocol buffers are optional, this may be specified +for emphasis if appropriate. +""" +REQUIRED: FieldBehavior.ValueType # 2 +"""Denotes a field as required. +This indicates that the field **must** be provided as part of the request, +and failure to do so will cause an error (usually `INVALID_ARGUMENT`). +""" +OUTPUT_ONLY: FieldBehavior.ValueType # 3 +"""Denotes a field as output only. +This indicates that the field is provided in responses, but including the +field in a request does nothing (the server *must* ignore it and +*must not* throw an error as a result of the field's presence). +""" +INPUT_ONLY: FieldBehavior.ValueType # 4 +"""Denotes a field as input only. +This indicates that the field is provided in requests, and the +corresponding field is not included in output. +""" +IMMUTABLE: FieldBehavior.ValueType # 5 +"""Denotes a field as immutable. +This indicates that the field may be set once in a request to create a +resource, but may not be changed thereafter. +""" +UNORDERED_LIST: FieldBehavior.ValueType # 6 +"""Denotes that a (repeated) field is an unordered list. +This indicates that the service may provide the elements of the list +in any arbitrary order, rather than the order the user originally +provided. Additionally, the list's order may or may not be stable. +""" +NON_EMPTY_DEFAULT: FieldBehavior.ValueType # 7 +"""Denotes that this field returns a non-empty default value if not set. +This indicates that if the user provides the empty value in a request, +a non-empty value will be returned. The user will not be aware of what +non-empty value to expect. +""" +global___FieldBehavior = FieldBehavior + +FIELD_BEHAVIOR_FIELD_NUMBER: builtins.int +field_behavior: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FieldOptions, google.protobuf.internal.containers.RepeatedScalarFieldContainer[global___FieldBehavior.ValueType]] +"""A designation of a specific field behavior (required, output only, etc.) +in protobuf messages. + +Examples: + + string name = 1 [(google.api.field_behavior) = REQUIRED]; + State state = 1 [(google.api.field_behavior) = OUTPUT_ONLY]; + google.protobuf.Duration ttl = 1 + [(google.api.field_behavior) = INPUT_ONLY]; + google.protobuf.Timestamp expire_time = 1 + [(google.api.field_behavior) = OUTPUT_ONLY, + (google.api.field_behavior) = IMMUTABLE]; +""" diff --git a/invest-python-master/t_tech/invest/grpc/google/api/field_behavior_pb2_grpc.py b/invest-python-master/t_tech/invest/grpc/google/api/field_behavior_pb2_grpc.py new file mode 100644 index 0000000..2daafff --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/google/api/field_behavior_pb2_grpc.py @@ -0,0 +1,4 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + diff --git a/invest-python-master/t_tech/invest/grpc/instruments_pb2.py b/invest-python-master/t_tech/invest/grpc/instruments_pb2.py new file mode 100644 index 0000000..afb8a39 --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/instruments_pb2.py @@ -0,0 +1,391 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: t_tech/invest/grpc/instruments.proto +# Protobuf Python Version: 4.25.1 +"""Generated protocol buffer code.""" +from google.protobuf import ( + descriptor as _descriptor, + descriptor_pool as _descriptor_pool, + symbol_database as _symbol_database, +) +from google.protobuf.internal import builder as _builder + +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 + +from t_tech.invest.grpc import common_pb2 as t__tech_dot_invest_dot_grpc_dot_common__pb2 +from t_tech.invest.grpc.google.api import ( + field_behavior_pb2 as t__tech_dot_invest_dot_grpc_dot_google_dot_api_dot_field__behavior__pb2, +) + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$t_tech/invest/grpc/instruments.proto\x12%tinkoff.public.invest.api.contract.v1\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1ft_tech/invest/grpc/common.proto\x1a\x32t_tech/invest/grpc/google/api/field_behavior.proto\"\xa9\x01\n\x17TradingSchedulesRequest\x12\x15\n\x08\x65xchange\x18\x01 \x01(\tH\x00\x88\x01\x01\x12-\n\x04\x66rom\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x01\x88\x01\x01\x12+\n\x02to\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x02\x88\x01\x01\x42\x0b\n\t_exchangeB\x07\n\x05_fromB\x05\n\x03_to\"e\n\x18TradingSchedulesResponse\x12I\n\texchanges\x18\x01 \x03(\x0b\x32\x36.tinkoff.public.invest.api.contract.v1.TradingSchedule\"d\n\x0fTradingSchedule\x12\x10\n\x08\x65xchange\x18\x01 \x01(\t\x12?\n\x04\x64\x61ys\x18\x02 \x03(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.TradingDay\"\x97\x07\n\nTradingDay\x12(\n\x04\x64\x61te\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x16\n\x0eis_trading_day\x18\x02 \x01(\x08\x12.\n\nstart_time\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12,\n\x08\x65nd_time\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12>\n\x1aopening_auction_start_time\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12<\n\x18\x63losing_auction_end_time\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x46\n\"evening_opening_auction_start_time\x18\t \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x36\n\x12\x65vening_start_time\x18\n \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x34\n\x10\x65vening_end_time\x18\x0b \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x37\n\x13\x63learing_start_time\x18\x0c \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x35\n\x11\x63learing_end_time\x18\r \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x38\n\x14premarket_start_time\x18\x0e \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x36\n\x12premarket_end_time\x18\x0f \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12>\n\x1a\x63losing_auction_start_time\x18\x10 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12<\n\x18opening_auction_end_time\x18\x11 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12I\n\tintervals\x18\x12 \x03(\x0b\x32\x36.tinkoff.public.invest.api.contract.v1.TradingIntervalJ\x04\x08\x05\x10\x06J\x04\x08\x06\x10\x07\"\x9d\x01\n\x11InstrumentRequest\x12N\n\x07id_type\x18\x01 \x01(\x0e\x32\x37.tinkoff.public.invest.api.contract.v1.InstrumentIdTypeB\x04\xe2\x41\x01\x02\x12\x17\n\nclass_code\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x10\n\x02id\x18\x03 \x01(\tB\x04\xe2\x41\x01\x02\x42\r\n\x0b_class_code\"\xfc\x01\n\x12InstrumentsRequest\x12W\n\x11instrument_status\x18\x01 \x01(\x0e\x32\x37.tinkoff.public.invest.api.contract.v1.InstrumentStatusH\x00\x88\x01\x01\x12_\n\x13instrument_exchange\x18\x02 \x01(\x0e\x32=.tinkoff.public.invest.api.contract.v1.InstrumentExchangeTypeH\x01\x88\x01\x01\x42\x14\n\x12_instrument_statusB\x16\n\x14_instrument_exchange\"\xc6\x01\n\x14\x46ilterOptionsRequest\x12\x1c\n\x0f\x62\x61sic_asset_uid\x18\x01 \x01(\tH\x00\x88\x01\x01\x12%\n\x18\x62\x61sic_asset_position_uid\x18\x02 \x01(\tH\x01\x88\x01\x01\x12 \n\x13\x62\x61sic_instrument_id\x18\x03 \x01(\tH\x02\x88\x01\x01\x42\x12\n\x10_basic_asset_uidB\x1b\n\x19_basic_asset_position_uidB\x16\n\x14_basic_instrument_id\"O\n\x0c\x42ondResponse\x12?\n\ninstrument\x18\x01 \x01(\x0b\x32+.tinkoff.public.invest.api.contract.v1.Bond\"Q\n\rBondsResponse\x12@\n\x0binstruments\x18\x01 \x03(\x0b\x32+.tinkoff.public.invest.api.contract.v1.Bond\"\xb2\x01\n\x15GetBondCouponsRequest\x12\x10\n\x04\x66igi\x18\x01 \x01(\tB\x02\x18\x01\x12-\n\x04\x66rom\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x00\x88\x01\x01\x12+\n\x02to\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x01\x88\x01\x01\x12\x1b\n\rinstrument_id\x18\x04 \x01(\tB\x04\xe2\x41\x01\x02\x42\x07\n\x05_fromB\x05\n\x03_to\"W\n\x16GetBondCouponsResponse\x12=\n\x06\x65vents\x18\x01 \x03(\x0b\x32-.tinkoff.public.invest.api.contract.v1.Coupon\"\xef\x02\n\x14GetBondEventsRequest\x12-\n\x04\x66rom\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x00\x88\x01\x01\x12+\n\x02to\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x01\x88\x01\x01\x12\x1b\n\rinstrument_id\x18\x04 \x01(\tB\x04\xe2\x41\x01\x02\x12S\n\x04type\x18\x05 \x01(\x0e\x32\x45.tinkoff.public.invest.api.contract.v1.GetBondEventsRequest.EventType\"y\n\tEventType\x12\x1a\n\x16\x45VENT_TYPE_UNSPECIFIED\x10\x00\x12\x12\n\x0e\x45VENT_TYPE_CPN\x10\x01\x12\x13\n\x0f\x45VENT_TYPE_CALL\x10\x02\x12\x12\n\x0e\x45VENT_TYPE_MTY\x10\x03\x12\x13\n\x0f\x45VENT_TYPE_CONV\x10\x04\x42\x07\n\x05_fromB\x05\n\x03_to\"\xf1\x08\n\x15GetBondEventsResponse\x12V\n\x06\x65vents\x18\x01 \x03(\x0b\x32\x46.tinkoff.public.invest.api.contract.v1.GetBondEventsResponse.BondEvent\x1a\xff\x07\n\tBondEvent\x12\x15\n\rinstrument_id\x18\x02 \x01(\t\x12\x14\n\x0c\x65vent_number\x18\x03 \x01(\x05\x12.\n\nevent_date\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12Y\n\nevent_type\x18\x05 \x01(\x0e\x32\x45.tinkoff.public.invest.api.contract.v1.GetBondEventsRequest.EventType\x12I\n\x0f\x65vent_total_vol\x18\x06 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12,\n\x08\x66ix_date\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12-\n\trate_date\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x30\n\x0c\x64\x65\x66\x61ult_date\x18\t \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x31\n\rreal_pay_date\x18\n \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12,\n\x08pay_date\x18\x0b \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12G\n\x0cpay_one_bond\x18\x0c \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12I\n\x0emoney_flow_val\x18\r \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x11\n\texecution\x18\x0e \x01(\t\x12\x16\n\x0eoperation_type\x18\x0f \x01(\t\x12?\n\x05value\x18\x10 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x0c\n\x04note\x18\x11 \x01(\t\x12\x1e\n\x16\x63onvert_to_fin_tool_id\x18\x12 \x01(\t\x12\x35\n\x11\x63oupon_start_date\x18\x13 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x33\n\x0f\x63oupon_end_date\x18\x14 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x15\n\rcoupon_period\x18\x15 \x01(\x05\x12N\n\x14\x63oupon_interest_rate\x18\x16 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\"\xa0\x03\n\x06\x43oupon\x12\x0c\n\x04\x66igi\x18\x01 \x01(\t\x12/\n\x0b\x63oupon_date\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x15\n\rcoupon_number\x18\x03 \x01(\x03\x12,\n\x08\x66ix_date\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12G\n\x0cpay_one_bond\x18\x05 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x46\n\x0b\x63oupon_type\x18\x06 \x01(\x0e\x32\x31.tinkoff.public.invest.api.contract.v1.CouponType\x12\x35\n\x11\x63oupon_start_date\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x33\n\x0f\x63oupon_end_date\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x15\n\rcoupon_period\x18\t \x01(\x05\"W\n\x10\x43urrencyResponse\x12\x43\n\ninstrument\x18\x01 \x01(\x0b\x32/.tinkoff.public.invest.api.contract.v1.Currency\"Z\n\x12\x43urrenciesResponse\x12\x44\n\x0binstruments\x18\x01 \x03(\x0b\x32/.tinkoff.public.invest.api.contract.v1.Currency\"M\n\x0b\x45tfResponse\x12>\n\ninstrument\x18\x01 \x01(\x0b\x32*.tinkoff.public.invest.api.contract.v1.Etf\"O\n\x0c\x45tfsResponse\x12?\n\x0binstruments\x18\x01 \x03(\x0b\x32*.tinkoff.public.invest.api.contract.v1.Etf\"S\n\x0e\x46utureResponse\x12\x41\n\ninstrument\x18\x01 \x01(\x0b\x32-.tinkoff.public.invest.api.contract.v1.Future\"U\n\x0f\x46uturesResponse\x12\x42\n\x0binstruments\x18\x01 \x03(\x0b\x32-.tinkoff.public.invest.api.contract.v1.Future\"S\n\x0eOptionResponse\x12\x41\n\ninstrument\x18\x01 \x01(\x0b\x32-.tinkoff.public.invest.api.contract.v1.Option\"U\n\x0fOptionsResponse\x12\x42\n\x0binstruments\x18\x01 \x03(\x0b\x32-.tinkoff.public.invest.api.contract.v1.Option\"\xa3\x11\n\x06Option\x12\x0b\n\x03uid\x18\x01 \x01(\t\x12\x14\n\x0cposition_uid\x18\x02 \x01(\t\x12\x0e\n\x06ticker\x18\x03 \x01(\t\x12\x12\n\nclass_code\x18\x04 \x01(\t\x12 \n\x18\x62\x61sic_asset_position_uid\x18\x05 \x01(\t\x12T\n\x0etrading_status\x18\x15 \x01(\x0e\x32<.tinkoff.public.invest.api.contract.v1.SecurityTradingStatus\x12J\n\rreal_exchange\x18\x1f \x01(\x0e\x32\x33.tinkoff.public.invest.api.contract.v1.RealExchange\x12I\n\tdirection\x18) \x01(\x0e\x32\x36.tinkoff.public.invest.api.contract.v1.OptionDirection\x12N\n\x0cpayment_type\x18* \x01(\x0e\x32\x38.tinkoff.public.invest.api.contract.v1.OptionPaymentType\x12\x41\n\x05style\x18+ \x01(\x0e\x32\x32.tinkoff.public.invest.api.contract.v1.OptionStyle\x12T\n\x0fsettlement_type\x18, \x01(\x0e\x32;.tinkoff.public.invest.api.contract.v1.OptionSettlementType\x12\x0c\n\x04name\x18\x65 \x01(\t\x12\x10\n\x08\x63urrency\x18o \x01(\t\x12\x1b\n\x13settlement_currency\x18p \x01(\t\x12\x13\n\nasset_type\x18\x83\x01 \x01(\t\x12\x14\n\x0b\x62\x61sic_asset\x18\x84\x01 \x01(\t\x12\x11\n\x08\x65xchange\x18\x8d\x01 \x01(\t\x12\x18\n\x0f\x63ountry_of_risk\x18\x97\x01 \x01(\t\x12\x1d\n\x14\x63ountry_of_risk_name\x18\x98\x01 \x01(\t\x12\x0f\n\x06sector\x18\xa1\x01 \x01(\t\x12@\n\x05\x62rand\x18\xa2\x01 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.BrandData\x12\x0c\n\x03lot\x18\xc9\x01 \x01(\x05\x12K\n\x10\x62\x61sic_asset_size\x18\xd3\x01 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x44\n\x05klong\x18\xdd\x01 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationB\x02\x18\x01\x12\x45\n\x06kshort\x18\xde\x01 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationB\x02\x18\x01\x12@\n\x05\x64long\x18\xdf\x01 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x41\n\x06\x64short\x18\xe0\x01 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x44\n\tdlong_min\x18\xe1\x01 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x45\n\ndshort_min\x18\xe2\x01 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12N\n\x13min_price_increment\x18\xe7\x01 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12H\n\x0cstrike_price\x18\xf1\x01 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12G\n\x0c\x64long_client\x18\xa2\x02 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12H\n\rdshort_client\x18\xa3\x02 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x34\n\x0f\x65xpiration_date\x18\xad\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x35\n\x10\x66irst_trade_date\x18\xb7\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x34\n\x0flast_trade_date\x18\xb8\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12;\n\x16\x66irst_1min_candle_date\x18\xc1\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12;\n\x16\x66irst_1day_candle_date\x18\xc2\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x1b\n\x12short_enabled_flag\x18\x91\x03 \x01(\x08\x12\x15\n\x0c\x66or_iis_flag\x18\x92\x03 \x01(\x08\x12\x11\n\x08otc_flag\x18\x93\x03 \x01(\x08\x12\x1b\n\x12\x62uy_available_flag\x18\x94\x03 \x01(\x08\x12\x1c\n\x13sell_available_flag\x18\x95\x03 \x01(\x08\x12\x1f\n\x16\x66or_qual_investor_flag\x18\x96\x03 \x01(\x08\x12\x15\n\x0cweekend_flag\x18\x97\x03 \x01(\x08\x12\x19\n\x10\x62locked_tca_flag\x18\x98\x03 \x01(\x08\x12!\n\x18\x61pi_trade_available_flag\x18\x99\x03 \x01(\x08\x12\x17\n\x0erequired_tests\x18\x9a\x03 \x03(\t\"Q\n\rShareResponse\x12@\n\ninstrument\x18\x01 \x01(\x0b\x32,.tinkoff.public.invest.api.contract.v1.Share\"S\n\x0eSharesResponse\x12\x41\n\x0binstruments\x18\x01 \x03(\x0b\x32,.tinkoff.public.invest.api.contract.v1.Share\"c\n\x16StructuredNoteResponse\x12I\n\ninstrument\x18\x01 \x01(\x0b\x32\x35.tinkoff.public.invest.api.contract.v1.StructuredNote\"e\n\x17StructuredNotesResponse\x12J\n\x0binstruments\x18\x01 \x03(\x0b\x32\x35.tinkoff.public.invest.api.contract.v1.StructuredNote\"\xba\x12\n\x04\x42ond\x12\x0c\n\x04\x66igi\x18\x01 \x01(\t\x12\x0e\n\x06ticker\x18\x02 \x01(\t\x12\x12\n\nclass_code\x18\x03 \x01(\t\x12\x0c\n\x04isin\x18\x04 \x01(\t\x12\x0b\n\x03lot\x18\x05 \x01(\x05\x12\x10\n\x08\x63urrency\x18\x06 \x01(\t\x12\x43\n\x05klong\x18\x07 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationB\x02\x18\x01\x12\x44\n\x06kshort\x18\x08 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationB\x02\x18\x01\x12?\n\x05\x64long\x18\t \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12@\n\x06\x64short\x18\n \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x43\n\tdlong_min\x18\x0b \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x44\n\ndshort_min\x18\x0c \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x1a\n\x12short_enabled_flag\x18\r \x01(\x08\x12\x0c\n\x04name\x18\x0f \x01(\t\x12\x10\n\x08\x65xchange\x18\x10 \x01(\t\x12 \n\x18\x63oupon_quantity_per_year\x18\x11 \x01(\x05\x12\x31\n\rmaturity_date\x18\x12 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x42\n\x07nominal\x18\x13 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12J\n\x0finitial_nominal\x18\x14 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x32\n\x0estate_reg_date\x18\x15 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x32\n\x0eplacement_date\x18\x16 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12J\n\x0fplacement_price\x18\x17 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x44\n\taci_value\x18\x18 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x17\n\x0f\x63ountry_of_risk\x18\x19 \x01(\t\x12\x1c\n\x14\x63ountry_of_risk_name\x18\x1a \x01(\t\x12\x0e\n\x06sector\x18\x1b \x01(\t\x12\x12\n\nissue_kind\x18\x1c \x01(\t\x12\x12\n\nissue_size\x18\x1d \x01(\x03\x12\x17\n\x0fissue_size_plan\x18\x1e \x01(\x03\x12T\n\x0etrading_status\x18\x1f \x01(\x0e\x32<.tinkoff.public.invest.api.contract.v1.SecurityTradingStatus\x12\x10\n\x08otc_flag\x18 \x01(\x08\x12\x1a\n\x12\x62uy_available_flag\x18! \x01(\x08\x12\x1b\n\x13sell_available_flag\x18\" \x01(\x08\x12\x1c\n\x14\x66loating_coupon_flag\x18# \x01(\x08\x12\x16\n\x0eperpetual_flag\x18$ \x01(\x08\x12\x19\n\x11\x61mortization_flag\x18% \x01(\x08\x12M\n\x13min_price_increment\x18& \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12 \n\x18\x61pi_trade_available_flag\x18\' \x01(\x08\x12\x0b\n\x03uid\x18( \x01(\t\x12J\n\rreal_exchange\x18) \x01(\x0e\x32\x33.tinkoff.public.invest.api.contract.v1.RealExchange\x12\x14\n\x0cposition_uid\x18* \x01(\t\x12\x11\n\tasset_uid\x18+ \x01(\t\x12\x16\n\x0erequired_tests\x18, \x03(\t\x12\x14\n\x0c\x66or_iis_flag\x18\x33 \x01(\x08\x12\x1e\n\x16\x66or_qual_investor_flag\x18\x34 \x01(\x08\x12\x14\n\x0cweekend_flag\x18\x35 \x01(\x08\x12\x18\n\x10\x62locked_tca_flag\x18\x36 \x01(\x08\x12\x19\n\x11subordinated_flag\x18\x37 \x01(\x08\x12\x16\n\x0eliquidity_flag\x18\x38 \x01(\x08\x12:\n\x16\x66irst_1min_candle_date\x18= \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12:\n\x16\x66irst_1day_candle_date\x18> \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x44\n\nrisk_level\x18? \x01(\x0e\x32\x30.tinkoff.public.invest.api.contract.v1.RiskLevel\x12?\n\x05\x62rand\x18@ \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.BrandData\x12\x42\n\tbond_type\x18\x41 \x01(\x0e\x32/.tinkoff.public.invest.api.contract.v1.BondType\x12-\n\tcall_date\x18\x45 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x46\n\x0c\x64long_client\x18Z \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12G\n\rdshort_client\x18[ \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\"\xb0\x0c\n\x08\x43urrency\x12\x0c\n\x04\x66igi\x18\x01 \x01(\t\x12\x0e\n\x06ticker\x18\x02 \x01(\t\x12\x12\n\nclass_code\x18\x03 \x01(\t\x12\x0c\n\x04isin\x18\x04 \x01(\t\x12\x0b\n\x03lot\x18\x05 \x01(\x05\x12\x10\n\x08\x63urrency\x18\x06 \x01(\t\x12\x43\n\x05klong\x18\x07 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationB\x02\x18\x01\x12\x44\n\x06kshort\x18\x08 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationB\x02\x18\x01\x12?\n\x05\x64long\x18\t \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12@\n\x06\x64short\x18\n \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x43\n\tdlong_min\x18\x0b \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x44\n\ndshort_min\x18\x0c \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x1a\n\x12short_enabled_flag\x18\r \x01(\x08\x12\x0c\n\x04name\x18\x0f \x01(\t\x12\x10\n\x08\x65xchange\x18\x10 \x01(\t\x12\x42\n\x07nominal\x18\x11 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x17\n\x0f\x63ountry_of_risk\x18\x12 \x01(\t\x12\x1c\n\x14\x63ountry_of_risk_name\x18\x13 \x01(\t\x12T\n\x0etrading_status\x18\x14 \x01(\x0e\x32<.tinkoff.public.invest.api.contract.v1.SecurityTradingStatus\x12\x10\n\x08otc_flag\x18\x15 \x01(\x08\x12\x1a\n\x12\x62uy_available_flag\x18\x16 \x01(\x08\x12\x1b\n\x13sell_available_flag\x18\x17 \x01(\x08\x12\x19\n\x11iso_currency_name\x18\x18 \x01(\t\x12M\n\x13min_price_increment\x18\x19 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12 \n\x18\x61pi_trade_available_flag\x18\x1a \x01(\x08\x12\x0b\n\x03uid\x18\x1b \x01(\t\x12J\n\rreal_exchange\x18\x1c \x01(\x0e\x32\x33.tinkoff.public.invest.api.contract.v1.RealExchange\x12\x14\n\x0cposition_uid\x18\x1d \x01(\t\x12\x16\n\x0erequired_tests\x18\x1e \x03(\t\x12\x11\n\tasset_uid\x18\x1f \x01(\t\x12\x14\n\x0c\x66or_iis_flag\x18) \x01(\x08\x12\x1e\n\x16\x66or_qual_investor_flag\x18\x34 \x01(\x08\x12\x14\n\x0cweekend_flag\x18\x35 \x01(\x08\x12\x18\n\x10\x62locked_tca_flag\x18\x36 \x01(\x08\x12:\n\x16\x66irst_1min_candle_date\x18\x38 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12:\n\x16\x66irst_1day_candle_date\x18\x39 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12?\n\x05\x62rand\x18< \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.BrandData\x12\x46\n\x0c\x64long_client\x18Z \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12G\n\rdshort_client\x18[ \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\"\xc3\x0e\n\x03\x45tf\x12\x0c\n\x04\x66igi\x18\x01 \x01(\t\x12\x0e\n\x06ticker\x18\x02 \x01(\t\x12\x12\n\nclass_code\x18\x03 \x01(\t\x12\x0c\n\x04isin\x18\x04 \x01(\t\x12\x0b\n\x03lot\x18\x05 \x01(\x05\x12\x10\n\x08\x63urrency\x18\x06 \x01(\t\x12\x43\n\x05klong\x18\x07 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationB\x02\x18\x01\x12\x44\n\x06kshort\x18\x08 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationB\x02\x18\x01\x12?\n\x05\x64long\x18\t \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12@\n\x06\x64short\x18\n \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x43\n\tdlong_min\x18\x0b \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x44\n\ndshort_min\x18\x0c \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x1a\n\x12short_enabled_flag\x18\r \x01(\x08\x12\x0c\n\x04name\x18\x0f \x01(\t\x12\x10\n\x08\x65xchange\x18\x10 \x01(\t\x12J\n\x10\x66ixed_commission\x18\x11 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x12\n\nfocus_type\x18\x12 \x01(\t\x12\x31\n\rreleased_date\x18\x13 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x44\n\nnum_shares\x18\x14 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x17\n\x0f\x63ountry_of_risk\x18\x15 \x01(\t\x12\x1c\n\x14\x63ountry_of_risk_name\x18\x16 \x01(\t\x12\x0e\n\x06sector\x18\x17 \x01(\t\x12\x18\n\x10rebalancing_freq\x18\x18 \x01(\t\x12T\n\x0etrading_status\x18\x19 \x01(\x0e\x32<.tinkoff.public.invest.api.contract.v1.SecurityTradingStatus\x12\x10\n\x08otc_flag\x18\x1a \x01(\x08\x12\x1a\n\x12\x62uy_available_flag\x18\x1b \x01(\x08\x12\x1b\n\x13sell_available_flag\x18\x1c \x01(\x08\x12M\n\x13min_price_increment\x18\x1d \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12 \n\x18\x61pi_trade_available_flag\x18\x1e \x01(\x08\x12\x0b\n\x03uid\x18\x1f \x01(\t\x12J\n\rreal_exchange\x18 \x01(\x0e\x32\x33.tinkoff.public.invest.api.contract.v1.RealExchange\x12\x14\n\x0cposition_uid\x18! \x01(\t\x12\x11\n\tasset_uid\x18\" \x01(\t\x12Z\n\x13instrument_exchange\x18# \x01(\x0e\x32=.tinkoff.public.invest.api.contract.v1.InstrumentExchangeType\x12\x16\n\x0erequired_tests\x18$ \x03(\t\x12\x14\n\x0c\x66or_iis_flag\x18) \x01(\x08\x12\x1e\n\x16\x66or_qual_investor_flag\x18* \x01(\x08\x12\x14\n\x0cweekend_flag\x18+ \x01(\x08\x12\x18\n\x10\x62locked_tca_flag\x18, \x01(\x08\x12\x16\n\x0eliquidity_flag\x18- \x01(\x08\x12:\n\x16\x66irst_1min_candle_date\x18\x38 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12:\n\x16\x66irst_1day_candle_date\x18\x39 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12?\n\x05\x62rand\x18< \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.BrandData\x12\x46\n\x0c\x64long_client\x18Z \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12G\n\rdshort_client\x18[ \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\"\x86\x10\n\x06\x46uture\x12\x0c\n\x04\x66igi\x18\x01 \x01(\t\x12\x0e\n\x06ticker\x18\x02 \x01(\t\x12\x12\n\nclass_code\x18\x03 \x01(\t\x12\x0b\n\x03lot\x18\x04 \x01(\x05\x12\x10\n\x08\x63urrency\x18\x05 \x01(\t\x12\x43\n\x05klong\x18\x06 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationB\x02\x18\x01\x12\x44\n\x06kshort\x18\x07 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationB\x02\x18\x01\x12?\n\x05\x64long\x18\x08 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12@\n\x06\x64short\x18\t \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x43\n\tdlong_min\x18\n \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x44\n\ndshort_min\x18\x0b \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x1a\n\x12short_enabled_flag\x18\x0c \x01(\x08\x12\x0c\n\x04name\x18\r \x01(\t\x12\x10\n\x08\x65xchange\x18\x0e \x01(\t\x12\x34\n\x10\x66irst_trade_date\x18\x0f \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x33\n\x0flast_trade_date\x18\x10 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x14\n\x0c\x66utures_type\x18\x11 \x01(\t\x12\x12\n\nasset_type\x18\x12 \x01(\t\x12\x13\n\x0b\x62\x61sic_asset\x18\x13 \x01(\t\x12J\n\x10\x62\x61sic_asset_size\x18\x14 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x17\n\x0f\x63ountry_of_risk\x18\x15 \x01(\t\x12\x1c\n\x14\x63ountry_of_risk_name\x18\x16 \x01(\t\x12\x0e\n\x06sector\x18\x17 \x01(\t\x12\x33\n\x0f\x65xpiration_date\x18\x18 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12T\n\x0etrading_status\x18\x19 \x01(\x0e\x32<.tinkoff.public.invest.api.contract.v1.SecurityTradingStatus\x12\x10\n\x08otc_flag\x18\x1a \x01(\x08\x12\x1a\n\x12\x62uy_available_flag\x18\x1b \x01(\x08\x12\x1b\n\x13sell_available_flag\x18\x1c \x01(\x08\x12M\n\x13min_price_increment\x18\x1d \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12 \n\x18\x61pi_trade_available_flag\x18\x1e \x01(\x08\x12\x0b\n\x03uid\x18\x1f \x01(\t\x12J\n\rreal_exchange\x18 \x01(\x0e\x32\x33.tinkoff.public.invest.api.contract.v1.RealExchange\x12\x14\n\x0cposition_uid\x18! \x01(\t\x12 \n\x18\x62\x61sic_asset_position_uid\x18\" \x01(\t\x12\x16\n\x0erequired_tests\x18# \x03(\t\x12\x14\n\x0c\x66or_iis_flag\x18) \x01(\x08\x12\x1e\n\x16\x66or_qual_investor_flag\x18* \x01(\x08\x12\x14\n\x0cweekend_flag\x18+ \x01(\x08\x12\x18\n\x10\x62locked_tca_flag\x18, \x01(\x08\x12:\n\x16\x66irst_1min_candle_date\x18\x38 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12:\n\x16\x66irst_1day_candle_date\x18\x39 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12P\n\x15initial_margin_on_buy\x18= \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12Q\n\x16initial_margin_on_sell\x18> \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12T\n\x1amin_price_increment_amount\x18? \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12?\n\x05\x62rand\x18@ \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.BrandData\x12\x46\n\x0c\x64long_client\x18Z \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12G\n\rdshort_client\x18[ \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\"\xcf\x0e\n\x05Share\x12\x0c\n\x04\x66igi\x18\x01 \x01(\t\x12\x0e\n\x06ticker\x18\x02 \x01(\t\x12\x12\n\nclass_code\x18\x03 \x01(\t\x12\x0c\n\x04isin\x18\x04 \x01(\t\x12\x0b\n\x03lot\x18\x05 \x01(\x05\x12\x10\n\x08\x63urrency\x18\x06 \x01(\t\x12\x43\n\x05klong\x18\x07 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationB\x02\x18\x01\x12\x44\n\x06kshort\x18\x08 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationB\x02\x18\x01\x12?\n\x05\x64long\x18\t \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12@\n\x06\x64short\x18\n \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x43\n\tdlong_min\x18\x0b \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x44\n\ndshort_min\x18\x0c \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x1a\n\x12short_enabled_flag\x18\r \x01(\x08\x12\x0c\n\x04name\x18\x0f \x01(\t\x12\x10\n\x08\x65xchange\x18\x10 \x01(\t\x12,\n\x08ipo_date\x18\x11 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x12\n\nissue_size\x18\x12 \x01(\x03\x12\x17\n\x0f\x63ountry_of_risk\x18\x13 \x01(\t\x12\x1c\n\x14\x63ountry_of_risk_name\x18\x14 \x01(\t\x12\x0e\n\x06sector\x18\x15 \x01(\t\x12\x17\n\x0fissue_size_plan\x18\x16 \x01(\x03\x12\x42\n\x07nominal\x18\x17 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12T\n\x0etrading_status\x18\x19 \x01(\x0e\x32<.tinkoff.public.invest.api.contract.v1.SecurityTradingStatus\x12\x10\n\x08otc_flag\x18\x1a \x01(\x08\x12\x1a\n\x12\x62uy_available_flag\x18\x1b \x01(\x08\x12\x1b\n\x13sell_available_flag\x18\x1c \x01(\x08\x12\x16\n\x0e\x64iv_yield_flag\x18\x1d \x01(\x08\x12\x44\n\nshare_type\x18\x1e \x01(\x0e\x32\x30.tinkoff.public.invest.api.contract.v1.ShareType\x12M\n\x13min_price_increment\x18\x1f \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12 \n\x18\x61pi_trade_available_flag\x18 \x01(\x08\x12\x0b\n\x03uid\x18! \x01(\t\x12J\n\rreal_exchange\x18\" \x01(\x0e\x32\x33.tinkoff.public.invest.api.contract.v1.RealExchange\x12\x14\n\x0cposition_uid\x18# \x01(\t\x12\x11\n\tasset_uid\x18$ \x01(\t\x12Z\n\x13instrument_exchange\x18% \x01(\x0e\x32=.tinkoff.public.invest.api.contract.v1.InstrumentExchangeType\x12\x16\n\x0erequired_tests\x18& \x03(\t\x12\x14\n\x0c\x66or_iis_flag\x18. \x01(\x08\x12\x1e\n\x16\x66or_qual_investor_flag\x18/ \x01(\x08\x12\x14\n\x0cweekend_flag\x18\x30 \x01(\x08\x12\x18\n\x10\x62locked_tca_flag\x18\x31 \x01(\x08\x12\x16\n\x0eliquidity_flag\x18\x32 \x01(\x08\x12:\n\x16\x66irst_1min_candle_date\x18\x38 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12:\n\x16\x66irst_1day_candle_date\x18\x39 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12?\n\x05\x62rand\x18< \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.BrandData\x12\x46\n\x0c\x64long_client\x18Z \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12G\n\rdshort_client\x18[ \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\"\x81\x17\n\x0eStructuredNote\x12\x0b\n\x03uid\x18\x01 \x01(\t\x12\x0c\n\x04\x66igi\x18\x02 \x01(\t\x12\x0e\n\x06ticker\x18\x03 \x01(\t\x12\x12\n\nclass_code\x18\x04 \x01(\t\x12\x0c\n\x04isin\x18\x05 \x01(\t\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x11\n\tasset_uid\x18\x07 \x01(\t\x12\x14\n\x0cposition_uid\x18\x08 \x01(\t\x12M\n\x13min_price_increment\x18\t \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x0b\n\x03lot\x18\n \x01(\x05\x12\x42\n\x07nominal\x18\x0b \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x10\n\x08\x63urrency\x18\x0c \x01(\t\x12\x31\n\rmaturity_date\x18\r \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x32\n\x0eplacement_date\x18\x0e \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x12\n\nissue_kind\x18\x0f \x01(\t\x12\x12\n\nissue_size\x18\x10 \x01(\x05\x12\x17\n\x0fissue_size_plan\x18\x11 \x01(\x05\x12\x46\n\x0c\x64long_client\x18\x12 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12G\n\rdshort_client\x18\x13 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x1a\n\x12short_enabled_flag\x18\x14 \x01(\x08\x12\x10\n\x08\x65xchange\x18\x15 \x01(\t\x12T\n\x0etrading_status\x18\x16 \x01(\x0e\x32<.tinkoff.public.invest.api.contract.v1.SecurityTradingStatus\x12 \n\x18\x61pi_trade_available_flag\x18\x17 \x01(\x08\x12\x1a\n\x12\x62uy_available_flag\x18\x18 \x01(\x08\x12\x1b\n\x13sell_available_flag\x18\x19 \x01(\x08\x12\"\n\x1alimit_order_available_flag\x18\x1a \x01(\x08\x12#\n\x1bmarket_order_available_flag\x18\x1b \x01(\x08\x12&\n\x1e\x62\x65stprice_order_available_flag\x18\x1c \x01(\x08\x12\x14\n\x0cweekend_flag\x18\x1d \x01(\x08\x12\x16\n\x0eliquidity_flag\x18\x1e \x01(\x08\x12\x14\n\x0c\x66or_iis_flag\x18\x1f \x01(\x08\x12\x1e\n\x16\x66or_qual_investor_flag\x18 \x01(\x08\x12\x1a\n\x12pawnshop_list_flag\x18! \x01(\x08\x12J\n\rreal_exchange\x18\" \x01(\x0e\x32\x33.tinkoff.public.invest.api.contract.v1.RealExchange\x12:\n\x16\x66irst_1min_candle_date\x18# \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12:\n\x16\x66irst_1day_candle_date\x18$ \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x13\n\x0b\x62orrow_name\x18% \x01(\t\x12\x0c\n\x04type\x18& \x01(\t\x12]\n\x0flogic_portfolio\x18\' \x01(\x0e\x32\x44.tinkoff.public.invest.api.contract.v1.StructuredNote.LogicPortfolio\x12\x44\n\nasset_type\x18( \x01(\x0e\x32\x30.tinkoff.public.invest.api.contract.v1.AssetType\x12V\n\x0c\x62\x61sic_assets\x18) \x03(\x0b\x32@.tinkoff.public.invest.api.contract.v1.StructuredNote.BasicAsset\x12H\n\x0esafety_barrier\x18* \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x1a\n\x12\x63oupon_period_base\x18+ \x01(\t\x12i\n\x15observation_principle\x18, \x01(\x0e\x32J.tinkoff.public.invest.api.contract.v1.StructuredNote.ObservationPrinciple\x12\x1d\n\x15observation_frequency\x18- \x01(\t\x12=\n\x19initial_price_fixing_date\x18. \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12J\n\x05yield\x18/ \x03(\x0b\x32;.tinkoff.public.invest.api.contract.v1.StructuredNote.Yield\x12\x1a\n\x12\x63oupon_saving_flag\x18\x30 \x01(\x08\x12\x0e\n\x06sector\x18\x31 \x01(\t\x12\x17\n\x0f\x63ountry_of_risk\x18\x32 \x01(\t\x12\x1c\n\x14\x63ountry_of_risk_name\x18\x33 \x01(\t\x12\x11\n\tlogo_name\x18\x34 \x01(\t\x12\x16\n\x0erequired_tests\x18\x35 \x03(\t\x1a\xa2\x01\n\nBasicAsset\x12\x0b\n\x03uid\x18\x01 \x01(\t\x12>\n\x04type\x18\x02 \x01(\x0e\x32\x30.tinkoff.public.invest.api.contract.v1.AssetType\x12G\n\rinitial_price\x18\x03 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x1a\x97\x01\n\x05Yield\x12M\n\x04type\x18\x01 \x01(\x0e\x32?.tinkoff.public.invest.api.contract.v1.StructuredNote.YieldType\x12?\n\x05value\x18\x02 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\"r\n\x0eLogicPortfolio\x12\x1f\n\x1bLOGIC_PORTFOLIO_UNSPECIFIED\x10\x00\x12\x1e\n\x1aLOGIC_PORTFOLIO_VOLATILITY\x10\x01\x12\x1f\n\x1bLOGIC_PORTFOLIO_CORRELATION\x10\x02\"\x83\x02\n\x14ObservationPrinciple\x12%\n!OBSERVATION_PRINCIPLE_UNSPECIFIED\x10\x00\x12+\n\'OBSERVATION_PRINCIPLE_WORST_BASIC_ASSET\x10\x01\x12*\n&OBSERVATION_PRINCIPLE_BEST_BASIC_ASSET\x10\x02\x12\x31\n-OBSERVATION_PRINCIPLE_AVERAGE_OF_BASIC_ASSETS\x10\x03\x12\x38\n4OBSERVATION_PRINCIPLE_SINGLE_BASIC_ASSET_PERFORMANCE\x10\x04\"\x89\x01\n\tYieldType\x12\x1a\n\x16YIELD_TYPE_UNSPECIFIED\x10\x00\x12\x1f\n\x1bYIELD_TYPE_GUARANTED_COUPON\x10\x01\x12!\n\x1dYIELD_TYPE_CONDITIONAL_COUPON\x10\x02\x12\x1c\n\x18YIELD_TYPE_PARTICIPATION\x10\x03\"\xa9\x01\n\x1aGetAccruedInterestsRequest\x12\x10\n\x04\x66igi\x18\x01 \x01(\tB\x02\x18\x01\x12.\n\x04\x66rom\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x04\xe2\x41\x01\x02\x12,\n\x02to\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x04\xe2\x41\x01\x02\x12\x1b\n\rinstrument_id\x18\x04 \x01(\tB\x04\xe2\x41\x01\x02\"p\n\x1bGetAccruedInterestsResponse\x12Q\n\x11\x61\x63\x63rued_interests\x18\x01 \x03(\x0b\x32\x36.tinkoff.public.invest.api.contract.v1.AccruedInterest\"\x88\x02\n\x0f\x41\x63\x63ruedInterest\x12(\n\x04\x64\x61te\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12?\n\x05value\x18\x02 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12G\n\rvalue_percent\x18\x03 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x41\n\x07nominal\x18\x04 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\"H\n\x17GetFuturesMarginRequest\x12\x10\n\x04\x66igi\x18\x01 \x01(\tB\x02\x18\x01\x12\x1b\n\rinstrument_id\x18\x04 \x01(\tB\x04\xe2\x41\x01\x02\"\xe4\x02\n\x18GetFuturesMarginResponse\x12P\n\x15initial_margin_on_buy\x18\x01 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12Q\n\x16initial_margin_on_sell\x18\x02 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12M\n\x13min_price_increment\x18\x03 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12T\n\x1amin_price_increment_amount\x18\x04 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\"[\n\x12InstrumentResponse\x12\x45\n\ninstrument\x18\x01 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.Instrument\"\xbe\x0c\n\nInstrument\x12\x0c\n\x04\x66igi\x18\x01 \x01(\t\x12\x0e\n\x06ticker\x18\x02 \x01(\t\x12\x12\n\nclass_code\x18\x03 \x01(\t\x12\x0c\n\x04isin\x18\x04 \x01(\t\x12\x0b\n\x03lot\x18\x05 \x01(\x05\x12\x10\n\x08\x63urrency\x18\x06 \x01(\t\x12\x43\n\x05klong\x18\x07 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationB\x02\x18\x01\x12\x44\n\x06kshort\x18\x08 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationB\x02\x18\x01\x12?\n\x05\x64long\x18\t \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12@\n\x06\x64short\x18\n \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x43\n\tdlong_min\x18\x0b \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x44\n\ndshort_min\x18\x0c \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x1a\n\x12short_enabled_flag\x18\r \x01(\x08\x12\x0c\n\x04name\x18\x0e \x01(\t\x12\x10\n\x08\x65xchange\x18\x0f \x01(\t\x12\x17\n\x0f\x63ountry_of_risk\x18\x10 \x01(\t\x12\x1c\n\x14\x63ountry_of_risk_name\x18\x11 \x01(\t\x12\x17\n\x0finstrument_type\x18\x12 \x01(\t\x12T\n\x0etrading_status\x18\x13 \x01(\x0e\x32<.tinkoff.public.invest.api.contract.v1.SecurityTradingStatus\x12\x10\n\x08otc_flag\x18\x14 \x01(\x08\x12\x1a\n\x12\x62uy_available_flag\x18\x15 \x01(\x08\x12\x1b\n\x13sell_available_flag\x18\x16 \x01(\x08\x12M\n\x13min_price_increment\x18\x17 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12 \n\x18\x61pi_trade_available_flag\x18\x18 \x01(\x08\x12\x0b\n\x03uid\x18\x19 \x01(\t\x12J\n\rreal_exchange\x18\x1a \x01(\x0e\x32\x33.tinkoff.public.invest.api.contract.v1.RealExchange\x12\x14\n\x0cposition_uid\x18\x1b \x01(\t\x12\x11\n\tasset_uid\x18\x1c \x01(\t\x12\x16\n\x0erequired_tests\x18\x1d \x03(\t\x12\x14\n\x0c\x66or_iis_flag\x18$ \x01(\x08\x12\x1e\n\x16\x66or_qual_investor_flag\x18% \x01(\x08\x12\x14\n\x0cweekend_flag\x18& \x01(\x08\x12\x18\n\x10\x62locked_tca_flag\x18\' \x01(\x08\x12N\n\x0finstrument_kind\x18( \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.InstrumentType\x12:\n\x16\x66irst_1min_candle_date\x18\x38 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12:\n\x16\x66irst_1day_candle_date\x18\x39 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12?\n\x05\x62rand\x18< \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.BrandData\x12G\n\x0c\x64long_client\x18\xea\x03 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12H\n\rdshort_client\x18\xeb\x03 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\"\xb0\x01\n\x13GetDividendsRequest\x12\x10\n\x04\x66igi\x18\x01 \x01(\tB\x02\x18\x01\x12-\n\x04\x66rom\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x00\x88\x01\x01\x12+\n\x02to\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x01\x88\x01\x01\x12\x1b\n\rinstrument_id\x18\x04 \x01(\tB\x04\xe2\x41\x01\x02\x42\x07\n\x05_fromB\x05\n\x03_to\"Z\n\x14GetDividendsResponse\x12\x42\n\tdividends\x18\x01 \x03(\x0b\x32/.tinkoff.public.invest.api.contract.v1.Dividend\"\x86\x04\n\x08\x44ividend\x12G\n\x0c\x64ividend_net\x18\x01 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x30\n\x0cpayment_date\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x31\n\rdeclared_date\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x31\n\rlast_buy_date\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x15\n\rdividend_type\x18\x05 \x01(\t\x12/\n\x0brecord_date\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x12\n\nregularity\x18\x07 \x01(\t\x12\x46\n\x0b\x63lose_price\x18\x08 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x45\n\x0byield_value\x18\t \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12.\n\ncreated_at\x18\n \x01(\x0b\x32\x1a.google.protobuf.Timestamp\" \n\x0c\x41ssetRequest\x12\x10\n\x02id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\"P\n\rAssetResponse\x12?\n\x05\x61sset\x18\x01 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.AssetFull\"\xe7\x01\n\rAssetsRequest\x12S\n\x0finstrument_type\x18\x01 \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.InstrumentTypeH\x00\x88\x01\x01\x12W\n\x11instrument_status\x18\x02 \x01(\x0e\x32\x37.tinkoff.public.invest.api.contract.v1.InstrumentStatusH\x01\x88\x01\x01\x42\x12\n\x10_instrument_typeB\x14\n\x12_instrument_status\"N\n\x0e\x41ssetsResponse\x12<\n\x06\x61ssets\x18\x01 \x03(\x0b\x32,.tinkoff.public.invest.api.contract.v1.Asset\"\x98\x05\n\tAssetFull\x12\x0b\n\x03uid\x18\x01 \x01(\t\x12>\n\x04type\x18\x02 \x01(\x0e\x32\x30.tinkoff.public.invest.api.contract.v1.AssetType\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x12\n\nname_brief\x18\x04 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x05 \x01(\t\x12.\n\ndeleted_at\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x16\n\x0erequired_tests\x18\x07 \x03(\t\x12H\n\x08\x63urrency\x18\x08 \x01(\x0b\x32\x34.tinkoff.public.invest.api.contract.v1.AssetCurrencyH\x00\x12H\n\x08security\x18\t \x01(\x0b\x32\x34.tinkoff.public.invest.api.contract.v1.AssetSecurityH\x00\x12\x14\n\x0cgos_reg_code\x18\n \x01(\t\x12\x0b\n\x03\x63\x66i\x18\x0b \x01(\t\x12\x10\n\x08\x63ode_nsd\x18\x0c \x01(\t\x12\x0e\n\x06status\x18\r \x01(\t\x12;\n\x05\x62rand\x18\x0e \x01(\x0b\x32,.tinkoff.public.invest.api.contract.v1.Brand\x12.\n\nupdated_at\x18\x0f \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0f\n\x07\x62r_code\x18\x10 \x01(\t\x12\x14\n\x0c\x62r_code_name\x18\x11 \x01(\t\x12K\n\x0binstruments\x18\x12 \x03(\x0b\x32\x36.tinkoff.public.invest.api.contract.v1.AssetInstrumentB\x05\n\x03\x65xt\"\xaf\x01\n\x05\x41sset\x12\x0b\n\x03uid\x18\x01 \x01(\t\x12>\n\x04type\x18\x02 \x01(\x0e\x32\x30.tinkoff.public.invest.api.contract.v1.AssetType\x12\x0c\n\x04name\x18\x03 \x01(\t\x12K\n\x0binstruments\x18\x04 \x03(\x0b\x32\x36.tinkoff.public.invest.api.contract.v1.AssetInstrument\"&\n\rAssetCurrency\x12\x15\n\rbase_currency\x18\x01 \x01(\t\"\xf6\x03\n\rAssetSecurity\x12\x0c\n\x04isin\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x02 \x01(\t\x12N\n\x0finstrument_kind\x18\n \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.InstrumentType\x12\x42\n\x05share\x18\x03 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.AssetShareH\x00\x12@\n\x04\x62ond\x18\x04 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.AssetBondH\x00\x12K\n\x02sp\x18\x05 \x01(\x0b\x32=.tinkoff.public.invest.api.contract.v1.AssetStructuredProductH\x00\x12>\n\x03\x65tf\x18\x06 \x01(\x0b\x32/.tinkoff.public.invest.api.contract.v1.AssetEtfH\x00\x12_\n\x14\x63learing_certificate\x18\x07 \x01(\x0b\x32?.tinkoff.public.invest.api.contract.v1.AssetClearingCertificateH\x00\x42\x05\n\x03\x65xt\"\xd5\x05\n\nAssetShare\x12>\n\x04type\x18\x01 \x01(\x0e\x32\x30.tinkoff.public.invest.api.contract.v1.ShareType\x12\x44\n\nissue_size\x18\x02 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x41\n\x07nominal\x18\x03 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x18\n\x10nominal_currency\x18\x04 \x01(\t\x12\x15\n\rprimary_index\x18\x05 \x01(\t\x12G\n\rdividend_rate\x18\x06 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x1c\n\x14preferred_share_type\x18\x07 \x01(\t\x12,\n\x08ipo_date\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x31\n\rregistry_date\x18\t \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x16\n\x0e\x64iv_yield_flag\x18\n \x01(\x08\x12\x12\n\nissue_kind\x18\x0b \x01(\t\x12\x32\n\x0eplacement_date\x18\x0c \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x13\n\x0brepres_isin\x18\r \x01(\t\x12I\n\x0fissue_size_plan\x18\x0e \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x45\n\x0btotal_float\x18\x0f \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\"\xe0\x06\n\tAssetBond\x12I\n\x0f\x63urrent_nominal\x18\x01 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x13\n\x0b\x62orrow_name\x18\x02 \x01(\t\x12\x44\n\nissue_size\x18\x03 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x41\n\x07nominal\x18\x04 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x18\n\x10nominal_currency\x18\x05 \x01(\t\x12\x12\n\nissue_kind\x18\x06 \x01(\t\x12\x15\n\rinterest_kind\x18\x07 \x01(\t\x12 \n\x18\x63oupon_quantity_per_year\x18\x08 \x01(\x05\x12\x1c\n\x14indexed_nominal_flag\x18\t \x01(\x08\x12\x19\n\x11subordinated_flag\x18\n \x01(\x08\x12\x17\n\x0f\x63ollateral_flag\x18\x0b \x01(\x08\x12\x15\n\rtax_free_flag\x18\x0c \x01(\x08\x12\x19\n\x11\x61mortization_flag\x18\r \x01(\x08\x12\x1c\n\x14\x66loating_coupon_flag\x18\x0e \x01(\x08\x12\x16\n\x0eperpetual_flag\x18\x0f \x01(\x08\x12\x31\n\rmaturity_date\x18\x10 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x18\n\x10return_condition\x18\x11 \x01(\t\x12\x32\n\x0estate_reg_date\x18\x12 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x32\n\x0eplacement_date\x18\x13 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12I\n\x0fplacement_price\x18\x14 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12I\n\x0fissue_size_plan\x18\x15 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\"\xa0\x05\n\x16\x41ssetStructuredProduct\x12\x13\n\x0b\x62orrow_name\x18\x01 \x01(\t\x12\x41\n\x07nominal\x18\x02 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x18\n\x10nominal_currency\x18\x03 \x01(\t\x12J\n\x04type\x18\x04 \x01(\x0e\x32<.tinkoff.public.invest.api.contract.v1.StructuredProductType\x12\x17\n\x0flogic_portfolio\x18\x05 \x01(\t\x12\x44\n\nasset_type\x18\x06 \x01(\x0e\x32\x30.tinkoff.public.invest.api.contract.v1.AssetType\x12\x13\n\x0b\x62\x61sic_asset\x18\x07 \x01(\t\x12H\n\x0esafety_barrier\x18\x08 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x31\n\rmaturity_date\x18\t \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12I\n\x0fissue_size_plan\x18\n \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x44\n\nissue_size\x18\x0b \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x32\n\x0eplacement_date\x18\x0c \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x12\n\nissue_kind\x18\r \x01(\t\"\xd8\n\n\x08\x41ssetEtf\x12G\n\rtotal_expense\x18\x01 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x45\n\x0bhurdle_rate\x18\x02 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12I\n\x0fperformance_fee\x18\x03 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12J\n\x10\x66ixed_commission\x18\x04 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x14\n\x0cpayment_type\x18\x05 \x01(\t\x12\x16\n\x0ewatermark_flag\x18\x06 \x01(\x08\x12\x45\n\x0b\x62uy_premium\x18\x07 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12G\n\rsell_discount\x18\x08 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x18\n\x10rebalancing_flag\x18\t \x01(\x08\x12\x18\n\x10rebalancing_freq\x18\n \x01(\t\x12\x17\n\x0fmanagement_type\x18\x0b \x01(\t\x12\x15\n\rprimary_index\x18\x0c \x01(\t\x12\x12\n\nfocus_type\x18\r \x01(\t\x12\x16\n\x0eleveraged_flag\x18\x0e \x01(\x08\x12\x43\n\tnum_share\x18\x0f \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x12\n\nucits_flag\x18\x10 \x01(\x08\x12\x31\n\rreleased_date\x18\x11 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x13\n\x0b\x64\x65scription\x18\x12 \x01(\t\x12!\n\x19primary_index_description\x18\x13 \x01(\t\x12\x1d\n\x15primary_index_company\x18\x14 \x01(\t\x12O\n\x15index_recovery_period\x18\x15 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x11\n\tinav_code\x18\x16 \x01(\t\x12\x16\n\x0e\x64iv_yield_flag\x18\x17 \x01(\x08\x12L\n\x12\x65xpense_commission\x18\x18 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12V\n\x1cprimary_index_tracking_error\x18\x19 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x18\n\x10rebalancing_plan\x18\x1a \x01(\t\x12\x10\n\x08tax_rate\x18\x1b \x01(\t\x12\x35\n\x11rebalancing_dates\x18\x1c \x03(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x12\n\nissue_kind\x18\x1d \x01(\t\x12\x41\n\x07nominal\x18\x1e \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x18\n\x10nominal_currency\x18\x1f \x01(\t\"w\n\x18\x41ssetClearingCertificate\x12\x41\n\x07nominal\x18\x01 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x18\n\x10nominal_currency\x18\x02 \x01(\t\"\x9d\x01\n\x05\x42rand\x12\x0b\n\x03uid\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12\x0c\n\x04info\x18\x04 \x01(\t\x12\x0f\n\x07\x63ompany\x18\x05 \x01(\t\x12\x0e\n\x06sector\x18\x06 \x01(\t\x12\x17\n\x0f\x63ountry_of_risk\x18\x07 \x01(\t\x12\x1c\n\x14\x63ountry_of_risk_name\x18\x08 \x01(\t\"\x95\x02\n\x0f\x41ssetInstrument\x12\x0b\n\x03uid\x18\x01 \x01(\t\x12\x0c\n\x04\x66igi\x18\x02 \x01(\t\x12\x17\n\x0finstrument_type\x18\x03 \x01(\t\x12\x0e\n\x06ticker\x18\x04 \x01(\t\x12\x12\n\nclass_code\x18\x05 \x01(\t\x12\x44\n\x05links\x18\x06 \x03(\x0b\x32\x35.tinkoff.public.invest.api.contract.v1.InstrumentLink\x12N\n\x0finstrument_kind\x18\n \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.InstrumentType\x12\x14\n\x0cposition_uid\x18\x0b \x01(\t\"6\n\x0eInstrumentLink\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x16\n\x0einstrument_uid\x18\x02 \x01(\t\"9\n\x13GetFavoritesRequest\x12\x15\n\x08group_id\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\x0b\n\t_group_id\"\x93\x01\n\x14GetFavoritesResponse\x12W\n\x14\x66\x61vorite_instruments\x18\x01 \x03(\x0b\x32\x39.tinkoff.public.invest.api.contract.v1.FavoriteInstrument\x12\x15\n\x08group_id\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0b\n\t_group_id\"\x8c\x02\n\x12\x46\x61voriteInstrument\x12\x0c\n\x04\x66igi\x18\x01 \x01(\t\x12\x0e\n\x06ticker\x18\x02 \x01(\t\x12\x12\n\nclass_code\x18\x03 \x01(\t\x12\x0c\n\x04isin\x18\x04 \x01(\t\x12\x17\n\x0finstrument_type\x18\x0b \x01(\t\x12\x0c\n\x04name\x18\x0c \x01(\t\x12\x0b\n\x03uid\x18\r \x01(\t\x12\x10\n\x08otc_flag\x18\x10 \x01(\x08\x12 \n\x18\x61pi_trade_available_flag\x18\x11 \x01(\x08\x12N\n\x0finstrument_kind\x18\x12 \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.InstrumentType\"\xf7\x01\n\x14\x45\x64itFavoritesRequest\x12`\n\x0binstruments\x18\x01 \x03(\x0b\x32\x45.tinkoff.public.invest.api.contract.v1.EditFavoritesRequestInstrumentB\x04\xe2\x41\x01\x02\x12Y\n\x0b\x61\x63tion_type\x18\x06 \x01(\x0e\x32>.tinkoff.public.invest.api.contract.v1.EditFavoritesActionTypeB\x04\xe2\x41\x01\x02\x12\x15\n\x08group_id\x18\x07 \x01(\tH\x00\x88\x01\x01\x42\x0b\n\t_group_id\"]\n\x1e\x45\x64itFavoritesRequestInstrument\x12\x15\n\x04\x66igi\x18\x01 \x01(\tB\x02\x18\x01H\x00\x88\x01\x01\x12\x1b\n\rinstrument_id\x18\x02 \x01(\tB\x04\xe2\x41\x01\x02\x42\x07\n\x05_figi\"\x94\x01\n\x15\x45\x64itFavoritesResponse\x12W\n\x14\x66\x61vorite_instruments\x18\x01 \x03(\x0b\x32\x39.tinkoff.public.invest.api.contract.v1.FavoriteInstrument\x12\x15\n\x08group_id\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0b\n\t_group_id\"m\n\x1a\x43reateFavoriteGroupRequest\x12\x18\n\ngroup_name\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\x12\x19\n\x0bgroup_color\x18\x02 \x01(\tB\x04\xe2\x41\x01\x02\x12\x11\n\x04note\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x07\n\x05_note\"C\n\x1b\x43reateFavoriteGroupResponse\x12\x10\n\x08group_id\x18\x01 \x01(\t\x12\x12\n\ngroup_name\x18\x02 \x01(\t\"4\n\x1a\x44\x65leteFavoriteGroupRequest\x12\x16\n\x08group_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\"\x1d\n\x1b\x44\x65leteFavoriteGroupResponse\"L\n\x18GetFavoriteGroupsRequest\x12\x15\n\rinstrument_id\x18\x01 \x03(\t\x12\x19\n\x11\x65xcluded_group_id\x18\x02 \x03(\t\"\xa2\x02\n\x19GetFavoriteGroupsResponse\x12^\n\x06groups\x18\x01 \x03(\x0b\x32N.tinkoff.public.invest.api.contract.v1.GetFavoriteGroupsResponse.FavoriteGroup\x1a\xa4\x01\n\rFavoriteGroup\x12\x16\n\x08group_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\x12\x18\n\ngroup_name\x18\x02 \x01(\tB\x04\xe2\x41\x01\x02\x12\x13\n\x05\x63olor\x18\x03 \x01(\tB\x04\xe2\x41\x01\x02\x12\x12\n\x04size\x18\x04 \x01(\x05\x42\x04\xe2\x41\x01\x02\x12 \n\x13\x63ontains_instrument\x18\x05 \x01(\x08H\x00\x88\x01\x01\x42\x16\n\x14_contains_instrument\"\x15\n\x13GetCountriesRequest\"a\n\x14GetCountriesResponse\x12I\n\tcountries\x18\x01 \x03(\x0b\x32\x36.tinkoff.public.invest.api.contract.v1.CountryResponse\"\x14\n\x12IndicativesRequest\"e\n\x13IndicativesResponse\x12N\n\x0binstruments\x18\x01 \x03(\x0b\x32\x39.tinkoff.public.invest.api.contract.v1.IndicativeResponse\"\x90\x02\n\x12IndicativeResponse\x12\x0c\n\x04\x66igi\x18\x01 \x01(\t\x12\x0e\n\x06ticker\x18\x02 \x01(\t\x12\x12\n\nclass_code\x18\x03 \x01(\t\x12\x10\n\x08\x63urrency\x18\x04 \x01(\t\x12N\n\x0finstrument_kind\x18\n \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.InstrumentType\x12\x0c\n\x04name\x18\x0c \x01(\t\x12\x10\n\x08\x65xchange\x18\r \x01(\t\x12\x0b\n\x03uid\x18\x0e \x01(\t\x12\x1b\n\x12\x62uy_available_flag\x18\x94\x03 \x01(\x08\x12\x1c\n\x13sell_available_flag\x18\x95\x03 \x01(\x08\"Y\n\x0f\x43ountryResponse\x12\x10\n\x08\x61lfa_two\x18\x01 \x01(\t\x12\x12\n\nalfa_three\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x12\n\nname_brief\x18\x04 \x01(\t\"\xd9\x01\n\x15\x46indInstrumentRequest\x12\x13\n\x05query\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\x12S\n\x0finstrument_kind\x18\x02 \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.InstrumentTypeH\x00\x88\x01\x01\x12%\n\x18\x61pi_trade_available_flag\x18\x03 \x01(\x08H\x01\x88\x01\x01\x42\x12\n\x10_instrument_kindB\x1b\n\x19_api_trade_available_flag\"e\n\x16\x46indInstrumentResponse\x12K\n\x0binstruments\x18\x01 \x03(\x0b\x32\x36.tinkoff.public.invest.api.contract.v1.InstrumentShort\"\xf8\x03\n\x0fInstrumentShort\x12\x0c\n\x04isin\x18\x01 \x01(\t\x12\x0c\n\x04\x66igi\x18\x02 \x01(\t\x12\x0e\n\x06ticker\x18\x03 \x01(\t\x12\x12\n\nclass_code\x18\x04 \x01(\t\x12\x17\n\x0finstrument_type\x18\x05 \x01(\t\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x0b\n\x03uid\x18\x07 \x01(\t\x12\x14\n\x0cposition_uid\x18\x08 \x01(\t\x12N\n\x0finstrument_kind\x18\n \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.InstrumentType\x12 \n\x18\x61pi_trade_available_flag\x18\x0b \x01(\x08\x12\x14\n\x0c\x66or_iis_flag\x18\x0c \x01(\x08\x12:\n\x16\x66irst_1min_candle_date\x18\x1a \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12:\n\x16\x66irst_1day_candle_date\x18\x1b \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x1e\n\x16\x66or_qual_investor_flag\x18\x1c \x01(\x08\x12\x14\n\x0cweekend_flag\x18\x1d \x01(\x08\x12\x18\n\x10\x62locked_tca_flag\x18\x1e \x01(\x08\x12\x0b\n\x03lot\x18\x1f \x01(\x05\"O\n\x10GetBrandsRequest\x12;\n\x06paging\x18\x01 \x01(\x0b\x32+.tinkoff.public.invest.api.contract.v1.Page\"#\n\x0fGetBrandRequest\x12\x10\n\x02id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\"\x96\x01\n\x11GetBrandsResponse\x12<\n\x06\x62rands\x18\x01 \x03(\x0b\x32,.tinkoff.public.invest.api.contract.v1.Brand\x12\x43\n\x06paging\x18\x02 \x01(\x0b\x32\x33.tinkoff.public.invest.api.contract.v1.PageResponse\"3\n\x1bGetAssetFundamentalsRequest\x12\x14\n\x06\x61ssets\x18\x01 \x03(\tB\x04\xe2\x41\x01\x02\"\xfd\x0e\n\x1cGetAssetFundamentalsResponse\x12k\n\x0c\x66undamentals\x18\x01 \x03(\x0b\x32U.tinkoff.public.invest.api.contract.v1.GetAssetFundamentalsResponse.StatisticResponse\x1a\xef\r\n\x11StatisticResponse\x12\x11\n\tasset_uid\x18\x01 \x01(\t\x12\x10\n\x08\x63urrency\x18\x02 \x01(\t\x12\x1d\n\x15market_capitalization\x18\x03 \x01(\x01\x12 \n\x18high_price_last_52_weeks\x18\x04 \x01(\x01\x12\x1f\n\x17low_price_last_52_weeks\x18\x05 \x01(\x01\x12)\n!average_daily_volume_last_10_days\x18\x06 \x01(\x01\x12)\n!average_daily_volume_last_4_weeks\x18\x07 \x01(\x01\x12\x0c\n\x04\x62\x65ta\x18\x08 \x01(\x01\x12\x12\n\nfree_float\x18\t \x01(\x01\x12%\n\x1d\x66orward_annual_dividend_yield\x18\n \x01(\x01\x12\x1a\n\x12shares_outstanding\x18\x0b \x01(\x01\x12\x13\n\x0brevenue_ttm\x18\x0c \x01(\x01\x12\x12\n\nebitda_ttm\x18\r \x01(\x01\x12\x16\n\x0enet_income_ttm\x18\x0e \x01(\x01\x12\x0f\n\x07\x65ps_ttm\x18\x0f \x01(\x01\x12\x17\n\x0f\x64iluted_eps_ttm\x18\x10 \x01(\x01\x12\x1a\n\x12\x66ree_cash_flow_ttm\x18\x11 \x01(\x01\x12,\n$five_year_annual_revenue_growth_rate\x18\x12 \x01(\x01\x12-\n%three_year_annual_revenue_growth_rate\x18\x13 \x01(\x01\x12\x14\n\x0cpe_ratio_ttm\x18\x14 \x01(\x01\x12\x1a\n\x12price_to_sales_ttm\x18\x15 \x01(\x01\x12\x19\n\x11price_to_book_ttm\x18\x16 \x01(\x01\x12#\n\x1bprice_to_free_cash_flow_ttm\x18\x17 \x01(\x01\x12\"\n\x1atotal_enterprise_value_mrq\x18\x18 \x01(\x01\x12\x18\n\x10\x65v_to_ebitda_mrq\x18\x19 \x01(\x01\x12\x16\n\x0enet_margin_mrq\x18\x1a \x01(\x01\x12\x1f\n\x17net_interest_margin_mrq\x18\x1b \x01(\x01\x12\x0b\n\x03roe\x18\x1c \x01(\x01\x12\x0b\n\x03roa\x18\x1d \x01(\x01\x12\x0c\n\x04roic\x18\x1e \x01(\x01\x12\x16\n\x0etotal_debt_mrq\x18\x1f \x01(\x01\x12 \n\x18total_debt_to_equity_mrq\x18 \x01(\x01\x12 \n\x18total_debt_to_ebitda_mrq\x18! \x01(\x01\x12\x1f\n\x17\x66ree_cash_flow_to_price\x18\" \x01(\x01\x12\x1a\n\x12net_debt_to_ebitda\x18# \x01(\x01\x12\x19\n\x11\x63urrent_ratio_mrq\x18$ \x01(\x01\x12&\n\x1e\x66ixed_charge_coverage_ratio_fy\x18% \x01(\x01\x12 \n\x18\x64ividend_yield_daily_ttm\x18& \x01(\x01\x12\x19\n\x11\x64ividend_rate_ttm\x18\' \x01(\x01\x12\x1b\n\x13\x64ividends_per_share\x18( \x01(\x01\x12)\n!five_years_average_dividend_yield\x18) \x01(\x01\x12-\n%five_year_annual_dividend_growth_rate\x18* \x01(\x01\x12 \n\x18\x64ividend_payout_ratio_fy\x18+ \x01(\x01\x12\x14\n\x0c\x62uy_back_ttm\x18, \x01(\x01\x12+\n#one_year_annual_revenue_growth_rate\x18- \x01(\x01\x12\x1f\n\x17\x64omicile_indicator_code\x18. \x01(\t\x12!\n\x19\x61\x64r_to_common_share_ratio\x18/ \x01(\x01\x12\x1b\n\x13number_of_employees\x18\x30 \x01(\x01\x12\x34\n\x10\x65x_dividend_date\x18\x31 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12<\n\x18\x66iscal_period_start_date\x18\x32 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12:\n\x16\x66iscal_period_end_date\x18\x33 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12!\n\x19revenue_change_five_years\x18\x35 \x01(\x01\x12\x1d\n\x15\x65ps_change_five_years\x18\x36 \x01(\x01\x12 \n\x18\x65\x62itda_change_five_years\x18\x37 \x01(\x01\x12$\n\x1ctotal_debt_change_five_years\x18\x38 \x01(\x01\x12\x13\n\x0b\x65v_to_sales\x18\x39 \x01(\x01\"\xa1\x01\n\x16GetAssetReportsRequest\x12\x1b\n\rinstrument_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\x12-\n\x04\x66rom\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x00\x88\x01\x01\x12+\n\x02to\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x01\x88\x01\x01\x42\x07\n\x05_fromB\x05\n\x03_to\"\xa7\x04\n\x17GetAssetReportsResponse\x12\x63\n\x06\x65vents\x18\x01 \x03(\x0b\x32S.tinkoff.public.invest.api.contract.v1.GetAssetReportsResponse.GetAssetReportsEvent\x1a\xa2\x02\n\x14GetAssetReportsEvent\x12\x15\n\rinstrument_id\x18\x01 \x01(\t\x12/\n\x0breport_date\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x13\n\x0bperiod_year\x18\x03 \x01(\x05\x12\x12\n\nperiod_num\x18\x04 \x01(\x05\x12i\n\x0bperiod_type\x18\x05 \x01(\x0e\x32T.tinkoff.public.invest.api.contract.v1.GetAssetReportsResponse.AssetReportPeriodType\x12.\n\ncreated_at\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\x81\x01\n\x15\x41ssetReportPeriodType\x12\x1b\n\x17PERIOD_TYPE_UNSPECIFIED\x10\x00\x12\x17\n\x13PERIOD_TYPE_QUARTER\x10\x01\x12\x1a\n\x16PERIOD_TYPE_SEMIANNUAL\x10\x02\x12\x16\n\x12PERIOD_TYPE_ANNUAL\x10\x03\"k\n\x1cGetConsensusForecastsRequest\x12@\n\x06paging\x18\x01 \x01(\x0b\x32+.tinkoff.public.invest.api.contract.v1.PageH\x00\x88\x01\x01\x42\t\n\x07_paging\"\x86\x06\n\x1dGetConsensusForecastsResponse\x12j\n\x05items\x18\x01 \x03(\x0b\x32[.tinkoff.public.invest.api.contract.v1.GetConsensusForecastsResponse.ConsensusForecastsItem\x12\x41\n\x04page\x18\x02 \x01(\x0b\x32\x33.tinkoff.public.invest.api.contract.v1.PageResponse\x1a\xb5\x04\n\x16\x43onsensusForecastsItem\x12\x0b\n\x03uid\x18\x01 \x01(\t\x12\x11\n\tasset_uid\x18\x02 \x01(\t\x12.\n\ncreated_at\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12K\n\x11\x62\x65st_target_price\x18\x04 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12I\n\x0f\x62\x65st_target_low\x18\x05 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12J\n\x10\x62\x65st_target_high\x18\x06 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x1b\n\x13total_buy_recommend\x18\x07 \x01(\x05\x12\x1c\n\x14total_hold_recommend\x18\x08 \x01(\x05\x12\x1c\n\x14total_sell_recommend\x18\t \x01(\x05\x12\x10\n\x08\x63urrency\x18\n \x01(\t\x12H\n\tconsensus\x18\x0b \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.Recommendation\x12\x32\n\x0eprognosis_date\x18\x0c \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"+\n\x12GetForecastRequest\x12\x15\n\rinstrument_id\x18\x01 \x01(\t\"\x97\n\n\x13GetForecastResponse\x12V\n\x07targets\x18\x01 \x03(\x0b\x32\x45.tinkoff.public.invest.api.contract.v1.GetForecastResponse.TargetItem\x12[\n\tconsensus\x18\x02 \x01(\x0b\x32H.tinkoff.public.invest.api.contract.v1.GetForecastResponse.ConsensusItem\x1a\x8c\x04\n\nTargetItem\x12\x0b\n\x03uid\x18\x01 \x01(\t\x12\x0e\n\x06ticker\x18\x02 \x01(\t\x12\x0f\n\x07\x63ompany\x18\x03 \x01(\t\x12M\n\x0erecommendation\x18\x04 \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.Recommendation\x12\x37\n\x13recommendation_date\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x10\n\x08\x63urrency\x18\x06 \x01(\t\x12G\n\rcurrent_price\x18\x07 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x46\n\x0ctarget_price\x18\x08 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x46\n\x0cprice_change\x18\t \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12J\n\x10price_change_rel\x18\n \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x11\n\tshow_name\x18\x0b \x01(\t\x1a\xbb\x04\n\rConsensusItem\x12\x0b\n\x03uid\x18\x01 \x01(\t\x12\x0e\n\x06ticker\x18\x02 \x01(\t\x12M\n\x0erecommendation\x18\x03 \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.Recommendation\x12\x10\n\x08\x63urrency\x18\x04 \x01(\t\x12G\n\rcurrent_price\x18\x05 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x43\n\tconsensus\x18\x06 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x44\n\nmin_target\x18\x07 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x44\n\nmax_target\x18\x08 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x46\n\x0cprice_change\x18\t \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12J\n\x10price_change_rel\x18\n \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\")\n\x10RiskRatesRequest\x12\x15\n\rinstrument_id\x18\x01 \x03(\t\"\xcb\x05\n\x11RiskRatesResponse\x12\x66\n\x15instrument_risk_rates\x18\x01 \x03(\x0b\x32G.tinkoff.public.invest.api.contract.v1.RiskRatesResponse.RiskRateResult\x1a\xe7\x03\n\x0eRiskRateResult\x12\x16\n\x0einstrument_uid\x18\x01 \x01(\t\x12_\n\x0fshort_risk_rate\x18\x02 \x01(\x0b\x32\x41.tinkoff.public.invest.api.contract.v1.RiskRatesResponse.RiskRateH\x00\x88\x01\x01\x12^\n\x0elong_risk_rate\x18\x03 \x01(\x0b\x32\x41.tinkoff.public.invest.api.contract.v1.RiskRatesResponse.RiskRateH\x01\x88\x01\x01\x12[\n\x10short_risk_rates\x18\x05 \x03(\x0b\x32\x41.tinkoff.public.invest.api.contract.v1.RiskRatesResponse.RiskRate\x12Z\n\x0flong_risk_rates\x18\x06 \x03(\x0b\x32\x41.tinkoff.public.invest.api.contract.v1.RiskRatesResponse.RiskRate\x12\x12\n\x05\x65rror\x18\t \x01(\tH\x02\x88\x01\x01\x42\x12\n\x10_short_risk_rateB\x11\n\x0f_long_risk_rateB\x08\n\x06_error\x1a\x64\n\x08RiskRate\x12\x17\n\x0frisk_level_code\x18\x02 \x01(\t\x12?\n\x05value\x18\x05 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\"\xe0\x01\n\x0fTradingInterval\x12\x0c\n\x04type\x18\x01 \x01(\t\x12U\n\x08interval\x18\x02 \x01(\x0b\x32\x43.tinkoff.public.invest.api.contract.v1.TradingInterval.TimeInterval\x1ah\n\x0cTimeInterval\x12,\n\x08start_ts\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12*\n\x06\x65nd_ts\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"h\n\x16GetInsiderDealsRequest\x12\x15\n\rinstrument_id\x18\x01 \x01(\t\x12\r\n\x05limit\x18\x02 \x01(\x05\x12\x18\n\x0bnext_cursor\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_next_cursor\"\x9c\x06\n\x17GetInsiderDealsResponse\x12\x61\n\rinsider_deals\x18\x01 \x03(\x0b\x32J.tinkoff.public.invest.api.contract.v1.GetInsiderDealsResponse.InsiderDeal\x12\x18\n\x0bnext_cursor\x18\x02 \x01(\tH\x00\x88\x01\x01\x1a\xd0\x03\n\x0bInsiderDeal\x12\x10\n\x08trade_id\x18\x01 \x01(\x03\x12`\n\tdirection\x18\x02 \x01(\x0e\x32M.tinkoff.public.invest.api.contract.v1.GetInsiderDealsResponse.TradeDirection\x12\x10\n\x08\x63urrency\x18\x03 \x01(\t\x12(\n\x04\x64\x61te\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x10\n\x08quantity\x18\x05 \x01(\x03\x12?\n\x05price\x18\x06 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x16\n\x0einstrument_uid\x18\x07 \x01(\t\x12\x0e\n\x06ticker\x18\x08 \x01(\t\x12\x15\n\rinvestor_name\x18\t \x01(\t\x12\x19\n\x11investor_position\x18\n \x01(\t\x12\x12\n\npercentage\x18\x0b \x01(\x02\x12\x1b\n\x13is_option_execution\x18\x0c \x01(\x08\x12\x33\n\x0f\x64isclosure_date\x18\r \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\xa0\x01\n\x0eTradeDirection\x12\x1f\n\x1bTRADE_DIRECTION_UNSPECIFIED\x10\x00\x12\x17\n\x13TRADE_DIRECTION_BUY\x10\x01\x12\x18\n\x14TRADE_DIRECTION_SELL\x10\x02\x12\x1c\n\x18TRADE_DIRECTION_INCREASE\x10\x03\x12\x1c\n\x18TRADE_DIRECTION_DECREASE\x10\x04\x42\x0e\n\x0c_next_cursor\"\r\n\x0b\x44\x66\x61sRequest\"\xfa\t\n\x0b\x44\x66\x61Response\x12\x0b\n\x03uid\x18\x01 \x01(\t\x12\x0e\n\x06ticker\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x14\n\x0cposition_uid\x18\x04 \x01(\t\x12M\n\x13min_price_increment\x18\x05 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x0b\n\x03lot\x18\x06 \x01(\x05\x12\x42\n\x07nominal\x18\x07 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x10\n\x08\x63urrency\x18\x08 \x01(\t\x12\x31\n\rmaturity_date\x18\t \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x1a\n\x12short_enabled_flag\x18\n \x01(\x08\x12 \n\x18\x61pi_trade_available_flag\x18\x0b \x01(\x08\x12\x1a\n\x12\x62uy_available_flag\x18\x0c \x01(\x08\x12\x1b\n\x13sell_available_flag\x18\r \x01(\x08\x12\"\n\x1alimit_order_available_flag\x18\x0e \x01(\x08\x12#\n\x1bmarket_order_available_flag\x18\x0f \x01(\x08\x12&\n\x1e\x62\x65stprice_order_available_flag\x18\x10 \x01(\x08\x12\x14\n\x0c\x66or_iis_flag\x18\x11 \x01(\x08\x12\x1e\n\x16\x66or_qual_investor_flag\x18\x12 \x01(\x08\x12\x0c\n\x04type\x18\x13 \x01(\t\x12S\n\x0c\x62\x61sic_assets\x18\x14 \x03(\x0b\x32=.tinkoff.public.invest.api.contract.v1.DfaResponse.BasicAsset\x12X\n\x0e\x66orecast_yield\x18\x15 \x01(\x0b\x32@.tinkoff.public.invest.api.contract.v1.DfaResponse.ForecastYield\x12K\n\x11yield_to_maturity\x18\x16 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x46\n\x0c\x63oupon_value\x18\x17 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12 \n\x18\x63oupon_payment_frequency\x18\x18 \x01(\x05\x12\x37\n\x13\x63oupon_payment_date\x18\x19 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x43\n\taci_value\x18\x1a \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x1a\x19\n\nBasicAsset\x12\x0b\n\x03uid\x18\x01 \x01(\t\x1a\x99\x01\n\rForecastYield\x12\x43\n\tmin_value\x18\x01 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x43\n\tmax_value\x18\x02 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\"W\n\x0c\x44\x66\x61sResponse\x12G\n\x0binstruments\x18\x01 \x03(\x0b\x32\x32.tinkoff.public.invest.api.contract.v1.DfaResponse*\xd7\x01\n\nCouponType\x12\x1b\n\x17\x43OUPON_TYPE_UNSPECIFIED\x10\x00\x12\x18\n\x14\x43OUPON_TYPE_CONSTANT\x10\x01\x12\x18\n\x14\x43OUPON_TYPE_FLOATING\x10\x02\x12\x18\n\x14\x43OUPON_TYPE_DISCOUNT\x10\x03\x12\x18\n\x14\x43OUPON_TYPE_MORTGAGE\x10\x04\x12\x13\n\x0f\x43OUPON_TYPE_FIX\x10\x05\x12\x18\n\x14\x43OUPON_TYPE_VARIABLE\x10\x06\x12\x15\n\x11\x43OUPON_TYPE_OTHER\x10\x07*h\n\x0fOptionDirection\x12 \n\x1cOPTION_DIRECTION_UNSPECIFIED\x10\x00\x12\x18\n\x14OPTION_DIRECTION_PUT\x10\x01\x12\x19\n\x15OPTION_DIRECTION_CALL\x10\x02*{\n\x11OptionPaymentType\x12#\n\x1fOPTION_PAYMENT_TYPE_UNSPECIFIED\x10\x00\x12\x1f\n\x1bOPTION_PAYMENT_TYPE_PREMIUM\x10\x01\x12 \n\x1cOPTION_PAYMENT_TYPE_MARGINAL\x10\x02*a\n\x0bOptionStyle\x12\x1c\n\x18OPTION_STYLE_UNSPECIFIED\x10\x00\x12\x19\n\x15OPTION_STYLE_AMERICAN\x10\x01\x12\x19\n\x15OPTION_STYLE_EUROPEAN\x10\x02*\x95\x01\n\x14OptionSettlementType\x12%\n!OPTION_EXECUTION_TYPE_UNSPECIFIED\x10\x00\x12+\n\'OPTION_EXECUTION_TYPE_PHYSICAL_DELIVERY\x10\x01\x12)\n%OPTION_EXECUTION_TYPE_CASH_SETTLEMENT\x10\x02*\xc9\x01\n\x10InstrumentIdType\x12\x1d\n\x19INSTRUMENT_ID_UNSPECIFIED\x10\x00\x12\x1b\n\x17INSTRUMENT_ID_TYPE_FIGI\x10\x01\x12\x1d\n\x19INSTRUMENT_ID_TYPE_TICKER\x10\x02\x12\x1a\n\x16INSTRUMENT_ID_TYPE_UID\x10\x03\x12#\n\x1fINSTRUMENT_ID_TYPE_POSITION_UID\x10\x04\x12\x19\n\x15INSTRUMENT_ID_TYPE_ID\x10\x05*\xe5\x01\n\tShareType\x12\x1a\n\x16SHARE_TYPE_UNSPECIFIED\x10\x00\x12\x15\n\x11SHARE_TYPE_COMMON\x10\x01\x12\x18\n\x14SHARE_TYPE_PREFERRED\x10\x02\x12\x12\n\x0eSHARE_TYPE_ADR\x10\x03\x12\x12\n\x0eSHARE_TYPE_GDR\x10\x04\x12\x12\n\x0eSHARE_TYPE_MLP\x10\x05\x12\x1a\n\x16SHARE_TYPE_NY_REG_SHRS\x10\x06\x12\x1e\n\x1aSHARE_TYPE_CLOSED_END_FUND\x10\x07\x12\x13\n\x0fSHARE_TYPE_REIT\x10\x08*\x89\x01\n\tAssetType\x12\x1a\n\x16\x41SSET_TYPE_UNSPECIFIED\x10\x00\x12\x17\n\x13\x41SSET_TYPE_CURRENCY\x10\x01\x12\x18\n\x14\x41SSET_TYPE_COMMODITY\x10\x02\x12\x14\n\x10\x41SSET_TYPE_INDEX\x10\x03\x12\x17\n\x13\x41SSET_TYPE_SECURITY\x10\x04*f\n\x15StructuredProductType\x12\x17\n\x13SP_TYPE_UNSPECIFIED\x10\x00\x12\x17\n\x13SP_TYPE_DELIVERABLE\x10\x01\x12\x1b\n\x17SP_TYPE_NON_DELIVERABLE\x10\x02*\x8d\x01\n\x17\x45\x64itFavoritesActionType\x12*\n&EDIT_FAVORITES_ACTION_TYPE_UNSPECIFIED\x10\x00\x12\"\n\x1e\x45\x44IT_FAVORITES_ACTION_TYPE_ADD\x10\x01\x12\"\n\x1e\x45\x44IT_FAVORITES_ACTION_TYPE_DEL\x10\x02*z\n\x0eRecommendation\x12\x1e\n\x1aRECOMMENDATION_UNSPECIFIED\x10\x00\x12\x16\n\x12RECOMMENDATION_BUY\x10\x01\x12\x17\n\x13RECOMMENDATION_HOLD\x10\x02\x12\x17\n\x13RECOMMENDATION_SELL\x10\x03*i\n\tRiskLevel\x12\x1a\n\x16RISK_LEVEL_UNSPECIFIED\x10\x00\x12\x12\n\x0eRISK_LEVEL_LOW\x10\x01\x12\x17\n\x13RISK_LEVEL_MODERATE\x10\x02\x12\x13\n\x0fRISK_LEVEL_HIGH\x10\x03*=\n\x08\x42ondType\x12\x19\n\x15\x42OND_TYPE_UNSPECIFIED\x10\x00\x12\x16\n\x12\x42OND_TYPE_REPLACED\x10\x01*]\n\x16InstrumentExchangeType\x12#\n\x1fINSTRUMENT_EXCHANGE_UNSPECIFIED\x10\x00\x12\x1e\n\x1aINSTRUMENT_EXCHANGE_DEALER\x10\x01\x32\xe2,\n\x12InstrumentsService\x12\x93\x01\n\x10TradingSchedules\x12>.tinkoff.public.invest.api.contract.v1.TradingSchedulesRequest\x1a?.tinkoff.public.invest.api.contract.v1.TradingSchedulesResponse\x12w\n\x06\x42ondBy\x12\x38.tinkoff.public.invest.api.contract.v1.InstrumentRequest\x1a\x33.tinkoff.public.invest.api.contract.v1.BondResponse\x12x\n\x05\x42onds\x12\x39.tinkoff.public.invest.api.contract.v1.InstrumentsRequest\x1a\x34.tinkoff.public.invest.api.contract.v1.BondsResponse\x12\x8d\x01\n\x0eGetBondCoupons\x12<.tinkoff.public.invest.api.contract.v1.GetBondCouponsRequest\x1a=.tinkoff.public.invest.api.contract.v1.GetBondCouponsResponse\x12\x8a\x01\n\rGetBondEvents\x12;.tinkoff.public.invest.api.contract.v1.GetBondEventsRequest\x1a<.tinkoff.public.invest.api.contract.v1.GetBondEventsResponse\x12\x7f\n\nCurrencyBy\x12\x38.tinkoff.public.invest.api.contract.v1.InstrumentRequest\x1a\x37.tinkoff.public.invest.api.contract.v1.CurrencyResponse\x12\x82\x01\n\nCurrencies\x12\x39.tinkoff.public.invest.api.contract.v1.InstrumentsRequest\x1a\x39.tinkoff.public.invest.api.contract.v1.CurrenciesResponse\x12u\n\x05\x45tfBy\x12\x38.tinkoff.public.invest.api.contract.v1.InstrumentRequest\x1a\x32.tinkoff.public.invest.api.contract.v1.EtfResponse\x12v\n\x04\x45tfs\x12\x39.tinkoff.public.invest.api.contract.v1.InstrumentsRequest\x1a\x33.tinkoff.public.invest.api.contract.v1.EtfsResponse\x12{\n\x08\x46utureBy\x12\x38.tinkoff.public.invest.api.contract.v1.InstrumentRequest\x1a\x35.tinkoff.public.invest.api.contract.v1.FutureResponse\x12|\n\x07\x46utures\x12\x39.tinkoff.public.invest.api.contract.v1.InstrumentsRequest\x1a\x36.tinkoff.public.invest.api.contract.v1.FuturesResponse\x12{\n\x08OptionBy\x12\x38.tinkoff.public.invest.api.contract.v1.InstrumentRequest\x1a\x35.tinkoff.public.invest.api.contract.v1.OptionResponse\x12\x81\x01\n\x07Options\x12\x39.tinkoff.public.invest.api.contract.v1.InstrumentsRequest\x1a\x36.tinkoff.public.invest.api.contract.v1.OptionsResponse\"\x03\x88\x02\x01\x12\x80\x01\n\tOptionsBy\x12;.tinkoff.public.invest.api.contract.v1.FilterOptionsRequest\x1a\x36.tinkoff.public.invest.api.contract.v1.OptionsResponse\x12y\n\x07ShareBy\x12\x38.tinkoff.public.invest.api.contract.v1.InstrumentRequest\x1a\x34.tinkoff.public.invest.api.contract.v1.ShareResponse\x12z\n\x06Shares\x12\x39.tinkoff.public.invest.api.contract.v1.InstrumentsRequest\x1a\x35.tinkoff.public.invest.api.contract.v1.SharesResponse\x12u\n\x05\x44\x66\x61\x42y\x12\x38.tinkoff.public.invest.api.contract.v1.InstrumentRequest\x1a\x32.tinkoff.public.invest.api.contract.v1.DfaResponse\x12o\n\x04\x44\x66\x61s\x12\x32.tinkoff.public.invest.api.contract.v1.DfasRequest\x1a\x33.tinkoff.public.invest.api.contract.v1.DfasResponse\x12\x84\x01\n\x0bIndicatives\x12\x39.tinkoff.public.invest.api.contract.v1.IndicativesRequest\x1a:.tinkoff.public.invest.api.contract.v1.IndicativesResponse\x12\x9c\x01\n\x13GetAccruedInterests\x12\x41.tinkoff.public.invest.api.contract.v1.GetAccruedInterestsRequest\x1a\x42.tinkoff.public.invest.api.contract.v1.GetAccruedInterestsResponse\x12\x93\x01\n\x10GetFuturesMargin\x12>.tinkoff.public.invest.api.contract.v1.GetFuturesMarginRequest\x1a?.tinkoff.public.invest.api.contract.v1.GetFuturesMarginResponse\x12\x86\x01\n\x0fGetInstrumentBy\x12\x38.tinkoff.public.invest.api.contract.v1.InstrumentRequest\x1a\x39.tinkoff.public.invest.api.contract.v1.InstrumentResponse\x12\x87\x01\n\x0cGetDividends\x12:.tinkoff.public.invest.api.contract.v1.GetDividendsRequest\x1a;.tinkoff.public.invest.api.contract.v1.GetDividendsResponse\x12w\n\nGetAssetBy\x12\x33.tinkoff.public.invest.api.contract.v1.AssetRequest\x1a\x34.tinkoff.public.invest.api.contract.v1.AssetResponse\x12x\n\tGetAssets\x12\x34.tinkoff.public.invest.api.contract.v1.AssetsRequest\x1a\x35.tinkoff.public.invest.api.contract.v1.AssetsResponse\x12\x87\x01\n\x0cGetFavorites\x12:.tinkoff.public.invest.api.contract.v1.GetFavoritesRequest\x1a;.tinkoff.public.invest.api.contract.v1.GetFavoritesResponse\x12\x8a\x01\n\rEditFavorites\x12;.tinkoff.public.invest.api.contract.v1.EditFavoritesRequest\x1a<.tinkoff.public.invest.api.contract.v1.EditFavoritesResponse\x12\x9c\x01\n\x13\x43reateFavoriteGroup\x12\x41.tinkoff.public.invest.api.contract.v1.CreateFavoriteGroupRequest\x1a\x42.tinkoff.public.invest.api.contract.v1.CreateFavoriteGroupResponse\x12\x9c\x01\n\x13\x44\x65leteFavoriteGroup\x12\x41.tinkoff.public.invest.api.contract.v1.DeleteFavoriteGroupRequest\x1a\x42.tinkoff.public.invest.api.contract.v1.DeleteFavoriteGroupResponse\x12\x96\x01\n\x11GetFavoriteGroups\x12?.tinkoff.public.invest.api.contract.v1.GetFavoriteGroupsRequest\x1a@.tinkoff.public.invest.api.contract.v1.GetFavoriteGroupsResponse\x12\x87\x01\n\x0cGetCountries\x12:.tinkoff.public.invest.api.contract.v1.GetCountriesRequest\x1a;.tinkoff.public.invest.api.contract.v1.GetCountriesResponse\x12\x8d\x01\n\x0e\x46indInstrument\x12<.tinkoff.public.invest.api.contract.v1.FindInstrumentRequest\x1a=.tinkoff.public.invest.api.contract.v1.FindInstrumentResponse\x12~\n\tGetBrands\x12\x37.tinkoff.public.invest.api.contract.v1.GetBrandsRequest\x1a\x38.tinkoff.public.invest.api.contract.v1.GetBrandsResponse\x12r\n\nGetBrandBy\x12\x36.tinkoff.public.invest.api.contract.v1.GetBrandRequest\x1a,.tinkoff.public.invest.api.contract.v1.Brand\x12\x9f\x01\n\x14GetAssetFundamentals\x12\x42.tinkoff.public.invest.api.contract.v1.GetAssetFundamentalsRequest\x1a\x43.tinkoff.public.invest.api.contract.v1.GetAssetFundamentalsResponse\x12\x90\x01\n\x0fGetAssetReports\x12=.tinkoff.public.invest.api.contract.v1.GetAssetReportsRequest\x1a>.tinkoff.public.invest.api.contract.v1.GetAssetReportsResponse\x12\xa2\x01\n\x15GetConsensusForecasts\x12\x43.tinkoff.public.invest.api.contract.v1.GetConsensusForecastsRequest\x1a\x44.tinkoff.public.invest.api.contract.v1.GetConsensusForecastsResponse\x12\x86\x01\n\rGetForecastBy\x12\x39.tinkoff.public.invest.api.contract.v1.GetForecastRequest\x1a:.tinkoff.public.invest.api.contract.v1.GetForecastResponse\x12\x81\x01\n\x0cGetRiskRates\x12\x37.tinkoff.public.invest.api.contract.v1.RiskRatesRequest\x1a\x38.tinkoff.public.invest.api.contract.v1.RiskRatesResponse\x12\x90\x01\n\x0fGetInsiderDeals\x12=.tinkoff.public.invest.api.contract.v1.GetInsiderDealsRequest\x1a>.tinkoff.public.invest.api.contract.v1.GetInsiderDealsResponse\x12\x8b\x01\n\x10StructuredNoteBy\x12\x38.tinkoff.public.invest.api.contract.v1.InstrumentRequest\x1a=.tinkoff.public.invest.api.contract.v1.StructuredNoteResponse\x12\x8c\x01\n\x0fStructuredNotes\x12\x39.tinkoff.public.invest.api.contract.v1.InstrumentsRequest\x1a>.tinkoff.public.invest.api.contract.v1.StructuredNotesResponseBa\n\x1cru.tinkoff.piapi.contract.v1P\x01Z\x0c./;investapi\xa2\x02\x05TIAPI\xaa\x02\x14Tinkoff.InvestApi.V1\xca\x02\x11Tinkoff\\Invest\\V1b\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 't_tech.invest.grpc.instruments_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\034ru.tinkoff.piapi.contract.v1P\001Z\014./;investapi\242\002\005TIAPI\252\002\024Tinkoff.InvestApi.V1\312\002\021Tinkoff\\Invest\\V1' + _globals['_INSTRUMENTREQUEST'].fields_by_name['id_type']._options = None + _globals['_INSTRUMENTREQUEST'].fields_by_name['id_type']._serialized_options = b'\342A\001\002' + _globals['_INSTRUMENTREQUEST'].fields_by_name['id']._options = None + _globals['_INSTRUMENTREQUEST'].fields_by_name['id']._serialized_options = b'\342A\001\002' + _globals['_GETBONDCOUPONSREQUEST'].fields_by_name['figi']._options = None + _globals['_GETBONDCOUPONSREQUEST'].fields_by_name['figi']._serialized_options = b'\030\001' + _globals['_GETBONDCOUPONSREQUEST'].fields_by_name['instrument_id']._options = None + _globals['_GETBONDCOUPONSREQUEST'].fields_by_name['instrument_id']._serialized_options = b'\342A\001\002' + _globals['_GETBONDEVENTSREQUEST'].fields_by_name['instrument_id']._options = None + _globals['_GETBONDEVENTSREQUEST'].fields_by_name['instrument_id']._serialized_options = b'\342A\001\002' + _globals['_OPTION'].fields_by_name['klong']._options = None + _globals['_OPTION'].fields_by_name['klong']._serialized_options = b'\030\001' + _globals['_OPTION'].fields_by_name['kshort']._options = None + _globals['_OPTION'].fields_by_name['kshort']._serialized_options = b'\030\001' + _globals['_BOND'].fields_by_name['klong']._options = None + _globals['_BOND'].fields_by_name['klong']._serialized_options = b'\030\001' + _globals['_BOND'].fields_by_name['kshort']._options = None + _globals['_BOND'].fields_by_name['kshort']._serialized_options = b'\030\001' + _globals['_CURRENCY'].fields_by_name['klong']._options = None + _globals['_CURRENCY'].fields_by_name['klong']._serialized_options = b'\030\001' + _globals['_CURRENCY'].fields_by_name['kshort']._options = None + _globals['_CURRENCY'].fields_by_name['kshort']._serialized_options = b'\030\001' + _globals['_ETF'].fields_by_name['klong']._options = None + _globals['_ETF'].fields_by_name['klong']._serialized_options = b'\030\001' + _globals['_ETF'].fields_by_name['kshort']._options = None + _globals['_ETF'].fields_by_name['kshort']._serialized_options = b'\030\001' + _globals['_FUTURE'].fields_by_name['klong']._options = None + _globals['_FUTURE'].fields_by_name['klong']._serialized_options = b'\030\001' + _globals['_FUTURE'].fields_by_name['kshort']._options = None + _globals['_FUTURE'].fields_by_name['kshort']._serialized_options = b'\030\001' + _globals['_SHARE'].fields_by_name['klong']._options = None + _globals['_SHARE'].fields_by_name['klong']._serialized_options = b'\030\001' + _globals['_SHARE'].fields_by_name['kshort']._options = None + _globals['_SHARE'].fields_by_name['kshort']._serialized_options = b'\030\001' + _globals['_GETACCRUEDINTERESTSREQUEST'].fields_by_name['figi']._options = None + _globals['_GETACCRUEDINTERESTSREQUEST'].fields_by_name['figi']._serialized_options = b'\030\001' + _globals['_GETACCRUEDINTERESTSREQUEST'].fields_by_name['from']._options = None + _globals['_GETACCRUEDINTERESTSREQUEST'].fields_by_name['from']._serialized_options = b'\342A\001\002' + _globals['_GETACCRUEDINTERESTSREQUEST'].fields_by_name['to']._options = None + _globals['_GETACCRUEDINTERESTSREQUEST'].fields_by_name['to']._serialized_options = b'\342A\001\002' + _globals['_GETACCRUEDINTERESTSREQUEST'].fields_by_name['instrument_id']._options = None + _globals['_GETACCRUEDINTERESTSREQUEST'].fields_by_name['instrument_id']._serialized_options = b'\342A\001\002' + _globals['_GETFUTURESMARGINREQUEST'].fields_by_name['figi']._options = None + _globals['_GETFUTURESMARGINREQUEST'].fields_by_name['figi']._serialized_options = b'\030\001' + _globals['_GETFUTURESMARGINREQUEST'].fields_by_name['instrument_id']._options = None + _globals['_GETFUTURESMARGINREQUEST'].fields_by_name['instrument_id']._serialized_options = b'\342A\001\002' + _globals['_INSTRUMENT'].fields_by_name['klong']._options = None + _globals['_INSTRUMENT'].fields_by_name['klong']._serialized_options = b'\030\001' + _globals['_INSTRUMENT'].fields_by_name['kshort']._options = None + _globals['_INSTRUMENT'].fields_by_name['kshort']._serialized_options = b'\030\001' + _globals['_GETDIVIDENDSREQUEST'].fields_by_name['figi']._options = None + _globals['_GETDIVIDENDSREQUEST'].fields_by_name['figi']._serialized_options = b'\030\001' + _globals['_GETDIVIDENDSREQUEST'].fields_by_name['instrument_id']._options = None + _globals['_GETDIVIDENDSREQUEST'].fields_by_name['instrument_id']._serialized_options = b'\342A\001\002' + _globals['_ASSETREQUEST'].fields_by_name['id']._options = None + _globals['_ASSETREQUEST'].fields_by_name['id']._serialized_options = b'\342A\001\002' + _globals['_EDITFAVORITESREQUEST'].fields_by_name['instruments']._options = None + _globals['_EDITFAVORITESREQUEST'].fields_by_name['instruments']._serialized_options = b'\342A\001\002' + _globals['_EDITFAVORITESREQUEST'].fields_by_name['action_type']._options = None + _globals['_EDITFAVORITESREQUEST'].fields_by_name['action_type']._serialized_options = b'\342A\001\002' + _globals['_EDITFAVORITESREQUESTINSTRUMENT'].fields_by_name['figi']._options = None + _globals['_EDITFAVORITESREQUESTINSTRUMENT'].fields_by_name['figi']._serialized_options = b'\030\001' + _globals['_EDITFAVORITESREQUESTINSTRUMENT'].fields_by_name['instrument_id']._options = None + _globals['_EDITFAVORITESREQUESTINSTRUMENT'].fields_by_name['instrument_id']._serialized_options = b'\342A\001\002' + _globals['_CREATEFAVORITEGROUPREQUEST'].fields_by_name['group_name']._options = None + _globals['_CREATEFAVORITEGROUPREQUEST'].fields_by_name['group_name']._serialized_options = b'\342A\001\002' + _globals['_CREATEFAVORITEGROUPREQUEST'].fields_by_name['group_color']._options = None + _globals['_CREATEFAVORITEGROUPREQUEST'].fields_by_name['group_color']._serialized_options = b'\342A\001\002' + _globals['_DELETEFAVORITEGROUPREQUEST'].fields_by_name['group_id']._options = None + _globals['_DELETEFAVORITEGROUPREQUEST'].fields_by_name['group_id']._serialized_options = b'\342A\001\002' + _globals['_GETFAVORITEGROUPSRESPONSE_FAVORITEGROUP'].fields_by_name['group_id']._options = None + _globals['_GETFAVORITEGROUPSRESPONSE_FAVORITEGROUP'].fields_by_name['group_id']._serialized_options = b'\342A\001\002' + _globals['_GETFAVORITEGROUPSRESPONSE_FAVORITEGROUP'].fields_by_name['group_name']._options = None + _globals['_GETFAVORITEGROUPSRESPONSE_FAVORITEGROUP'].fields_by_name['group_name']._serialized_options = b'\342A\001\002' + _globals['_GETFAVORITEGROUPSRESPONSE_FAVORITEGROUP'].fields_by_name['color']._options = None + _globals['_GETFAVORITEGROUPSRESPONSE_FAVORITEGROUP'].fields_by_name['color']._serialized_options = b'\342A\001\002' + _globals['_GETFAVORITEGROUPSRESPONSE_FAVORITEGROUP'].fields_by_name['size']._options = None + _globals['_GETFAVORITEGROUPSRESPONSE_FAVORITEGROUP'].fields_by_name['size']._serialized_options = b'\342A\001\002' + _globals['_FINDINSTRUMENTREQUEST'].fields_by_name['query']._options = None + _globals['_FINDINSTRUMENTREQUEST'].fields_by_name['query']._serialized_options = b'\342A\001\002' + _globals['_GETBRANDREQUEST'].fields_by_name['id']._options = None + _globals['_GETBRANDREQUEST'].fields_by_name['id']._serialized_options = b'\342A\001\002' + _globals['_GETASSETFUNDAMENTALSREQUEST'].fields_by_name['assets']._options = None + _globals['_GETASSETFUNDAMENTALSREQUEST'].fields_by_name['assets']._serialized_options = b'\342A\001\002' + _globals['_GETASSETREPORTSREQUEST'].fields_by_name['instrument_id']._options = None + _globals['_GETASSETREPORTSREQUEST'].fields_by_name['instrument_id']._serialized_options = b'\342A\001\002' + _globals['_INSTRUMENTSSERVICE'].methods_by_name['Options']._options = None + _globals['_INSTRUMENTSSERVICE'].methods_by_name['Options']._serialized_options = b'\210\002\001' + _globals['_COUPONTYPE']._serialized_start=41518 + _globals['_COUPONTYPE']._serialized_end=41733 + _globals['_OPTIONDIRECTION']._serialized_start=41735 + _globals['_OPTIONDIRECTION']._serialized_end=41839 + _globals['_OPTIONPAYMENTTYPE']._serialized_start=41841 + _globals['_OPTIONPAYMENTTYPE']._serialized_end=41964 + _globals['_OPTIONSTYLE']._serialized_start=41966 + _globals['_OPTIONSTYLE']._serialized_end=42063 + _globals['_OPTIONSETTLEMENTTYPE']._serialized_start=42066 + _globals['_OPTIONSETTLEMENTTYPE']._serialized_end=42215 + _globals['_INSTRUMENTIDTYPE']._serialized_start=42218 + _globals['_INSTRUMENTIDTYPE']._serialized_end=42419 + _globals['_SHARETYPE']._serialized_start=42422 + _globals['_SHARETYPE']._serialized_end=42651 + _globals['_ASSETTYPE']._serialized_start=42654 + _globals['_ASSETTYPE']._serialized_end=42791 + _globals['_STRUCTUREDPRODUCTTYPE']._serialized_start=42793 + _globals['_STRUCTUREDPRODUCTTYPE']._serialized_end=42895 + _globals['_EDITFAVORITESACTIONTYPE']._serialized_start=42898 + _globals['_EDITFAVORITESACTIONTYPE']._serialized_end=43039 + _globals['_RECOMMENDATION']._serialized_start=43041 + _globals['_RECOMMENDATION']._serialized_end=43163 + _globals['_RISKLEVEL']._serialized_start=43165 + _globals['_RISKLEVEL']._serialized_end=43270 + _globals['_BONDTYPE']._serialized_start=43272 + _globals['_BONDTYPE']._serialized_end=43333 + _globals['_INSTRUMENTEXCHANGETYPE']._serialized_start=43335 + _globals['_INSTRUMENTEXCHANGETYPE']._serialized_end=43428 + _globals['_TRADINGSCHEDULESREQUEST']._serialized_start=198 + _globals['_TRADINGSCHEDULESREQUEST']._serialized_end=367 + _globals['_TRADINGSCHEDULESRESPONSE']._serialized_start=369 + _globals['_TRADINGSCHEDULESRESPONSE']._serialized_end=470 + _globals['_TRADINGSCHEDULE']._serialized_start=472 + _globals['_TRADINGSCHEDULE']._serialized_end=572 + _globals['_TRADINGDAY']._serialized_start=575 + _globals['_TRADINGDAY']._serialized_end=1494 + _globals['_INSTRUMENTREQUEST']._serialized_start=1497 + _globals['_INSTRUMENTREQUEST']._serialized_end=1654 + _globals['_INSTRUMENTSREQUEST']._serialized_start=1657 + _globals['_INSTRUMENTSREQUEST']._serialized_end=1909 + _globals['_FILTEROPTIONSREQUEST']._serialized_start=1912 + _globals['_FILTEROPTIONSREQUEST']._serialized_end=2110 + _globals['_BONDRESPONSE']._serialized_start=2112 + _globals['_BONDRESPONSE']._serialized_end=2191 + _globals['_BONDSRESPONSE']._serialized_start=2193 + _globals['_BONDSRESPONSE']._serialized_end=2274 + _globals['_GETBONDCOUPONSREQUEST']._serialized_start=2277 + _globals['_GETBONDCOUPONSREQUEST']._serialized_end=2455 + _globals['_GETBONDCOUPONSRESPONSE']._serialized_start=2457 + _globals['_GETBONDCOUPONSRESPONSE']._serialized_end=2544 + _globals['_GETBONDEVENTSREQUEST']._serialized_start=2547 + _globals['_GETBONDEVENTSREQUEST']._serialized_end=2914 + _globals['_GETBONDEVENTSREQUEST_EVENTTYPE']._serialized_start=2777 + _globals['_GETBONDEVENTSREQUEST_EVENTTYPE']._serialized_end=2898 + _globals['_GETBONDEVENTSRESPONSE']._serialized_start=2917 + _globals['_GETBONDEVENTSRESPONSE']._serialized_end=4054 + _globals['_GETBONDEVENTSRESPONSE_BONDEVENT']._serialized_start=3031 + _globals['_GETBONDEVENTSRESPONSE_BONDEVENT']._serialized_end=4054 + _globals['_COUPON']._serialized_start=4057 + _globals['_COUPON']._serialized_end=4473 + _globals['_CURRENCYRESPONSE']._serialized_start=4475 + _globals['_CURRENCYRESPONSE']._serialized_end=4562 + _globals['_CURRENCIESRESPONSE']._serialized_start=4564 + _globals['_CURRENCIESRESPONSE']._serialized_end=4654 + _globals['_ETFRESPONSE']._serialized_start=4656 + _globals['_ETFRESPONSE']._serialized_end=4733 + _globals['_ETFSRESPONSE']._serialized_start=4735 + _globals['_ETFSRESPONSE']._serialized_end=4814 + _globals['_FUTURERESPONSE']._serialized_start=4816 + _globals['_FUTURERESPONSE']._serialized_end=4899 + _globals['_FUTURESRESPONSE']._serialized_start=4901 + _globals['_FUTURESRESPONSE']._serialized_end=4986 + _globals['_OPTIONRESPONSE']._serialized_start=4988 + _globals['_OPTIONRESPONSE']._serialized_end=5071 + _globals['_OPTIONSRESPONSE']._serialized_start=5073 + _globals['_OPTIONSRESPONSE']._serialized_end=5158 + _globals['_OPTION']._serialized_start=5161 + _globals['_OPTION']._serialized_end=7372 + _globals['_SHARERESPONSE']._serialized_start=7374 + _globals['_SHARERESPONSE']._serialized_end=7455 + _globals['_SHARESRESPONSE']._serialized_start=7457 + _globals['_SHARESRESPONSE']._serialized_end=7540 + _globals['_STRUCTUREDNOTERESPONSE']._serialized_start=7542 + _globals['_STRUCTUREDNOTERESPONSE']._serialized_end=7641 + _globals['_STRUCTUREDNOTESRESPONSE']._serialized_start=7643 + _globals['_STRUCTUREDNOTESRESPONSE']._serialized_end=7744 + _globals['_BOND']._serialized_start=7747 + _globals['_BOND']._serialized_end=10109 + _globals['_CURRENCY']._serialized_start=10112 + _globals['_CURRENCY']._serialized_end=11696 + _globals['_ETF']._serialized_start=11699 + _globals['_ETF']._serialized_end=13558 + _globals['_FUTURE']._serialized_start=13561 + _globals['_FUTURE']._serialized_end=15615 + _globals['_SHARE']._serialized_start=15618 + _globals['_SHARE']._serialized_end=17489 + _globals['_STRUCTUREDNOTE']._serialized_start=17492 + _globals['_STRUCTUREDNOTE']._serialized_end=20437 + _globals['_STRUCTUREDNOTE_BASICASSET']._serialized_start=19603 + _globals['_STRUCTUREDNOTE_BASICASSET']._serialized_end=19765 + _globals['_STRUCTUREDNOTE_YIELD']._serialized_start=19768 + _globals['_STRUCTUREDNOTE_YIELD']._serialized_end=19919 + _globals['_STRUCTUREDNOTE_LOGICPORTFOLIO']._serialized_start=19921 + _globals['_STRUCTUREDNOTE_LOGICPORTFOLIO']._serialized_end=20035 + _globals['_STRUCTUREDNOTE_OBSERVATIONPRINCIPLE']._serialized_start=20038 + _globals['_STRUCTUREDNOTE_OBSERVATIONPRINCIPLE']._serialized_end=20297 + _globals['_STRUCTUREDNOTE_YIELDTYPE']._serialized_start=20300 + _globals['_STRUCTUREDNOTE_YIELDTYPE']._serialized_end=20437 + _globals['_GETACCRUEDINTERESTSREQUEST']._serialized_start=20440 + _globals['_GETACCRUEDINTERESTSREQUEST']._serialized_end=20609 + _globals['_GETACCRUEDINTERESTSRESPONSE']._serialized_start=20611 + _globals['_GETACCRUEDINTERESTSRESPONSE']._serialized_end=20723 + _globals['_ACCRUEDINTEREST']._serialized_start=20726 + _globals['_ACCRUEDINTEREST']._serialized_end=20990 + _globals['_GETFUTURESMARGINREQUEST']._serialized_start=20992 + _globals['_GETFUTURESMARGINREQUEST']._serialized_end=21064 + _globals['_GETFUTURESMARGINRESPONSE']._serialized_start=21067 + _globals['_GETFUTURESMARGINRESPONSE']._serialized_end=21423 + _globals['_INSTRUMENTRESPONSE']._serialized_start=21425 + _globals['_INSTRUMENTRESPONSE']._serialized_end=21516 + _globals['_INSTRUMENT']._serialized_start=21519 + _globals['_INSTRUMENT']._serialized_end=23117 + _globals['_GETDIVIDENDSREQUEST']._serialized_start=23120 + _globals['_GETDIVIDENDSREQUEST']._serialized_end=23296 + _globals['_GETDIVIDENDSRESPONSE']._serialized_start=23298 + _globals['_GETDIVIDENDSRESPONSE']._serialized_end=23388 + _globals['_DIVIDEND']._serialized_start=23391 + _globals['_DIVIDEND']._serialized_end=23909 + _globals['_ASSETREQUEST']._serialized_start=23911 + _globals['_ASSETREQUEST']._serialized_end=23943 + _globals['_ASSETRESPONSE']._serialized_start=23945 + _globals['_ASSETRESPONSE']._serialized_end=24025 + _globals['_ASSETSREQUEST']._serialized_start=24028 + _globals['_ASSETSREQUEST']._serialized_end=24259 + _globals['_ASSETSRESPONSE']._serialized_start=24261 + _globals['_ASSETSRESPONSE']._serialized_end=24339 + _globals['_ASSETFULL']._serialized_start=24342 + _globals['_ASSETFULL']._serialized_end=25006 + _globals['_ASSET']._serialized_start=25009 + _globals['_ASSET']._serialized_end=25184 + _globals['_ASSETCURRENCY']._serialized_start=25186 + _globals['_ASSETCURRENCY']._serialized_end=25224 + _globals['_ASSETSECURITY']._serialized_start=25227 + _globals['_ASSETSECURITY']._serialized_end=25729 + _globals['_ASSETSHARE']._serialized_start=25732 + _globals['_ASSETSHARE']._serialized_end=26457 + _globals['_ASSETBOND']._serialized_start=26460 + _globals['_ASSETBOND']._serialized_end=27324 + _globals['_ASSETSTRUCTUREDPRODUCT']._serialized_start=27327 + _globals['_ASSETSTRUCTUREDPRODUCT']._serialized_end=27999 + _globals['_ASSETETF']._serialized_start=28002 + _globals['_ASSETETF']._serialized_end=29370 + _globals['_ASSETCLEARINGCERTIFICATE']._serialized_start=29372 + _globals['_ASSETCLEARINGCERTIFICATE']._serialized_end=29491 + _globals['_BRAND']._serialized_start=29494 + _globals['_BRAND']._serialized_end=29651 + _globals['_ASSETINSTRUMENT']._serialized_start=29654 + _globals['_ASSETINSTRUMENT']._serialized_end=29931 + _globals['_INSTRUMENTLINK']._serialized_start=29933 + _globals['_INSTRUMENTLINK']._serialized_end=29987 + _globals['_GETFAVORITESREQUEST']._serialized_start=29989 + _globals['_GETFAVORITESREQUEST']._serialized_end=30046 + _globals['_GETFAVORITESRESPONSE']._serialized_start=30049 + _globals['_GETFAVORITESRESPONSE']._serialized_end=30196 + _globals['_FAVORITEINSTRUMENT']._serialized_start=30199 + _globals['_FAVORITEINSTRUMENT']._serialized_end=30467 + _globals['_EDITFAVORITESREQUEST']._serialized_start=30470 + _globals['_EDITFAVORITESREQUEST']._serialized_end=30717 + _globals['_EDITFAVORITESREQUESTINSTRUMENT']._serialized_start=30719 + _globals['_EDITFAVORITESREQUESTINSTRUMENT']._serialized_end=30812 + _globals['_EDITFAVORITESRESPONSE']._serialized_start=30815 + _globals['_EDITFAVORITESRESPONSE']._serialized_end=30963 + _globals['_CREATEFAVORITEGROUPREQUEST']._serialized_start=30965 + _globals['_CREATEFAVORITEGROUPREQUEST']._serialized_end=31074 + _globals['_CREATEFAVORITEGROUPRESPONSE']._serialized_start=31076 + _globals['_CREATEFAVORITEGROUPRESPONSE']._serialized_end=31143 + _globals['_DELETEFAVORITEGROUPREQUEST']._serialized_start=31145 + _globals['_DELETEFAVORITEGROUPREQUEST']._serialized_end=31197 + _globals['_DELETEFAVORITEGROUPRESPONSE']._serialized_start=31199 + _globals['_DELETEFAVORITEGROUPRESPONSE']._serialized_end=31228 + _globals['_GETFAVORITEGROUPSREQUEST']._serialized_start=31230 + _globals['_GETFAVORITEGROUPSREQUEST']._serialized_end=31306 + _globals['_GETFAVORITEGROUPSRESPONSE']._serialized_start=31309 + _globals['_GETFAVORITEGROUPSRESPONSE']._serialized_end=31599 + _globals['_GETFAVORITEGROUPSRESPONSE_FAVORITEGROUP']._serialized_start=31435 + _globals['_GETFAVORITEGROUPSRESPONSE_FAVORITEGROUP']._serialized_end=31599 + _globals['_GETCOUNTRIESREQUEST']._serialized_start=31601 + _globals['_GETCOUNTRIESREQUEST']._serialized_end=31622 + _globals['_GETCOUNTRIESRESPONSE']._serialized_start=31624 + _globals['_GETCOUNTRIESRESPONSE']._serialized_end=31721 + _globals['_INDICATIVESREQUEST']._serialized_start=31723 + _globals['_INDICATIVESREQUEST']._serialized_end=31743 + _globals['_INDICATIVESRESPONSE']._serialized_start=31745 + _globals['_INDICATIVESRESPONSE']._serialized_end=31846 + _globals['_INDICATIVERESPONSE']._serialized_start=31849 + _globals['_INDICATIVERESPONSE']._serialized_end=32121 + _globals['_COUNTRYRESPONSE']._serialized_start=32123 + _globals['_COUNTRYRESPONSE']._serialized_end=32212 + _globals['_FINDINSTRUMENTREQUEST']._serialized_start=32215 + _globals['_FINDINSTRUMENTREQUEST']._serialized_end=32432 + _globals['_FINDINSTRUMENTRESPONSE']._serialized_start=32434 + _globals['_FINDINSTRUMENTRESPONSE']._serialized_end=32535 + _globals['_INSTRUMENTSHORT']._serialized_start=32538 + _globals['_INSTRUMENTSHORT']._serialized_end=33042 + _globals['_GETBRANDSREQUEST']._serialized_start=33044 + _globals['_GETBRANDSREQUEST']._serialized_end=33123 + _globals['_GETBRANDREQUEST']._serialized_start=33125 + _globals['_GETBRANDREQUEST']._serialized_end=33160 + _globals['_GETBRANDSRESPONSE']._serialized_start=33163 + _globals['_GETBRANDSRESPONSE']._serialized_end=33313 + _globals['_GETASSETFUNDAMENTALSREQUEST']._serialized_start=33315 + _globals['_GETASSETFUNDAMENTALSREQUEST']._serialized_end=33366 + _globals['_GETASSETFUNDAMENTALSRESPONSE']._serialized_start=33369 + _globals['_GETASSETFUNDAMENTALSRESPONSE']._serialized_end=35286 + _globals['_GETASSETFUNDAMENTALSRESPONSE_STATISTICRESPONSE']._serialized_start=33511 + _globals['_GETASSETFUNDAMENTALSRESPONSE_STATISTICRESPONSE']._serialized_end=35286 + _globals['_GETASSETREPORTSREQUEST']._serialized_start=35289 + _globals['_GETASSETREPORTSREQUEST']._serialized_end=35450 + _globals['_GETASSETREPORTSRESPONSE']._serialized_start=35453 + _globals['_GETASSETREPORTSRESPONSE']._serialized_end=36004 + _globals['_GETASSETREPORTSRESPONSE_GETASSETREPORTSEVENT']._serialized_start=35582 + _globals['_GETASSETREPORTSRESPONSE_GETASSETREPORTSEVENT']._serialized_end=35872 + _globals['_GETASSETREPORTSRESPONSE_ASSETREPORTPERIODTYPE']._serialized_start=35875 + _globals['_GETASSETREPORTSRESPONSE_ASSETREPORTPERIODTYPE']._serialized_end=36004 + _globals['_GETCONSENSUSFORECASTSREQUEST']._serialized_start=36006 + _globals['_GETCONSENSUSFORECASTSREQUEST']._serialized_end=36113 + _globals['_GETCONSENSUSFORECASTSRESPONSE']._serialized_start=36116 + _globals['_GETCONSENSUSFORECASTSRESPONSE']._serialized_end=36890 + _globals['_GETCONSENSUSFORECASTSRESPONSE_CONSENSUSFORECASTSITEM']._serialized_start=36325 + _globals['_GETCONSENSUSFORECASTSRESPONSE_CONSENSUSFORECASTSITEM']._serialized_end=36890 + _globals['_GETFORECASTREQUEST']._serialized_start=36892 + _globals['_GETFORECASTREQUEST']._serialized_end=36935 + _globals['_GETFORECASTRESPONSE']._serialized_start=36938 + _globals['_GETFORECASTRESPONSE']._serialized_end=38241 + _globals['_GETFORECASTRESPONSE_TARGETITEM']._serialized_start=37143 + _globals['_GETFORECASTRESPONSE_TARGETITEM']._serialized_end=37667 + _globals['_GETFORECASTRESPONSE_CONSENSUSITEM']._serialized_start=37670 + _globals['_GETFORECASTRESPONSE_CONSENSUSITEM']._serialized_end=38241 + _globals['_RISKRATESREQUEST']._serialized_start=38243 + _globals['_RISKRATESREQUEST']._serialized_end=38284 + _globals['_RISKRATESRESPONSE']._serialized_start=38287 + _globals['_RISKRATESRESPONSE']._serialized_end=39002 + _globals['_RISKRATESRESPONSE_RISKRATERESULT']._serialized_start=38413 + _globals['_RISKRATESRESPONSE_RISKRATERESULT']._serialized_end=38900 + _globals['_RISKRATESRESPONSE_RISKRATE']._serialized_start=38902 + _globals['_RISKRATESRESPONSE_RISKRATE']._serialized_end=39002 + _globals['_TRADINGINTERVAL']._serialized_start=39005 + _globals['_TRADINGINTERVAL']._serialized_end=39229 + _globals['_TRADINGINTERVAL_TIMEINTERVAL']._serialized_start=39125 + _globals['_TRADINGINTERVAL_TIMEINTERVAL']._serialized_end=39229 + _globals['_GETINSIDERDEALSREQUEST']._serialized_start=39231 + _globals['_GETINSIDERDEALSREQUEST']._serialized_end=39335 + _globals['_GETINSIDERDEALSRESPONSE']._serialized_start=39338 + _globals['_GETINSIDERDEALSRESPONSE']._serialized_end=40134 + _globals['_GETINSIDERDEALSRESPONSE_INSIDERDEAL']._serialized_start=39491 + _globals['_GETINSIDERDEALSRESPONSE_INSIDERDEAL']._serialized_end=39955 + _globals['_GETINSIDERDEALSRESPONSE_TRADEDIRECTION']._serialized_start=39958 + _globals['_GETINSIDERDEALSRESPONSE_TRADEDIRECTION']._serialized_end=40118 + _globals['_DFASREQUEST']._serialized_start=40136 + _globals['_DFASREQUEST']._serialized_end=40149 + _globals['_DFARESPONSE']._serialized_start=40152 + _globals['_DFARESPONSE']._serialized_end=41426 + _globals['_DFARESPONSE_BASICASSET']._serialized_start=19603 + _globals['_DFARESPONSE_BASICASSET']._serialized_end=19628 + _globals['_DFARESPONSE_FORECASTYIELD']._serialized_start=41273 + _globals['_DFARESPONSE_FORECASTYIELD']._serialized_end=41426 + _globals['_DFASRESPONSE']._serialized_start=41428 + _globals['_DFASRESPONSE']._serialized_end=41515 + _globals['_INSTRUMENTSSERVICE']._serialized_start=43431 + _globals['_INSTRUMENTSSERVICE']._serialized_end=49161 +# @@protoc_insertion_point(module_scope) diff --git a/invest-python-master/t_tech/invest/grpc/instruments_pb2.pyi b/invest-python-master/t_tech/invest/grpc/instruments_pb2.pyi new file mode 100644 index 0000000..ac6b818 --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/instruments_pb2.pyi @@ -0,0 +1,6369 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" + +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.internal.enum_type_wrapper +import google.protobuf.message +import google.protobuf.timestamp_pb2 +import sys +import t_tech.invest.grpc.common_pb2 +import typing + +if sys.version_info >= (3, 10): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +class _CouponType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _CouponTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_CouponType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + COUPON_TYPE_UNSPECIFIED: _CouponType.ValueType # 0 + """Неопределенное значение.""" + COUPON_TYPE_CONSTANT: _CouponType.ValueType # 1 + """Постоянный.""" + COUPON_TYPE_FLOATING: _CouponType.ValueType # 2 + """Плавающий.""" + COUPON_TYPE_DISCOUNT: _CouponType.ValueType # 3 + """Дисконт.""" + COUPON_TYPE_MORTGAGE: _CouponType.ValueType # 4 + """Ипотечный.""" + COUPON_TYPE_FIX: _CouponType.ValueType # 5 + """Фиксированный.""" + COUPON_TYPE_VARIABLE: _CouponType.ValueType # 6 + """Переменный.""" + COUPON_TYPE_OTHER: _CouponType.ValueType # 7 + """Прочее.""" + +class CouponType(_CouponType, metaclass=_CouponTypeEnumTypeWrapper): + """Тип купонов.""" + +COUPON_TYPE_UNSPECIFIED: CouponType.ValueType # 0 +"""Неопределенное значение.""" +COUPON_TYPE_CONSTANT: CouponType.ValueType # 1 +"""Постоянный.""" +COUPON_TYPE_FLOATING: CouponType.ValueType # 2 +"""Плавающий.""" +COUPON_TYPE_DISCOUNT: CouponType.ValueType # 3 +"""Дисконт.""" +COUPON_TYPE_MORTGAGE: CouponType.ValueType # 4 +"""Ипотечный.""" +COUPON_TYPE_FIX: CouponType.ValueType # 5 +"""Фиксированный.""" +COUPON_TYPE_VARIABLE: CouponType.ValueType # 6 +"""Переменный.""" +COUPON_TYPE_OTHER: CouponType.ValueType # 7 +"""Прочее.""" +global___CouponType = CouponType + +class _OptionDirection: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _OptionDirectionEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_OptionDirection.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + OPTION_DIRECTION_UNSPECIFIED: _OptionDirection.ValueType # 0 + """Тип не определен.""" + OPTION_DIRECTION_PUT: _OptionDirection.ValueType # 1 + """Опцион на продажу.""" + OPTION_DIRECTION_CALL: _OptionDirection.ValueType # 2 + """Опцион на покупку.""" + +class OptionDirection(_OptionDirection, metaclass=_OptionDirectionEnumTypeWrapper): + """Тип опциона по направлению сделки.""" + +OPTION_DIRECTION_UNSPECIFIED: OptionDirection.ValueType # 0 +"""Тип не определен.""" +OPTION_DIRECTION_PUT: OptionDirection.ValueType # 1 +"""Опцион на продажу.""" +OPTION_DIRECTION_CALL: OptionDirection.ValueType # 2 +"""Опцион на покупку.""" +global___OptionDirection = OptionDirection + +class _OptionPaymentType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _OptionPaymentTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_OptionPaymentType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + OPTION_PAYMENT_TYPE_UNSPECIFIED: _OptionPaymentType.ValueType # 0 + """Тип не определен.""" + OPTION_PAYMENT_TYPE_PREMIUM: _OptionPaymentType.ValueType # 1 + """Опционы с использованием премии в расчетах.""" + OPTION_PAYMENT_TYPE_MARGINAL: _OptionPaymentType.ValueType # 2 + """Маржируемые опционы.""" + +class OptionPaymentType(_OptionPaymentType, metaclass=_OptionPaymentTypeEnumTypeWrapper): + """Тип расчетов по опциону.""" + +OPTION_PAYMENT_TYPE_UNSPECIFIED: OptionPaymentType.ValueType # 0 +"""Тип не определен.""" +OPTION_PAYMENT_TYPE_PREMIUM: OptionPaymentType.ValueType # 1 +"""Опционы с использованием премии в расчетах.""" +OPTION_PAYMENT_TYPE_MARGINAL: OptionPaymentType.ValueType # 2 +"""Маржируемые опционы.""" +global___OptionPaymentType = OptionPaymentType + +class _OptionStyle: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _OptionStyleEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_OptionStyle.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + OPTION_STYLE_UNSPECIFIED: _OptionStyle.ValueType # 0 + """Тип не определен.""" + OPTION_STYLE_AMERICAN: _OptionStyle.ValueType # 1 + """Американский опцион.""" + OPTION_STYLE_EUROPEAN: _OptionStyle.ValueType # 2 + """Европейский опцион.""" + +class OptionStyle(_OptionStyle, metaclass=_OptionStyleEnumTypeWrapper): + """Тип опциона по стилю.""" + +OPTION_STYLE_UNSPECIFIED: OptionStyle.ValueType # 0 +"""Тип не определен.""" +OPTION_STYLE_AMERICAN: OptionStyle.ValueType # 1 +"""Американский опцион.""" +OPTION_STYLE_EUROPEAN: OptionStyle.ValueType # 2 +"""Европейский опцион.""" +global___OptionStyle = OptionStyle + +class _OptionSettlementType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _OptionSettlementTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_OptionSettlementType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + OPTION_EXECUTION_TYPE_UNSPECIFIED: _OptionSettlementType.ValueType # 0 + """Тип не определен.""" + OPTION_EXECUTION_TYPE_PHYSICAL_DELIVERY: _OptionSettlementType.ValueType # 1 + """Поставочный тип опциона.""" + OPTION_EXECUTION_TYPE_CASH_SETTLEMENT: _OptionSettlementType.ValueType # 2 + """Расчетный тип опциона.""" + +class OptionSettlementType(_OptionSettlementType, metaclass=_OptionSettlementTypeEnumTypeWrapper): + """Тип опциона по способу исполнения.""" + +OPTION_EXECUTION_TYPE_UNSPECIFIED: OptionSettlementType.ValueType # 0 +"""Тип не определен.""" +OPTION_EXECUTION_TYPE_PHYSICAL_DELIVERY: OptionSettlementType.ValueType # 1 +"""Поставочный тип опциона.""" +OPTION_EXECUTION_TYPE_CASH_SETTLEMENT: OptionSettlementType.ValueType # 2 +"""Расчетный тип опциона.""" +global___OptionSettlementType = OptionSettlementType + +class _InstrumentIdType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _InstrumentIdTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_InstrumentIdType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + INSTRUMENT_ID_UNSPECIFIED: _InstrumentIdType.ValueType # 0 + """Значение не определено.""" + INSTRUMENT_ID_TYPE_FIGI: _InstrumentIdType.ValueType # 1 + """FIGI.""" + INSTRUMENT_ID_TYPE_TICKER: _InstrumentIdType.ValueType # 2 + """Ticker.""" + INSTRUMENT_ID_TYPE_UID: _InstrumentIdType.ValueType # 3 + """Уникальный идентификатор.""" + INSTRUMENT_ID_TYPE_POSITION_UID: _InstrumentIdType.ValueType # 4 + """Идентификатор позиции.""" + INSTRUMENT_ID_TYPE_ID: _InstrumentIdType.ValueType # 5 + """Универсальный тип идентификатора инструмента.""" + +class InstrumentIdType(_InstrumentIdType, metaclass=_InstrumentIdTypeEnumTypeWrapper): + """Тип идентификатора инструмента. [Подробнее об идентификации инструментов](/invest/intro/intro/faq_identification).""" + +INSTRUMENT_ID_UNSPECIFIED: InstrumentIdType.ValueType # 0 +"""Значение не определено.""" +INSTRUMENT_ID_TYPE_FIGI: InstrumentIdType.ValueType # 1 +"""FIGI.""" +INSTRUMENT_ID_TYPE_TICKER: InstrumentIdType.ValueType # 2 +"""Ticker.""" +INSTRUMENT_ID_TYPE_UID: InstrumentIdType.ValueType # 3 +"""Уникальный идентификатор.""" +INSTRUMENT_ID_TYPE_POSITION_UID: InstrumentIdType.ValueType # 4 +"""Идентификатор позиции.""" +INSTRUMENT_ID_TYPE_ID: InstrumentIdType.ValueType # 5 +"""Универсальный тип идентификатора инструмента.""" +global___InstrumentIdType = InstrumentIdType + +class _ShareType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _ShareTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_ShareType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + SHARE_TYPE_UNSPECIFIED: _ShareType.ValueType # 0 + """Значение не определено.""" + SHARE_TYPE_COMMON: _ShareType.ValueType # 1 + """Обыкновенная.""" + SHARE_TYPE_PREFERRED: _ShareType.ValueType # 2 + """Привилегированная.""" + SHARE_TYPE_ADR: _ShareType.ValueType # 3 + """Американские депозитарные расписки.""" + SHARE_TYPE_GDR: _ShareType.ValueType # 4 + """Глобальные депозитарные расписки.""" + SHARE_TYPE_MLP: _ShareType.ValueType # 5 + """Товарищество с ограниченной ответственностью.""" + SHARE_TYPE_NY_REG_SHRS: _ShareType.ValueType # 6 + """Акции из реестра Нью-Йорка.""" + SHARE_TYPE_CLOSED_END_FUND: _ShareType.ValueType # 7 + """Закрытый инвестиционный фонд.""" + SHARE_TYPE_REIT: _ShareType.ValueType # 8 + """Траст недвижимости.""" + +class ShareType(_ShareType, metaclass=_ShareTypeEnumTypeWrapper): + """Тип акций.""" + +SHARE_TYPE_UNSPECIFIED: ShareType.ValueType # 0 +"""Значение не определено.""" +SHARE_TYPE_COMMON: ShareType.ValueType # 1 +"""Обыкновенная.""" +SHARE_TYPE_PREFERRED: ShareType.ValueType # 2 +"""Привилегированная.""" +SHARE_TYPE_ADR: ShareType.ValueType # 3 +"""Американские депозитарные расписки.""" +SHARE_TYPE_GDR: ShareType.ValueType # 4 +"""Глобальные депозитарные расписки.""" +SHARE_TYPE_MLP: ShareType.ValueType # 5 +"""Товарищество с ограниченной ответственностью.""" +SHARE_TYPE_NY_REG_SHRS: ShareType.ValueType # 6 +"""Акции из реестра Нью-Йорка.""" +SHARE_TYPE_CLOSED_END_FUND: ShareType.ValueType # 7 +"""Закрытый инвестиционный фонд.""" +SHARE_TYPE_REIT: ShareType.ValueType # 8 +"""Траст недвижимости.""" +global___ShareType = ShareType + +class _AssetType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _AssetTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_AssetType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + ASSET_TYPE_UNSPECIFIED: _AssetType.ValueType # 0 + """Тип не определен.""" + ASSET_TYPE_CURRENCY: _AssetType.ValueType # 1 + """Валюта.""" + ASSET_TYPE_COMMODITY: _AssetType.ValueType # 2 + """Товар.""" + ASSET_TYPE_INDEX: _AssetType.ValueType # 3 + """Индекс.""" + ASSET_TYPE_SECURITY: _AssetType.ValueType # 4 + """Ценная бумага.""" + +class AssetType(_AssetType, metaclass=_AssetTypeEnumTypeWrapper): + """Тип актива.""" + +ASSET_TYPE_UNSPECIFIED: AssetType.ValueType # 0 +"""Тип не определен.""" +ASSET_TYPE_CURRENCY: AssetType.ValueType # 1 +"""Валюта.""" +ASSET_TYPE_COMMODITY: AssetType.ValueType # 2 +"""Товар.""" +ASSET_TYPE_INDEX: AssetType.ValueType # 3 +"""Индекс.""" +ASSET_TYPE_SECURITY: AssetType.ValueType # 4 +"""Ценная бумага.""" +global___AssetType = AssetType + +class _StructuredProductType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _StructuredProductTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_StructuredProductType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + SP_TYPE_UNSPECIFIED: _StructuredProductType.ValueType # 0 + """Тип не определен.""" + SP_TYPE_DELIVERABLE: _StructuredProductType.ValueType # 1 + """Поставочный.""" + SP_TYPE_NON_DELIVERABLE: _StructuredProductType.ValueType # 2 + """Беспоставочный.""" + +class StructuredProductType(_StructuredProductType, metaclass=_StructuredProductTypeEnumTypeWrapper): + """Тип структурной ноты.""" + +SP_TYPE_UNSPECIFIED: StructuredProductType.ValueType # 0 +"""Тип не определен.""" +SP_TYPE_DELIVERABLE: StructuredProductType.ValueType # 1 +"""Поставочный.""" +SP_TYPE_NON_DELIVERABLE: StructuredProductType.ValueType # 2 +"""Беспоставочный.""" +global___StructuredProductType = StructuredProductType + +class _EditFavoritesActionType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _EditFavoritesActionTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_EditFavoritesActionType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + EDIT_FAVORITES_ACTION_TYPE_UNSPECIFIED: _EditFavoritesActionType.ValueType # 0 + """Тип не определен.""" + EDIT_FAVORITES_ACTION_TYPE_ADD: _EditFavoritesActionType.ValueType # 1 + """Добавить в список.""" + EDIT_FAVORITES_ACTION_TYPE_DEL: _EditFavoritesActionType.ValueType # 2 + """Удалить из списка.""" + +class EditFavoritesActionType(_EditFavoritesActionType, metaclass=_EditFavoritesActionTypeEnumTypeWrapper): + """Тип действия со списком избранных инструментов.""" + +EDIT_FAVORITES_ACTION_TYPE_UNSPECIFIED: EditFavoritesActionType.ValueType # 0 +"""Тип не определен.""" +EDIT_FAVORITES_ACTION_TYPE_ADD: EditFavoritesActionType.ValueType # 1 +"""Добавить в список.""" +EDIT_FAVORITES_ACTION_TYPE_DEL: EditFavoritesActionType.ValueType # 2 +"""Удалить из списка.""" +global___EditFavoritesActionType = EditFavoritesActionType + +class _Recommendation: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _RecommendationEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_Recommendation.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + RECOMMENDATION_UNSPECIFIED: _Recommendation.ValueType # 0 + """Не определено.""" + RECOMMENDATION_BUY: _Recommendation.ValueType # 1 + """Покупать.""" + RECOMMENDATION_HOLD: _Recommendation.ValueType # 2 + """Держать.""" + RECOMMENDATION_SELL: _Recommendation.ValueType # 3 + """Продавать.""" + +class Recommendation(_Recommendation, metaclass=_RecommendationEnumTypeWrapper): ... + +RECOMMENDATION_UNSPECIFIED: Recommendation.ValueType # 0 +"""Не определено.""" +RECOMMENDATION_BUY: Recommendation.ValueType # 1 +"""Покупать.""" +RECOMMENDATION_HOLD: Recommendation.ValueType # 2 +"""Держать.""" +RECOMMENDATION_SELL: Recommendation.ValueType # 3 +"""Продавать.""" +global___Recommendation = Recommendation + +class _RiskLevel: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _RiskLevelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_RiskLevel.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + RISK_LEVEL_UNSPECIFIED: _RiskLevel.ValueType # 0 + """Не указан.""" + RISK_LEVEL_LOW: _RiskLevel.ValueType # 1 + """Низкий уровень риска.""" + RISK_LEVEL_MODERATE: _RiskLevel.ValueType # 2 + """Средний уровень риска.""" + RISK_LEVEL_HIGH: _RiskLevel.ValueType # 3 + """Высокий уровень риска.""" + +class RiskLevel(_RiskLevel, metaclass=_RiskLevelEnumTypeWrapper): + """Уровень риска облигации.""" + +RISK_LEVEL_UNSPECIFIED: RiskLevel.ValueType # 0 +"""Не указан.""" +RISK_LEVEL_LOW: RiskLevel.ValueType # 1 +"""Низкий уровень риска.""" +RISK_LEVEL_MODERATE: RiskLevel.ValueType # 2 +"""Средний уровень риска.""" +RISK_LEVEL_HIGH: RiskLevel.ValueType # 3 +"""Высокий уровень риска.""" +global___RiskLevel = RiskLevel + +class _BondType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _BondTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_BondType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + BOND_TYPE_UNSPECIFIED: _BondType.ValueType # 0 + """Тип облигации не определен.""" + BOND_TYPE_REPLACED: _BondType.ValueType # 1 + """Замещающая облигация.""" + +class BondType(_BondType, metaclass=_BondTypeEnumTypeWrapper): ... + +BOND_TYPE_UNSPECIFIED: BondType.ValueType # 0 +"""Тип облигации не определен.""" +BOND_TYPE_REPLACED: BondType.ValueType # 1 +"""Замещающая облигация.""" +global___BondType = BondType + +class _InstrumentExchangeType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _InstrumentExchangeTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_InstrumentExchangeType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + INSTRUMENT_EXCHANGE_UNSPECIFIED: _InstrumentExchangeType.ValueType # 0 + """Площадка торговли не определена.""" + INSTRUMENT_EXCHANGE_DEALER: _InstrumentExchangeType.ValueType # 1 + """Бумага, торгуемая у дилера.""" + +class InstrumentExchangeType(_InstrumentExchangeType, metaclass=_InstrumentExchangeTypeEnumTypeWrapper): + """Площадка торговли.""" + +INSTRUMENT_EXCHANGE_UNSPECIFIED: InstrumentExchangeType.ValueType # 0 +"""Площадка торговли не определена.""" +INSTRUMENT_EXCHANGE_DEALER: InstrumentExchangeType.ValueType # 1 +"""Бумага, торгуемая у дилера.""" +global___InstrumentExchangeType = InstrumentExchangeType + +@typing.final +class TradingSchedulesRequest(google.protobuf.message.Message): + """Запрос расписания торгов.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + EXCHANGE_FIELD_NUMBER: builtins.int + FROM_FIELD_NUMBER: builtins.int + TO_FIELD_NUMBER: builtins.int + exchange: builtins.str + """Наименование биржи или расчетного календаря.
Если не передается, возвращается информация по всем доступным торговым площадкам.""" + @property + def to(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Окончание периода по UTC.""" + + def __init__( + self, + *, + exchange: builtins.str | None = ..., + to: google.protobuf.timestamp_pb2.Timestamp | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_exchange", b"_exchange", "_from", b"_from", "_to", b"_to", "exchange", b"exchange", "from", b"from", "to", b"to"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_exchange", b"_exchange", "_from", b"_from", "_to", b"_to", "exchange", b"exchange", "from", b"from", "to", b"to"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_exchange", b"_exchange"]) -> typing.Literal["exchange"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_from", b"_from"]) -> typing.Literal["from"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_to", b"_to"]) -> typing.Literal["to"] | None: ... + +global___TradingSchedulesRequest = TradingSchedulesRequest + +@typing.final +class TradingSchedulesResponse(google.protobuf.message.Message): + """Список торговых площадок.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + EXCHANGES_FIELD_NUMBER: builtins.int + @property + def exchanges(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___TradingSchedule]: + """Список торговых площадок и режимов торгов.""" + + def __init__( + self, + *, + exchanges: collections.abc.Iterable[global___TradingSchedule] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["exchanges", b"exchanges"]) -> None: ... + +global___TradingSchedulesResponse = TradingSchedulesResponse + +@typing.final +class TradingSchedule(google.protobuf.message.Message): + """Данные по торговой площадке.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + EXCHANGE_FIELD_NUMBER: builtins.int + DAYS_FIELD_NUMBER: builtins.int + exchange: builtins.str + """Наименование торговой площадки.""" + @property + def days(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___TradingDay]: + """Массив с торговыми и неторговыми днями.""" + + def __init__( + self, + *, + exchange: builtins.str = ..., + days: collections.abc.Iterable[global___TradingDay] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["days", b"days", "exchange", b"exchange"]) -> None: ... + +global___TradingSchedule = TradingSchedule + +@typing.final +class TradingDay(google.protobuf.message.Message): + """Информация о времени торгов.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + DATE_FIELD_NUMBER: builtins.int + IS_TRADING_DAY_FIELD_NUMBER: builtins.int + START_TIME_FIELD_NUMBER: builtins.int + END_TIME_FIELD_NUMBER: builtins.int + OPENING_AUCTION_START_TIME_FIELD_NUMBER: builtins.int + CLOSING_AUCTION_END_TIME_FIELD_NUMBER: builtins.int + EVENING_OPENING_AUCTION_START_TIME_FIELD_NUMBER: builtins.int + EVENING_START_TIME_FIELD_NUMBER: builtins.int + EVENING_END_TIME_FIELD_NUMBER: builtins.int + CLEARING_START_TIME_FIELD_NUMBER: builtins.int + CLEARING_END_TIME_FIELD_NUMBER: builtins.int + PREMARKET_START_TIME_FIELD_NUMBER: builtins.int + PREMARKET_END_TIME_FIELD_NUMBER: builtins.int + CLOSING_AUCTION_START_TIME_FIELD_NUMBER: builtins.int + OPENING_AUCTION_END_TIME_FIELD_NUMBER: builtins.int + INTERVALS_FIELD_NUMBER: builtins.int + is_trading_day: builtins.bool + """Признак торгового дня на бирже.""" + @property + def date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата.""" + + @property + def start_time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время начала торгов по UTC.""" + + @property + def end_time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время окончания торгов по UTC.""" + + @property + def opening_auction_start_time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время начала аукциона открытия по UTC.""" + + @property + def closing_auction_end_time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время окончания аукциона закрытия по UTC.""" + + @property + def evening_opening_auction_start_time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время начала аукциона открытия вечерней сессии по UTC.""" + + @property + def evening_start_time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время начала вечерней сессии по UTC.""" + + @property + def evening_end_time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время окончания вечерней сессии по UTC.""" + + @property + def clearing_start_time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время начала основного клиринга по UTC.""" + + @property + def clearing_end_time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время окончания основного клиринга по UTC.""" + + @property + def premarket_start_time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время начала премаркета по UTC.""" + + @property + def premarket_end_time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время окончания премаркета по UTC.""" + + @property + def closing_auction_start_time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время начала аукциона закрытия по UTC.""" + + @property + def opening_auction_end_time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время окончания аукциона открытия по UTC.""" + + @property + def intervals(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___TradingInterval]: + """Торговые интервалы.""" + + def __init__( + self, + *, + date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + is_trading_day: builtins.bool = ..., + start_time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + end_time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + opening_auction_start_time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + closing_auction_end_time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + evening_opening_auction_start_time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + evening_start_time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + evening_end_time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + clearing_start_time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + clearing_end_time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + premarket_start_time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + premarket_end_time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + closing_auction_start_time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + opening_auction_end_time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + intervals: collections.abc.Iterable[global___TradingInterval] | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["clearing_end_time", b"clearing_end_time", "clearing_start_time", b"clearing_start_time", "closing_auction_end_time", b"closing_auction_end_time", "closing_auction_start_time", b"closing_auction_start_time", "date", b"date", "end_time", b"end_time", "evening_end_time", b"evening_end_time", "evening_opening_auction_start_time", b"evening_opening_auction_start_time", "evening_start_time", b"evening_start_time", "opening_auction_end_time", b"opening_auction_end_time", "opening_auction_start_time", b"opening_auction_start_time", "premarket_end_time", b"premarket_end_time", "premarket_start_time", b"premarket_start_time", "start_time", b"start_time"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["clearing_end_time", b"clearing_end_time", "clearing_start_time", b"clearing_start_time", "closing_auction_end_time", b"closing_auction_end_time", "closing_auction_start_time", b"closing_auction_start_time", "date", b"date", "end_time", b"end_time", "evening_end_time", b"evening_end_time", "evening_opening_auction_start_time", b"evening_opening_auction_start_time", "evening_start_time", b"evening_start_time", "intervals", b"intervals", "is_trading_day", b"is_trading_day", "opening_auction_end_time", b"opening_auction_end_time", "opening_auction_start_time", b"opening_auction_start_time", "premarket_end_time", b"premarket_end_time", "premarket_start_time", b"premarket_start_time", "start_time", b"start_time"]) -> None: ... + +global___TradingDay = TradingDay + +@typing.final +class InstrumentRequest(google.protobuf.message.Message): + """Запрос получения инструмента по идентификатору.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ID_TYPE_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + ID_FIELD_NUMBER: builtins.int + id_type: global___InstrumentIdType.ValueType + """Тип идентификатора инструмента. Возможные значения — `figi`, `ticker`. [Подробнее об идентификации инструментов](/invest/intro/intro/faq_identification).""" + class_code: builtins.str + """Идентификатор `class_code`. Обязательный, если `id_type = ticker`.""" + id: builtins.str + """Идентификатор запрашиваемого инструмента.""" + def __init__( + self, + *, + id_type: global___InstrumentIdType.ValueType = ..., + class_code: builtins.str | None = ..., + id: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_class_code", b"_class_code", "class_code", b"class_code"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_class_code", b"_class_code", "class_code", b"class_code", "id", b"id", "id_type", b"id_type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_class_code", b"_class_code"]) -> typing.Literal["class_code"] | None: ... + +global___InstrumentRequest = InstrumentRequest + +@typing.final +class InstrumentsRequest(google.protobuf.message.Message): + """Запрос получения инструментов.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENT_STATUS_FIELD_NUMBER: builtins.int + INSTRUMENT_EXCHANGE_FIELD_NUMBER: builtins.int + instrument_status: t_tech.invest.grpc.common_pb2.InstrumentStatus.ValueType + """Статус запрашиваемых инструментов. [Возможные значения](#instrumentstatus).""" + instrument_exchange: global___InstrumentExchangeType.ValueType + """Тип площадки торговли. [Возможные значения](#instrumentexchangetype).""" + def __init__( + self, + *, + instrument_status: t_tech.invest.grpc.common_pb2.InstrumentStatus.ValueType | None = ..., + instrument_exchange: global___InstrumentExchangeType.ValueType | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_instrument_exchange", b"_instrument_exchange", "_instrument_status", b"_instrument_status", "instrument_exchange", b"instrument_exchange", "instrument_status", b"instrument_status"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_instrument_exchange", b"_instrument_exchange", "_instrument_status", b"_instrument_status", "instrument_exchange", b"instrument_exchange", "instrument_status", b"instrument_status"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_instrument_exchange", b"_instrument_exchange"]) -> typing.Literal["instrument_exchange"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_instrument_status", b"_instrument_status"]) -> typing.Literal["instrument_status"] | None: ... + +global___InstrumentsRequest = InstrumentsRequest + +@typing.final +class FilterOptionsRequest(google.protobuf.message.Message): + """Параметры фильтрации опционов.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + BASIC_ASSET_UID_FIELD_NUMBER: builtins.int + BASIC_ASSET_POSITION_UID_FIELD_NUMBER: builtins.int + BASIC_INSTRUMENT_ID_FIELD_NUMBER: builtins.int + basic_asset_uid: builtins.str + """Идентификатор базового актива опциона. Обязательный параметр.""" + basic_asset_position_uid: builtins.str + """Идентификатор позиции базового актива опциона.""" + basic_instrument_id: builtins.str + """Идентификатор базового инструмента, принимает значение принимает значения figi, instrument_uid или ticker+"_"+classCode.""" + def __init__( + self, + *, + basic_asset_uid: builtins.str | None = ..., + basic_asset_position_uid: builtins.str | None = ..., + basic_instrument_id: builtins.str | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_basic_asset_position_uid", b"_basic_asset_position_uid", "_basic_asset_uid", b"_basic_asset_uid", "_basic_instrument_id", b"_basic_instrument_id", "basic_asset_position_uid", b"basic_asset_position_uid", "basic_asset_uid", b"basic_asset_uid", "basic_instrument_id", b"basic_instrument_id"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_basic_asset_position_uid", b"_basic_asset_position_uid", "_basic_asset_uid", b"_basic_asset_uid", "_basic_instrument_id", b"_basic_instrument_id", "basic_asset_position_uid", b"basic_asset_position_uid", "basic_asset_uid", b"basic_asset_uid", "basic_instrument_id", b"basic_instrument_id"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_basic_asset_position_uid", b"_basic_asset_position_uid"]) -> typing.Literal["basic_asset_position_uid"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_basic_asset_uid", b"_basic_asset_uid"]) -> typing.Literal["basic_asset_uid"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_basic_instrument_id", b"_basic_instrument_id"]) -> typing.Literal["basic_instrument_id"] | None: ... + +global___FilterOptionsRequest = FilterOptionsRequest + +@typing.final +class BondResponse(google.protobuf.message.Message): + """Информация об облигации.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENT_FIELD_NUMBER: builtins.int + @property + def instrument(self) -> global___Bond: + """Информация об облигации.""" + + def __init__( + self, + *, + instrument: global___Bond | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["instrument", b"instrument"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["instrument", b"instrument"]) -> None: ... + +global___BondResponse = BondResponse + +@typing.final +class BondsResponse(google.protobuf.message.Message): + """Список облигаций.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENTS_FIELD_NUMBER: builtins.int + @property + def instruments(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Bond]: + """Массив облигаций.""" + + def __init__( + self, + *, + instruments: collections.abc.Iterable[global___Bond] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["instruments", b"instruments"]) -> None: ... + +global___BondsResponse = BondsResponse + +@typing.final +class GetBondCouponsRequest(google.protobuf.message.Message): + """Запрос купонов по облигации.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + FROM_FIELD_NUMBER: builtins.int + TO_FIELD_NUMBER: builtins.int + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI-идентификатор инструмента.""" + instrument_id: builtins.str + """Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`.""" + @property + def to(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Окончание запрашиваемого периода по UTC. Фильтрация по `coupon_date` — дата выплаты купона.""" + + def __init__( + self, + *, + figi: builtins.str = ..., + to: google.protobuf.timestamp_pb2.Timestamp | None = ..., + instrument_id: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_from", b"_from", "_to", b"_to", "from", b"from", "to", b"to"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_from", b"_from", "_to", b"_to", "figi", b"figi", "from", b"from", "instrument_id", b"instrument_id", "to", b"to"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_from", b"_from"]) -> typing.Literal["from"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_to", b"_to"]) -> typing.Literal["to"] | None: ... + +global___GetBondCouponsRequest = GetBondCouponsRequest + +@typing.final +class GetBondCouponsResponse(google.protobuf.message.Message): + """Купоны по облигации.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + EVENTS_FIELD_NUMBER: builtins.int + @property + def events(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Coupon]: ... + def __init__( + self, + *, + events: collections.abc.Iterable[global___Coupon] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["events", b"events"]) -> None: ... + +global___GetBondCouponsResponse = GetBondCouponsResponse + +@typing.final +class GetBondEventsRequest(google.protobuf.message.Message): + """События по облигации.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _EventType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _EventTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[GetBondEventsRequest._EventType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + EVENT_TYPE_UNSPECIFIED: GetBondEventsRequest._EventType.ValueType # 0 + """Неопределенное значение.""" + EVENT_TYPE_CPN: GetBondEventsRequest._EventType.ValueType # 1 + """Купон.""" + EVENT_TYPE_CALL: GetBondEventsRequest._EventType.ValueType # 2 + """Опцион (оферта).""" + EVENT_TYPE_MTY: GetBondEventsRequest._EventType.ValueType # 3 + """Погашение.""" + EVENT_TYPE_CONV: GetBondEventsRequest._EventType.ValueType # 4 + """Конвертация.""" + + class EventType(_EventType, metaclass=_EventTypeEnumTypeWrapper): ... + EVENT_TYPE_UNSPECIFIED: GetBondEventsRequest.EventType.ValueType # 0 + """Неопределенное значение.""" + EVENT_TYPE_CPN: GetBondEventsRequest.EventType.ValueType # 1 + """Купон.""" + EVENT_TYPE_CALL: GetBondEventsRequest.EventType.ValueType # 2 + """Опцион (оферта).""" + EVENT_TYPE_MTY: GetBondEventsRequest.EventType.ValueType # 3 + """Погашение.""" + EVENT_TYPE_CONV: GetBondEventsRequest.EventType.ValueType # 4 + """Конвертация.""" + + FROM_FIELD_NUMBER: builtins.int + TO_FIELD_NUMBER: builtins.int + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + TYPE_FIELD_NUMBER: builtins.int + instrument_id: builtins.str + """Идентификатор инструмента — `figi` или `instrument_uid`.""" + type: global___GetBondEventsRequest.EventType.ValueType + """Тип события""" + @property + def to(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Окончание запрашиваемого периода по UTC.""" + + def __init__( + self, + *, + to: google.protobuf.timestamp_pb2.Timestamp | None = ..., + instrument_id: builtins.str = ..., + type: global___GetBondEventsRequest.EventType.ValueType = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_from", b"_from", "_to", b"_to", "from", b"from", "to", b"to"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_from", b"_from", "_to", b"_to", "from", b"from", "instrument_id", b"instrument_id", "to", b"to", "type", b"type"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_from", b"_from"]) -> typing.Literal["from"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_to", b"_to"]) -> typing.Literal["to"] | None: ... + +global___GetBondEventsRequest = GetBondEventsRequest + +@typing.final +class GetBondEventsResponse(google.protobuf.message.Message): + """Объект передачи информации о событии облигации.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing.final + class BondEvent(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + EVENT_NUMBER_FIELD_NUMBER: builtins.int + EVENT_DATE_FIELD_NUMBER: builtins.int + EVENT_TYPE_FIELD_NUMBER: builtins.int + EVENT_TOTAL_VOL_FIELD_NUMBER: builtins.int + FIX_DATE_FIELD_NUMBER: builtins.int + RATE_DATE_FIELD_NUMBER: builtins.int + DEFAULT_DATE_FIELD_NUMBER: builtins.int + REAL_PAY_DATE_FIELD_NUMBER: builtins.int + PAY_DATE_FIELD_NUMBER: builtins.int + PAY_ONE_BOND_FIELD_NUMBER: builtins.int + MONEY_FLOW_VAL_FIELD_NUMBER: builtins.int + EXECUTION_FIELD_NUMBER: builtins.int + OPERATION_TYPE_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + NOTE_FIELD_NUMBER: builtins.int + CONVERT_TO_FIN_TOOL_ID_FIELD_NUMBER: builtins.int + COUPON_START_DATE_FIELD_NUMBER: builtins.int + COUPON_END_DATE_FIELD_NUMBER: builtins.int + COUPON_PERIOD_FIELD_NUMBER: builtins.int + COUPON_INTEREST_RATE_FIELD_NUMBER: builtins.int + instrument_id: builtins.str + """Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`.""" + event_number: builtins.int + """Номер события для данного типа события.""" + event_type: global___GetBondEventsRequest.EventType.ValueType + """Тип события.""" + execution: builtins.str + """Признак исполнения.""" + operation_type: builtins.str + """Тип операции.""" + note: builtins.str + """Примечание.""" + convert_to_fin_tool_id: builtins.str + """ID выпуска бумаг, в который произведена конвертация (для конвертаций).""" + coupon_period: builtins.int + """Купонный период.""" + @property + def event_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата события.""" + + @property + def event_total_vol(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Полное количество бумаг, задействованных в событии.""" + + @property + def fix_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата фиксации владельцев для участия в событии.""" + + @property + def rate_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата определения даты или факта события.""" + + @property + def default_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата дефолта, если применимо.""" + + @property + def real_pay_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата реального исполнения обязательства.""" + + @property + def pay_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата выплаты.""" + + @property + def pay_one_bond(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Выплата на одну облигацию.""" + + @property + def money_flow_val(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Выплаты на все бумаги, задействованные в событии.""" + + @property + def value(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Стоимость операции — ставка купона, доля номинала, цена выкупа или коэффициент конвертации.""" + + @property + def coupon_start_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Начало купонного периода.""" + + @property + def coupon_end_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Окончание купонного периода.""" + + @property + def coupon_interest_rate(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка купона, процентов годовых.""" + + def __init__( + self, + *, + instrument_id: builtins.str = ..., + event_number: builtins.int = ..., + event_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + event_type: global___GetBondEventsRequest.EventType.ValueType = ..., + event_total_vol: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + fix_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + rate_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + default_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + real_pay_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + pay_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + pay_one_bond: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + money_flow_val: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + execution: builtins.str = ..., + operation_type: builtins.str = ..., + value: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + note: builtins.str = ..., + convert_to_fin_tool_id: builtins.str = ..., + coupon_start_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + coupon_end_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + coupon_period: builtins.int = ..., + coupon_interest_rate: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["coupon_end_date", b"coupon_end_date", "coupon_interest_rate", b"coupon_interest_rate", "coupon_start_date", b"coupon_start_date", "default_date", b"default_date", "event_date", b"event_date", "event_total_vol", b"event_total_vol", "fix_date", b"fix_date", "money_flow_val", b"money_flow_val", "pay_date", b"pay_date", "pay_one_bond", b"pay_one_bond", "rate_date", b"rate_date", "real_pay_date", b"real_pay_date", "value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["convert_to_fin_tool_id", b"convert_to_fin_tool_id", "coupon_end_date", b"coupon_end_date", "coupon_interest_rate", b"coupon_interest_rate", "coupon_period", b"coupon_period", "coupon_start_date", b"coupon_start_date", "default_date", b"default_date", "event_date", b"event_date", "event_number", b"event_number", "event_total_vol", b"event_total_vol", "event_type", b"event_type", "execution", b"execution", "fix_date", b"fix_date", "instrument_id", b"instrument_id", "money_flow_val", b"money_flow_val", "note", b"note", "operation_type", b"operation_type", "pay_date", b"pay_date", "pay_one_bond", b"pay_one_bond", "rate_date", b"rate_date", "real_pay_date", b"real_pay_date", "value", b"value"]) -> None: ... + + EVENTS_FIELD_NUMBER: builtins.int + @property + def events(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___GetBondEventsResponse.BondEvent]: ... + def __init__( + self, + *, + events: collections.abc.Iterable[global___GetBondEventsResponse.BondEvent] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["events", b"events"]) -> None: ... + +global___GetBondEventsResponse = GetBondEventsResponse + +@typing.final +class Coupon(google.protobuf.message.Message): + """Объект передачи информации о купоне облигации.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + COUPON_DATE_FIELD_NUMBER: builtins.int + COUPON_NUMBER_FIELD_NUMBER: builtins.int + FIX_DATE_FIELD_NUMBER: builtins.int + PAY_ONE_BOND_FIELD_NUMBER: builtins.int + COUPON_TYPE_FIELD_NUMBER: builtins.int + COUPON_START_DATE_FIELD_NUMBER: builtins.int + COUPON_END_DATE_FIELD_NUMBER: builtins.int + COUPON_PERIOD_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI-идентификатор инструмента.""" + coupon_number: builtins.int + """Номер купона.""" + coupon_type: global___CouponType.ValueType + """Тип купона.""" + coupon_period: builtins.int + """Купонный период в днях.""" + @property + def coupon_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата выплаты купона.""" + + @property + def fix_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата фиксации реестра для выплаты купона — опционально.""" + + @property + def pay_one_bond(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Выплата на одну облигацию.""" + + @property + def coupon_start_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Начало купонного периода.""" + + @property + def coupon_end_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Окончание купонного периода.""" + + def __init__( + self, + *, + figi: builtins.str = ..., + coupon_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + coupon_number: builtins.int = ..., + fix_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + pay_one_bond: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + coupon_type: global___CouponType.ValueType = ..., + coupon_start_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + coupon_end_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + coupon_period: builtins.int = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["coupon_date", b"coupon_date", "coupon_end_date", b"coupon_end_date", "coupon_start_date", b"coupon_start_date", "fix_date", b"fix_date", "pay_one_bond", b"pay_one_bond"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["coupon_date", b"coupon_date", "coupon_end_date", b"coupon_end_date", "coupon_number", b"coupon_number", "coupon_period", b"coupon_period", "coupon_start_date", b"coupon_start_date", "coupon_type", b"coupon_type", "figi", b"figi", "fix_date", b"fix_date", "pay_one_bond", b"pay_one_bond"]) -> None: ... + +global___Coupon = Coupon + +@typing.final +class CurrencyResponse(google.protobuf.message.Message): + """Данные по валюте.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENT_FIELD_NUMBER: builtins.int + @property + def instrument(self) -> global___Currency: + """Информация о валюте.""" + + def __init__( + self, + *, + instrument: global___Currency | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["instrument", b"instrument"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["instrument", b"instrument"]) -> None: ... + +global___CurrencyResponse = CurrencyResponse + +@typing.final +class CurrenciesResponse(google.protobuf.message.Message): + """Данные по валютам.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENTS_FIELD_NUMBER: builtins.int + @property + def instruments(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Currency]: + """Массив валют.""" + + def __init__( + self, + *, + instruments: collections.abc.Iterable[global___Currency] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["instruments", b"instruments"]) -> None: ... + +global___CurrenciesResponse = CurrenciesResponse + +@typing.final +class EtfResponse(google.protobuf.message.Message): + """Данные по фонду.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENT_FIELD_NUMBER: builtins.int + @property + def instrument(self) -> global___Etf: + """Информация о фонде.""" + + def __init__( + self, + *, + instrument: global___Etf | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["instrument", b"instrument"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["instrument", b"instrument"]) -> None: ... + +global___EtfResponse = EtfResponse + +@typing.final +class EtfsResponse(google.protobuf.message.Message): + """Данные по фондам.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENTS_FIELD_NUMBER: builtins.int + @property + def instruments(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Etf]: + """Массив фондов.""" + + def __init__( + self, + *, + instruments: collections.abc.Iterable[global___Etf] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["instruments", b"instruments"]) -> None: ... + +global___EtfsResponse = EtfsResponse + +@typing.final +class FutureResponse(google.protobuf.message.Message): + """Данные по фьючерсу.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENT_FIELD_NUMBER: builtins.int + @property + def instrument(self) -> global___Future: + """Информация о фьючерсу.""" + + def __init__( + self, + *, + instrument: global___Future | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["instrument", b"instrument"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["instrument", b"instrument"]) -> None: ... + +global___FutureResponse = FutureResponse + +@typing.final +class FuturesResponse(google.protobuf.message.Message): + """Данные по фьючерсам.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENTS_FIELD_NUMBER: builtins.int + @property + def instruments(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Future]: + """Массив фьючерсов.""" + + def __init__( + self, + *, + instruments: collections.abc.Iterable[global___Future] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["instruments", b"instruments"]) -> None: ... + +global___FuturesResponse = FuturesResponse + +@typing.final +class OptionResponse(google.protobuf.message.Message): + """Данные по опциону.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENT_FIELD_NUMBER: builtins.int + @property + def instrument(self) -> global___Option: + """Информация по опциону.""" + + def __init__( + self, + *, + instrument: global___Option | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["instrument", b"instrument"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["instrument", b"instrument"]) -> None: ... + +global___OptionResponse = OptionResponse + +@typing.final +class OptionsResponse(google.protobuf.message.Message): + """Данные по опционам.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENTS_FIELD_NUMBER: builtins.int + @property + def instruments(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Option]: + """Массив данных по опциону.""" + + def __init__( + self, + *, + instruments: collections.abc.Iterable[global___Option] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["instruments", b"instruments"]) -> None: ... + +global___OptionsResponse = OptionsResponse + +@typing.final +class Option(google.protobuf.message.Message): + """Опцион.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + UID_FIELD_NUMBER: builtins.int + POSITION_UID_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + BASIC_ASSET_POSITION_UID_FIELD_NUMBER: builtins.int + TRADING_STATUS_FIELD_NUMBER: builtins.int + REAL_EXCHANGE_FIELD_NUMBER: builtins.int + DIRECTION_FIELD_NUMBER: builtins.int + PAYMENT_TYPE_FIELD_NUMBER: builtins.int + STYLE_FIELD_NUMBER: builtins.int + SETTLEMENT_TYPE_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + CURRENCY_FIELD_NUMBER: builtins.int + SETTLEMENT_CURRENCY_FIELD_NUMBER: builtins.int + ASSET_TYPE_FIELD_NUMBER: builtins.int + BASIC_ASSET_FIELD_NUMBER: builtins.int + EXCHANGE_FIELD_NUMBER: builtins.int + COUNTRY_OF_RISK_FIELD_NUMBER: builtins.int + COUNTRY_OF_RISK_NAME_FIELD_NUMBER: builtins.int + SECTOR_FIELD_NUMBER: builtins.int + BRAND_FIELD_NUMBER: builtins.int + LOT_FIELD_NUMBER: builtins.int + BASIC_ASSET_SIZE_FIELD_NUMBER: builtins.int + KLONG_FIELD_NUMBER: builtins.int + KSHORT_FIELD_NUMBER: builtins.int + DLONG_FIELD_NUMBER: builtins.int + DSHORT_FIELD_NUMBER: builtins.int + DLONG_MIN_FIELD_NUMBER: builtins.int + DSHORT_MIN_FIELD_NUMBER: builtins.int + MIN_PRICE_INCREMENT_FIELD_NUMBER: builtins.int + STRIKE_PRICE_FIELD_NUMBER: builtins.int + DLONG_CLIENT_FIELD_NUMBER: builtins.int + DSHORT_CLIENT_FIELD_NUMBER: builtins.int + EXPIRATION_DATE_FIELD_NUMBER: builtins.int + FIRST_TRADE_DATE_FIELD_NUMBER: builtins.int + LAST_TRADE_DATE_FIELD_NUMBER: builtins.int + FIRST_1MIN_CANDLE_DATE_FIELD_NUMBER: builtins.int + FIRST_1DAY_CANDLE_DATE_FIELD_NUMBER: builtins.int + SHORT_ENABLED_FLAG_FIELD_NUMBER: builtins.int + FOR_IIS_FLAG_FIELD_NUMBER: builtins.int + OTC_FLAG_FIELD_NUMBER: builtins.int + BUY_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + SELL_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + FOR_QUAL_INVESTOR_FLAG_FIELD_NUMBER: builtins.int + WEEKEND_FLAG_FIELD_NUMBER: builtins.int + BLOCKED_TCA_FLAG_FIELD_NUMBER: builtins.int + API_TRADE_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + REQUIRED_TESTS_FIELD_NUMBER: builtins.int + uid: builtins.str + """Уникальный идентификатор инструмента.""" + position_uid: builtins.str + """Уникальный идентификатор позиции.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код.""" + basic_asset_position_uid: builtins.str + """Уникальный идентификатор позиции основного инструмента.""" + trading_status: t_tech.invest.grpc.common_pb2.SecurityTradingStatus.ValueType + """Текущий режим торгов инструмента.""" + real_exchange: t_tech.invest.grpc.common_pb2.RealExchange.ValueType + """Реальная площадка исполнения расчетов (биржа).""" + direction: global___OptionDirection.ValueType + """Направление опциона.""" + payment_type: global___OptionPaymentType.ValueType + """Тип расчетов по опциону.""" + style: global___OptionStyle.ValueType + """Стиль опциона.""" + settlement_type: global___OptionSettlementType.ValueType + """Способ исполнения опциона.""" + name: builtins.str + """Название инструмента.""" + currency: builtins.str + """Валюта.""" + settlement_currency: builtins.str + """Валюта, в которой оценивается контракт.""" + asset_type: builtins.str + """Тип актива.""" + basic_asset: builtins.str + """Основной актив.""" + exchange: builtins.str + """Tорговая площадка (секция биржи).""" + country_of_risk: builtins.str + """Код страны рисков.""" + country_of_risk_name: builtins.str + """Наименование страны рисков.""" + sector: builtins.str + """Сектор экономики.""" + lot: builtins.int + """Количество бумаг в лоте.""" + short_enabled_flag: builtins.bool + """Признак доступности для операций шорт.""" + for_iis_flag: builtins.bool + """Возможность покупки или продажи на ИИС.""" + otc_flag: builtins.bool + """Флаг, используемый ранее для определения внебиржевых инструментов. На данный момент не используется для торгуемых через API инструментов. Может использоваться как фильтр для операций, совершавшихся некоторое время назад на ОТС площадке.""" + buy_available_flag: builtins.bool + """Признак доступности для покупки.""" + sell_available_flag: builtins.bool + """Признак доступности для продажи.""" + for_qual_investor_flag: builtins.bool + """Флаг, отображающий доступность торговли инструментом только для квалифицированных инвесторов.""" + weekend_flag: builtins.bool + """Флаг, отображающий доступность торговли инструментом по выходным.""" + blocked_tca_flag: builtins.bool + """Флаг заблокированного ТКС.""" + api_trade_available_flag: builtins.bool + """Возможность торговать инструментом через API.""" + @property + def brand(self) -> t_tech.invest.grpc.common_pb2.BrandData: + """Информация о бренде.""" + + @property + def basic_asset_size(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Размер основного актива.""" + + @property + def klong(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Коэффициент ставки риска длинной позиции по клиенту. 2 – клиент со стандартным уровнем риска (КСУР); 1 – клиент с повышенным уровнем риска (КПУР).""" + + @property + def kshort(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Коэффициент ставки риска короткой позиции по клиенту. 2 – клиент со стандартным уровнем риска (КСУР); 1 – клиент с повышенным уровнем риска (КПУР).""" + + @property + def dlong(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска начальной маржи для КСУР лонг. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def dshort(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска начальной маржи для КСУР шорт. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def dlong_min(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска начальной маржи для КПУР лонг. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def dshort_min(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска начальной маржи для КПУР шорт. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def min_price_increment(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Минимальный шаг цены.""" + + @property + def strike_price(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Цена страйка.""" + + @property + def dlong_client(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска в лонг с учетом текущего уровня риска портфеля клиента. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def dshort_client(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска в шорт с учетом текущего уровня риска портфеля клиента. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def expiration_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата истечения срока в формате UTC.""" + + @property + def first_trade_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата начала обращения контракта в формате UTC.""" + + @property + def last_trade_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата исполнения в формате UTC.""" + + @property + def first_1min_candle_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата первой минутной свечи в формате UTC.""" + + @property + def first_1day_candle_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата первой дневной свечи в формате UTC.""" + + @property + def required_tests(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Тесты, которые необходимо пройти клиенту, чтобы совершать сделки по инструменту.""" + + def __init__( + self, + *, + uid: builtins.str = ..., + position_uid: builtins.str = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + basic_asset_position_uid: builtins.str = ..., + trading_status: t_tech.invest.grpc.common_pb2.SecurityTradingStatus.ValueType = ..., + real_exchange: t_tech.invest.grpc.common_pb2.RealExchange.ValueType = ..., + direction: global___OptionDirection.ValueType = ..., + payment_type: global___OptionPaymentType.ValueType = ..., + style: global___OptionStyle.ValueType = ..., + settlement_type: global___OptionSettlementType.ValueType = ..., + name: builtins.str = ..., + currency: builtins.str = ..., + settlement_currency: builtins.str = ..., + asset_type: builtins.str = ..., + basic_asset: builtins.str = ..., + exchange: builtins.str = ..., + country_of_risk: builtins.str = ..., + country_of_risk_name: builtins.str = ..., + sector: builtins.str = ..., + brand: t_tech.invest.grpc.common_pb2.BrandData | None = ..., + lot: builtins.int = ..., + basic_asset_size: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + klong: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + kshort: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dlong: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dshort: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dlong_min: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dshort_min: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + min_price_increment: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + strike_price: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + dlong_client: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dshort_client: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + expiration_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + first_trade_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + last_trade_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + first_1min_candle_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + first_1day_candle_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + short_enabled_flag: builtins.bool = ..., + for_iis_flag: builtins.bool = ..., + otc_flag: builtins.bool = ..., + buy_available_flag: builtins.bool = ..., + sell_available_flag: builtins.bool = ..., + for_qual_investor_flag: builtins.bool = ..., + weekend_flag: builtins.bool = ..., + blocked_tca_flag: builtins.bool = ..., + api_trade_available_flag: builtins.bool = ..., + required_tests: collections.abc.Iterable[builtins.str] | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["basic_asset_size", b"basic_asset_size", "brand", b"brand", "dlong", b"dlong", "dlong_client", b"dlong_client", "dlong_min", b"dlong_min", "dshort", b"dshort", "dshort_client", b"dshort_client", "dshort_min", b"dshort_min", "expiration_date", b"expiration_date", "first_1day_candle_date", b"first_1day_candle_date", "first_1min_candle_date", b"first_1min_candle_date", "first_trade_date", b"first_trade_date", "klong", b"klong", "kshort", b"kshort", "last_trade_date", b"last_trade_date", "min_price_increment", b"min_price_increment", "strike_price", b"strike_price"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["api_trade_available_flag", b"api_trade_available_flag", "asset_type", b"asset_type", "basic_asset", b"basic_asset", "basic_asset_position_uid", b"basic_asset_position_uid", "basic_asset_size", b"basic_asset_size", "blocked_tca_flag", b"blocked_tca_flag", "brand", b"brand", "buy_available_flag", b"buy_available_flag", "class_code", b"class_code", "country_of_risk", b"country_of_risk", "country_of_risk_name", b"country_of_risk_name", "currency", b"currency", "direction", b"direction", "dlong", b"dlong", "dlong_client", b"dlong_client", "dlong_min", b"dlong_min", "dshort", b"dshort", "dshort_client", b"dshort_client", "dshort_min", b"dshort_min", "exchange", b"exchange", "expiration_date", b"expiration_date", "first_1day_candle_date", b"first_1day_candle_date", "first_1min_candle_date", b"first_1min_candle_date", "first_trade_date", b"first_trade_date", "for_iis_flag", b"for_iis_flag", "for_qual_investor_flag", b"for_qual_investor_flag", "klong", b"klong", "kshort", b"kshort", "last_trade_date", b"last_trade_date", "lot", b"lot", "min_price_increment", b"min_price_increment", "name", b"name", "otc_flag", b"otc_flag", "payment_type", b"payment_type", "position_uid", b"position_uid", "real_exchange", b"real_exchange", "required_tests", b"required_tests", "sector", b"sector", "sell_available_flag", b"sell_available_flag", "settlement_currency", b"settlement_currency", "settlement_type", b"settlement_type", "short_enabled_flag", b"short_enabled_flag", "strike_price", b"strike_price", "style", b"style", "ticker", b"ticker", "trading_status", b"trading_status", "uid", b"uid", "weekend_flag", b"weekend_flag"]) -> None: ... + +global___Option = Option + +@typing.final +class ShareResponse(google.protobuf.message.Message): + """Данные по акции.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENT_FIELD_NUMBER: builtins.int + @property + def instrument(self) -> global___Share: + """Информация об акции.""" + + def __init__( + self, + *, + instrument: global___Share | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["instrument", b"instrument"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["instrument", b"instrument"]) -> None: ... + +global___ShareResponse = ShareResponse + +@typing.final +class SharesResponse(google.protobuf.message.Message): + """Данные по акциям.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENTS_FIELD_NUMBER: builtins.int + @property + def instruments(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Share]: + """Массив акций.""" + + def __init__( + self, + *, + instruments: collections.abc.Iterable[global___Share] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["instruments", b"instruments"]) -> None: ... + +global___SharesResponse = SharesResponse + +@typing.final +class StructuredNoteResponse(google.protobuf.message.Message): + """Данные по структурной ноте.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENT_FIELD_NUMBER: builtins.int + @property + def instrument(self) -> global___StructuredNote: + """Информация о структурной ноте.""" + + def __init__( + self, + *, + instrument: global___StructuredNote | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["instrument", b"instrument"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["instrument", b"instrument"]) -> None: ... + +global___StructuredNoteResponse = StructuredNoteResponse + +@typing.final +class StructuredNotesResponse(google.protobuf.message.Message): + """Данные по структурным нотам.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENTS_FIELD_NUMBER: builtins.int + @property + def instruments(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___StructuredNote]: + """Массив структурных нот.""" + + def __init__( + self, + *, + instruments: collections.abc.Iterable[global___StructuredNote] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["instruments", b"instruments"]) -> None: ... + +global___StructuredNotesResponse = StructuredNotesResponse + +@typing.final +class Bond(google.protobuf.message.Message): + """Объект передачи информации об облигации.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + ISIN_FIELD_NUMBER: builtins.int + LOT_FIELD_NUMBER: builtins.int + CURRENCY_FIELD_NUMBER: builtins.int + KLONG_FIELD_NUMBER: builtins.int + KSHORT_FIELD_NUMBER: builtins.int + DLONG_FIELD_NUMBER: builtins.int + DSHORT_FIELD_NUMBER: builtins.int + DLONG_MIN_FIELD_NUMBER: builtins.int + DSHORT_MIN_FIELD_NUMBER: builtins.int + SHORT_ENABLED_FLAG_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + EXCHANGE_FIELD_NUMBER: builtins.int + COUPON_QUANTITY_PER_YEAR_FIELD_NUMBER: builtins.int + MATURITY_DATE_FIELD_NUMBER: builtins.int + NOMINAL_FIELD_NUMBER: builtins.int + INITIAL_NOMINAL_FIELD_NUMBER: builtins.int + STATE_REG_DATE_FIELD_NUMBER: builtins.int + PLACEMENT_DATE_FIELD_NUMBER: builtins.int + PLACEMENT_PRICE_FIELD_NUMBER: builtins.int + ACI_VALUE_FIELD_NUMBER: builtins.int + COUNTRY_OF_RISK_FIELD_NUMBER: builtins.int + COUNTRY_OF_RISK_NAME_FIELD_NUMBER: builtins.int + SECTOR_FIELD_NUMBER: builtins.int + ISSUE_KIND_FIELD_NUMBER: builtins.int + ISSUE_SIZE_FIELD_NUMBER: builtins.int + ISSUE_SIZE_PLAN_FIELD_NUMBER: builtins.int + TRADING_STATUS_FIELD_NUMBER: builtins.int + OTC_FLAG_FIELD_NUMBER: builtins.int + BUY_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + SELL_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + FLOATING_COUPON_FLAG_FIELD_NUMBER: builtins.int + PERPETUAL_FLAG_FIELD_NUMBER: builtins.int + AMORTIZATION_FLAG_FIELD_NUMBER: builtins.int + MIN_PRICE_INCREMENT_FIELD_NUMBER: builtins.int + API_TRADE_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + UID_FIELD_NUMBER: builtins.int + REAL_EXCHANGE_FIELD_NUMBER: builtins.int + POSITION_UID_FIELD_NUMBER: builtins.int + ASSET_UID_FIELD_NUMBER: builtins.int + REQUIRED_TESTS_FIELD_NUMBER: builtins.int + FOR_IIS_FLAG_FIELD_NUMBER: builtins.int + FOR_QUAL_INVESTOR_FLAG_FIELD_NUMBER: builtins.int + WEEKEND_FLAG_FIELD_NUMBER: builtins.int + BLOCKED_TCA_FLAG_FIELD_NUMBER: builtins.int + SUBORDINATED_FLAG_FIELD_NUMBER: builtins.int + LIQUIDITY_FLAG_FIELD_NUMBER: builtins.int + FIRST_1MIN_CANDLE_DATE_FIELD_NUMBER: builtins.int + FIRST_1DAY_CANDLE_DATE_FIELD_NUMBER: builtins.int + RISK_LEVEL_FIELD_NUMBER: builtins.int + BRAND_FIELD_NUMBER: builtins.int + BOND_TYPE_FIELD_NUMBER: builtins.int + CALL_DATE_FIELD_NUMBER: builtins.int + DLONG_CLIENT_FIELD_NUMBER: builtins.int + DSHORT_CLIENT_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI-идентификатор инструмента.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + isin: builtins.str + """ISIN-идентификатор инструмента.""" + lot: builtins.int + """Лотность инструмента. Возможно совершение операций только на количества ценной бумаги, кратные параметру `lot`. [Подробнее](./glossary#lot).""" + currency: builtins.str + """Валюта расчетов.""" + short_enabled_flag: builtins.bool + """Признак доступности для операций в шорт.""" + name: builtins.str + """Название инструмента.""" + exchange: builtins.str + """Tорговая площадка (секция биржи).""" + coupon_quantity_per_year: builtins.int + """Количество выплат по купонам в год.""" + country_of_risk: builtins.str + """Код страны риска — то есть страны, в которой компания ведет основной бизнес.""" + country_of_risk_name: builtins.str + """Наименование страны риска — то есть страны, в которой компания ведет основной бизнес.""" + sector: builtins.str + """Сектор экономики.""" + issue_kind: builtins.str + """Форма выпуска. Возможные значения:
**documentary** — документарная;
**non_documentary** — бездокументарная.""" + issue_size: builtins.int + """Размер выпуска.""" + issue_size_plan: builtins.int + """Плановый размер выпуска.""" + trading_status: t_tech.invest.grpc.common_pb2.SecurityTradingStatus.ValueType + """Текущий режим торгов инструмента.""" + otc_flag: builtins.bool + """Флаг, используемый ранее для определения внебиржевых инструментов. На данный момент не используется для торгуемых через API инструментов. Может использоваться как фильтр для операций, совершавшихся некоторое время назад на ОТС площадке.""" + buy_available_flag: builtins.bool + """Признак доступности для покупки.""" + sell_available_flag: builtins.bool + """Признак доступности для продажи.""" + floating_coupon_flag: builtins.bool + """Признак облигации с плавающим купоном.""" + perpetual_flag: builtins.bool + """Признак бессрочной облигации.""" + amortization_flag: builtins.bool + """Признак облигации с амортизацией долга.""" + api_trade_available_flag: builtins.bool + """Параметр указывает на возможность торговать инструментом через API.""" + uid: builtins.str + """Уникальный идентификатор инструмента.""" + real_exchange: t_tech.invest.grpc.common_pb2.RealExchange.ValueType + """Реальная площадка исполнения расчетов. (биржа)""" + position_uid: builtins.str + """Уникальный идентификатор позиции инструмента.""" + asset_uid: builtins.str + """Уникальный идентификатор актива.""" + for_iis_flag: builtins.bool + """Признак доступности для ИИС.""" + for_qual_investor_flag: builtins.bool + """Флаг, отображающий доступность торговли инструментом только для квалифицированных инвесторов.""" + weekend_flag: builtins.bool + """Флаг, отображающий доступность торговли инструментом по выходным.""" + blocked_tca_flag: builtins.bool + """Флаг заблокированного ТКС.""" + subordinated_flag: builtins.bool + """Признак субординированной облигации.""" + liquidity_flag: builtins.bool + """Флаг достаточной ликвидности.""" + risk_level: global___RiskLevel.ValueType + """Уровень риска.""" + bond_type: global___BondType.ValueType + """Тип облигации.""" + @property + def klong(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Коэффициент ставки риска длинной позиции по клиенту. 2 – клиент со стандартным уровнем риска (КСУР); 1 – клиент с повышенным уровнем риска (КПУР).""" + + @property + def kshort(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Коэффициент ставки риска короткой позиции по клиенту. 2 – клиент со стандартным уровнем риска (КСУР); 1 – клиент с повышенным уровнем риска (КПУР).""" + + @property + def dlong(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска начальной маржи для КСУР лонг. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def dshort(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска начальной маржи для КСУР шорт. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def dlong_min(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска начальной маржи для КПУР лонг. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def dshort_min(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска начальной маржи для КПУР шорт. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def maturity_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата погашения облигации по UTC.""" + + @property + def nominal(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Номинал облигации.""" + + @property + def initial_nominal(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Первоначальный номинал облигации.""" + + @property + def state_reg_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата выпуска облигации по UTC.""" + + @property + def placement_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата размещения по UTC.""" + + @property + def placement_price(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Цена размещения.""" + + @property + def aci_value(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Значение НКД (накопленного купонного дохода) на дату.""" + + @property + def min_price_increment(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Шаг цены.""" + + @property + def required_tests(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Тесты, которые необходимо пройти клиенту, чтобы совершать сделки по инструменту.""" + + @property + def first_1min_candle_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата первой минутной свечи.""" + + @property + def first_1day_candle_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата первой дневной свечи.""" + + @property + def brand(self) -> t_tech.invest.grpc.common_pb2.BrandData: + """Информация о бренде.""" + + @property + def call_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата погашения облигации.""" + + @property + def dlong_client(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска в лонг с учетом текущего уровня риска портфеля клиента. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def dshort_client(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска в шорт с учетом текущего уровня риска портфеля клиента. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + def __init__( + self, + *, + figi: builtins.str = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + isin: builtins.str = ..., + lot: builtins.int = ..., + currency: builtins.str = ..., + klong: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + kshort: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dlong: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dshort: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dlong_min: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dshort_min: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + short_enabled_flag: builtins.bool = ..., + name: builtins.str = ..., + exchange: builtins.str = ..., + coupon_quantity_per_year: builtins.int = ..., + maturity_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + nominal: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + initial_nominal: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + state_reg_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + placement_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + placement_price: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + aci_value: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + country_of_risk: builtins.str = ..., + country_of_risk_name: builtins.str = ..., + sector: builtins.str = ..., + issue_kind: builtins.str = ..., + issue_size: builtins.int = ..., + issue_size_plan: builtins.int = ..., + trading_status: t_tech.invest.grpc.common_pb2.SecurityTradingStatus.ValueType = ..., + otc_flag: builtins.bool = ..., + buy_available_flag: builtins.bool = ..., + sell_available_flag: builtins.bool = ..., + floating_coupon_flag: builtins.bool = ..., + perpetual_flag: builtins.bool = ..., + amortization_flag: builtins.bool = ..., + min_price_increment: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + api_trade_available_flag: builtins.bool = ..., + uid: builtins.str = ..., + real_exchange: t_tech.invest.grpc.common_pb2.RealExchange.ValueType = ..., + position_uid: builtins.str = ..., + asset_uid: builtins.str = ..., + required_tests: collections.abc.Iterable[builtins.str] | None = ..., + for_iis_flag: builtins.bool = ..., + for_qual_investor_flag: builtins.bool = ..., + weekend_flag: builtins.bool = ..., + blocked_tca_flag: builtins.bool = ..., + subordinated_flag: builtins.bool = ..., + liquidity_flag: builtins.bool = ..., + first_1min_candle_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + first_1day_candle_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + risk_level: global___RiskLevel.ValueType = ..., + brand: t_tech.invest.grpc.common_pb2.BrandData | None = ..., + bond_type: global___BondType.ValueType = ..., + call_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + dlong_client: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dshort_client: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["aci_value", b"aci_value", "brand", b"brand", "call_date", b"call_date", "dlong", b"dlong", "dlong_client", b"dlong_client", "dlong_min", b"dlong_min", "dshort", b"dshort", "dshort_client", b"dshort_client", "dshort_min", b"dshort_min", "first_1day_candle_date", b"first_1day_candle_date", "first_1min_candle_date", b"first_1min_candle_date", "initial_nominal", b"initial_nominal", "klong", b"klong", "kshort", b"kshort", "maturity_date", b"maturity_date", "min_price_increment", b"min_price_increment", "nominal", b"nominal", "placement_date", b"placement_date", "placement_price", b"placement_price", "state_reg_date", b"state_reg_date"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["aci_value", b"aci_value", "amortization_flag", b"amortization_flag", "api_trade_available_flag", b"api_trade_available_flag", "asset_uid", b"asset_uid", "blocked_tca_flag", b"blocked_tca_flag", "bond_type", b"bond_type", "brand", b"brand", "buy_available_flag", b"buy_available_flag", "call_date", b"call_date", "class_code", b"class_code", "country_of_risk", b"country_of_risk", "country_of_risk_name", b"country_of_risk_name", "coupon_quantity_per_year", b"coupon_quantity_per_year", "currency", b"currency", "dlong", b"dlong", "dlong_client", b"dlong_client", "dlong_min", b"dlong_min", "dshort", b"dshort", "dshort_client", b"dshort_client", "dshort_min", b"dshort_min", "exchange", b"exchange", "figi", b"figi", "first_1day_candle_date", b"first_1day_candle_date", "first_1min_candle_date", b"first_1min_candle_date", "floating_coupon_flag", b"floating_coupon_flag", "for_iis_flag", b"for_iis_flag", "for_qual_investor_flag", b"for_qual_investor_flag", "initial_nominal", b"initial_nominal", "isin", b"isin", "issue_kind", b"issue_kind", "issue_size", b"issue_size", "issue_size_plan", b"issue_size_plan", "klong", b"klong", "kshort", b"kshort", "liquidity_flag", b"liquidity_flag", "lot", b"lot", "maturity_date", b"maturity_date", "min_price_increment", b"min_price_increment", "name", b"name", "nominal", b"nominal", "otc_flag", b"otc_flag", "perpetual_flag", b"perpetual_flag", "placement_date", b"placement_date", "placement_price", b"placement_price", "position_uid", b"position_uid", "real_exchange", b"real_exchange", "required_tests", b"required_tests", "risk_level", b"risk_level", "sector", b"sector", "sell_available_flag", b"sell_available_flag", "short_enabled_flag", b"short_enabled_flag", "state_reg_date", b"state_reg_date", "subordinated_flag", b"subordinated_flag", "ticker", b"ticker", "trading_status", b"trading_status", "uid", b"uid", "weekend_flag", b"weekend_flag"]) -> None: ... + +global___Bond = Bond + +@typing.final +class Currency(google.protobuf.message.Message): + """Объект передачи информации о валюте.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + ISIN_FIELD_NUMBER: builtins.int + LOT_FIELD_NUMBER: builtins.int + CURRENCY_FIELD_NUMBER: builtins.int + KLONG_FIELD_NUMBER: builtins.int + KSHORT_FIELD_NUMBER: builtins.int + DLONG_FIELD_NUMBER: builtins.int + DSHORT_FIELD_NUMBER: builtins.int + DLONG_MIN_FIELD_NUMBER: builtins.int + DSHORT_MIN_FIELD_NUMBER: builtins.int + SHORT_ENABLED_FLAG_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + EXCHANGE_FIELD_NUMBER: builtins.int + NOMINAL_FIELD_NUMBER: builtins.int + COUNTRY_OF_RISK_FIELD_NUMBER: builtins.int + COUNTRY_OF_RISK_NAME_FIELD_NUMBER: builtins.int + TRADING_STATUS_FIELD_NUMBER: builtins.int + OTC_FLAG_FIELD_NUMBER: builtins.int + BUY_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + SELL_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + ISO_CURRENCY_NAME_FIELD_NUMBER: builtins.int + MIN_PRICE_INCREMENT_FIELD_NUMBER: builtins.int + API_TRADE_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + UID_FIELD_NUMBER: builtins.int + REAL_EXCHANGE_FIELD_NUMBER: builtins.int + POSITION_UID_FIELD_NUMBER: builtins.int + REQUIRED_TESTS_FIELD_NUMBER: builtins.int + ASSET_UID_FIELD_NUMBER: builtins.int + FOR_IIS_FLAG_FIELD_NUMBER: builtins.int + FOR_QUAL_INVESTOR_FLAG_FIELD_NUMBER: builtins.int + WEEKEND_FLAG_FIELD_NUMBER: builtins.int + BLOCKED_TCA_FLAG_FIELD_NUMBER: builtins.int + FIRST_1MIN_CANDLE_DATE_FIELD_NUMBER: builtins.int + FIRST_1DAY_CANDLE_DATE_FIELD_NUMBER: builtins.int + BRAND_FIELD_NUMBER: builtins.int + DLONG_CLIENT_FIELD_NUMBER: builtins.int + DSHORT_CLIENT_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI-идентификатор инструмента.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + isin: builtins.str + """ISIN-идентификатор инструмента.""" + lot: builtins.int + """Лотность инструмента. Возможно совершение операций только на количества ценной бумаги, кратные параметру `lot`. [Подробнее](./glossary#lot).""" + currency: builtins.str + """Валюта расчетов.""" + short_enabled_flag: builtins.bool + """Признак доступности для операций в шорт.""" + name: builtins.str + """Название инструмента.""" + exchange: builtins.str + """Tорговая площадка (секция биржи).""" + country_of_risk: builtins.str + """Код страны риска — то есть страны, в которой компания ведет основной бизнес.""" + country_of_risk_name: builtins.str + """Наименование страны риска — то есть страны, в которой компания ведет основной бизнес.""" + trading_status: t_tech.invest.grpc.common_pb2.SecurityTradingStatus.ValueType + """Текущий режим торгов инструмента.""" + otc_flag: builtins.bool + """Флаг, используемый ранее для определения внебиржевых инструментов. На данный момент не используется для торгуемых через API инструментов. Может использоваться как фильтр для операций, совершавшихся некоторое время назад на ОТС площадке.""" + buy_available_flag: builtins.bool + """Признак доступности для покупки.""" + sell_available_flag: builtins.bool + """Признак доступности для продажи.""" + iso_currency_name: builtins.str + """Строковый ISO-код валюты.""" + api_trade_available_flag: builtins.bool + """Параметр указывает на возможность торговать инструментом через API.""" + uid: builtins.str + """Уникальный идентификатор инструмента.""" + real_exchange: t_tech.invest.grpc.common_pb2.RealExchange.ValueType + """Реальная площадка исполнения расчетов (биржа).""" + position_uid: builtins.str + """Уникальный идентификатор позиции инструмента.""" + asset_uid: builtins.str + """Уникальный идентификатор актива.""" + for_iis_flag: builtins.bool + """Признак доступности для ИИС.""" + for_qual_investor_flag: builtins.bool + """Флаг, отображающий доступность торговли инструментом только для квалифицированных инвесторов.""" + weekend_flag: builtins.bool + """Флаг, отображающий доступность торговли инструментом по выходным.""" + blocked_tca_flag: builtins.bool + """Флаг заблокированного ТКС.""" + @property + def klong(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Коэффициент ставки риска длинной позиции по клиенту. 2 – клиент со стандартным уровнем риска (КСУР); 1 – клиент с повышенным уровнем риска (КПУР).""" + + @property + def kshort(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Коэффициент ставки риска короткой позиции по клиенту. 2 – клиент со стандартным уровнем риска (КСУР); 1 – клиент с повышенным уровнем риска (КПУР).""" + + @property + def dlong(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска начальной маржи для КСУР лонг. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def dshort(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска начальной маржи для КСУР шорт. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def dlong_min(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска начальной маржи для КПУР лонг. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def dshort_min(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска начальной маржи для КПУР шорт. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def nominal(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Номинал.""" + + @property + def min_price_increment(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Шаг цены.""" + + @property + def required_tests(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Тесты, которые необходимо пройти клиенту, чтобы совершать сделки по инструменту.""" + + @property + def first_1min_candle_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата первой минутной свечи.""" + + @property + def first_1day_candle_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата первой дневной свечи.""" + + @property + def brand(self) -> t_tech.invest.grpc.common_pb2.BrandData: + """Информация о бренде.""" + + @property + def dlong_client(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска в лонг с учетом текущего уровня риска портфеля клиента. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def dshort_client(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска в шорт с учетом текущего уровня риска портфеля клиента. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + def __init__( + self, + *, + figi: builtins.str = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + isin: builtins.str = ..., + lot: builtins.int = ..., + currency: builtins.str = ..., + klong: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + kshort: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dlong: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dshort: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dlong_min: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dshort_min: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + short_enabled_flag: builtins.bool = ..., + name: builtins.str = ..., + exchange: builtins.str = ..., + nominal: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + country_of_risk: builtins.str = ..., + country_of_risk_name: builtins.str = ..., + trading_status: t_tech.invest.grpc.common_pb2.SecurityTradingStatus.ValueType = ..., + otc_flag: builtins.bool = ..., + buy_available_flag: builtins.bool = ..., + sell_available_flag: builtins.bool = ..., + iso_currency_name: builtins.str = ..., + min_price_increment: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + api_trade_available_flag: builtins.bool = ..., + uid: builtins.str = ..., + real_exchange: t_tech.invest.grpc.common_pb2.RealExchange.ValueType = ..., + position_uid: builtins.str = ..., + required_tests: collections.abc.Iterable[builtins.str] | None = ..., + asset_uid: builtins.str = ..., + for_iis_flag: builtins.bool = ..., + for_qual_investor_flag: builtins.bool = ..., + weekend_flag: builtins.bool = ..., + blocked_tca_flag: builtins.bool = ..., + first_1min_candle_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + first_1day_candle_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + brand: t_tech.invest.grpc.common_pb2.BrandData | None = ..., + dlong_client: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dshort_client: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["brand", b"brand", "dlong", b"dlong", "dlong_client", b"dlong_client", "dlong_min", b"dlong_min", "dshort", b"dshort", "dshort_client", b"dshort_client", "dshort_min", b"dshort_min", "first_1day_candle_date", b"first_1day_candle_date", "first_1min_candle_date", b"first_1min_candle_date", "klong", b"klong", "kshort", b"kshort", "min_price_increment", b"min_price_increment", "nominal", b"nominal"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["api_trade_available_flag", b"api_trade_available_flag", "asset_uid", b"asset_uid", "blocked_tca_flag", b"blocked_tca_flag", "brand", b"brand", "buy_available_flag", b"buy_available_flag", "class_code", b"class_code", "country_of_risk", b"country_of_risk", "country_of_risk_name", b"country_of_risk_name", "currency", b"currency", "dlong", b"dlong", "dlong_client", b"dlong_client", "dlong_min", b"dlong_min", "dshort", b"dshort", "dshort_client", b"dshort_client", "dshort_min", b"dshort_min", "exchange", b"exchange", "figi", b"figi", "first_1day_candle_date", b"first_1day_candle_date", "first_1min_candle_date", b"first_1min_candle_date", "for_iis_flag", b"for_iis_flag", "for_qual_investor_flag", b"for_qual_investor_flag", "isin", b"isin", "iso_currency_name", b"iso_currency_name", "klong", b"klong", "kshort", b"kshort", "lot", b"lot", "min_price_increment", b"min_price_increment", "name", b"name", "nominal", b"nominal", "otc_flag", b"otc_flag", "position_uid", b"position_uid", "real_exchange", b"real_exchange", "required_tests", b"required_tests", "sell_available_flag", b"sell_available_flag", "short_enabled_flag", b"short_enabled_flag", "ticker", b"ticker", "trading_status", b"trading_status", "uid", b"uid", "weekend_flag", b"weekend_flag"]) -> None: ... + +global___Currency = Currency + +@typing.final +class Etf(google.protobuf.message.Message): + """Объект передачи информации об инвестиционном фонде.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + ISIN_FIELD_NUMBER: builtins.int + LOT_FIELD_NUMBER: builtins.int + CURRENCY_FIELD_NUMBER: builtins.int + KLONG_FIELD_NUMBER: builtins.int + KSHORT_FIELD_NUMBER: builtins.int + DLONG_FIELD_NUMBER: builtins.int + DSHORT_FIELD_NUMBER: builtins.int + DLONG_MIN_FIELD_NUMBER: builtins.int + DSHORT_MIN_FIELD_NUMBER: builtins.int + SHORT_ENABLED_FLAG_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + EXCHANGE_FIELD_NUMBER: builtins.int + FIXED_COMMISSION_FIELD_NUMBER: builtins.int + FOCUS_TYPE_FIELD_NUMBER: builtins.int + RELEASED_DATE_FIELD_NUMBER: builtins.int + NUM_SHARES_FIELD_NUMBER: builtins.int + COUNTRY_OF_RISK_FIELD_NUMBER: builtins.int + COUNTRY_OF_RISK_NAME_FIELD_NUMBER: builtins.int + SECTOR_FIELD_NUMBER: builtins.int + REBALANCING_FREQ_FIELD_NUMBER: builtins.int + TRADING_STATUS_FIELD_NUMBER: builtins.int + OTC_FLAG_FIELD_NUMBER: builtins.int + BUY_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + SELL_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + MIN_PRICE_INCREMENT_FIELD_NUMBER: builtins.int + API_TRADE_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + UID_FIELD_NUMBER: builtins.int + REAL_EXCHANGE_FIELD_NUMBER: builtins.int + POSITION_UID_FIELD_NUMBER: builtins.int + ASSET_UID_FIELD_NUMBER: builtins.int + INSTRUMENT_EXCHANGE_FIELD_NUMBER: builtins.int + REQUIRED_TESTS_FIELD_NUMBER: builtins.int + FOR_IIS_FLAG_FIELD_NUMBER: builtins.int + FOR_QUAL_INVESTOR_FLAG_FIELD_NUMBER: builtins.int + WEEKEND_FLAG_FIELD_NUMBER: builtins.int + BLOCKED_TCA_FLAG_FIELD_NUMBER: builtins.int + LIQUIDITY_FLAG_FIELD_NUMBER: builtins.int + FIRST_1MIN_CANDLE_DATE_FIELD_NUMBER: builtins.int + FIRST_1DAY_CANDLE_DATE_FIELD_NUMBER: builtins.int + BRAND_FIELD_NUMBER: builtins.int + DLONG_CLIENT_FIELD_NUMBER: builtins.int + DSHORT_CLIENT_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI-идентификатор инструмента.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + isin: builtins.str + """ISIN-идентификатор инструмента.""" + lot: builtins.int + """Лотность инструмента. Возможно совершение операций только на количества ценной бумаги, кратные параметру `lot`. [Подробнее](./glossary#lot).""" + currency: builtins.str + """Валюта расчетов.""" + short_enabled_flag: builtins.bool + """Признак доступности для операций в шорт.""" + name: builtins.str + """Название инструмента.""" + exchange: builtins.str + """Tорговая площадка (секция биржи).""" + focus_type: builtins.str + """Возможные значения:
**equity** — акции;
**fixed_income** — облигации;
**mixed_allocation** — смешанный;
**money_market** — денежный рынок;
**real_estate** — недвижимость;
**commodity** — товары;
**specialty** — специальный;
**private_equity** — private equity;
**alternative_investment** — альтернативные инвестиции.""" + country_of_risk: builtins.str + """Код страны риска — то есть страны, в которой компания ведет основной бизнес.""" + country_of_risk_name: builtins.str + """Наименование страны риска — то есть страны, в которой компания ведет основной бизнес.""" + sector: builtins.str + """Сектор экономики.""" + rebalancing_freq: builtins.str + """Частота ребалансировки.""" + trading_status: t_tech.invest.grpc.common_pb2.SecurityTradingStatus.ValueType + """Текущий режим торгов инструмента.""" + otc_flag: builtins.bool + """Флаг, используемый ранее для определения внебиржевых инструментов. На данный момент не используется для торгуемых через API инструментов. Может использоваться как фильтр для операций, совершавшихся некоторое время назад на ОТС площадке.""" + buy_available_flag: builtins.bool + """Признак доступности для покупки.""" + sell_available_flag: builtins.bool + """Признак доступности для продажи.""" + api_trade_available_flag: builtins.bool + """Параметр указывает на возможность торговать инструментом через API.""" + uid: builtins.str + """Уникальный идентификатор инструмента.""" + real_exchange: t_tech.invest.grpc.common_pb2.RealExchange.ValueType + """Реальная площадка исполнения расчетов (биржа).""" + position_uid: builtins.str + """Уникальный идентификатор позиции инструмента.""" + asset_uid: builtins.str + """Уникальный идентификатор актива.""" + instrument_exchange: global___InstrumentExchangeType.ValueType + """Тип площадки торговли.""" + for_iis_flag: builtins.bool + """Признак доступности для ИИС.""" + for_qual_investor_flag: builtins.bool + """Флаг, отображающий доступность торговли инструментом только для квалифицированных инвесторов.""" + weekend_flag: builtins.bool + """ФлагФлаг, отображающий доступность торговли инструментом по выходным.""" + blocked_tca_flag: builtins.bool + """Флаг заблокированного ТКС.""" + liquidity_flag: builtins.bool + """Флаг достаточной ликвидности.""" + @property + def klong(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Коэффициент ставки риска длинной позиции по клиенту. 2 – клиент со стандартным уровнем риска (КСУР); 1 – клиент с повышенным уровнем риска (КПУР).""" + + @property + def kshort(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Коэффициент ставки риска короткой позиции по клиенту. 2 – клиент со стандартным уровнем риска (КСУР); 1 – клиент с повышенным уровнем риска (КПУР).""" + + @property + def dlong(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска начальной маржи для КСУР лонг. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def dshort(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска начальной маржи для КСУР шорт. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def dlong_min(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска начальной маржи для КПУР лонг. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def dshort_min(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска начальной маржи для КПУР шорт. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def fixed_commission(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Размер фиксированной комиссии фонда.""" + + @property + def released_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата выпуска по UTC.""" + + @property + def num_shares(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Количество паев фонда в обращении.""" + + @property + def min_price_increment(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Шаг цены.""" + + @property + def required_tests(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Тесты, которые необходимо пройти клиенту, чтобы совершать сделки по инструменту.""" + + @property + def first_1min_candle_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата первой минутной свечи.""" + + @property + def first_1day_candle_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата первой дневной свечи.""" + + @property + def brand(self) -> t_tech.invest.grpc.common_pb2.BrandData: + """Информация о бренде.""" + + @property + def dlong_client(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска в лонг с учетом текущего уровня риска портфеля клиента. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def dshort_client(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска в шорт с учетом текущего уровня риска портфеля клиента. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + def __init__( + self, + *, + figi: builtins.str = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + isin: builtins.str = ..., + lot: builtins.int = ..., + currency: builtins.str = ..., + klong: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + kshort: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dlong: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dshort: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dlong_min: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dshort_min: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + short_enabled_flag: builtins.bool = ..., + name: builtins.str = ..., + exchange: builtins.str = ..., + fixed_commission: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + focus_type: builtins.str = ..., + released_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + num_shares: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + country_of_risk: builtins.str = ..., + country_of_risk_name: builtins.str = ..., + sector: builtins.str = ..., + rebalancing_freq: builtins.str = ..., + trading_status: t_tech.invest.grpc.common_pb2.SecurityTradingStatus.ValueType = ..., + otc_flag: builtins.bool = ..., + buy_available_flag: builtins.bool = ..., + sell_available_flag: builtins.bool = ..., + min_price_increment: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + api_trade_available_flag: builtins.bool = ..., + uid: builtins.str = ..., + real_exchange: t_tech.invest.grpc.common_pb2.RealExchange.ValueType = ..., + position_uid: builtins.str = ..., + asset_uid: builtins.str = ..., + instrument_exchange: global___InstrumentExchangeType.ValueType = ..., + required_tests: collections.abc.Iterable[builtins.str] | None = ..., + for_iis_flag: builtins.bool = ..., + for_qual_investor_flag: builtins.bool = ..., + weekend_flag: builtins.bool = ..., + blocked_tca_flag: builtins.bool = ..., + liquidity_flag: builtins.bool = ..., + first_1min_candle_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + first_1day_candle_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + brand: t_tech.invest.grpc.common_pb2.BrandData | None = ..., + dlong_client: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dshort_client: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["brand", b"brand", "dlong", b"dlong", "dlong_client", b"dlong_client", "dlong_min", b"dlong_min", "dshort", b"dshort", "dshort_client", b"dshort_client", "dshort_min", b"dshort_min", "first_1day_candle_date", b"first_1day_candle_date", "first_1min_candle_date", b"first_1min_candle_date", "fixed_commission", b"fixed_commission", "klong", b"klong", "kshort", b"kshort", "min_price_increment", b"min_price_increment", "num_shares", b"num_shares", "released_date", b"released_date"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["api_trade_available_flag", b"api_trade_available_flag", "asset_uid", b"asset_uid", "blocked_tca_flag", b"blocked_tca_flag", "brand", b"brand", "buy_available_flag", b"buy_available_flag", "class_code", b"class_code", "country_of_risk", b"country_of_risk", "country_of_risk_name", b"country_of_risk_name", "currency", b"currency", "dlong", b"dlong", "dlong_client", b"dlong_client", "dlong_min", b"dlong_min", "dshort", b"dshort", "dshort_client", b"dshort_client", "dshort_min", b"dshort_min", "exchange", b"exchange", "figi", b"figi", "first_1day_candle_date", b"first_1day_candle_date", "first_1min_candle_date", b"first_1min_candle_date", "fixed_commission", b"fixed_commission", "focus_type", b"focus_type", "for_iis_flag", b"for_iis_flag", "for_qual_investor_flag", b"for_qual_investor_flag", "instrument_exchange", b"instrument_exchange", "isin", b"isin", "klong", b"klong", "kshort", b"kshort", "liquidity_flag", b"liquidity_flag", "lot", b"lot", "min_price_increment", b"min_price_increment", "name", b"name", "num_shares", b"num_shares", "otc_flag", b"otc_flag", "position_uid", b"position_uid", "real_exchange", b"real_exchange", "rebalancing_freq", b"rebalancing_freq", "released_date", b"released_date", "required_tests", b"required_tests", "sector", b"sector", "sell_available_flag", b"sell_available_flag", "short_enabled_flag", b"short_enabled_flag", "ticker", b"ticker", "trading_status", b"trading_status", "uid", b"uid", "weekend_flag", b"weekend_flag"]) -> None: ... + +global___Etf = Etf + +@typing.final +class Future(google.protobuf.message.Message): + """Объект передачи информации о фьючерсе.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + LOT_FIELD_NUMBER: builtins.int + CURRENCY_FIELD_NUMBER: builtins.int + KLONG_FIELD_NUMBER: builtins.int + KSHORT_FIELD_NUMBER: builtins.int + DLONG_FIELD_NUMBER: builtins.int + DSHORT_FIELD_NUMBER: builtins.int + DLONG_MIN_FIELD_NUMBER: builtins.int + DSHORT_MIN_FIELD_NUMBER: builtins.int + SHORT_ENABLED_FLAG_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + EXCHANGE_FIELD_NUMBER: builtins.int + FIRST_TRADE_DATE_FIELD_NUMBER: builtins.int + LAST_TRADE_DATE_FIELD_NUMBER: builtins.int + FUTURES_TYPE_FIELD_NUMBER: builtins.int + ASSET_TYPE_FIELD_NUMBER: builtins.int + BASIC_ASSET_FIELD_NUMBER: builtins.int + BASIC_ASSET_SIZE_FIELD_NUMBER: builtins.int + COUNTRY_OF_RISK_FIELD_NUMBER: builtins.int + COUNTRY_OF_RISK_NAME_FIELD_NUMBER: builtins.int + SECTOR_FIELD_NUMBER: builtins.int + EXPIRATION_DATE_FIELD_NUMBER: builtins.int + TRADING_STATUS_FIELD_NUMBER: builtins.int + OTC_FLAG_FIELD_NUMBER: builtins.int + BUY_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + SELL_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + MIN_PRICE_INCREMENT_FIELD_NUMBER: builtins.int + API_TRADE_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + UID_FIELD_NUMBER: builtins.int + REAL_EXCHANGE_FIELD_NUMBER: builtins.int + POSITION_UID_FIELD_NUMBER: builtins.int + BASIC_ASSET_POSITION_UID_FIELD_NUMBER: builtins.int + REQUIRED_TESTS_FIELD_NUMBER: builtins.int + FOR_IIS_FLAG_FIELD_NUMBER: builtins.int + FOR_QUAL_INVESTOR_FLAG_FIELD_NUMBER: builtins.int + WEEKEND_FLAG_FIELD_NUMBER: builtins.int + BLOCKED_TCA_FLAG_FIELD_NUMBER: builtins.int + FIRST_1MIN_CANDLE_DATE_FIELD_NUMBER: builtins.int + FIRST_1DAY_CANDLE_DATE_FIELD_NUMBER: builtins.int + INITIAL_MARGIN_ON_BUY_FIELD_NUMBER: builtins.int + INITIAL_MARGIN_ON_SELL_FIELD_NUMBER: builtins.int + MIN_PRICE_INCREMENT_AMOUNT_FIELD_NUMBER: builtins.int + BRAND_FIELD_NUMBER: builtins.int + DLONG_CLIENT_FIELD_NUMBER: builtins.int + DSHORT_CLIENT_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI-идентификатор инструмента.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + lot: builtins.int + """Лотность инструмента. Возможно совершение операций только на количества ценной бумаги, кратные параметру `lot`. [Подробнее](./glossary#lot).""" + currency: builtins.str + """Валюта расчетов.""" + short_enabled_flag: builtins.bool + """Признак доступности для операций шорт.""" + name: builtins.str + """Название инструмента.""" + exchange: builtins.str + """Tорговая площадка (секция биржи).""" + futures_type: builtins.str + """Тип фьючерса. Возможные значения:
**physical_delivery** — физические поставки;
**cash_settlement** — денежный эквивалент.""" + asset_type: builtins.str + """Тип актива. Возможные значения:
**commodity** — товар;
**currency** — валюта;
**security** — ценная бумага;
**index** — индекс.""" + basic_asset: builtins.str + """Основной актив.""" + country_of_risk: builtins.str + """Код страны риска — то есть страны, в которой компания ведет основной бизнес.""" + country_of_risk_name: builtins.str + """Наименование страны риска — то есть страны, в которой компания ведет основной бизнес.""" + sector: builtins.str + """Сектор экономики.""" + trading_status: t_tech.invest.grpc.common_pb2.SecurityTradingStatus.ValueType + """Текущий режим торгов инструмента.""" + otc_flag: builtins.bool + """Флаг, используемый ранее для определения внебиржевых инструментов. На данный момент не используется для торгуемых через API инструментов. Может использоваться как фильтр для операций, совершавшихся некоторое время назад на ОТС площадке.""" + buy_available_flag: builtins.bool + """Признак доступности для покупки.""" + sell_available_flag: builtins.bool + """Признак доступности для продажи.""" + api_trade_available_flag: builtins.bool + """Параметр указывает на возможность торговать инструментом через API.""" + uid: builtins.str + """Уникальный идентификатор инструмента.""" + real_exchange: t_tech.invest.grpc.common_pb2.RealExchange.ValueType + """Реальная площадка исполнения расчетов (биржа).""" + position_uid: builtins.str + """Уникальный идентификатор позиции инструмента.""" + basic_asset_position_uid: builtins.str + """Уникальный идентификатор позиции основного инструмента.""" + for_iis_flag: builtins.bool + """Признак доступности для ИИС.""" + for_qual_investor_flag: builtins.bool + """Флаг, отображающий доступность торговли инструментом только для квалифицированных инвесторов.""" + weekend_flag: builtins.bool + """Флаг, отображающий доступность торговли инструментом по выходным.""" + blocked_tca_flag: builtins.bool + """Флаг заблокированного ТКС.""" + @property + def klong(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Коэффициент ставки риска длинной позиции по клиенту. 2 – клиент со стандартным уровнем риска (КСУР); 1 – клиент с повышенным уровнем риска (КПУР).""" + + @property + def kshort(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Коэффициент ставки риска короткой позиции по клиенту. 2 – клиент со стандартным уровнем риска (КСУР); 1 – клиент с повышенным уровнем риска (КПУР).""" + + @property + def dlong(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска начальной маржи для КСУР лонг. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def dshort(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска начальной маржи для КСУР шорт. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def dlong_min(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска начальной маржи для КПУР лонг. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def dshort_min(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска начальной маржи для КПУР шорт. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def first_trade_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата начала обращения контракта по UTC.""" + + @property + def last_trade_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата по UTC, до которой возможно проведение операций с фьючерсом.""" + + @property + def basic_asset_size(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Размер основного актива.""" + + @property + def expiration_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата истечения срока в часов поясе UTC.""" + + @property + def min_price_increment(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Шаг цены.""" + + @property + def required_tests(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Тесты, которые необходимо пройти клиенту, чтобы совершать сделки по инструменту.""" + + @property + def first_1min_candle_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата первой минутной свечи.""" + + @property + def first_1day_candle_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата первой дневной свечи.""" + + @property + def initial_margin_on_buy(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Гарантийное обеспечение при покупке.""" + + @property + def initial_margin_on_sell(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Гарантийное обеспечение при продаже.""" + + @property + def min_price_increment_amount(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Стоимость шага цены.""" + + @property + def brand(self) -> t_tech.invest.grpc.common_pb2.BrandData: + """Информация о бренде.""" + + @property + def dlong_client(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска в лонг с учетом текущего уровня риска портфеля клиента. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def dshort_client(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска в шорт с учетом текущего уровня риска портфеля клиента. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + def __init__( + self, + *, + figi: builtins.str = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + lot: builtins.int = ..., + currency: builtins.str = ..., + klong: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + kshort: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dlong: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dshort: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dlong_min: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dshort_min: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + short_enabled_flag: builtins.bool = ..., + name: builtins.str = ..., + exchange: builtins.str = ..., + first_trade_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + last_trade_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + futures_type: builtins.str = ..., + asset_type: builtins.str = ..., + basic_asset: builtins.str = ..., + basic_asset_size: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + country_of_risk: builtins.str = ..., + country_of_risk_name: builtins.str = ..., + sector: builtins.str = ..., + expiration_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + trading_status: t_tech.invest.grpc.common_pb2.SecurityTradingStatus.ValueType = ..., + otc_flag: builtins.bool = ..., + buy_available_flag: builtins.bool = ..., + sell_available_flag: builtins.bool = ..., + min_price_increment: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + api_trade_available_flag: builtins.bool = ..., + uid: builtins.str = ..., + real_exchange: t_tech.invest.grpc.common_pb2.RealExchange.ValueType = ..., + position_uid: builtins.str = ..., + basic_asset_position_uid: builtins.str = ..., + required_tests: collections.abc.Iterable[builtins.str] | None = ..., + for_iis_flag: builtins.bool = ..., + for_qual_investor_flag: builtins.bool = ..., + weekend_flag: builtins.bool = ..., + blocked_tca_flag: builtins.bool = ..., + first_1min_candle_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + first_1day_candle_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + initial_margin_on_buy: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + initial_margin_on_sell: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + min_price_increment_amount: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + brand: t_tech.invest.grpc.common_pb2.BrandData | None = ..., + dlong_client: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dshort_client: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["basic_asset_size", b"basic_asset_size", "brand", b"brand", "dlong", b"dlong", "dlong_client", b"dlong_client", "dlong_min", b"dlong_min", "dshort", b"dshort", "dshort_client", b"dshort_client", "dshort_min", b"dshort_min", "expiration_date", b"expiration_date", "first_1day_candle_date", b"first_1day_candle_date", "first_1min_candle_date", b"first_1min_candle_date", "first_trade_date", b"first_trade_date", "initial_margin_on_buy", b"initial_margin_on_buy", "initial_margin_on_sell", b"initial_margin_on_sell", "klong", b"klong", "kshort", b"kshort", "last_trade_date", b"last_trade_date", "min_price_increment", b"min_price_increment", "min_price_increment_amount", b"min_price_increment_amount"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["api_trade_available_flag", b"api_trade_available_flag", "asset_type", b"asset_type", "basic_asset", b"basic_asset", "basic_asset_position_uid", b"basic_asset_position_uid", "basic_asset_size", b"basic_asset_size", "blocked_tca_flag", b"blocked_tca_flag", "brand", b"brand", "buy_available_flag", b"buy_available_flag", "class_code", b"class_code", "country_of_risk", b"country_of_risk", "country_of_risk_name", b"country_of_risk_name", "currency", b"currency", "dlong", b"dlong", "dlong_client", b"dlong_client", "dlong_min", b"dlong_min", "dshort", b"dshort", "dshort_client", b"dshort_client", "dshort_min", b"dshort_min", "exchange", b"exchange", "expiration_date", b"expiration_date", "figi", b"figi", "first_1day_candle_date", b"first_1day_candle_date", "first_1min_candle_date", b"first_1min_candle_date", "first_trade_date", b"first_trade_date", "for_iis_flag", b"for_iis_flag", "for_qual_investor_flag", b"for_qual_investor_flag", "futures_type", b"futures_type", "initial_margin_on_buy", b"initial_margin_on_buy", "initial_margin_on_sell", b"initial_margin_on_sell", "klong", b"klong", "kshort", b"kshort", "last_trade_date", b"last_trade_date", "lot", b"lot", "min_price_increment", b"min_price_increment", "min_price_increment_amount", b"min_price_increment_amount", "name", b"name", "otc_flag", b"otc_flag", "position_uid", b"position_uid", "real_exchange", b"real_exchange", "required_tests", b"required_tests", "sector", b"sector", "sell_available_flag", b"sell_available_flag", "short_enabled_flag", b"short_enabled_flag", "ticker", b"ticker", "trading_status", b"trading_status", "uid", b"uid", "weekend_flag", b"weekend_flag"]) -> None: ... + +global___Future = Future + +@typing.final +class Share(google.protobuf.message.Message): + """Объект передачи информации об акции.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + ISIN_FIELD_NUMBER: builtins.int + LOT_FIELD_NUMBER: builtins.int + CURRENCY_FIELD_NUMBER: builtins.int + KLONG_FIELD_NUMBER: builtins.int + KSHORT_FIELD_NUMBER: builtins.int + DLONG_FIELD_NUMBER: builtins.int + DSHORT_FIELD_NUMBER: builtins.int + DLONG_MIN_FIELD_NUMBER: builtins.int + DSHORT_MIN_FIELD_NUMBER: builtins.int + SHORT_ENABLED_FLAG_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + EXCHANGE_FIELD_NUMBER: builtins.int + IPO_DATE_FIELD_NUMBER: builtins.int + ISSUE_SIZE_FIELD_NUMBER: builtins.int + COUNTRY_OF_RISK_FIELD_NUMBER: builtins.int + COUNTRY_OF_RISK_NAME_FIELD_NUMBER: builtins.int + SECTOR_FIELD_NUMBER: builtins.int + ISSUE_SIZE_PLAN_FIELD_NUMBER: builtins.int + NOMINAL_FIELD_NUMBER: builtins.int + TRADING_STATUS_FIELD_NUMBER: builtins.int + OTC_FLAG_FIELD_NUMBER: builtins.int + BUY_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + SELL_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + DIV_YIELD_FLAG_FIELD_NUMBER: builtins.int + SHARE_TYPE_FIELD_NUMBER: builtins.int + MIN_PRICE_INCREMENT_FIELD_NUMBER: builtins.int + API_TRADE_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + UID_FIELD_NUMBER: builtins.int + REAL_EXCHANGE_FIELD_NUMBER: builtins.int + POSITION_UID_FIELD_NUMBER: builtins.int + ASSET_UID_FIELD_NUMBER: builtins.int + INSTRUMENT_EXCHANGE_FIELD_NUMBER: builtins.int + REQUIRED_TESTS_FIELD_NUMBER: builtins.int + FOR_IIS_FLAG_FIELD_NUMBER: builtins.int + FOR_QUAL_INVESTOR_FLAG_FIELD_NUMBER: builtins.int + WEEKEND_FLAG_FIELD_NUMBER: builtins.int + BLOCKED_TCA_FLAG_FIELD_NUMBER: builtins.int + LIQUIDITY_FLAG_FIELD_NUMBER: builtins.int + FIRST_1MIN_CANDLE_DATE_FIELD_NUMBER: builtins.int + FIRST_1DAY_CANDLE_DATE_FIELD_NUMBER: builtins.int + BRAND_FIELD_NUMBER: builtins.int + DLONG_CLIENT_FIELD_NUMBER: builtins.int + DSHORT_CLIENT_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI-идентификатор инструмента.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + isin: builtins.str + """ISIN-идентификатор инструмента.""" + lot: builtins.int + """Лотность инструмента. Возможно совершение операций только на количества ценной бумаги, кратные параметру `lot`. [Подробнее](./glossary#lot)""" + currency: builtins.str + """Валюта расчетов.""" + short_enabled_flag: builtins.bool + """Признак доступности для операций в шорт.""" + name: builtins.str + """Название инструмента.""" + exchange: builtins.str + """Tорговая площадка (секция биржи).""" + issue_size: builtins.int + """Размер выпуска.""" + country_of_risk: builtins.str + """Код страны риска — то есть страны, в которой компания ведет основной бизнес.""" + country_of_risk_name: builtins.str + """Наименование страны риска — то есть страны, в которой компания ведет основной бизнес.""" + sector: builtins.str + """Сектор экономики.""" + issue_size_plan: builtins.int + """Плановый размер выпуска.""" + trading_status: t_tech.invest.grpc.common_pb2.SecurityTradingStatus.ValueType + """Текущий режим торгов инструмента.""" + otc_flag: builtins.bool + """Флаг, используемый ранее для определения внебиржевых инструментов. На данный момент не используется для торгуемых через API инструментов. Может использоваться как фильтр для операций, совершавшихся некоторое время назад на ОТС площадке.""" + buy_available_flag: builtins.bool + """Признак доступности для покупки.""" + sell_available_flag: builtins.bool + """Признак доступности для продажи.""" + div_yield_flag: builtins.bool + """Признак наличия дивидендной доходности.""" + share_type: global___ShareType.ValueType + """Тип акции. Возможные значения — `[ShareType](./instruments#sharetype)`.""" + api_trade_available_flag: builtins.bool + """Возможность торговать инструментом через API.""" + uid: builtins.str + """Уникальный идентификатор инструмента.""" + real_exchange: t_tech.invest.grpc.common_pb2.RealExchange.ValueType + """Реальная площадка исполнения расчетов (биржа).""" + position_uid: builtins.str + """Уникальный идентификатор позиции инструмента.""" + asset_uid: builtins.str + """Уникальный идентификатор актива.""" + instrument_exchange: global___InstrumentExchangeType.ValueType + """Тип площадки торговли.""" + for_iis_flag: builtins.bool + """Признак доступности для ИИС.""" + for_qual_investor_flag: builtins.bool + """Флаг, отображающий доступность торговли инструментом только для квалифицированных инвесторов.""" + weekend_flag: builtins.bool + """Флаг, отображающий доступность торговли инструментом по выходным.""" + blocked_tca_flag: builtins.bool + """Флаг заблокированного ТКС.""" + liquidity_flag: builtins.bool + """Флаг достаточной ликвидности.""" + @property + def klong(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Коэффициент ставки риска длинной позиции по клиенту. 2 – клиент со стандартным уровнем риска (КСУР); 1 – клиент с повышенным уровнем риска (КПУР).""" + + @property + def kshort(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Коэффициент ставки риска короткой позиции по клиенту. 2 – клиент со стандартным уровнем риска (КСУР); 1 – клиент с повышенным уровнем риска (КПУР).""" + + @property + def dlong(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска начальной маржи для КСУР лонг. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def dshort(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска начальной маржи для КСУР шорт. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def dlong_min(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска начальной маржи для КПУР лонг. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def dshort_min(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска начальной маржи для КПУР шорт. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def ipo_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата IPO акции по UTC.""" + + @property + def nominal(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Номинал.""" + + @property + def min_price_increment(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Шаг цены.""" + + @property + def required_tests(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Тесты, которые необходимо пройти клиенту, чтобы совершать сделки по инструменту.""" + + @property + def first_1min_candle_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата первой минутной свечи.""" + + @property + def first_1day_candle_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата первой дневной свечи.""" + + @property + def brand(self) -> t_tech.invest.grpc.common_pb2.BrandData: + """Информация о бренде.""" + + @property + def dlong_client(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска в лонг с учетом текущего уровня риска портфеля клиента. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def dshort_client(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска в шорт с учетом текущего уровня риска портфеля клиента. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + def __init__( + self, + *, + figi: builtins.str = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + isin: builtins.str = ..., + lot: builtins.int = ..., + currency: builtins.str = ..., + klong: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + kshort: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dlong: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dshort: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dlong_min: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dshort_min: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + short_enabled_flag: builtins.bool = ..., + name: builtins.str = ..., + exchange: builtins.str = ..., + ipo_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + issue_size: builtins.int = ..., + country_of_risk: builtins.str = ..., + country_of_risk_name: builtins.str = ..., + sector: builtins.str = ..., + issue_size_plan: builtins.int = ..., + nominal: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + trading_status: t_tech.invest.grpc.common_pb2.SecurityTradingStatus.ValueType = ..., + otc_flag: builtins.bool = ..., + buy_available_flag: builtins.bool = ..., + sell_available_flag: builtins.bool = ..., + div_yield_flag: builtins.bool = ..., + share_type: global___ShareType.ValueType = ..., + min_price_increment: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + api_trade_available_flag: builtins.bool = ..., + uid: builtins.str = ..., + real_exchange: t_tech.invest.grpc.common_pb2.RealExchange.ValueType = ..., + position_uid: builtins.str = ..., + asset_uid: builtins.str = ..., + instrument_exchange: global___InstrumentExchangeType.ValueType = ..., + required_tests: collections.abc.Iterable[builtins.str] | None = ..., + for_iis_flag: builtins.bool = ..., + for_qual_investor_flag: builtins.bool = ..., + weekend_flag: builtins.bool = ..., + blocked_tca_flag: builtins.bool = ..., + liquidity_flag: builtins.bool = ..., + first_1min_candle_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + first_1day_candle_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + brand: t_tech.invest.grpc.common_pb2.BrandData | None = ..., + dlong_client: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dshort_client: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["brand", b"brand", "dlong", b"dlong", "dlong_client", b"dlong_client", "dlong_min", b"dlong_min", "dshort", b"dshort", "dshort_client", b"dshort_client", "dshort_min", b"dshort_min", "first_1day_candle_date", b"first_1day_candle_date", "first_1min_candle_date", b"first_1min_candle_date", "ipo_date", b"ipo_date", "klong", b"klong", "kshort", b"kshort", "min_price_increment", b"min_price_increment", "nominal", b"nominal"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["api_trade_available_flag", b"api_trade_available_flag", "asset_uid", b"asset_uid", "blocked_tca_flag", b"blocked_tca_flag", "brand", b"brand", "buy_available_flag", b"buy_available_flag", "class_code", b"class_code", "country_of_risk", b"country_of_risk", "country_of_risk_name", b"country_of_risk_name", "currency", b"currency", "div_yield_flag", b"div_yield_flag", "dlong", b"dlong", "dlong_client", b"dlong_client", "dlong_min", b"dlong_min", "dshort", b"dshort", "dshort_client", b"dshort_client", "dshort_min", b"dshort_min", "exchange", b"exchange", "figi", b"figi", "first_1day_candle_date", b"first_1day_candle_date", "first_1min_candle_date", b"first_1min_candle_date", "for_iis_flag", b"for_iis_flag", "for_qual_investor_flag", b"for_qual_investor_flag", "instrument_exchange", b"instrument_exchange", "ipo_date", b"ipo_date", "isin", b"isin", "issue_size", b"issue_size", "issue_size_plan", b"issue_size_plan", "klong", b"klong", "kshort", b"kshort", "liquidity_flag", b"liquidity_flag", "lot", b"lot", "min_price_increment", b"min_price_increment", "name", b"name", "nominal", b"nominal", "otc_flag", b"otc_flag", "position_uid", b"position_uid", "real_exchange", b"real_exchange", "required_tests", b"required_tests", "sector", b"sector", "sell_available_flag", b"sell_available_flag", "share_type", b"share_type", "short_enabled_flag", b"short_enabled_flag", "ticker", b"ticker", "trading_status", b"trading_status", "uid", b"uid", "weekend_flag", b"weekend_flag"]) -> None: ... + +global___Share = Share + +@typing.final +class StructuredNote(google.protobuf.message.Message): + """Объект передачи информации о структурной ноте.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _LogicPortfolio: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _LogicPortfolioEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[StructuredNote._LogicPortfolio.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + LOGIC_PORTFOLIO_UNSPECIFIED: StructuredNote._LogicPortfolio.ValueType # 0 + """Стратегия портфеля не определена.""" + LOGIC_PORTFOLIO_VOLATILITY: StructuredNote._LogicPortfolio.ValueType # 1 + """Волатильность.""" + LOGIC_PORTFOLIO_CORRELATION: StructuredNote._LogicPortfolio.ValueType # 2 + """Корреляция.""" + + class LogicPortfolio(_LogicPortfolio, metaclass=_LogicPortfolioEnumTypeWrapper): + """Стратегия портфеля.""" + + LOGIC_PORTFOLIO_UNSPECIFIED: StructuredNote.LogicPortfolio.ValueType # 0 + """Стратегия портфеля не определена.""" + LOGIC_PORTFOLIO_VOLATILITY: StructuredNote.LogicPortfolio.ValueType # 1 + """Волатильность.""" + LOGIC_PORTFOLIO_CORRELATION: StructuredNote.LogicPortfolio.ValueType # 2 + """Корреляция.""" + + class _ObservationPrinciple: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _ObservationPrincipleEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[StructuredNote._ObservationPrinciple.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + OBSERVATION_PRINCIPLE_UNSPECIFIED: StructuredNote._ObservationPrinciple.ValueType # 0 + """Принцип наблюдений не определен.""" + OBSERVATION_PRINCIPLE_WORST_BASIC_ASSET: StructuredNote._ObservationPrinciple.ValueType # 1 + """По худшему базовому активу.""" + OBSERVATION_PRINCIPLE_BEST_BASIC_ASSET: StructuredNote._ObservationPrinciple.ValueType # 2 + """По лучшему базовому активу.""" + OBSERVATION_PRINCIPLE_AVERAGE_OF_BASIC_ASSETS: StructuredNote._ObservationPrinciple.ValueType # 3 + """Среднее значение по базовым активам.""" + OBSERVATION_PRINCIPLE_SINGLE_BASIC_ASSET_PERFORMANCE: StructuredNote._ObservationPrinciple.ValueType # 4 + """Динамика актива (только если у ноты один базовый актив).""" + + class ObservationPrinciple(_ObservationPrinciple, metaclass=_ObservationPrincipleEnumTypeWrapper): + """Принцип наблюдений.""" + + OBSERVATION_PRINCIPLE_UNSPECIFIED: StructuredNote.ObservationPrinciple.ValueType # 0 + """Принцип наблюдений не определен.""" + OBSERVATION_PRINCIPLE_WORST_BASIC_ASSET: StructuredNote.ObservationPrinciple.ValueType # 1 + """По худшему базовому активу.""" + OBSERVATION_PRINCIPLE_BEST_BASIC_ASSET: StructuredNote.ObservationPrinciple.ValueType # 2 + """По лучшему базовому активу.""" + OBSERVATION_PRINCIPLE_AVERAGE_OF_BASIC_ASSETS: StructuredNote.ObservationPrinciple.ValueType # 3 + """Среднее значение по базовым активам.""" + OBSERVATION_PRINCIPLE_SINGLE_BASIC_ASSET_PERFORMANCE: StructuredNote.ObservationPrinciple.ValueType # 4 + """Динамика актива (только если у ноты один базовый актив).""" + + class _YieldType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _YieldTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[StructuredNote._YieldType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + YIELD_TYPE_UNSPECIFIED: StructuredNote._YieldType.ValueType # 0 + """Тип доходности не определен.""" + YIELD_TYPE_GUARANTED_COUPON: StructuredNote._YieldType.ValueType # 1 + """Гарантированный купон.""" + YIELD_TYPE_CONDITIONAL_COUPON: StructuredNote._YieldType.ValueType # 2 + """Условный купон.""" + YIELD_TYPE_PARTICIPATION: StructuredNote._YieldType.ValueType # 3 + """Участие в росте.""" + + class YieldType(_YieldType, metaclass=_YieldTypeEnumTypeWrapper): + """Тип доходности.""" + + YIELD_TYPE_UNSPECIFIED: StructuredNote.YieldType.ValueType # 0 + """Тип доходности не определен.""" + YIELD_TYPE_GUARANTED_COUPON: StructuredNote.YieldType.ValueType # 1 + """Гарантированный купон.""" + YIELD_TYPE_CONDITIONAL_COUPON: StructuredNote.YieldType.ValueType # 2 + """Условный купон.""" + YIELD_TYPE_PARTICIPATION: StructuredNote.YieldType.ValueType # 3 + """Участие в росте.""" + + @typing.final + class BasicAsset(google.protobuf.message.Message): + """Базовый актив.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + UID_FIELD_NUMBER: builtins.int + TYPE_FIELD_NUMBER: builtins.int + INITIAL_PRICE_FIELD_NUMBER: builtins.int + uid: builtins.str + """Уникальный идентификатор базового актива.""" + type: global___AssetType.ValueType + """Тип базового актива.""" + @property + def initial_price(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Начальная цена базового актива.""" + + def __init__( + self, + *, + uid: builtins.str = ..., + type: global___AssetType.ValueType = ..., + initial_price: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["initial_price", b"initial_price"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["initial_price", b"initial_price", "type", b"type", "uid", b"uid"]) -> None: ... + + @typing.final + class Yield(google.protobuf.message.Message): + """Доходность.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TYPE_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + type: global___StructuredNote.YieldType.ValueType + """Тип доходности.""" + @property + def value(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Значение доходности.""" + + def __init__( + self, + *, + type: global___StructuredNote.YieldType.ValueType = ..., + value: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["type", b"type", "value", b"value"]) -> None: ... + + UID_FIELD_NUMBER: builtins.int + FIGI_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + ISIN_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + ASSET_UID_FIELD_NUMBER: builtins.int + POSITION_UID_FIELD_NUMBER: builtins.int + MIN_PRICE_INCREMENT_FIELD_NUMBER: builtins.int + LOT_FIELD_NUMBER: builtins.int + NOMINAL_FIELD_NUMBER: builtins.int + CURRENCY_FIELD_NUMBER: builtins.int + MATURITY_DATE_FIELD_NUMBER: builtins.int + PLACEMENT_DATE_FIELD_NUMBER: builtins.int + ISSUE_KIND_FIELD_NUMBER: builtins.int + ISSUE_SIZE_FIELD_NUMBER: builtins.int + ISSUE_SIZE_PLAN_FIELD_NUMBER: builtins.int + DLONG_CLIENT_FIELD_NUMBER: builtins.int + DSHORT_CLIENT_FIELD_NUMBER: builtins.int + SHORT_ENABLED_FLAG_FIELD_NUMBER: builtins.int + EXCHANGE_FIELD_NUMBER: builtins.int + TRADING_STATUS_FIELD_NUMBER: builtins.int + API_TRADE_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + BUY_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + SELL_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + LIMIT_ORDER_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + MARKET_ORDER_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + BESTPRICE_ORDER_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + WEEKEND_FLAG_FIELD_NUMBER: builtins.int + LIQUIDITY_FLAG_FIELD_NUMBER: builtins.int + FOR_IIS_FLAG_FIELD_NUMBER: builtins.int + FOR_QUAL_INVESTOR_FLAG_FIELD_NUMBER: builtins.int + PAWNSHOP_LIST_FLAG_FIELD_NUMBER: builtins.int + REAL_EXCHANGE_FIELD_NUMBER: builtins.int + FIRST_1MIN_CANDLE_DATE_FIELD_NUMBER: builtins.int + FIRST_1DAY_CANDLE_DATE_FIELD_NUMBER: builtins.int + BORROW_NAME_FIELD_NUMBER: builtins.int + TYPE_FIELD_NUMBER: builtins.int + LOGIC_PORTFOLIO_FIELD_NUMBER: builtins.int + ASSET_TYPE_FIELD_NUMBER: builtins.int + BASIC_ASSETS_FIELD_NUMBER: builtins.int + SAFETY_BARRIER_FIELD_NUMBER: builtins.int + COUPON_PERIOD_BASE_FIELD_NUMBER: builtins.int + OBSERVATION_PRINCIPLE_FIELD_NUMBER: builtins.int + OBSERVATION_FREQUENCY_FIELD_NUMBER: builtins.int + INITIAL_PRICE_FIXING_DATE_FIELD_NUMBER: builtins.int + YIELD_FIELD_NUMBER: builtins.int + COUPON_SAVING_FLAG_FIELD_NUMBER: builtins.int + SECTOR_FIELD_NUMBER: builtins.int + COUNTRY_OF_RISK_FIELD_NUMBER: builtins.int + COUNTRY_OF_RISK_NAME_FIELD_NUMBER: builtins.int + LOGO_NAME_FIELD_NUMBER: builtins.int + REQUIRED_TESTS_FIELD_NUMBER: builtins.int + uid: builtins.str + """Уникальный идентификатор инструмента.""" + figi: builtins.str + """FIGI-идентификатор инструмента.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + isin: builtins.str + """ISIN-идентификатор инструмента.""" + name: builtins.str + """Название инструмента.""" + asset_uid: builtins.str + """Уникальный идентификатор актива.""" + position_uid: builtins.str + """Уникальный идентификатор позиции.""" + lot: builtins.int + """Лотность инструмента.""" + currency: builtins.str + """Валюта расчетов.""" + issue_kind: builtins.str + """Форма выпуска.""" + issue_size: builtins.int + """Размер выпуска.""" + issue_size_plan: builtins.int + """Плановый размер выпуска.""" + short_enabled_flag: builtins.bool + """Признак доступности для операций в шорт.""" + exchange: builtins.str + """Торговая площадка (секция биржи).""" + trading_status: t_tech.invest.grpc.common_pb2.SecurityTradingStatus.ValueType + """Текущий режим торгов инструмента.""" + api_trade_available_flag: builtins.bool + """Признак доступности торгов по бумаге через API.""" + buy_available_flag: builtins.bool + """Признак доступности для покупки.""" + sell_available_flag: builtins.bool + """Признак доступности для продажи.""" + limit_order_available_flag: builtins.bool + """Признак доступности выставления лимитной заявки по инструменту.""" + market_order_available_flag: builtins.bool + """Признак доступности выставления рыночной заявки по инструменту.""" + bestprice_order_available_flag: builtins.bool + """Признак доступности выставления bestprice заявки по инструменту.""" + weekend_flag: builtins.bool + """Флаг отображающий доступность торговли инструментом по выходным.""" + liquidity_flag: builtins.bool + """Флаг достаточной ликвидности.""" + for_iis_flag: builtins.bool + """Возможность покупки/продажи на ИИС.""" + for_qual_investor_flag: builtins.bool + """Флаг отображающий доступность торговли инструментом только для квалифицированных инвесторов.""" + pawnshop_list_flag: builtins.bool + """Признак ФИ, включенного в ломбардный список.""" + real_exchange: t_tech.invest.grpc.common_pb2.RealExchange.ValueType + """Реальная площадка исполнения расчётов.""" + borrow_name: builtins.str + """Название заемщика.""" + type: builtins.str + """Тип структурной ноты.""" + logic_portfolio: global___StructuredNote.LogicPortfolio.ValueType + """Стратегия портфеля.""" + asset_type: global___AssetType.ValueType + """Тип базового актива.""" + coupon_period_base: builtins.str + """Базис расчета НКД.""" + observation_principle: global___StructuredNote.ObservationPrinciple.ValueType + """Принцип наблюдений.""" + observation_frequency: builtins.str + """Частота наблюдений.""" + coupon_saving_flag: builtins.bool + """Признак сохранения купонов.""" + sector: builtins.str + """Сектор экономики.""" + country_of_risk: builtins.str + """Код страны рисков.""" + country_of_risk_name: builtins.str + """Наименование страны рисков.""" + logo_name: builtins.str + """Имя файла логотипа эмитента.""" + @property + def min_price_increment(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Шаг цены.""" + + @property + def nominal(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Номинал.""" + + @property + def maturity_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата погашения облигации в формате UTC.""" + + @property + def placement_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата размещения в формате UTC.""" + + @property + def dlong_client(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска клиента по инструменту лонг.""" + + @property + def dshort_client(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска клиента по инструменту шорт.""" + + @property + def first_1min_candle_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата первой минутной свечи.""" + + @property + def first_1day_candle_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата первой дневной свечи.""" + + @property + def basic_assets(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___StructuredNote.BasicAsset]: + """Базовые активы, входящие в ноту.""" + + @property + def safety_barrier(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Барьер сохранности (в процентах).""" + + @property + def initial_price_fixing_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата фиксации цен базовых активов.""" + + @property + def required_tests(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Тесты, которые необходимо пройти клиенту, чтобы совершать покупки по бумаге.""" + + def __init__( + self, + *, + uid: builtins.str = ..., + figi: builtins.str = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + isin: builtins.str = ..., + name: builtins.str = ..., + asset_uid: builtins.str = ..., + position_uid: builtins.str = ..., + min_price_increment: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + lot: builtins.int = ..., + nominal: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + currency: builtins.str = ..., + maturity_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + placement_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + issue_kind: builtins.str = ..., + issue_size: builtins.int = ..., + issue_size_plan: builtins.int = ..., + dlong_client: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dshort_client: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + short_enabled_flag: builtins.bool = ..., + exchange: builtins.str = ..., + trading_status: t_tech.invest.grpc.common_pb2.SecurityTradingStatus.ValueType = ..., + api_trade_available_flag: builtins.bool = ..., + buy_available_flag: builtins.bool = ..., + sell_available_flag: builtins.bool = ..., + limit_order_available_flag: builtins.bool = ..., + market_order_available_flag: builtins.bool = ..., + bestprice_order_available_flag: builtins.bool = ..., + weekend_flag: builtins.bool = ..., + liquidity_flag: builtins.bool = ..., + for_iis_flag: builtins.bool = ..., + for_qual_investor_flag: builtins.bool = ..., + pawnshop_list_flag: builtins.bool = ..., + real_exchange: t_tech.invest.grpc.common_pb2.RealExchange.ValueType = ..., + first_1min_candle_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + first_1day_candle_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + borrow_name: builtins.str = ..., + type: builtins.str = ..., + logic_portfolio: global___StructuredNote.LogicPortfolio.ValueType = ..., + asset_type: global___AssetType.ValueType = ..., + basic_assets: collections.abc.Iterable[global___StructuredNote.BasicAsset] | None = ..., + safety_barrier: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + coupon_period_base: builtins.str = ..., + observation_principle: global___StructuredNote.ObservationPrinciple.ValueType = ..., + observation_frequency: builtins.str = ..., + initial_price_fixing_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + coupon_saving_flag: builtins.bool = ..., + sector: builtins.str = ..., + country_of_risk: builtins.str = ..., + country_of_risk_name: builtins.str = ..., + logo_name: builtins.str = ..., + required_tests: collections.abc.Iterable[builtins.str] | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["dlong_client", b"dlong_client", "dshort_client", b"dshort_client", "first_1day_candle_date", b"first_1day_candle_date", "first_1min_candle_date", b"first_1min_candle_date", "initial_price_fixing_date", b"initial_price_fixing_date", "maturity_date", b"maturity_date", "min_price_increment", b"min_price_increment", "nominal", b"nominal", "placement_date", b"placement_date", "safety_barrier", b"safety_barrier"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["api_trade_available_flag", b"api_trade_available_flag", "asset_type", b"asset_type", "asset_uid", b"asset_uid", "basic_assets", b"basic_assets", "bestprice_order_available_flag", b"bestprice_order_available_flag", "borrow_name", b"borrow_name", "buy_available_flag", b"buy_available_flag", "class_code", b"class_code", "country_of_risk", b"country_of_risk", "country_of_risk_name", b"country_of_risk_name", "coupon_period_base", b"coupon_period_base", "coupon_saving_flag", b"coupon_saving_flag", "currency", b"currency", "dlong_client", b"dlong_client", "dshort_client", b"dshort_client", "exchange", b"exchange", "figi", b"figi", "first_1day_candle_date", b"first_1day_candle_date", "first_1min_candle_date", b"first_1min_candle_date", "for_iis_flag", b"for_iis_flag", "for_qual_investor_flag", b"for_qual_investor_flag", "initial_price_fixing_date", b"initial_price_fixing_date", "isin", b"isin", "issue_kind", b"issue_kind", "issue_size", b"issue_size", "issue_size_plan", b"issue_size_plan", "limit_order_available_flag", b"limit_order_available_flag", "liquidity_flag", b"liquidity_flag", "logic_portfolio", b"logic_portfolio", "logo_name", b"logo_name", "lot", b"lot", "market_order_available_flag", b"market_order_available_flag", "maturity_date", b"maturity_date", "min_price_increment", b"min_price_increment", "name", b"name", "nominal", b"nominal", "observation_frequency", b"observation_frequency", "observation_principle", b"observation_principle", "pawnshop_list_flag", b"pawnshop_list_flag", "placement_date", b"placement_date", "position_uid", b"position_uid", "real_exchange", b"real_exchange", "required_tests", b"required_tests", "safety_barrier", b"safety_barrier", "sector", b"sector", "sell_available_flag", b"sell_available_flag", "short_enabled_flag", b"short_enabled_flag", "ticker", b"ticker", "trading_status", b"trading_status", "type", b"type", "uid", b"uid", "weekend_flag", b"weekend_flag", "yield", b"yield"]) -> None: ... + +global___StructuredNote = StructuredNote + +@typing.final +class GetAccruedInterestsRequest(google.protobuf.message.Message): + """Запрос НКД по облигации.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + FROM_FIELD_NUMBER: builtins.int + TO_FIELD_NUMBER: builtins.int + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI-идентификатор инструмента.""" + instrument_id: builtins.str + """Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`.""" + @property + def to(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Окончание запрашиваемого периода по UTC.""" + + def __init__( + self, + *, + figi: builtins.str = ..., + to: google.protobuf.timestamp_pb2.Timestamp | None = ..., + instrument_id: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["from", b"from", "to", b"to"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["figi", b"figi", "from", b"from", "instrument_id", b"instrument_id", "to", b"to"]) -> None: ... + +global___GetAccruedInterestsRequest = GetAccruedInterestsRequest + +@typing.final +class GetAccruedInterestsResponse(google.protobuf.message.Message): + """НКД облигации.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCRUED_INTERESTS_FIELD_NUMBER: builtins.int + @property + def accrued_interests(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___AccruedInterest]: + """Массив операций начисления купонов.""" + + def __init__( + self, + *, + accrued_interests: collections.abc.Iterable[global___AccruedInterest] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["accrued_interests", b"accrued_interests"]) -> None: ... + +global___GetAccruedInterestsResponse = GetAccruedInterestsResponse + +@typing.final +class AccruedInterest(google.protobuf.message.Message): + """Операция начисления купонов.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + DATE_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + VALUE_PERCENT_FIELD_NUMBER: builtins.int + NOMINAL_FIELD_NUMBER: builtins.int + @property + def date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата и время выплаты по UTC.""" + + @property + def value(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Величина выплаты.""" + + @property + def value_percent(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Величина выплаты в процентах от номинала.""" + + @property + def nominal(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Номинал облигации.""" + + def __init__( + self, + *, + date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + value: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + value_percent: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + nominal: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["date", b"date", "nominal", b"nominal", "value", b"value", "value_percent", b"value_percent"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["date", b"date", "nominal", b"nominal", "value", b"value", "value_percent", b"value_percent"]) -> None: ... + +global___AccruedInterest = AccruedInterest + +@typing.final +class GetFuturesMarginRequest(google.protobuf.message.Message): + """Запрос информации о фьючерсе""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + figi: builtins.str + """Идентификатор инструмента.""" + instrument_id: builtins.str + """Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`.""" + def __init__( + self, + *, + figi: builtins.str = ..., + instrument_id: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["figi", b"figi", "instrument_id", b"instrument_id"]) -> None: ... + +global___GetFuturesMarginRequest = GetFuturesMarginRequest + +@typing.final +class GetFuturesMarginResponse(google.protobuf.message.Message): + """Данные по фьючерсу""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INITIAL_MARGIN_ON_BUY_FIELD_NUMBER: builtins.int + INITIAL_MARGIN_ON_SELL_FIELD_NUMBER: builtins.int + MIN_PRICE_INCREMENT_FIELD_NUMBER: builtins.int + MIN_PRICE_INCREMENT_AMOUNT_FIELD_NUMBER: builtins.int + @property + def initial_margin_on_buy(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Гарантийное обеспечение при покупке.""" + + @property + def initial_margin_on_sell(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Гарантийное обеспечение при продаже.""" + + @property + def min_price_increment(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Шаг цены.""" + + @property + def min_price_increment_amount(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Стоимость шага цены.""" + + def __init__( + self, + *, + initial_margin_on_buy: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + initial_margin_on_sell: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + min_price_increment: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + min_price_increment_amount: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["initial_margin_on_buy", b"initial_margin_on_buy", "initial_margin_on_sell", b"initial_margin_on_sell", "min_price_increment", b"min_price_increment", "min_price_increment_amount", b"min_price_increment_amount"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["initial_margin_on_buy", b"initial_margin_on_buy", "initial_margin_on_sell", b"initial_margin_on_sell", "min_price_increment", b"min_price_increment", "min_price_increment_amount", b"min_price_increment_amount"]) -> None: ... + +global___GetFuturesMarginResponse = GetFuturesMarginResponse + +@typing.final +class InstrumentResponse(google.protobuf.message.Message): + """Данные по инструменту.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENT_FIELD_NUMBER: builtins.int + @property + def instrument(self) -> global___Instrument: + """Основная информация об инструменте.""" + + def __init__( + self, + *, + instrument: global___Instrument | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["instrument", b"instrument"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["instrument", b"instrument"]) -> None: ... + +global___InstrumentResponse = InstrumentResponse + +@typing.final +class Instrument(google.protobuf.message.Message): + """Объект передачи основной информации об инструменте.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + ISIN_FIELD_NUMBER: builtins.int + LOT_FIELD_NUMBER: builtins.int + CURRENCY_FIELD_NUMBER: builtins.int + KLONG_FIELD_NUMBER: builtins.int + KSHORT_FIELD_NUMBER: builtins.int + DLONG_FIELD_NUMBER: builtins.int + DSHORT_FIELD_NUMBER: builtins.int + DLONG_MIN_FIELD_NUMBER: builtins.int + DSHORT_MIN_FIELD_NUMBER: builtins.int + SHORT_ENABLED_FLAG_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + EXCHANGE_FIELD_NUMBER: builtins.int + COUNTRY_OF_RISK_FIELD_NUMBER: builtins.int + COUNTRY_OF_RISK_NAME_FIELD_NUMBER: builtins.int + INSTRUMENT_TYPE_FIELD_NUMBER: builtins.int + TRADING_STATUS_FIELD_NUMBER: builtins.int + OTC_FLAG_FIELD_NUMBER: builtins.int + BUY_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + SELL_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + MIN_PRICE_INCREMENT_FIELD_NUMBER: builtins.int + API_TRADE_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + UID_FIELD_NUMBER: builtins.int + REAL_EXCHANGE_FIELD_NUMBER: builtins.int + POSITION_UID_FIELD_NUMBER: builtins.int + ASSET_UID_FIELD_NUMBER: builtins.int + REQUIRED_TESTS_FIELD_NUMBER: builtins.int + FOR_IIS_FLAG_FIELD_NUMBER: builtins.int + FOR_QUAL_INVESTOR_FLAG_FIELD_NUMBER: builtins.int + WEEKEND_FLAG_FIELD_NUMBER: builtins.int + BLOCKED_TCA_FLAG_FIELD_NUMBER: builtins.int + INSTRUMENT_KIND_FIELD_NUMBER: builtins.int + FIRST_1MIN_CANDLE_DATE_FIELD_NUMBER: builtins.int + FIRST_1DAY_CANDLE_DATE_FIELD_NUMBER: builtins.int + BRAND_FIELD_NUMBER: builtins.int + DLONG_CLIENT_FIELD_NUMBER: builtins.int + DSHORT_CLIENT_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI-идентификатор инструмента.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код инструмента.""" + isin: builtins.str + """ISIN-идентификатор инструмента.""" + lot: builtins.int + """Лотность инструмента. Возможно совершение операций только на количества ценной бумаги, кратные параметру `lot`. [Подробнее](./glossary#lot).""" + currency: builtins.str + """Валюта расчетов.""" + short_enabled_flag: builtins.bool + """Признак доступности для операций в шорт.""" + name: builtins.str + """Название инструмента.""" + exchange: builtins.str + """Tорговая площадка (секция биржи).""" + country_of_risk: builtins.str + """Код страны риска — то есть страны, в которой компания ведет основной бизнес.""" + country_of_risk_name: builtins.str + """Наименование страны риска — то есть страны, в которой компания ведет основной бизнес.""" + instrument_type: builtins.str + """Тип инструмента.""" + trading_status: t_tech.invest.grpc.common_pb2.SecurityTradingStatus.ValueType + """Текущий режим торгов инструмента.""" + otc_flag: builtins.bool + """Флаг, используемый ранее для определения внебиржевых инструментов. На данный момент не используется для торгуемых через API инструментов. Может использоваться как фильтр для операций, совершавшихся некоторое время назад на ОТС площадке.""" + buy_available_flag: builtins.bool + """Признак доступности для покупки.""" + sell_available_flag: builtins.bool + """Признак доступности для продажи.""" + api_trade_available_flag: builtins.bool + """Параметр указывает на возможность торговать инструментом через API.""" + uid: builtins.str + """Уникальный идентификатор инструмента.""" + real_exchange: t_tech.invest.grpc.common_pb2.RealExchange.ValueType + """Реальная площадка исполнения расчетов (биржа).""" + position_uid: builtins.str + """Уникальный идентификатор позиции инструмента.""" + asset_uid: builtins.str + """Уникальный идентификатор актива.""" + for_iis_flag: builtins.bool + """Признак доступности для ИИС.""" + for_qual_investor_flag: builtins.bool + """Флаг, отображающий доступность торговли инструментом только для квалифицированных инвесторов.""" + weekend_flag: builtins.bool + """Флаг, отображающий доступность торговли инструментом по выходным.""" + blocked_tca_flag: builtins.bool + """Флаг заблокированного ТКС.""" + instrument_kind: t_tech.invest.grpc.common_pb2.InstrumentType.ValueType + """Тип инструмента.""" + @property + def klong(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Коэффициент ставки риска длинной позиции по клиенту. 2 – клиент со стандартным уровнем риска (КСУР); 1 – клиент с повышенным уровнем риска (КПУР).""" + + @property + def kshort(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Коэффициент ставки риска короткой позиции по клиенту. 2 – клиент со стандартным уровнем риска (КСУР); 1 – клиент с повышенным уровнем риска (КПУР).""" + + @property + def dlong(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска начальной маржи для КСУР лонг. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def dshort(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска начальной маржи для КСУР шорт. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def dlong_min(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска начальной маржи для КПУР лонг. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def dshort_min(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска начальной маржи для КПУР шорт. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def min_price_increment(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Шаг цены.""" + + @property + def required_tests(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Тесты, которые необходимо пройти клиенту, чтобы совершать сделки по инструменту.""" + + @property + def first_1min_candle_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата первой минутной свечи.""" + + @property + def first_1day_candle_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата первой дневной свечи.""" + + @property + def brand(self) -> t_tech.invest.grpc.common_pb2.BrandData: + """Информация о бренде.""" + + @property + def dlong_client(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска в лонг с учетом текущего уровня риска портфеля клиента. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + @property + def dshort_client(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка риска в шорт с учетом текущего уровня риска портфеля клиента. [Подробнее про ставки риска](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q5).""" + + def __init__( + self, + *, + figi: builtins.str = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + isin: builtins.str = ..., + lot: builtins.int = ..., + currency: builtins.str = ..., + klong: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + kshort: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dlong: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dshort: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dlong_min: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dshort_min: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + short_enabled_flag: builtins.bool = ..., + name: builtins.str = ..., + exchange: builtins.str = ..., + country_of_risk: builtins.str = ..., + country_of_risk_name: builtins.str = ..., + instrument_type: builtins.str = ..., + trading_status: t_tech.invest.grpc.common_pb2.SecurityTradingStatus.ValueType = ..., + otc_flag: builtins.bool = ..., + buy_available_flag: builtins.bool = ..., + sell_available_flag: builtins.bool = ..., + min_price_increment: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + api_trade_available_flag: builtins.bool = ..., + uid: builtins.str = ..., + real_exchange: t_tech.invest.grpc.common_pb2.RealExchange.ValueType = ..., + position_uid: builtins.str = ..., + asset_uid: builtins.str = ..., + required_tests: collections.abc.Iterable[builtins.str] | None = ..., + for_iis_flag: builtins.bool = ..., + for_qual_investor_flag: builtins.bool = ..., + weekend_flag: builtins.bool = ..., + blocked_tca_flag: builtins.bool = ..., + instrument_kind: t_tech.invest.grpc.common_pb2.InstrumentType.ValueType = ..., + first_1min_candle_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + first_1day_candle_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + brand: t_tech.invest.grpc.common_pb2.BrandData | None = ..., + dlong_client: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dshort_client: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["brand", b"brand", "dlong", b"dlong", "dlong_client", b"dlong_client", "dlong_min", b"dlong_min", "dshort", b"dshort", "dshort_client", b"dshort_client", "dshort_min", b"dshort_min", "first_1day_candle_date", b"first_1day_candle_date", "first_1min_candle_date", b"first_1min_candle_date", "klong", b"klong", "kshort", b"kshort", "min_price_increment", b"min_price_increment"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["api_trade_available_flag", b"api_trade_available_flag", "asset_uid", b"asset_uid", "blocked_tca_flag", b"blocked_tca_flag", "brand", b"brand", "buy_available_flag", b"buy_available_flag", "class_code", b"class_code", "country_of_risk", b"country_of_risk", "country_of_risk_name", b"country_of_risk_name", "currency", b"currency", "dlong", b"dlong", "dlong_client", b"dlong_client", "dlong_min", b"dlong_min", "dshort", b"dshort", "dshort_client", b"dshort_client", "dshort_min", b"dshort_min", "exchange", b"exchange", "figi", b"figi", "first_1day_candle_date", b"first_1day_candle_date", "first_1min_candle_date", b"first_1min_candle_date", "for_iis_flag", b"for_iis_flag", "for_qual_investor_flag", b"for_qual_investor_flag", "instrument_kind", b"instrument_kind", "instrument_type", b"instrument_type", "isin", b"isin", "klong", b"klong", "kshort", b"kshort", "lot", b"lot", "min_price_increment", b"min_price_increment", "name", b"name", "otc_flag", b"otc_flag", "position_uid", b"position_uid", "real_exchange", b"real_exchange", "required_tests", b"required_tests", "sell_available_flag", b"sell_available_flag", "short_enabled_flag", b"short_enabled_flag", "ticker", b"ticker", "trading_status", b"trading_status", "uid", b"uid", "weekend_flag", b"weekend_flag"]) -> None: ... + +global___Instrument = Instrument + +@typing.final +class GetDividendsRequest(google.protobuf.message.Message): + """Запрос дивидендов.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + FROM_FIELD_NUMBER: builtins.int + TO_FIELD_NUMBER: builtins.int + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI-идентификатор инструмента.""" + instrument_id: builtins.str + """Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`.""" + @property + def to(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Окончание запрашиваемого периода по UTC. Фильтрация происходит по параметру `record_date` — дата фиксации реестра.""" + + def __init__( + self, + *, + figi: builtins.str = ..., + to: google.protobuf.timestamp_pb2.Timestamp | None = ..., + instrument_id: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_from", b"_from", "_to", b"_to", "from", b"from", "to", b"to"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_from", b"_from", "_to", b"_to", "figi", b"figi", "from", b"from", "instrument_id", b"instrument_id", "to", b"to"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_from", b"_from"]) -> typing.Literal["from"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_to", b"_to"]) -> typing.Literal["to"] | None: ... + +global___GetDividendsRequest = GetDividendsRequest + +@typing.final +class GetDividendsResponse(google.protobuf.message.Message): + """Дивиденды.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + DIVIDENDS_FIELD_NUMBER: builtins.int + @property + def dividends(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Dividend]: ... + def __init__( + self, + *, + dividends: collections.abc.Iterable[global___Dividend] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["dividends", b"dividends"]) -> None: ... + +global___GetDividendsResponse = GetDividendsResponse + +@typing.final +class Dividend(google.protobuf.message.Message): + """Информация о выплате.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + DIVIDEND_NET_FIELD_NUMBER: builtins.int + PAYMENT_DATE_FIELD_NUMBER: builtins.int + DECLARED_DATE_FIELD_NUMBER: builtins.int + LAST_BUY_DATE_FIELD_NUMBER: builtins.int + DIVIDEND_TYPE_FIELD_NUMBER: builtins.int + RECORD_DATE_FIELD_NUMBER: builtins.int + REGULARITY_FIELD_NUMBER: builtins.int + CLOSE_PRICE_FIELD_NUMBER: builtins.int + YIELD_VALUE_FIELD_NUMBER: builtins.int + CREATED_AT_FIELD_NUMBER: builtins.int + dividend_type: builtins.str + """Тип выплаты. Возможные значения: `Regular Cash` – регулярные выплаты, `Cancelled` – выплата отменена, `Daily Accrual` – ежедневное начисление, `Return of Capital` – возврат капитала, прочие типы выплат.""" + regularity: builtins.str + """Регулярность выплаты. Возможные значения: `Annual` – ежегодная, `Semi-Anl` – каждые полгода, прочие типы выплат.""" + @property + def dividend_net(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Величина дивиденда на 1 ценную бумагу (включая валюту).""" + + @property + def payment_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата фактических выплат по UTC.""" + + @property + def declared_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата объявления дивидендов по UTC.""" + + @property + def last_buy_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Последний день (включительно) покупки для получения выплаты по UTC.""" + + @property + def record_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата фиксации реестра по UTC.""" + + @property + def close_price(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Цена закрытия инструмента на момент `ex_dividend_date`.""" + + @property + def yield_value(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Величина доходности.""" + + @property + def created_at(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата и время создания записи по UTC.""" + + def __init__( + self, + *, + dividend_net: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + payment_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + declared_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + last_buy_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + dividend_type: builtins.str = ..., + record_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + regularity: builtins.str = ..., + close_price: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + yield_value: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + created_at: google.protobuf.timestamp_pb2.Timestamp | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["close_price", b"close_price", "created_at", b"created_at", "declared_date", b"declared_date", "dividend_net", b"dividend_net", "last_buy_date", b"last_buy_date", "payment_date", b"payment_date", "record_date", b"record_date", "yield_value", b"yield_value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["close_price", b"close_price", "created_at", b"created_at", "declared_date", b"declared_date", "dividend_net", b"dividend_net", "dividend_type", b"dividend_type", "last_buy_date", b"last_buy_date", "payment_date", b"payment_date", "record_date", b"record_date", "regularity", b"regularity", "yield_value", b"yield_value"]) -> None: ... + +global___Dividend = Dividend + +@typing.final +class AssetRequest(google.protobuf.message.Message): + """Запрос актива по идентификатору.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ID_FIELD_NUMBER: builtins.int + id: builtins.str + """UID-идентификатор актива.""" + def __init__( + self, + *, + id: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["id", b"id"]) -> None: ... + +global___AssetRequest = AssetRequest + +@typing.final +class AssetResponse(google.protobuf.message.Message): + """Данные по активу.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ASSET_FIELD_NUMBER: builtins.int + @property + def asset(self) -> global___AssetFull: + """Актив.""" + + def __init__( + self, + *, + asset: global___AssetFull | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["asset", b"asset"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["asset", b"asset"]) -> None: ... + +global___AssetResponse = AssetResponse + +@typing.final +class AssetsRequest(google.protobuf.message.Message): + """Запрос списка активов.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENT_TYPE_FIELD_NUMBER: builtins.int + INSTRUMENT_STATUS_FIELD_NUMBER: builtins.int + instrument_type: t_tech.invest.grpc.common_pb2.InstrumentType.ValueType + instrument_status: t_tech.invest.grpc.common_pb2.InstrumentStatus.ValueType + """Статус запрашиваемых инструментов. [Возможные значения](#instrumentstatus).""" + def __init__( + self, + *, + instrument_type: t_tech.invest.grpc.common_pb2.InstrumentType.ValueType | None = ..., + instrument_status: t_tech.invest.grpc.common_pb2.InstrumentStatus.ValueType | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_instrument_status", b"_instrument_status", "_instrument_type", b"_instrument_type", "instrument_status", b"instrument_status", "instrument_type", b"instrument_type"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_instrument_status", b"_instrument_status", "_instrument_type", b"_instrument_type", "instrument_status", b"instrument_status", "instrument_type", b"instrument_type"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_instrument_status", b"_instrument_status"]) -> typing.Literal["instrument_status"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_instrument_type", b"_instrument_type"]) -> typing.Literal["instrument_type"] | None: ... + +global___AssetsRequest = AssetsRequest + +@typing.final +class AssetsResponse(google.protobuf.message.Message): + """Список активов.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ASSETS_FIELD_NUMBER: builtins.int + @property + def assets(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Asset]: + """Активы.""" + + def __init__( + self, + *, + assets: collections.abc.Iterable[global___Asset] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["assets", b"assets"]) -> None: ... + +global___AssetsResponse = AssetsResponse + +@typing.final +class AssetFull(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + UID_FIELD_NUMBER: builtins.int + TYPE_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + NAME_BRIEF_FIELD_NUMBER: builtins.int + DESCRIPTION_FIELD_NUMBER: builtins.int + DELETED_AT_FIELD_NUMBER: builtins.int + REQUIRED_TESTS_FIELD_NUMBER: builtins.int + CURRENCY_FIELD_NUMBER: builtins.int + SECURITY_FIELD_NUMBER: builtins.int + GOS_REG_CODE_FIELD_NUMBER: builtins.int + CFI_FIELD_NUMBER: builtins.int + CODE_NSD_FIELD_NUMBER: builtins.int + STATUS_FIELD_NUMBER: builtins.int + BRAND_FIELD_NUMBER: builtins.int + UPDATED_AT_FIELD_NUMBER: builtins.int + BR_CODE_FIELD_NUMBER: builtins.int + BR_CODE_NAME_FIELD_NUMBER: builtins.int + INSTRUMENTS_FIELD_NUMBER: builtins.int + uid: builtins.str + """Уникальный идентификатор актива.""" + type: global___AssetType.ValueType + """Тип актива.""" + name: builtins.str + """Наименование актива.""" + name_brief: builtins.str + """Короткое наименование актива.""" + description: builtins.str + """Описание актива.""" + gos_reg_code: builtins.str + """Номер государственной регистрации.""" + cfi: builtins.str + """Код CFI.""" + code_nsd: builtins.str + """Код НРД инструмента.""" + status: builtins.str + """Статус актива.""" + br_code: builtins.str + """Код типа ц.б. по классификации Банка России.""" + br_code_name: builtins.str + """Наименование кода типа ц.б. по классификации Банка России.""" + @property + def deleted_at(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата и время удаления актива.""" + + @property + def required_tests(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Тестирование клиентов.""" + + @property + def currency(self) -> global___AssetCurrency: + """Валюта. Обязательно и заполняется только для `type = ASSET_TYPE_CURRENCY`.""" + + @property + def security(self) -> global___AssetSecurity: + """Ценная бумага. Обязательно и заполняется только для `type = ASSET_TYPE_SECURITY`.""" + + @property + def brand(self) -> global___Brand: + """Бренд.""" + + @property + def updated_at(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата и время последнего обновления записи.""" + + @property + def instruments(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___AssetInstrument]: + """Массив идентификаторов инструментов.""" + + def __init__( + self, + *, + uid: builtins.str = ..., + type: global___AssetType.ValueType = ..., + name: builtins.str = ..., + name_brief: builtins.str = ..., + description: builtins.str = ..., + deleted_at: google.protobuf.timestamp_pb2.Timestamp | None = ..., + required_tests: collections.abc.Iterable[builtins.str] | None = ..., + currency: global___AssetCurrency | None = ..., + security: global___AssetSecurity | None = ..., + gos_reg_code: builtins.str = ..., + cfi: builtins.str = ..., + code_nsd: builtins.str = ..., + status: builtins.str = ..., + brand: global___Brand | None = ..., + updated_at: google.protobuf.timestamp_pb2.Timestamp | None = ..., + br_code: builtins.str = ..., + br_code_name: builtins.str = ..., + instruments: collections.abc.Iterable[global___AssetInstrument] | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["brand", b"brand", "currency", b"currency", "deleted_at", b"deleted_at", "ext", b"ext", "security", b"security", "updated_at", b"updated_at"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["br_code", b"br_code", "br_code_name", b"br_code_name", "brand", b"brand", "cfi", b"cfi", "code_nsd", b"code_nsd", "currency", b"currency", "deleted_at", b"deleted_at", "description", b"description", "ext", b"ext", "gos_reg_code", b"gos_reg_code", "instruments", b"instruments", "name", b"name", "name_brief", b"name_brief", "required_tests", b"required_tests", "security", b"security", "status", b"status", "type", b"type", "uid", b"uid", "updated_at", b"updated_at"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["ext", b"ext"]) -> typing.Literal["currency", "security"] | None: ... + +global___AssetFull = AssetFull + +@typing.final +class Asset(google.protobuf.message.Message): + """Информация об активе.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + UID_FIELD_NUMBER: builtins.int + TYPE_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + INSTRUMENTS_FIELD_NUMBER: builtins.int + uid: builtins.str + """Уникальный идентификатор актива.""" + type: global___AssetType.ValueType + """Тип актива.""" + name: builtins.str + """Наименование актива.""" + @property + def instruments(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___AssetInstrument]: + """Массив идентификаторов инструментов.""" + + def __init__( + self, + *, + uid: builtins.str = ..., + type: global___AssetType.ValueType = ..., + name: builtins.str = ..., + instruments: collections.abc.Iterable[global___AssetInstrument] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["instruments", b"instruments", "name", b"name", "type", b"type", "uid", b"uid"]) -> None: ... + +global___Asset = Asset + +@typing.final +class AssetCurrency(google.protobuf.message.Message): + """Валюта.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + BASE_CURRENCY_FIELD_NUMBER: builtins.int + base_currency: builtins.str + """ISO-код валюты.""" + def __init__( + self, + *, + base_currency: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["base_currency", b"base_currency"]) -> None: ... + +global___AssetCurrency = AssetCurrency + +@typing.final +class AssetSecurity(google.protobuf.message.Message): + """Ценная бумага.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ISIN_FIELD_NUMBER: builtins.int + TYPE_FIELD_NUMBER: builtins.int + INSTRUMENT_KIND_FIELD_NUMBER: builtins.int + SHARE_FIELD_NUMBER: builtins.int + BOND_FIELD_NUMBER: builtins.int + SP_FIELD_NUMBER: builtins.int + ETF_FIELD_NUMBER: builtins.int + CLEARING_CERTIFICATE_FIELD_NUMBER: builtins.int + isin: builtins.str + """ISIN-идентификатор ценной бумаги.""" + type: builtins.str + """Тип ценной бумаги.""" + instrument_kind: t_tech.invest.grpc.common_pb2.InstrumentType.ValueType + """Тип инструмента.""" + @property + def share(self) -> global___AssetShare: + """Акция. Заполняется только для акций — тип актива `asset.type = ASSET_TYPE_SECURITY` и `security.type = share`.""" + + @property + def bond(self) -> global___AssetBond: + """Облигация. Заполняется только для облигаций — тип актива `asset.type = ASSET_TYPE_SECURITY` и `security.type = bond`.""" + + @property + def sp(self) -> global___AssetStructuredProduct: + """Структурная нота. Заполняется только для структурных продуктов — тип актива `asset.type = ASSET_TYPE_SECURITY` и `security.type = sp`.""" + + @property + def etf(self) -> global___AssetEtf: + """Фонд. Заполняется только для фондов — тип актива `asset.type = ASSET_TYPE_SECURITY` и `security.type = etf`.""" + + @property + def clearing_certificate(self) -> global___AssetClearingCertificate: + """Клиринговый сертификат участия. Заполняется только для клиринговых сертификатов — тип актива `asset.type = ASSET_TYPE_SECURITY` и security.type = `clearing_certificate`.""" + + def __init__( + self, + *, + isin: builtins.str = ..., + type: builtins.str = ..., + instrument_kind: t_tech.invest.grpc.common_pb2.InstrumentType.ValueType = ..., + share: global___AssetShare | None = ..., + bond: global___AssetBond | None = ..., + sp: global___AssetStructuredProduct | None = ..., + etf: global___AssetEtf | None = ..., + clearing_certificate: global___AssetClearingCertificate | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["bond", b"bond", "clearing_certificate", b"clearing_certificate", "etf", b"etf", "ext", b"ext", "share", b"share", "sp", b"sp"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["bond", b"bond", "clearing_certificate", b"clearing_certificate", "etf", b"etf", "ext", b"ext", "instrument_kind", b"instrument_kind", "isin", b"isin", "share", b"share", "sp", b"sp", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["ext", b"ext"]) -> typing.Literal["share", "bond", "sp", "etf", "clearing_certificate"] | None: ... + +global___AssetSecurity = AssetSecurity + +@typing.final +class AssetShare(google.protobuf.message.Message): + """Акция.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TYPE_FIELD_NUMBER: builtins.int + ISSUE_SIZE_FIELD_NUMBER: builtins.int + NOMINAL_FIELD_NUMBER: builtins.int + NOMINAL_CURRENCY_FIELD_NUMBER: builtins.int + PRIMARY_INDEX_FIELD_NUMBER: builtins.int + DIVIDEND_RATE_FIELD_NUMBER: builtins.int + PREFERRED_SHARE_TYPE_FIELD_NUMBER: builtins.int + IPO_DATE_FIELD_NUMBER: builtins.int + REGISTRY_DATE_FIELD_NUMBER: builtins.int + DIV_YIELD_FLAG_FIELD_NUMBER: builtins.int + ISSUE_KIND_FIELD_NUMBER: builtins.int + PLACEMENT_DATE_FIELD_NUMBER: builtins.int + REPRES_ISIN_FIELD_NUMBER: builtins.int + ISSUE_SIZE_PLAN_FIELD_NUMBER: builtins.int + TOTAL_FLOAT_FIELD_NUMBER: builtins.int + type: global___ShareType.ValueType + """Тип акции.""" + nominal_currency: builtins.str + """Валюта номинала.""" + primary_index: builtins.str + """Индекс (Bloomberg).""" + preferred_share_type: builtins.str + """Тип привилегированных акций.""" + div_yield_flag: builtins.bool + """Признак наличия дивидендной доходности.""" + issue_kind: builtins.str + """Форма выпуска ФИ.""" + repres_isin: builtins.str + """ISIN базового актива.""" + @property + def issue_size(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Объем выпуска (шт.).""" + + @property + def nominal(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Номинал.""" + + @property + def dividend_rate(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка дивиденда (для привилегированных акций).""" + + @property + def ipo_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата IPO.""" + + @property + def registry_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата регистрации.""" + + @property + def placement_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата размещения акции.""" + + @property + def issue_size_plan(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Объявленное количество, шт.""" + + @property + def total_float(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Количество акций в свободном обращении.""" + + def __init__( + self, + *, + type: global___ShareType.ValueType = ..., + issue_size: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + nominal: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + nominal_currency: builtins.str = ..., + primary_index: builtins.str = ..., + dividend_rate: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + preferred_share_type: builtins.str = ..., + ipo_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + registry_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + div_yield_flag: builtins.bool = ..., + issue_kind: builtins.str = ..., + placement_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + repres_isin: builtins.str = ..., + issue_size_plan: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + total_float: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["dividend_rate", b"dividend_rate", "ipo_date", b"ipo_date", "issue_size", b"issue_size", "issue_size_plan", b"issue_size_plan", "nominal", b"nominal", "placement_date", b"placement_date", "registry_date", b"registry_date", "total_float", b"total_float"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["div_yield_flag", b"div_yield_flag", "dividend_rate", b"dividend_rate", "ipo_date", b"ipo_date", "issue_kind", b"issue_kind", "issue_size", b"issue_size", "issue_size_plan", b"issue_size_plan", "nominal", b"nominal", "nominal_currency", b"nominal_currency", "placement_date", b"placement_date", "preferred_share_type", b"preferred_share_type", "primary_index", b"primary_index", "registry_date", b"registry_date", "repres_isin", b"repres_isin", "total_float", b"total_float", "type", b"type"]) -> None: ... + +global___AssetShare = AssetShare + +@typing.final +class AssetBond(google.protobuf.message.Message): + """Облигация.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + CURRENT_NOMINAL_FIELD_NUMBER: builtins.int + BORROW_NAME_FIELD_NUMBER: builtins.int + ISSUE_SIZE_FIELD_NUMBER: builtins.int + NOMINAL_FIELD_NUMBER: builtins.int + NOMINAL_CURRENCY_FIELD_NUMBER: builtins.int + ISSUE_KIND_FIELD_NUMBER: builtins.int + INTEREST_KIND_FIELD_NUMBER: builtins.int + COUPON_QUANTITY_PER_YEAR_FIELD_NUMBER: builtins.int + INDEXED_NOMINAL_FLAG_FIELD_NUMBER: builtins.int + SUBORDINATED_FLAG_FIELD_NUMBER: builtins.int + COLLATERAL_FLAG_FIELD_NUMBER: builtins.int + TAX_FREE_FLAG_FIELD_NUMBER: builtins.int + AMORTIZATION_FLAG_FIELD_NUMBER: builtins.int + FLOATING_COUPON_FLAG_FIELD_NUMBER: builtins.int + PERPETUAL_FLAG_FIELD_NUMBER: builtins.int + MATURITY_DATE_FIELD_NUMBER: builtins.int + RETURN_CONDITION_FIELD_NUMBER: builtins.int + STATE_REG_DATE_FIELD_NUMBER: builtins.int + PLACEMENT_DATE_FIELD_NUMBER: builtins.int + PLACEMENT_PRICE_FIELD_NUMBER: builtins.int + ISSUE_SIZE_PLAN_FIELD_NUMBER: builtins.int + borrow_name: builtins.str + """Наименование заемщика.""" + nominal_currency: builtins.str + """Валюта номинала.""" + issue_kind: builtins.str + """Форма выпуска облигации.""" + interest_kind: builtins.str + """Форма дохода облигации.""" + coupon_quantity_per_year: builtins.int + """Количество выплат в год.""" + indexed_nominal_flag: builtins.bool + """Признак облигации с индексируемым номиналом.""" + subordinated_flag: builtins.bool + """Признак субординированной облигации.""" + collateral_flag: builtins.bool + """Признак обеспеченной облигации.""" + tax_free_flag: builtins.bool + """Признак показывает, что купоны облигации не облагаются налогом — для mass market.""" + amortization_flag: builtins.bool + """Признак облигации с амортизацией долга.""" + floating_coupon_flag: builtins.bool + """Признак облигации с плавающим купоном.""" + perpetual_flag: builtins.bool + """Признак бессрочной облигации.""" + return_condition: builtins.str + """Описание и условия получения дополнительного дохода.""" + @property + def current_nominal(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Текущий номинал.""" + + @property + def issue_size(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Объем эмиссии облигации (стоимость).""" + + @property + def nominal(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Номинал облигации.""" + + @property + def maturity_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата погашения облигации.""" + + @property + def state_reg_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата выпуска облигации.""" + + @property + def placement_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата размещения облигации.""" + + @property + def placement_price(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Цена размещения облигации.""" + + @property + def issue_size_plan(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Объявленное количество, шт.""" + + def __init__( + self, + *, + current_nominal: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + borrow_name: builtins.str = ..., + issue_size: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + nominal: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + nominal_currency: builtins.str = ..., + issue_kind: builtins.str = ..., + interest_kind: builtins.str = ..., + coupon_quantity_per_year: builtins.int = ..., + indexed_nominal_flag: builtins.bool = ..., + subordinated_flag: builtins.bool = ..., + collateral_flag: builtins.bool = ..., + tax_free_flag: builtins.bool = ..., + amortization_flag: builtins.bool = ..., + floating_coupon_flag: builtins.bool = ..., + perpetual_flag: builtins.bool = ..., + maturity_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + return_condition: builtins.str = ..., + state_reg_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + placement_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + placement_price: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + issue_size_plan: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["current_nominal", b"current_nominal", "issue_size", b"issue_size", "issue_size_plan", b"issue_size_plan", "maturity_date", b"maturity_date", "nominal", b"nominal", "placement_date", b"placement_date", "placement_price", b"placement_price", "state_reg_date", b"state_reg_date"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["amortization_flag", b"amortization_flag", "borrow_name", b"borrow_name", "collateral_flag", b"collateral_flag", "coupon_quantity_per_year", b"coupon_quantity_per_year", "current_nominal", b"current_nominal", "floating_coupon_flag", b"floating_coupon_flag", "indexed_nominal_flag", b"indexed_nominal_flag", "interest_kind", b"interest_kind", "issue_kind", b"issue_kind", "issue_size", b"issue_size", "issue_size_plan", b"issue_size_plan", "maturity_date", b"maturity_date", "nominal", b"nominal", "nominal_currency", b"nominal_currency", "perpetual_flag", b"perpetual_flag", "placement_date", b"placement_date", "placement_price", b"placement_price", "return_condition", b"return_condition", "state_reg_date", b"state_reg_date", "subordinated_flag", b"subordinated_flag", "tax_free_flag", b"tax_free_flag"]) -> None: ... + +global___AssetBond = AssetBond + +@typing.final +class AssetStructuredProduct(google.protobuf.message.Message): + """Структурная нота.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + BORROW_NAME_FIELD_NUMBER: builtins.int + NOMINAL_FIELD_NUMBER: builtins.int + NOMINAL_CURRENCY_FIELD_NUMBER: builtins.int + TYPE_FIELD_NUMBER: builtins.int + LOGIC_PORTFOLIO_FIELD_NUMBER: builtins.int + ASSET_TYPE_FIELD_NUMBER: builtins.int + BASIC_ASSET_FIELD_NUMBER: builtins.int + SAFETY_BARRIER_FIELD_NUMBER: builtins.int + MATURITY_DATE_FIELD_NUMBER: builtins.int + ISSUE_SIZE_PLAN_FIELD_NUMBER: builtins.int + ISSUE_SIZE_FIELD_NUMBER: builtins.int + PLACEMENT_DATE_FIELD_NUMBER: builtins.int + ISSUE_KIND_FIELD_NUMBER: builtins.int + borrow_name: builtins.str + """Наименование заемщика.""" + nominal_currency: builtins.str + """Валюта номинала.""" + type: global___StructuredProductType.ValueType + """Тип структурной ноты.""" + logic_portfolio: builtins.str + """Стратегия портфеля.""" + asset_type: global___AssetType.ValueType + """Тип базового актива.""" + basic_asset: builtins.str + """Вид базового актива в зависимости от типа базового актива.""" + issue_kind: builtins.str + """Форма выпуска.""" + @property + def nominal(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Номинал.""" + + @property + def safety_barrier(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Барьер сохранности в процентах.""" + + @property + def maturity_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата погашения.""" + + @property + def issue_size_plan(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Объявленное количество, шт.""" + + @property + def issue_size(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Объем размещения.""" + + @property + def placement_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата размещения ноты.""" + + def __init__( + self, + *, + borrow_name: builtins.str = ..., + nominal: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + nominal_currency: builtins.str = ..., + type: global___StructuredProductType.ValueType = ..., + logic_portfolio: builtins.str = ..., + asset_type: global___AssetType.ValueType = ..., + basic_asset: builtins.str = ..., + safety_barrier: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + maturity_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + issue_size_plan: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + issue_size: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + placement_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + issue_kind: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["issue_size", b"issue_size", "issue_size_plan", b"issue_size_plan", "maturity_date", b"maturity_date", "nominal", b"nominal", "placement_date", b"placement_date", "safety_barrier", b"safety_barrier"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["asset_type", b"asset_type", "basic_asset", b"basic_asset", "borrow_name", b"borrow_name", "issue_kind", b"issue_kind", "issue_size", b"issue_size", "issue_size_plan", b"issue_size_plan", "logic_portfolio", b"logic_portfolio", "maturity_date", b"maturity_date", "nominal", b"nominal", "nominal_currency", b"nominal_currency", "placement_date", b"placement_date", "safety_barrier", b"safety_barrier", "type", b"type"]) -> None: ... + +global___AssetStructuredProduct = AssetStructuredProduct + +@typing.final +class AssetEtf(google.protobuf.message.Message): + """Фонд.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TOTAL_EXPENSE_FIELD_NUMBER: builtins.int + HURDLE_RATE_FIELD_NUMBER: builtins.int + PERFORMANCE_FEE_FIELD_NUMBER: builtins.int + FIXED_COMMISSION_FIELD_NUMBER: builtins.int + PAYMENT_TYPE_FIELD_NUMBER: builtins.int + WATERMARK_FLAG_FIELD_NUMBER: builtins.int + BUY_PREMIUM_FIELD_NUMBER: builtins.int + SELL_DISCOUNT_FIELD_NUMBER: builtins.int + REBALANCING_FLAG_FIELD_NUMBER: builtins.int + REBALANCING_FREQ_FIELD_NUMBER: builtins.int + MANAGEMENT_TYPE_FIELD_NUMBER: builtins.int + PRIMARY_INDEX_FIELD_NUMBER: builtins.int + FOCUS_TYPE_FIELD_NUMBER: builtins.int + LEVERAGED_FLAG_FIELD_NUMBER: builtins.int + NUM_SHARE_FIELD_NUMBER: builtins.int + UCITS_FLAG_FIELD_NUMBER: builtins.int + RELEASED_DATE_FIELD_NUMBER: builtins.int + DESCRIPTION_FIELD_NUMBER: builtins.int + PRIMARY_INDEX_DESCRIPTION_FIELD_NUMBER: builtins.int + PRIMARY_INDEX_COMPANY_FIELD_NUMBER: builtins.int + INDEX_RECOVERY_PERIOD_FIELD_NUMBER: builtins.int + INAV_CODE_FIELD_NUMBER: builtins.int + DIV_YIELD_FLAG_FIELD_NUMBER: builtins.int + EXPENSE_COMMISSION_FIELD_NUMBER: builtins.int + PRIMARY_INDEX_TRACKING_ERROR_FIELD_NUMBER: builtins.int + REBALANCING_PLAN_FIELD_NUMBER: builtins.int + TAX_RATE_FIELD_NUMBER: builtins.int + REBALANCING_DATES_FIELD_NUMBER: builtins.int + ISSUE_KIND_FIELD_NUMBER: builtins.int + NOMINAL_FIELD_NUMBER: builtins.int + NOMINAL_CURRENCY_FIELD_NUMBER: builtins.int + payment_type: builtins.str + """Тип распределения доходов от выплат по бумагам.""" + watermark_flag: builtins.bool + """Признак необходимости выхода фонда в плюс для получения комиссии.""" + rebalancing_flag: builtins.bool + """Признак ребалансируемости портфеля фонда.""" + rebalancing_freq: builtins.str + """Периодичность ребалансировки.""" + management_type: builtins.str + """Тип управления.""" + primary_index: builtins.str + """Индекс, который реплицирует (старается копировать) фонд.""" + focus_type: builtins.str + """База ETF.""" + leveraged_flag: builtins.bool + """Признак использования заемных активов (плечо).""" + ucits_flag: builtins.bool + """Признак обязательства по отчетности перед регулятором.""" + description: builtins.str + """Описание фонда.""" + primary_index_description: builtins.str + """Описание индекса, за которым следует фонд.""" + primary_index_company: builtins.str + """Основные компании, в которые вкладывается фонд.""" + inav_code: builtins.str + """IVAV-код.""" + div_yield_flag: builtins.bool + """Признак наличия дивидендной доходности.""" + rebalancing_plan: builtins.str + """Плановая ребалансировка портфеля.""" + tax_rate: builtins.str + """Ставки налогообложения дивидендов и купонов.""" + issue_kind: builtins.str + """Форма выпуска.""" + nominal_currency: builtins.str + """Валюта номинала.""" + @property + def total_expense(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Суммарные расходы фонда в процентах.""" + + @property + def hurdle_rate(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Барьерная ставка доходности, после которой фонд имеет право на perfomance fee — в процентах.""" + + @property + def performance_fee(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Комиссия за успешные результаты фонда в процентах.""" + + @property + def fixed_commission(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Фиксированная комиссия за управление в процентах.""" + + @property + def buy_premium(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Премия (надбавка к цене) при покупке доли в фонде — в процентах.""" + + @property + def sell_discount(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка дисконта (вычет из цены) при продаже доли в фонде — в процентах.""" + + @property + def num_share(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Количество акций в обращении.""" + + @property + def released_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата выпуска.""" + + @property + def index_recovery_period(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Срок восстановления индекса после просадки.""" + + @property + def expense_commission(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Комиссия на покрытие расходов фонда в процентах.""" + + @property + def primary_index_tracking_error(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ошибка следования за индексом в процентах.""" + + @property + def rebalancing_dates(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[google.protobuf.timestamp_pb2.Timestamp]: + """Даты ребалансировок.""" + + @property + def nominal(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Номинал.""" + + def __init__( + self, + *, + total_expense: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + hurdle_rate: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + performance_fee: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + fixed_commission: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + payment_type: builtins.str = ..., + watermark_flag: builtins.bool = ..., + buy_premium: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + sell_discount: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + rebalancing_flag: builtins.bool = ..., + rebalancing_freq: builtins.str = ..., + management_type: builtins.str = ..., + primary_index: builtins.str = ..., + focus_type: builtins.str = ..., + leveraged_flag: builtins.bool = ..., + num_share: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + ucits_flag: builtins.bool = ..., + released_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + description: builtins.str = ..., + primary_index_description: builtins.str = ..., + primary_index_company: builtins.str = ..., + index_recovery_period: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + inav_code: builtins.str = ..., + div_yield_flag: builtins.bool = ..., + expense_commission: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + primary_index_tracking_error: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + rebalancing_plan: builtins.str = ..., + tax_rate: builtins.str = ..., + rebalancing_dates: collections.abc.Iterable[google.protobuf.timestamp_pb2.Timestamp] | None = ..., + issue_kind: builtins.str = ..., + nominal: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + nominal_currency: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["buy_premium", b"buy_premium", "expense_commission", b"expense_commission", "fixed_commission", b"fixed_commission", "hurdle_rate", b"hurdle_rate", "index_recovery_period", b"index_recovery_period", "nominal", b"nominal", "num_share", b"num_share", "performance_fee", b"performance_fee", "primary_index_tracking_error", b"primary_index_tracking_error", "released_date", b"released_date", "sell_discount", b"sell_discount", "total_expense", b"total_expense"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["buy_premium", b"buy_premium", "description", b"description", "div_yield_flag", b"div_yield_flag", "expense_commission", b"expense_commission", "fixed_commission", b"fixed_commission", "focus_type", b"focus_type", "hurdle_rate", b"hurdle_rate", "inav_code", b"inav_code", "index_recovery_period", b"index_recovery_period", "issue_kind", b"issue_kind", "leveraged_flag", b"leveraged_flag", "management_type", b"management_type", "nominal", b"nominal", "nominal_currency", b"nominal_currency", "num_share", b"num_share", "payment_type", b"payment_type", "performance_fee", b"performance_fee", "primary_index", b"primary_index", "primary_index_company", b"primary_index_company", "primary_index_description", b"primary_index_description", "primary_index_tracking_error", b"primary_index_tracking_error", "rebalancing_dates", b"rebalancing_dates", "rebalancing_flag", b"rebalancing_flag", "rebalancing_freq", b"rebalancing_freq", "rebalancing_plan", b"rebalancing_plan", "released_date", b"released_date", "sell_discount", b"sell_discount", "tax_rate", b"tax_rate", "total_expense", b"total_expense", "ucits_flag", b"ucits_flag", "watermark_flag", b"watermark_flag"]) -> None: ... + +global___AssetEtf = AssetEtf + +@typing.final +class AssetClearingCertificate(google.protobuf.message.Message): + """Клиринговый сертификат участия.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + NOMINAL_FIELD_NUMBER: builtins.int + NOMINAL_CURRENCY_FIELD_NUMBER: builtins.int + nominal_currency: builtins.str + """Валюта номинала.""" + @property + def nominal(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Номинал.""" + + def __init__( + self, + *, + nominal: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + nominal_currency: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["nominal", b"nominal"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["nominal", b"nominal", "nominal_currency", b"nominal_currency"]) -> None: ... + +global___AssetClearingCertificate = AssetClearingCertificate + +@typing.final +class Brand(google.protobuf.message.Message): + """Бренд.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + UID_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + DESCRIPTION_FIELD_NUMBER: builtins.int + INFO_FIELD_NUMBER: builtins.int + COMPANY_FIELD_NUMBER: builtins.int + SECTOR_FIELD_NUMBER: builtins.int + COUNTRY_OF_RISK_FIELD_NUMBER: builtins.int + COUNTRY_OF_RISK_NAME_FIELD_NUMBER: builtins.int + uid: builtins.str + """UID-идентификатор бренда.""" + name: builtins.str + """Наименование бренда.""" + description: builtins.str + """Описание.""" + info: builtins.str + """Информация о бренде.""" + company: builtins.str + """Компания.""" + sector: builtins.str + """Сектор.""" + country_of_risk: builtins.str + """Код страны риска.""" + country_of_risk_name: builtins.str + """Наименование страны риска.""" + def __init__( + self, + *, + uid: builtins.str = ..., + name: builtins.str = ..., + description: builtins.str = ..., + info: builtins.str = ..., + company: builtins.str = ..., + sector: builtins.str = ..., + country_of_risk: builtins.str = ..., + country_of_risk_name: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["company", b"company", "country_of_risk", b"country_of_risk", "country_of_risk_name", b"country_of_risk_name", "description", b"description", "info", b"info", "name", b"name", "sector", b"sector", "uid", b"uid"]) -> None: ... + +global___Brand = Brand + +@typing.final +class AssetInstrument(google.protobuf.message.Message): + """Идентификаторы инструмента.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + UID_FIELD_NUMBER: builtins.int + FIGI_FIELD_NUMBER: builtins.int + INSTRUMENT_TYPE_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + LINKS_FIELD_NUMBER: builtins.int + INSTRUMENT_KIND_FIELD_NUMBER: builtins.int + POSITION_UID_FIELD_NUMBER: builtins.int + uid: builtins.str + """UID-идентификатор инструмента.""" + figi: builtins.str + """FIGI-идентификатор инструмента.""" + instrument_type: builtins.str + """Тип инструмента.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + instrument_kind: t_tech.invest.grpc.common_pb2.InstrumentType.ValueType + """Тип инструмента.""" + position_uid: builtins.str + """ID позиции.""" + @property + def links(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___InstrumentLink]: + """Массив связанных инструментов.""" + + def __init__( + self, + *, + uid: builtins.str = ..., + figi: builtins.str = ..., + instrument_type: builtins.str = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + links: collections.abc.Iterable[global___InstrumentLink] | None = ..., + instrument_kind: t_tech.invest.grpc.common_pb2.InstrumentType.ValueType = ..., + position_uid: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["class_code", b"class_code", "figi", b"figi", "instrument_kind", b"instrument_kind", "instrument_type", b"instrument_type", "links", b"links", "position_uid", b"position_uid", "ticker", b"ticker", "uid", b"uid"]) -> None: ... + +global___AssetInstrument = AssetInstrument + +@typing.final +class InstrumentLink(google.protobuf.message.Message): + """Связь с другим инструментом.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TYPE_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + type: builtins.str + """Тип связи.""" + instrument_uid: builtins.str + """UID-идентификатор связанного инструмента.""" + def __init__( + self, + *, + type: builtins.str = ..., + instrument_uid: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["instrument_uid", b"instrument_uid", "type", b"type"]) -> None: ... + +global___InstrumentLink = InstrumentLink + +@typing.final +class GetFavoritesRequest(google.protobuf.message.Message): + """Запрос списка избранных инструментов, входные параметры не требуются.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + GROUP_ID_FIELD_NUMBER: builtins.int + group_id: builtins.str + """Уникальный идентификатор группы.""" + def __init__( + self, + *, + group_id: builtins.str | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_group_id", b"_group_id", "group_id", b"group_id"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_group_id", b"_group_id", "group_id", b"group_id"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_group_id", b"_group_id"]) -> typing.Literal["group_id"] | None: ... + +global___GetFavoritesRequest = GetFavoritesRequest + +@typing.final +class GetFavoritesResponse(google.protobuf.message.Message): + """В ответ передается список избранных инструментов в качестве массива.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FAVORITE_INSTRUMENTS_FIELD_NUMBER: builtins.int + GROUP_ID_FIELD_NUMBER: builtins.int + group_id: builtins.str + """Уникальный идентификатор группы.""" + @property + def favorite_instruments(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___FavoriteInstrument]: + """Массив инструментов.""" + + def __init__( + self, + *, + favorite_instruments: collections.abc.Iterable[global___FavoriteInstrument] | None = ..., + group_id: builtins.str | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_group_id", b"_group_id", "group_id", b"group_id"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_group_id", b"_group_id", "favorite_instruments", b"favorite_instruments", "group_id", b"group_id"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_group_id", b"_group_id"]) -> typing.Literal["group_id"] | None: ... + +global___GetFavoritesResponse = GetFavoritesResponse + +@typing.final +class FavoriteInstrument(google.protobuf.message.Message): + """Массив избранных инструментов.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + ISIN_FIELD_NUMBER: builtins.int + INSTRUMENT_TYPE_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + UID_FIELD_NUMBER: builtins.int + OTC_FLAG_FIELD_NUMBER: builtins.int + API_TRADE_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + INSTRUMENT_KIND_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI-идентификатор инструмента.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код инструмента.""" + isin: builtins.str + """ISIN-идентификатор инструмента.""" + instrument_type: builtins.str + """Тип инструмента.""" + name: builtins.str + """Название инструмента.""" + uid: builtins.str + """Уникальный идентификатор инструмента.""" + otc_flag: builtins.bool + """Флаг, используемый ранее для определения внебиржевых инструментов. На данный момент не используется для торгуемых через API инструментов. Может использоваться как фильтр для операций, совершавшихся некоторое время назад на ОТС площадке.""" + api_trade_available_flag: builtins.bool + """Возможность торговать инструментом через API.""" + instrument_kind: t_tech.invest.grpc.common_pb2.InstrumentType.ValueType + """Тип инструмента.""" + def __init__( + self, + *, + figi: builtins.str = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + isin: builtins.str = ..., + instrument_type: builtins.str = ..., + name: builtins.str = ..., + uid: builtins.str = ..., + otc_flag: builtins.bool = ..., + api_trade_available_flag: builtins.bool = ..., + instrument_kind: t_tech.invest.grpc.common_pb2.InstrumentType.ValueType = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["api_trade_available_flag", b"api_trade_available_flag", "class_code", b"class_code", "figi", b"figi", "instrument_kind", b"instrument_kind", "instrument_type", b"instrument_type", "isin", b"isin", "name", b"name", "otc_flag", b"otc_flag", "ticker", b"ticker", "uid", b"uid"]) -> None: ... + +global___FavoriteInstrument = FavoriteInstrument + +@typing.final +class EditFavoritesRequest(google.protobuf.message.Message): + """Запрос редактирования списка избранных инструментов.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENTS_FIELD_NUMBER: builtins.int + ACTION_TYPE_FIELD_NUMBER: builtins.int + GROUP_ID_FIELD_NUMBER: builtins.int + action_type: global___EditFavoritesActionType.ValueType + """Тип действия со списком.""" + group_id: builtins.str + """Уникальный идентификатор группы.""" + @property + def instruments(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___EditFavoritesRequestInstrument]: + """Массив инструментов.""" + + def __init__( + self, + *, + instruments: collections.abc.Iterable[global___EditFavoritesRequestInstrument] | None = ..., + action_type: global___EditFavoritesActionType.ValueType = ..., + group_id: builtins.str | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_group_id", b"_group_id", "group_id", b"group_id"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_group_id", b"_group_id", "action_type", b"action_type", "group_id", b"group_id", "instruments", b"instruments"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_group_id", b"_group_id"]) -> typing.Literal["group_id"] | None: ... + +global___EditFavoritesRequest = EditFavoritesRequest + +@typing.final +class EditFavoritesRequestInstrument(google.protobuf.message.Message): + """Массив инструментов для редактирования списка избранных инструментов.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI-идентификатор инструмента.""" + instrument_id: builtins.str + """Идентификатор инструмента — `figi` или `instrument_uid`.""" + def __init__( + self, + *, + figi: builtins.str | None = ..., + instrument_id: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_figi", b"_figi", "figi", b"figi"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_figi", b"_figi", "figi", b"figi", "instrument_id", b"instrument_id"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_figi", b"_figi"]) -> typing.Literal["figi"] | None: ... + +global___EditFavoritesRequestInstrument = EditFavoritesRequestInstrument + +@typing.final +class EditFavoritesResponse(google.protobuf.message.Message): + """Результат редактирования списка избранных инструментов.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FAVORITE_INSTRUMENTS_FIELD_NUMBER: builtins.int + GROUP_ID_FIELD_NUMBER: builtins.int + group_id: builtins.str + """Уникальный идентификатор группы.""" + @property + def favorite_instruments(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___FavoriteInstrument]: + """Массив инструментов.""" + + def __init__( + self, + *, + favorite_instruments: collections.abc.Iterable[global___FavoriteInstrument] | None = ..., + group_id: builtins.str | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_group_id", b"_group_id", "group_id", b"group_id"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_group_id", b"_group_id", "favorite_instruments", b"favorite_instruments", "group_id", b"group_id"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_group_id", b"_group_id"]) -> typing.Literal["group_id"] | None: ... + +global___EditFavoritesResponse = EditFavoritesResponse + +@typing.final +class CreateFavoriteGroupRequest(google.protobuf.message.Message): + """Запрос создания новой группы избранных инструментов.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + GROUP_NAME_FIELD_NUMBER: builtins.int + GROUP_COLOR_FIELD_NUMBER: builtins.int + NOTE_FIELD_NUMBER: builtins.int + group_name: builtins.str + """Название группы, не более 255 символов.""" + group_color: builtins.str + """Цвет группы. Принимает значения в HEX-формате, от "000000" до "FFFFFF" """ + note: builtins.str + """Описание""" + def __init__( + self, + *, + group_name: builtins.str = ..., + group_color: builtins.str = ..., + note: builtins.str | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_note", b"_note", "note", b"note"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_note", b"_note", "group_color", b"group_color", "group_name", b"group_name", "note", b"note"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_note", b"_note"]) -> typing.Literal["note"] | None: ... + +global___CreateFavoriteGroupRequest = CreateFavoriteGroupRequest + +@typing.final +class CreateFavoriteGroupResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + GROUP_ID_FIELD_NUMBER: builtins.int + GROUP_NAME_FIELD_NUMBER: builtins.int + group_id: builtins.str + """Уникальный идентификатор группы.""" + group_name: builtins.str + """Название группы.""" + def __init__( + self, + *, + group_id: builtins.str = ..., + group_name: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["group_id", b"group_id", "group_name", b"group_name"]) -> None: ... + +global___CreateFavoriteGroupResponse = CreateFavoriteGroupResponse + +@typing.final +class DeleteFavoriteGroupRequest(google.protobuf.message.Message): + """Запрос удаления избранной группы""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + GROUP_ID_FIELD_NUMBER: builtins.int + group_id: builtins.str + """Уникальный идентификатор группы.""" + def __init__( + self, + *, + group_id: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["group_id", b"group_id"]) -> None: ... + +global___DeleteFavoriteGroupRequest = DeleteFavoriteGroupRequest + +@typing.final +class DeleteFavoriteGroupResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + def __init__( + self, + ) -> None: ... + +global___DeleteFavoriteGroupResponse = DeleteFavoriteGroupResponse + +@typing.final +class GetFavoriteGroupsRequest(google.protobuf.message.Message): + """Запрос получения списка избранных групп""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + EXCLUDED_GROUP_ID_FIELD_NUMBER: builtins.int + @property + def instrument_id(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Массив идентификаторов инструментов. Принимает значение `figi` или `instrument_uid`. Если в группе будет хотя бы один из инструментов массива, то в ответе у группы вернется признак `containsInstrument = true`.""" + + @property + def excluded_group_id(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Массив идентификаторов групп, которые необходимо исключить из ответа.""" + + def __init__( + self, + *, + instrument_id: collections.abc.Iterable[builtins.str] | None = ..., + excluded_group_id: collections.abc.Iterable[builtins.str] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["excluded_group_id", b"excluded_group_id", "instrument_id", b"instrument_id"]) -> None: ... + +global___GetFavoriteGroupsRequest = GetFavoriteGroupsRequest + +@typing.final +class GetFavoriteGroupsResponse(google.protobuf.message.Message): + """Избранные группы""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing.final + class FavoriteGroup(google.protobuf.message.Message): + """Избранная группа""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + GROUP_ID_FIELD_NUMBER: builtins.int + GROUP_NAME_FIELD_NUMBER: builtins.int + COLOR_FIELD_NUMBER: builtins.int + SIZE_FIELD_NUMBER: builtins.int + CONTAINS_INSTRUMENT_FIELD_NUMBER: builtins.int + group_id: builtins.str + """Уникальный идентификатор группы.""" + group_name: builtins.str + """Название группы.""" + color: builtins.str + """Цвет группы в HEX-формате.""" + size: builtins.int + """Количество инструментов в группе.""" + contains_instrument: builtins.bool + """Признак наличия в группе хотя бы одного инструмента из запроса.""" + def __init__( + self, + *, + group_id: builtins.str = ..., + group_name: builtins.str = ..., + color: builtins.str = ..., + size: builtins.int = ..., + contains_instrument: builtins.bool | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_contains_instrument", b"_contains_instrument", "contains_instrument", b"contains_instrument"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_contains_instrument", b"_contains_instrument", "color", b"color", "contains_instrument", b"contains_instrument", "group_id", b"group_id", "group_name", b"group_name", "size", b"size"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_contains_instrument", b"_contains_instrument"]) -> typing.Literal["contains_instrument"] | None: ... + + GROUPS_FIELD_NUMBER: builtins.int + @property + def groups(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___GetFavoriteGroupsResponse.FavoriteGroup]: + """Массив групп избранных списков инструментов.""" + + def __init__( + self, + *, + groups: collections.abc.Iterable[global___GetFavoriteGroupsResponse.FavoriteGroup] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["groups", b"groups"]) -> None: ... + +global___GetFavoriteGroupsResponse = GetFavoriteGroupsResponse + +@typing.final +class GetCountriesRequest(google.protobuf.message.Message): + """Запрос справочника стран.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + def __init__( + self, + ) -> None: ... + +global___GetCountriesRequest = GetCountriesRequest + +@typing.final +class GetCountriesResponse(google.protobuf.message.Message): + """Справочник стран.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + COUNTRIES_FIELD_NUMBER: builtins.int + @property + def countries(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___CountryResponse]: + """Массив стран.""" + + def __init__( + self, + *, + countries: collections.abc.Iterable[global___CountryResponse] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["countries", b"countries"]) -> None: ... + +global___GetCountriesResponse = GetCountriesResponse + +@typing.final +class IndicativesRequest(google.protobuf.message.Message): + """Запрос справочника индексов и товаров""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + def __init__( + self, + ) -> None: ... + +global___IndicativesRequest = IndicativesRequest + +@typing.final +class IndicativesResponse(google.protobuf.message.Message): + """Справочник индексов и товаров""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENTS_FIELD_NUMBER: builtins.int + @property + def instruments(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___IndicativeResponse]: + """Массив инструментов.""" + + def __init__( + self, + *, + instruments: collections.abc.Iterable[global___IndicativeResponse] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["instruments", b"instruments"]) -> None: ... + +global___IndicativesResponse = IndicativesResponse + +@typing.final +class IndicativeResponse(google.protobuf.message.Message): + """Индикатив""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + CURRENCY_FIELD_NUMBER: builtins.int + INSTRUMENT_KIND_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + EXCHANGE_FIELD_NUMBER: builtins.int + UID_FIELD_NUMBER: builtins.int + BUY_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + SELL_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI-идентификатор инструмента.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код инструмента.""" + currency: builtins.str + """Валюта расчетов.""" + instrument_kind: t_tech.invest.grpc.common_pb2.InstrumentType.ValueType + """Тип инструмента.""" + name: builtins.str + """Название инструмента.""" + exchange: builtins.str + """Tорговая площадка (секция биржи).""" + uid: builtins.str + """Уникальный идентификатор инструмента.""" + buy_available_flag: builtins.bool + """Признак доступности для покупки.""" + sell_available_flag: builtins.bool + """Признак доступности для продажи.""" + def __init__( + self, + *, + figi: builtins.str = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + currency: builtins.str = ..., + instrument_kind: t_tech.invest.grpc.common_pb2.InstrumentType.ValueType = ..., + name: builtins.str = ..., + exchange: builtins.str = ..., + uid: builtins.str = ..., + buy_available_flag: builtins.bool = ..., + sell_available_flag: builtins.bool = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["buy_available_flag", b"buy_available_flag", "class_code", b"class_code", "currency", b"currency", "exchange", b"exchange", "figi", b"figi", "instrument_kind", b"instrument_kind", "name", b"name", "sell_available_flag", b"sell_available_flag", "ticker", b"ticker", "uid", b"uid"]) -> None: ... + +global___IndicativeResponse = IndicativeResponse + +@typing.final +class CountryResponse(google.protobuf.message.Message): + """Данные о стране.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ALFA_TWO_FIELD_NUMBER: builtins.int + ALFA_THREE_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + NAME_BRIEF_FIELD_NUMBER: builtins.int + alfa_two: builtins.str + """Двухбуквенный код страны.""" + alfa_three: builtins.str + """Трехбуквенный код страны.""" + name: builtins.str + """Наименование страны.""" + name_brief: builtins.str + """Краткое наименование страны.""" + def __init__( + self, + *, + alfa_two: builtins.str = ..., + alfa_three: builtins.str = ..., + name: builtins.str = ..., + name_brief: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["alfa_three", b"alfa_three", "alfa_two", b"alfa_two", "name", b"name", "name_brief", b"name_brief"]) -> None: ... + +global___CountryResponse = CountryResponse + +@typing.final +class FindInstrumentRequest(google.protobuf.message.Message): + """Запрос на поиск инструментов.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + QUERY_FIELD_NUMBER: builtins.int + INSTRUMENT_KIND_FIELD_NUMBER: builtins.int + API_TRADE_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + query: builtins.str + """Строка поиска.""" + instrument_kind: t_tech.invest.grpc.common_pb2.InstrumentType.ValueType + """Фильтр по типу инструмента.""" + api_trade_available_flag: builtins.bool + """Фильтр для отображения только торговых инструментов.""" + def __init__( + self, + *, + query: builtins.str = ..., + instrument_kind: t_tech.invest.grpc.common_pb2.InstrumentType.ValueType | None = ..., + api_trade_available_flag: builtins.bool | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_api_trade_available_flag", b"_api_trade_available_flag", "_instrument_kind", b"_instrument_kind", "api_trade_available_flag", b"api_trade_available_flag", "instrument_kind", b"instrument_kind"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_api_trade_available_flag", b"_api_trade_available_flag", "_instrument_kind", b"_instrument_kind", "api_trade_available_flag", b"api_trade_available_flag", "instrument_kind", b"instrument_kind", "query", b"query"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_api_trade_available_flag", b"_api_trade_available_flag"]) -> typing.Literal["api_trade_available_flag"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_instrument_kind", b"_instrument_kind"]) -> typing.Literal["instrument_kind"] | None: ... + +global___FindInstrumentRequest = FindInstrumentRequest + +@typing.final +class FindInstrumentResponse(google.protobuf.message.Message): + """Результат поиска инструментов.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENTS_FIELD_NUMBER: builtins.int + @property + def instruments(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___InstrumentShort]: + """Массив инструментов, удовлетворяющих условиям поиска.""" + + def __init__( + self, + *, + instruments: collections.abc.Iterable[global___InstrumentShort] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["instruments", b"instruments"]) -> None: ... + +global___FindInstrumentResponse = FindInstrumentResponse + +@typing.final +class InstrumentShort(google.protobuf.message.Message): + """Краткая информация об инструменте.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ISIN_FIELD_NUMBER: builtins.int + FIGI_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + INSTRUMENT_TYPE_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + UID_FIELD_NUMBER: builtins.int + POSITION_UID_FIELD_NUMBER: builtins.int + INSTRUMENT_KIND_FIELD_NUMBER: builtins.int + API_TRADE_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + FOR_IIS_FLAG_FIELD_NUMBER: builtins.int + FIRST_1MIN_CANDLE_DATE_FIELD_NUMBER: builtins.int + FIRST_1DAY_CANDLE_DATE_FIELD_NUMBER: builtins.int + FOR_QUAL_INVESTOR_FLAG_FIELD_NUMBER: builtins.int + WEEKEND_FLAG_FIELD_NUMBER: builtins.int + BLOCKED_TCA_FLAG_FIELD_NUMBER: builtins.int + LOT_FIELD_NUMBER: builtins.int + isin: builtins.str + """ISIN инструмента.""" + figi: builtins.str + """FIGI инструмента.""" + ticker: builtins.str + """Ticker инструмента.""" + class_code: builtins.str + """ClassCode инструмента.""" + instrument_type: builtins.str + """Тип инструмента.""" + name: builtins.str + """Название инструмента.""" + uid: builtins.str + """Уникальный идентификатор инструмента.""" + position_uid: builtins.str + """Уникальный идентификатор позиции инструмента.""" + instrument_kind: t_tech.invest.grpc.common_pb2.InstrumentType.ValueType + """Тип инструмента.""" + api_trade_available_flag: builtins.bool + """Возможность торговать инструментом через API.""" + for_iis_flag: builtins.bool + """Признак доступности для ИИС.""" + for_qual_investor_flag: builtins.bool + """Флаг, отображающий доступность торговли инструментом только для квалифицированных инвесторов.""" + weekend_flag: builtins.bool + """Флаг, отображающий доступность торговли инструментом по выходным.""" + blocked_tca_flag: builtins.bool + """Флаг заблокированного ТКС.""" + lot: builtins.int + """Количество бумаг в лоте.""" + @property + def first_1min_candle_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата первой минутной свечи.""" + + @property + def first_1day_candle_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата первой дневной свечи.""" + + def __init__( + self, + *, + isin: builtins.str = ..., + figi: builtins.str = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + instrument_type: builtins.str = ..., + name: builtins.str = ..., + uid: builtins.str = ..., + position_uid: builtins.str = ..., + instrument_kind: t_tech.invest.grpc.common_pb2.InstrumentType.ValueType = ..., + api_trade_available_flag: builtins.bool = ..., + for_iis_flag: builtins.bool = ..., + first_1min_candle_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + first_1day_candle_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + for_qual_investor_flag: builtins.bool = ..., + weekend_flag: builtins.bool = ..., + blocked_tca_flag: builtins.bool = ..., + lot: builtins.int = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["first_1day_candle_date", b"first_1day_candle_date", "first_1min_candle_date", b"first_1min_candle_date"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["api_trade_available_flag", b"api_trade_available_flag", "blocked_tca_flag", b"blocked_tca_flag", "class_code", b"class_code", "figi", b"figi", "first_1day_candle_date", b"first_1day_candle_date", "first_1min_candle_date", b"first_1min_candle_date", "for_iis_flag", b"for_iis_flag", "for_qual_investor_flag", b"for_qual_investor_flag", "instrument_kind", b"instrument_kind", "instrument_type", b"instrument_type", "isin", b"isin", "lot", b"lot", "name", b"name", "position_uid", b"position_uid", "ticker", b"ticker", "uid", b"uid", "weekend_flag", b"weekend_flag"]) -> None: ... + +global___InstrumentShort = InstrumentShort + +@typing.final +class GetBrandsRequest(google.protobuf.message.Message): + """Запрос списка брендов.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PAGING_FIELD_NUMBER: builtins.int + @property + def paging(self) -> t_tech.invest.grpc.common_pb2.Page: + """Настройки пагинации.""" + + def __init__( + self, + *, + paging: t_tech.invest.grpc.common_pb2.Page | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["paging", b"paging"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["paging", b"paging"]) -> None: ... + +global___GetBrandsRequest = GetBrandsRequest + +@typing.final +class GetBrandRequest(google.protobuf.message.Message): + """Запрос бренда.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ID_FIELD_NUMBER: builtins.int + id: builtins.str + """UID-идентификатор бренда.""" + def __init__( + self, + *, + id: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["id", b"id"]) -> None: ... + +global___GetBrandRequest = GetBrandRequest + +@typing.final +class GetBrandsResponse(google.protobuf.message.Message): + """Список брендов.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + BRANDS_FIELD_NUMBER: builtins.int + PAGING_FIELD_NUMBER: builtins.int + @property + def brands(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Brand]: + """Массив брендов.""" + + @property + def paging(self) -> t_tech.invest.grpc.common_pb2.PageResponse: + """Данные по пагинации.""" + + def __init__( + self, + *, + brands: collections.abc.Iterable[global___Brand] | None = ..., + paging: t_tech.invest.grpc.common_pb2.PageResponse | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["paging", b"paging"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["brands", b"brands", "paging", b"paging"]) -> None: ... + +global___GetBrandsResponse = GetBrandsResponse + +@typing.final +class GetAssetFundamentalsRequest(google.protobuf.message.Message): + """Запрос фундаментальных показателей""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ASSETS_FIELD_NUMBER: builtins.int + @property + def assets(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Массив идентификаторов активов, не более 100 шт.""" + + def __init__( + self, + *, + assets: collections.abc.Iterable[builtins.str] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["assets", b"assets"]) -> None: ... + +global___GetAssetFundamentalsRequest = GetAssetFundamentalsRequest + +@typing.final +class GetAssetFundamentalsResponse(google.protobuf.message.Message): + """Фундаментальные показатели""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing.final + class StatisticResponse(google.protobuf.message.Message): + """Фундаментальные показатели по активу""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ASSET_UID_FIELD_NUMBER: builtins.int + CURRENCY_FIELD_NUMBER: builtins.int + MARKET_CAPITALIZATION_FIELD_NUMBER: builtins.int + HIGH_PRICE_LAST_52_WEEKS_FIELD_NUMBER: builtins.int + LOW_PRICE_LAST_52_WEEKS_FIELD_NUMBER: builtins.int + AVERAGE_DAILY_VOLUME_LAST_10_DAYS_FIELD_NUMBER: builtins.int + AVERAGE_DAILY_VOLUME_LAST_4_WEEKS_FIELD_NUMBER: builtins.int + BETA_FIELD_NUMBER: builtins.int + FREE_FLOAT_FIELD_NUMBER: builtins.int + FORWARD_ANNUAL_DIVIDEND_YIELD_FIELD_NUMBER: builtins.int + SHARES_OUTSTANDING_FIELD_NUMBER: builtins.int + REVENUE_TTM_FIELD_NUMBER: builtins.int + EBITDA_TTM_FIELD_NUMBER: builtins.int + NET_INCOME_TTM_FIELD_NUMBER: builtins.int + EPS_TTM_FIELD_NUMBER: builtins.int + DILUTED_EPS_TTM_FIELD_NUMBER: builtins.int + FREE_CASH_FLOW_TTM_FIELD_NUMBER: builtins.int + FIVE_YEAR_ANNUAL_REVENUE_GROWTH_RATE_FIELD_NUMBER: builtins.int + THREE_YEAR_ANNUAL_REVENUE_GROWTH_RATE_FIELD_NUMBER: builtins.int + PE_RATIO_TTM_FIELD_NUMBER: builtins.int + PRICE_TO_SALES_TTM_FIELD_NUMBER: builtins.int + PRICE_TO_BOOK_TTM_FIELD_NUMBER: builtins.int + PRICE_TO_FREE_CASH_FLOW_TTM_FIELD_NUMBER: builtins.int + TOTAL_ENTERPRISE_VALUE_MRQ_FIELD_NUMBER: builtins.int + EV_TO_EBITDA_MRQ_FIELD_NUMBER: builtins.int + NET_MARGIN_MRQ_FIELD_NUMBER: builtins.int + NET_INTEREST_MARGIN_MRQ_FIELD_NUMBER: builtins.int + ROE_FIELD_NUMBER: builtins.int + ROA_FIELD_NUMBER: builtins.int + ROIC_FIELD_NUMBER: builtins.int + TOTAL_DEBT_MRQ_FIELD_NUMBER: builtins.int + TOTAL_DEBT_TO_EQUITY_MRQ_FIELD_NUMBER: builtins.int + TOTAL_DEBT_TO_EBITDA_MRQ_FIELD_NUMBER: builtins.int + FREE_CASH_FLOW_TO_PRICE_FIELD_NUMBER: builtins.int + NET_DEBT_TO_EBITDA_FIELD_NUMBER: builtins.int + CURRENT_RATIO_MRQ_FIELD_NUMBER: builtins.int + FIXED_CHARGE_COVERAGE_RATIO_FY_FIELD_NUMBER: builtins.int + DIVIDEND_YIELD_DAILY_TTM_FIELD_NUMBER: builtins.int + DIVIDEND_RATE_TTM_FIELD_NUMBER: builtins.int + DIVIDENDS_PER_SHARE_FIELD_NUMBER: builtins.int + FIVE_YEARS_AVERAGE_DIVIDEND_YIELD_FIELD_NUMBER: builtins.int + FIVE_YEAR_ANNUAL_DIVIDEND_GROWTH_RATE_FIELD_NUMBER: builtins.int + DIVIDEND_PAYOUT_RATIO_FY_FIELD_NUMBER: builtins.int + BUY_BACK_TTM_FIELD_NUMBER: builtins.int + ONE_YEAR_ANNUAL_REVENUE_GROWTH_RATE_FIELD_NUMBER: builtins.int + DOMICILE_INDICATOR_CODE_FIELD_NUMBER: builtins.int + ADR_TO_COMMON_SHARE_RATIO_FIELD_NUMBER: builtins.int + NUMBER_OF_EMPLOYEES_FIELD_NUMBER: builtins.int + EX_DIVIDEND_DATE_FIELD_NUMBER: builtins.int + FISCAL_PERIOD_START_DATE_FIELD_NUMBER: builtins.int + FISCAL_PERIOD_END_DATE_FIELD_NUMBER: builtins.int + REVENUE_CHANGE_FIVE_YEARS_FIELD_NUMBER: builtins.int + EPS_CHANGE_FIVE_YEARS_FIELD_NUMBER: builtins.int + EBITDA_CHANGE_FIVE_YEARS_FIELD_NUMBER: builtins.int + TOTAL_DEBT_CHANGE_FIVE_YEARS_FIELD_NUMBER: builtins.int + EV_TO_SALES_FIELD_NUMBER: builtins.int + asset_uid: builtins.str + """Идентификатор актива.""" + currency: builtins.str + """Валюта.""" + market_capitalization: builtins.float + """Рыночная капитализация.""" + high_price_last_52_weeks: builtins.float + """Максимум за год.""" + low_price_last_52_weeks: builtins.float + """Минимум за год.""" + average_daily_volume_last_10_days: builtins.float + """Средний объем торгов за 10 дней.""" + average_daily_volume_last_4_weeks: builtins.float + """Средний объем торгов за месяц.""" + beta: builtins.float + free_float: builtins.float + """Доля акций в свободном обращении.""" + forward_annual_dividend_yield: builtins.float + """Процент форвардной дивидендной доходности по отношению к цене акций.""" + shares_outstanding: builtins.float + """Количество акций в обращении.""" + revenue_ttm: builtins.float + """Выручка.""" + ebitda_ttm: builtins.float + """EBITDA — прибыль до вычета процентов, налогов, износа и амортизации.""" + net_income_ttm: builtins.float + """Чистая прибыль.""" + eps_ttm: builtins.float + """EPS — величина чистой прибыли компании, которая приходится на каждую обыкновенную акцию.""" + diluted_eps_ttm: builtins.float + """EPS компании с допущением, что все конвертируемые ценные бумаги компании были сконвертированы в обыкновенные акции.""" + free_cash_flow_ttm: builtins.float + """Свободный денежный поток.""" + five_year_annual_revenue_growth_rate: builtins.float + """Среднегодовой рocт выручки за 5 лет.""" + three_year_annual_revenue_growth_rate: builtins.float + """Среднегодовой рocт выручки за 3 года.""" + pe_ratio_ttm: builtins.float + """Соотношение рыночной капитализации компании к ее чистой прибыли.""" + price_to_sales_ttm: builtins.float + """Соотношение рыночной капитализации компании к ее выручке.""" + price_to_book_ttm: builtins.float + """Соотношение рыночной капитализации компании к ее балансовой стоимости.""" + price_to_free_cash_flow_ttm: builtins.float + """Соотношение рыночной капитализации компании к ее свободному денежному потоку.""" + total_enterprise_value_mrq: builtins.float + """Рыночная стоимость компании.""" + ev_to_ebitda_mrq: builtins.float + """Соотношение EV и EBITDA.""" + net_margin_mrq: builtins.float + """Маржа чистой прибыли.""" + net_interest_margin_mrq: builtins.float + """Рентабельность чистой прибыли.""" + roe: builtins.float + """Рентабельность собственного капитала.""" + roa: builtins.float + """Рентабельность активов.""" + roic: builtins.float + """Рентабельность активов.""" + total_debt_mrq: builtins.float + """Сумма краткосрочных и долгосрочных обязательств компании.""" + total_debt_to_equity_mrq: builtins.float + """Соотношение долга к собственному капиталу.""" + total_debt_to_ebitda_mrq: builtins.float + """Total Debt/EBITDA.""" + free_cash_flow_to_price: builtins.float + """Отношение свободногоо кэша к стоимости.""" + net_debt_to_ebitda: builtins.float + """Отношение чистого долга к EBITDA.""" + current_ratio_mrq: builtins.float + """Коэффициент текущей ликвидности.""" + fixed_charge_coverage_ratio_fy: builtins.float + """Коэффициент покрытия фиксированных платежей — FCCR.""" + dividend_yield_daily_ttm: builtins.float + """Дивидендная доходность за 12 месяцев.""" + dividend_rate_ttm: builtins.float + """Выплаченные дивиденды за 12 месяцев.""" + dividends_per_share: builtins.float + """Значение дивидендов на акцию.""" + five_years_average_dividend_yield: builtins.float + """Средняя дивидендная доходность за 5 лет.""" + five_year_annual_dividend_growth_rate: builtins.float + """Среднегодовой рост дивидендов за 5 лет.""" + dividend_payout_ratio_fy: builtins.float + """Процент чистой прибыли, уходящий на выплату дивидендов.""" + buy_back_ttm: builtins.float + """Деньги, потраченные на обратный выкуп акций.""" + one_year_annual_revenue_growth_rate: builtins.float + """Рост выручки за 1 год.""" + domicile_indicator_code: builtins.str + """Код страны.""" + adr_to_common_share_ratio: builtins.float + """Соотношение депозитарной расписки к акциям.""" + number_of_employees: builtins.float + """Количество сотрудников.""" + revenue_change_five_years: builtins.float + """Изменение общего дохода за 5 лет.""" + eps_change_five_years: builtins.float + """Изменение EPS за 5 лет.""" + ebitda_change_five_years: builtins.float + """Изменение EBIDTA за 5 лет.""" + total_debt_change_five_years: builtins.float + """Изменение общей задолжности за 5 лет.""" + ev_to_sales: builtins.float + """Отношение EV к выручке.""" + @property + def ex_dividend_date(self) -> google.protobuf.timestamp_pb2.Timestamp: ... + @property + def fiscal_period_start_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Начало фискального периода.""" + + @property + def fiscal_period_end_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Окончание фискального периода.""" + + def __init__( + self, + *, + asset_uid: builtins.str = ..., + currency: builtins.str = ..., + market_capitalization: builtins.float = ..., + high_price_last_52_weeks: builtins.float = ..., + low_price_last_52_weeks: builtins.float = ..., + average_daily_volume_last_10_days: builtins.float = ..., + average_daily_volume_last_4_weeks: builtins.float = ..., + beta: builtins.float = ..., + free_float: builtins.float = ..., + forward_annual_dividend_yield: builtins.float = ..., + shares_outstanding: builtins.float = ..., + revenue_ttm: builtins.float = ..., + ebitda_ttm: builtins.float = ..., + net_income_ttm: builtins.float = ..., + eps_ttm: builtins.float = ..., + diluted_eps_ttm: builtins.float = ..., + free_cash_flow_ttm: builtins.float = ..., + five_year_annual_revenue_growth_rate: builtins.float = ..., + three_year_annual_revenue_growth_rate: builtins.float = ..., + pe_ratio_ttm: builtins.float = ..., + price_to_sales_ttm: builtins.float = ..., + price_to_book_ttm: builtins.float = ..., + price_to_free_cash_flow_ttm: builtins.float = ..., + total_enterprise_value_mrq: builtins.float = ..., + ev_to_ebitda_mrq: builtins.float = ..., + net_margin_mrq: builtins.float = ..., + net_interest_margin_mrq: builtins.float = ..., + roe: builtins.float = ..., + roa: builtins.float = ..., + roic: builtins.float = ..., + total_debt_mrq: builtins.float = ..., + total_debt_to_equity_mrq: builtins.float = ..., + total_debt_to_ebitda_mrq: builtins.float = ..., + free_cash_flow_to_price: builtins.float = ..., + net_debt_to_ebitda: builtins.float = ..., + current_ratio_mrq: builtins.float = ..., + fixed_charge_coverage_ratio_fy: builtins.float = ..., + dividend_yield_daily_ttm: builtins.float = ..., + dividend_rate_ttm: builtins.float = ..., + dividends_per_share: builtins.float = ..., + five_years_average_dividend_yield: builtins.float = ..., + five_year_annual_dividend_growth_rate: builtins.float = ..., + dividend_payout_ratio_fy: builtins.float = ..., + buy_back_ttm: builtins.float = ..., + one_year_annual_revenue_growth_rate: builtins.float = ..., + domicile_indicator_code: builtins.str = ..., + adr_to_common_share_ratio: builtins.float = ..., + number_of_employees: builtins.float = ..., + ex_dividend_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + fiscal_period_start_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + fiscal_period_end_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + revenue_change_five_years: builtins.float = ..., + eps_change_five_years: builtins.float = ..., + ebitda_change_five_years: builtins.float = ..., + total_debt_change_five_years: builtins.float = ..., + ev_to_sales: builtins.float = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["ex_dividend_date", b"ex_dividend_date", "fiscal_period_end_date", b"fiscal_period_end_date", "fiscal_period_start_date", b"fiscal_period_start_date"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["adr_to_common_share_ratio", b"adr_to_common_share_ratio", "asset_uid", b"asset_uid", "average_daily_volume_last_10_days", b"average_daily_volume_last_10_days", "average_daily_volume_last_4_weeks", b"average_daily_volume_last_4_weeks", "beta", b"beta", "buy_back_ttm", b"buy_back_ttm", "currency", b"currency", "current_ratio_mrq", b"current_ratio_mrq", "diluted_eps_ttm", b"diluted_eps_ttm", "dividend_payout_ratio_fy", b"dividend_payout_ratio_fy", "dividend_rate_ttm", b"dividend_rate_ttm", "dividend_yield_daily_ttm", b"dividend_yield_daily_ttm", "dividends_per_share", b"dividends_per_share", "domicile_indicator_code", b"domicile_indicator_code", "ebitda_change_five_years", b"ebitda_change_five_years", "ebitda_ttm", b"ebitda_ttm", "eps_change_five_years", b"eps_change_five_years", "eps_ttm", b"eps_ttm", "ev_to_ebitda_mrq", b"ev_to_ebitda_mrq", "ev_to_sales", b"ev_to_sales", "ex_dividend_date", b"ex_dividend_date", "fiscal_period_end_date", b"fiscal_period_end_date", "fiscal_period_start_date", b"fiscal_period_start_date", "five_year_annual_dividend_growth_rate", b"five_year_annual_dividend_growth_rate", "five_year_annual_revenue_growth_rate", b"five_year_annual_revenue_growth_rate", "five_years_average_dividend_yield", b"five_years_average_dividend_yield", "fixed_charge_coverage_ratio_fy", b"fixed_charge_coverage_ratio_fy", "forward_annual_dividend_yield", b"forward_annual_dividend_yield", "free_cash_flow_to_price", b"free_cash_flow_to_price", "free_cash_flow_ttm", b"free_cash_flow_ttm", "free_float", b"free_float", "high_price_last_52_weeks", b"high_price_last_52_weeks", "low_price_last_52_weeks", b"low_price_last_52_weeks", "market_capitalization", b"market_capitalization", "net_debt_to_ebitda", b"net_debt_to_ebitda", "net_income_ttm", b"net_income_ttm", "net_interest_margin_mrq", b"net_interest_margin_mrq", "net_margin_mrq", b"net_margin_mrq", "number_of_employees", b"number_of_employees", "one_year_annual_revenue_growth_rate", b"one_year_annual_revenue_growth_rate", "pe_ratio_ttm", b"pe_ratio_ttm", "price_to_book_ttm", b"price_to_book_ttm", "price_to_free_cash_flow_ttm", b"price_to_free_cash_flow_ttm", "price_to_sales_ttm", b"price_to_sales_ttm", "revenue_change_five_years", b"revenue_change_five_years", "revenue_ttm", b"revenue_ttm", "roa", b"roa", "roe", b"roe", "roic", b"roic", "shares_outstanding", b"shares_outstanding", "three_year_annual_revenue_growth_rate", b"three_year_annual_revenue_growth_rate", "total_debt_change_five_years", b"total_debt_change_five_years", "total_debt_mrq", b"total_debt_mrq", "total_debt_to_ebitda_mrq", b"total_debt_to_ebitda_mrq", "total_debt_to_equity_mrq", b"total_debt_to_equity_mrq", "total_enterprise_value_mrq", b"total_enterprise_value_mrq"]) -> None: ... + + FUNDAMENTALS_FIELD_NUMBER: builtins.int + @property + def fundamentals(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___GetAssetFundamentalsResponse.StatisticResponse]: ... + def __init__( + self, + *, + fundamentals: collections.abc.Iterable[global___GetAssetFundamentalsResponse.StatisticResponse] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["fundamentals", b"fundamentals"]) -> None: ... + +global___GetAssetFundamentalsResponse = GetAssetFundamentalsResponse + +@typing.final +class GetAssetReportsRequest(google.protobuf.message.Message): + """Запрос отчетов эмитентов""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + FROM_FIELD_NUMBER: builtins.int + TO_FIELD_NUMBER: builtins.int + instrument_id: builtins.str + """Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`.""" + @property + def to(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Окончание запрашиваемого периода по UTC.""" + + def __init__( + self, + *, + instrument_id: builtins.str = ..., + to: google.protobuf.timestamp_pb2.Timestamp | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_from", b"_from", "_to", b"_to", "from", b"from", "to", b"to"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_from", b"_from", "_to", b"_to", "from", b"from", "instrument_id", b"instrument_id", "to", b"to"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_from", b"_from"]) -> typing.Literal["from"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_to", b"_to"]) -> typing.Literal["to"] | None: ... + +global___GetAssetReportsRequest = GetAssetReportsRequest + +@typing.final +class GetAssetReportsResponse(google.protobuf.message.Message): + """Отчеты эмитентов""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _AssetReportPeriodType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _AssetReportPeriodTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[GetAssetReportsResponse._AssetReportPeriodType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + PERIOD_TYPE_UNSPECIFIED: GetAssetReportsResponse._AssetReportPeriodType.ValueType # 0 + """Не указан.""" + PERIOD_TYPE_QUARTER: GetAssetReportsResponse._AssetReportPeriodType.ValueType # 1 + """Квартальный.""" + PERIOD_TYPE_SEMIANNUAL: GetAssetReportsResponse._AssetReportPeriodType.ValueType # 2 + """Полугодовой.""" + PERIOD_TYPE_ANNUAL: GetAssetReportsResponse._AssetReportPeriodType.ValueType # 3 + """Годовой.""" + + class AssetReportPeriodType(_AssetReportPeriodType, metaclass=_AssetReportPeriodTypeEnumTypeWrapper): ... + PERIOD_TYPE_UNSPECIFIED: GetAssetReportsResponse.AssetReportPeriodType.ValueType # 0 + """Не указан.""" + PERIOD_TYPE_QUARTER: GetAssetReportsResponse.AssetReportPeriodType.ValueType # 1 + """Квартальный.""" + PERIOD_TYPE_SEMIANNUAL: GetAssetReportsResponse.AssetReportPeriodType.ValueType # 2 + """Полугодовой.""" + PERIOD_TYPE_ANNUAL: GetAssetReportsResponse.AssetReportPeriodType.ValueType # 3 + """Годовой.""" + + @typing.final + class GetAssetReportsEvent(google.protobuf.message.Message): + """Отчет""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + REPORT_DATE_FIELD_NUMBER: builtins.int + PERIOD_YEAR_FIELD_NUMBER: builtins.int + PERIOD_NUM_FIELD_NUMBER: builtins.int + PERIOD_TYPE_FIELD_NUMBER: builtins.int + CREATED_AT_FIELD_NUMBER: builtins.int + instrument_id: builtins.str + """Идентификатор инструмента.""" + period_year: builtins.int + """Год периода отчета.""" + period_num: builtins.int + """Номер периода.""" + period_type: global___GetAssetReportsResponse.AssetReportPeriodType.ValueType + """Тип отчета.""" + @property + def report_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата публикации отчета.""" + + @property + def created_at(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата создания записи.""" + + def __init__( + self, + *, + instrument_id: builtins.str = ..., + report_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + period_year: builtins.int = ..., + period_num: builtins.int = ..., + period_type: global___GetAssetReportsResponse.AssetReportPeriodType.ValueType = ..., + created_at: google.protobuf.timestamp_pb2.Timestamp | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["created_at", b"created_at", "report_date", b"report_date"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["created_at", b"created_at", "instrument_id", b"instrument_id", "period_num", b"period_num", "period_type", b"period_type", "period_year", b"period_year", "report_date", b"report_date"]) -> None: ... + + EVENTS_FIELD_NUMBER: builtins.int + @property + def events(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___GetAssetReportsResponse.GetAssetReportsEvent]: + """Массив событий по облигации.""" + + def __init__( + self, + *, + events: collections.abc.Iterable[global___GetAssetReportsResponse.GetAssetReportsEvent] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["events", b"events"]) -> None: ... + +global___GetAssetReportsResponse = GetAssetReportsResponse + +@typing.final +class GetConsensusForecastsRequest(google.protobuf.message.Message): + """Запрос консенсус-прогнозов""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PAGING_FIELD_NUMBER: builtins.int + @property + def paging(self) -> t_tech.invest.grpc.common_pb2.Page: + """Настройки пагинации.""" + + def __init__( + self, + *, + paging: t_tech.invest.grpc.common_pb2.Page | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_paging", b"_paging", "paging", b"paging"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_paging", b"_paging", "paging", b"paging"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_paging", b"_paging"]) -> typing.Literal["paging"] | None: ... + +global___GetConsensusForecastsRequest = GetConsensusForecastsRequest + +@typing.final +class GetConsensusForecastsResponse(google.protobuf.message.Message): + """Консенсус-прогнозы""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing.final + class ConsensusForecastsItem(google.protobuf.message.Message): + """Прогноз""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + UID_FIELD_NUMBER: builtins.int + ASSET_UID_FIELD_NUMBER: builtins.int + CREATED_AT_FIELD_NUMBER: builtins.int + BEST_TARGET_PRICE_FIELD_NUMBER: builtins.int + BEST_TARGET_LOW_FIELD_NUMBER: builtins.int + BEST_TARGET_HIGH_FIELD_NUMBER: builtins.int + TOTAL_BUY_RECOMMEND_FIELD_NUMBER: builtins.int + TOTAL_HOLD_RECOMMEND_FIELD_NUMBER: builtins.int + TOTAL_SELL_RECOMMEND_FIELD_NUMBER: builtins.int + CURRENCY_FIELD_NUMBER: builtins.int + CONSENSUS_FIELD_NUMBER: builtins.int + PROGNOSIS_DATE_FIELD_NUMBER: builtins.int + uid: builtins.str + """UID-идентификатор.""" + asset_uid: builtins.str + """UID-идентификатор актива.""" + total_buy_recommend: builtins.int + """Количество аналитиков рекомендующих покупать.""" + total_hold_recommend: builtins.int + """Количество аналитиков рекомендующих держать.""" + total_sell_recommend: builtins.int + """Количество аналитиков рекомендующих продавать.""" + currency: builtins.str + """Валюта прогнозов инструмента.""" + consensus: global___Recommendation.ValueType + """Консенсус-прогноз.""" + @property + def created_at(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата и время создания записи.""" + + @property + def best_target_price(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Целевая цена на 12 месяцев.""" + + @property + def best_target_low(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Минимальная прогнозная цена.""" + + @property + def best_target_high(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Максимальная прогнозная цена.""" + + @property + def prognosis_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата прогноза.""" + + def __init__( + self, + *, + uid: builtins.str = ..., + asset_uid: builtins.str = ..., + created_at: google.protobuf.timestamp_pb2.Timestamp | None = ..., + best_target_price: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + best_target_low: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + best_target_high: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + total_buy_recommend: builtins.int = ..., + total_hold_recommend: builtins.int = ..., + total_sell_recommend: builtins.int = ..., + currency: builtins.str = ..., + consensus: global___Recommendation.ValueType = ..., + prognosis_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["best_target_high", b"best_target_high", "best_target_low", b"best_target_low", "best_target_price", b"best_target_price", "created_at", b"created_at", "prognosis_date", b"prognosis_date"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["asset_uid", b"asset_uid", "best_target_high", b"best_target_high", "best_target_low", b"best_target_low", "best_target_price", b"best_target_price", "consensus", b"consensus", "created_at", b"created_at", "currency", b"currency", "prognosis_date", b"prognosis_date", "total_buy_recommend", b"total_buy_recommend", "total_hold_recommend", b"total_hold_recommend", "total_sell_recommend", b"total_sell_recommend", "uid", b"uid"]) -> None: ... + + ITEMS_FIELD_NUMBER: builtins.int + PAGE_FIELD_NUMBER: builtins.int + @property + def items(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___GetConsensusForecastsResponse.ConsensusForecastsItem]: + """Массив прогнозов.""" + + @property + def page(self) -> t_tech.invest.grpc.common_pb2.PageResponse: + """Данные по пагинации.""" + + def __init__( + self, + *, + items: collections.abc.Iterable[global___GetConsensusForecastsResponse.ConsensusForecastsItem] | None = ..., + page: t_tech.invest.grpc.common_pb2.PageResponse | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["page", b"page"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["items", b"items", "page", b"page"]) -> None: ... + +global___GetConsensusForecastsResponse = GetConsensusForecastsResponse + +@typing.final +class GetForecastRequest(google.protobuf.message.Message): + """Запрос прогнозов инвестдомов.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + instrument_id: builtins.str + """Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`.""" + def __init__( + self, + *, + instrument_id: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["instrument_id", b"instrument_id"]) -> None: ... + +global___GetForecastRequest = GetForecastRequest + +@typing.final +class GetForecastResponse(google.protobuf.message.Message): + """Прогнозы инвестдомов по инструменту.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing.final + class TargetItem(google.protobuf.message.Message): + """Прогноз""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + UID_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + COMPANY_FIELD_NUMBER: builtins.int + RECOMMENDATION_FIELD_NUMBER: builtins.int + RECOMMENDATION_DATE_FIELD_NUMBER: builtins.int + CURRENCY_FIELD_NUMBER: builtins.int + CURRENT_PRICE_FIELD_NUMBER: builtins.int + TARGET_PRICE_FIELD_NUMBER: builtins.int + PRICE_CHANGE_FIELD_NUMBER: builtins.int + PRICE_CHANGE_REL_FIELD_NUMBER: builtins.int + SHOW_NAME_FIELD_NUMBER: builtins.int + uid: builtins.str + """Уникальный идентификатор инструмента.""" + ticker: builtins.str + """Тикер инструмента.""" + company: builtins.str + """Название компании, давшей прогноз.""" + recommendation: global___Recommendation.ValueType + """Прогноз.""" + currency: builtins.str + """Валюта.""" + show_name: builtins.str + """Наименование инструмента.""" + @property + def recommendation_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата прогноза.""" + + @property + def current_price(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Текущая цена.""" + + @property + def target_price(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Прогнозируемая цена.""" + + @property + def price_change(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Изменение цены.""" + + @property + def price_change_rel(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Относительное изменение цены.""" + + def __init__( + self, + *, + uid: builtins.str = ..., + ticker: builtins.str = ..., + company: builtins.str = ..., + recommendation: global___Recommendation.ValueType = ..., + recommendation_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + currency: builtins.str = ..., + current_price: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + target_price: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + price_change: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + price_change_rel: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + show_name: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["current_price", b"current_price", "price_change", b"price_change", "price_change_rel", b"price_change_rel", "recommendation_date", b"recommendation_date", "target_price", b"target_price"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["company", b"company", "currency", b"currency", "current_price", b"current_price", "price_change", b"price_change", "price_change_rel", b"price_change_rel", "recommendation", b"recommendation", "recommendation_date", b"recommendation_date", "show_name", b"show_name", "target_price", b"target_price", "ticker", b"ticker", "uid", b"uid"]) -> None: ... + + @typing.final + class ConsensusItem(google.protobuf.message.Message): + """Консенсус-прогноз.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + UID_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + RECOMMENDATION_FIELD_NUMBER: builtins.int + CURRENCY_FIELD_NUMBER: builtins.int + CURRENT_PRICE_FIELD_NUMBER: builtins.int + CONSENSUS_FIELD_NUMBER: builtins.int + MIN_TARGET_FIELD_NUMBER: builtins.int + MAX_TARGET_FIELD_NUMBER: builtins.int + PRICE_CHANGE_FIELD_NUMBER: builtins.int + PRICE_CHANGE_REL_FIELD_NUMBER: builtins.int + uid: builtins.str + """Уникальный идентификатор инструмента.""" + ticker: builtins.str + """Тикер инструмента.""" + recommendation: global___Recommendation.ValueType + """Прогноз.""" + currency: builtins.str + """Валюта.""" + @property + def current_price(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Текущая цена.""" + + @property + def consensus(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Прогнозируемая цена.""" + + @property + def min_target(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Минимальная цена прогноза.""" + + @property + def max_target(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Максимальная цена прогноза.""" + + @property + def price_change(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Изменение цены.""" + + @property + def price_change_rel(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Относительное изменение цены.""" + + def __init__( + self, + *, + uid: builtins.str = ..., + ticker: builtins.str = ..., + recommendation: global___Recommendation.ValueType = ..., + currency: builtins.str = ..., + current_price: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + consensus: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + min_target: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + max_target: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + price_change: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + price_change_rel: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["consensus", b"consensus", "current_price", b"current_price", "max_target", b"max_target", "min_target", b"min_target", "price_change", b"price_change", "price_change_rel", b"price_change_rel"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["consensus", b"consensus", "currency", b"currency", "current_price", b"current_price", "max_target", b"max_target", "min_target", b"min_target", "price_change", b"price_change", "price_change_rel", b"price_change_rel", "recommendation", b"recommendation", "ticker", b"ticker", "uid", b"uid"]) -> None: ... + + TARGETS_FIELD_NUMBER: builtins.int + CONSENSUS_FIELD_NUMBER: builtins.int + @property + def targets(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___GetForecastResponse.TargetItem]: + """Массив прогнозов.""" + + @property + def consensus(self) -> global___GetForecastResponse.ConsensusItem: + """Согласованный прогноз.""" + + def __init__( + self, + *, + targets: collections.abc.Iterable[global___GetForecastResponse.TargetItem] | None = ..., + consensus: global___GetForecastResponse.ConsensusItem | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["consensus", b"consensus"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["consensus", b"consensus", "targets", b"targets"]) -> None: ... + +global___GetForecastResponse = GetForecastResponse + +@typing.final +class RiskRatesRequest(google.protobuf.message.Message): + """Запрос ставок риска""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + @property + def instrument_id(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`.""" + + def __init__( + self, + *, + instrument_id: collections.abc.Iterable[builtins.str] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["instrument_id", b"instrument_id"]) -> None: ... + +global___RiskRatesRequest = RiskRatesRequest + +@typing.final +class RiskRatesResponse(google.protobuf.message.Message): + """Ставки риска""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing.final + class RiskRateResult(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + SHORT_RISK_RATE_FIELD_NUMBER: builtins.int + LONG_RISK_RATE_FIELD_NUMBER: builtins.int + SHORT_RISK_RATES_FIELD_NUMBER: builtins.int + LONG_RISK_RATES_FIELD_NUMBER: builtins.int + ERROR_FIELD_NUMBER: builtins.int + instrument_uid: builtins.str + error: builtins.str + """Ошибка.""" + @property + def short_risk_rate(self) -> global___RiskRatesResponse.RiskRate: + """Ставка риска пользователя в шорт""" + + @property + def long_risk_rate(self) -> global___RiskRatesResponse.RiskRate: + """Ставка риска пользователя в лонг""" + + @property + def short_risk_rates(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___RiskRatesResponse.RiskRate]: + """Доступные ставки риска в шорт""" + + @property + def long_risk_rates(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___RiskRatesResponse.RiskRate]: + """Доступные ставки риска в лонг""" + + def __init__( + self, + *, + instrument_uid: builtins.str = ..., + short_risk_rate: global___RiskRatesResponse.RiskRate | None = ..., + long_risk_rate: global___RiskRatesResponse.RiskRate | None = ..., + short_risk_rates: collections.abc.Iterable[global___RiskRatesResponse.RiskRate] | None = ..., + long_risk_rates: collections.abc.Iterable[global___RiskRatesResponse.RiskRate] | None = ..., + error: builtins.str | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_error", b"_error", "_long_risk_rate", b"_long_risk_rate", "_short_risk_rate", b"_short_risk_rate", "error", b"error", "long_risk_rate", b"long_risk_rate", "short_risk_rate", b"short_risk_rate"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_error", b"_error", "_long_risk_rate", b"_long_risk_rate", "_short_risk_rate", b"_short_risk_rate", "error", b"error", "instrument_uid", b"instrument_uid", "long_risk_rate", b"long_risk_rate", "long_risk_rates", b"long_risk_rates", "short_risk_rate", b"short_risk_rate", "short_risk_rates", b"short_risk_rates"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_error", b"_error"]) -> typing.Literal["error"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_long_risk_rate", b"_long_risk_rate"]) -> typing.Literal["long_risk_rate"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_short_risk_rate", b"_short_risk_rate"]) -> typing.Literal["short_risk_rate"] | None: ... + + @typing.final + class RiskRate(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + RISK_LEVEL_CODE_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + risk_level_code: builtins.str + """Категория риска.""" + @property + def value(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Значение ставки риска.""" + + def __init__( + self, + *, + risk_level_code: builtins.str = ..., + value: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["risk_level_code", b"risk_level_code", "value", b"value"]) -> None: ... + + INSTRUMENT_RISK_RATES_FIELD_NUMBER: builtins.int + @property + def instrument_risk_rates(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___RiskRatesResponse.RiskRateResult]: ... + def __init__( + self, + *, + instrument_risk_rates: collections.abc.Iterable[global___RiskRatesResponse.RiskRateResult] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["instrument_risk_rates", b"instrument_risk_rates"]) -> None: ... + +global___RiskRatesResponse = RiskRatesResponse + +@typing.final +class TradingInterval(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing.final + class TimeInterval(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + START_TS_FIELD_NUMBER: builtins.int + END_TS_FIELD_NUMBER: builtins.int + @property + def start_ts(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время начала интервала.""" + + @property + def end_ts(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время окончания интервала.""" + + def __init__( + self, + *, + start_ts: google.protobuf.timestamp_pb2.Timestamp | None = ..., + end_ts: google.protobuf.timestamp_pb2.Timestamp | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["end_ts", b"end_ts", "start_ts", b"start_ts"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["end_ts", b"end_ts", "start_ts", b"start_ts"]) -> None: ... + + TYPE_FIELD_NUMBER: builtins.int + INTERVAL_FIELD_NUMBER: builtins.int + type: builtins.str + """Название интервала.""" + @property + def interval(self) -> global___TradingInterval.TimeInterval: + """Интервал.""" + + def __init__( + self, + *, + type: builtins.str = ..., + interval: global___TradingInterval.TimeInterval | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["interval", b"interval"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["interval", b"interval", "type", b"type"]) -> None: ... + +global___TradingInterval = TradingInterval + +@typing.final +class GetInsiderDealsRequest(google.protobuf.message.Message): + """Запрос сделок по инсайдерам""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + LIMIT_FIELD_NUMBER: builtins.int + NEXT_CURSOR_FIELD_NUMBER: builtins.int + instrument_id: builtins.str + """Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`.""" + limit: builtins.int + """Количество выводимых записей в ответе, не больше 100.""" + next_cursor: builtins.str + """Курсор.""" + def __init__( + self, + *, + instrument_id: builtins.str = ..., + limit: builtins.int = ..., + next_cursor: builtins.str | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_next_cursor", b"_next_cursor", "next_cursor", b"next_cursor"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_next_cursor", b"_next_cursor", "instrument_id", b"instrument_id", "limit", b"limit", "next_cursor", b"next_cursor"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_next_cursor", b"_next_cursor"]) -> typing.Literal["next_cursor"] | None: ... + +global___GetInsiderDealsRequest = GetInsiderDealsRequest + +@typing.final +class GetInsiderDealsResponse(google.protobuf.message.Message): + """сделки инсайдеров""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _TradeDirection: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _TradeDirectionEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[GetInsiderDealsResponse._TradeDirection.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + TRADE_DIRECTION_UNSPECIFIED: GetInsiderDealsResponse._TradeDirection.ValueType # 0 + """Не определено.""" + TRADE_DIRECTION_BUY: GetInsiderDealsResponse._TradeDirection.ValueType # 1 + """Покупка.""" + TRADE_DIRECTION_SELL: GetInsiderDealsResponse._TradeDirection.ValueType # 2 + """Продажа.""" + TRADE_DIRECTION_INCREASE: GetInsiderDealsResponse._TradeDirection.ValueType # 3 + """Увеличение доли.""" + TRADE_DIRECTION_DECREASE: GetInsiderDealsResponse._TradeDirection.ValueType # 4 + """Уменьшение доли.""" + + class TradeDirection(_TradeDirection, metaclass=_TradeDirectionEnumTypeWrapper): ... + TRADE_DIRECTION_UNSPECIFIED: GetInsiderDealsResponse.TradeDirection.ValueType # 0 + """Не определено.""" + TRADE_DIRECTION_BUY: GetInsiderDealsResponse.TradeDirection.ValueType # 1 + """Покупка.""" + TRADE_DIRECTION_SELL: GetInsiderDealsResponse.TradeDirection.ValueType # 2 + """Продажа.""" + TRADE_DIRECTION_INCREASE: GetInsiderDealsResponse.TradeDirection.ValueType # 3 + """Увеличение доли.""" + TRADE_DIRECTION_DECREASE: GetInsiderDealsResponse.TradeDirection.ValueType # 4 + """Уменьшение доли.""" + + @typing.final + class InsiderDeal(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TRADE_ID_FIELD_NUMBER: builtins.int + DIRECTION_FIELD_NUMBER: builtins.int + CURRENCY_FIELD_NUMBER: builtins.int + DATE_FIELD_NUMBER: builtins.int + QUANTITY_FIELD_NUMBER: builtins.int + PRICE_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + INVESTOR_NAME_FIELD_NUMBER: builtins.int + INVESTOR_POSITION_FIELD_NUMBER: builtins.int + PERCENTAGE_FIELD_NUMBER: builtins.int + IS_OPTION_EXECUTION_FIELD_NUMBER: builtins.int + DISCLOSURE_DATE_FIELD_NUMBER: builtins.int + trade_id: builtins.int + """Уникальный идентификатор сделки.""" + direction: global___GetInsiderDealsResponse.TradeDirection.ValueType + """Направление сделки.""" + currency: builtins.str + """Валюта сделки.""" + quantity: builtins.int + """Количество.""" + instrument_uid: builtins.str + """Уникальный идентификатор инструмента.""" + ticker: builtins.str + """Тикер инструмента.""" + investor_name: builtins.str + """Имя инвестора.""" + investor_position: builtins.str + """Какое отношение покупатель/продавец имеет к эмитенту""" + percentage: builtins.float + """Купленный/проданный объём от общего количества ценных бумаг на рынке""" + is_option_execution: builtins.bool + """Признак является ли сделка реализацией опциона""" + @property + def date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата сделки.""" + + @property + def price(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Цена.""" + + @property + def disclosure_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата раскрытия сделки.""" + + def __init__( + self, + *, + trade_id: builtins.int = ..., + direction: global___GetInsiderDealsResponse.TradeDirection.ValueType = ..., + currency: builtins.str = ..., + date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + quantity: builtins.int = ..., + price: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + instrument_uid: builtins.str = ..., + ticker: builtins.str = ..., + investor_name: builtins.str = ..., + investor_position: builtins.str = ..., + percentage: builtins.float = ..., + is_option_execution: builtins.bool = ..., + disclosure_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["date", b"date", "disclosure_date", b"disclosure_date", "price", b"price"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["currency", b"currency", "date", b"date", "direction", b"direction", "disclosure_date", b"disclosure_date", "instrument_uid", b"instrument_uid", "investor_name", b"investor_name", "investor_position", b"investor_position", "is_option_execution", b"is_option_execution", "percentage", b"percentage", "price", b"price", "quantity", b"quantity", "ticker", b"ticker", "trade_id", b"trade_id"]) -> None: ... + + INSIDER_DEALS_FIELD_NUMBER: builtins.int + NEXT_CURSOR_FIELD_NUMBER: builtins.int + next_cursor: builtins.str + """Курсор для получения следующей страницы.""" + @property + def insider_deals(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___GetInsiderDealsResponse.InsiderDeal]: + """Массив сделок.""" + + def __init__( + self, + *, + insider_deals: collections.abc.Iterable[global___GetInsiderDealsResponse.InsiderDeal] | None = ..., + next_cursor: builtins.str | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_next_cursor", b"_next_cursor", "next_cursor", b"next_cursor"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_next_cursor", b"_next_cursor", "insider_deals", b"insider_deals", "next_cursor", b"next_cursor"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_next_cursor", b"_next_cursor"]) -> typing.Literal["next_cursor"] | None: ... + +global___GetInsiderDealsResponse = GetInsiderDealsResponse + +@typing.final +class DfasRequest(google.protobuf.message.Message): + """Запрос цифровых активов""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + def __init__( + self, + ) -> None: ... + +global___DfasRequest = DfasRequest + +@typing.final +class DfaResponse(google.protobuf.message.Message): + """Цифровой актив""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing.final + class BasicAsset(google.protobuf.message.Message): + """Базовый актив.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + UID_FIELD_NUMBER: builtins.int + uid: builtins.str + """UID базового актива""" + def __init__( + self, + *, + uid: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["uid", b"uid"]) -> None: ... + + @typing.final + class ForecastYield(google.protobuf.message.Message): + """Прогнозная доходность смарт-портфелей.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + MIN_VALUE_FIELD_NUMBER: builtins.int + MAX_VALUE_FIELD_NUMBER: builtins.int + @property + def min_value(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Минимальное значение прогнозной доходности в %""" + + @property + def max_value(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Максимальное значение прогнозной доходности в %""" + + def __init__( + self, + *, + min_value: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + max_value: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["max_value", b"max_value", "min_value", b"min_value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["max_value", b"max_value", "min_value", b"min_value"]) -> None: ... + + UID_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + POSITION_UID_FIELD_NUMBER: builtins.int + MIN_PRICE_INCREMENT_FIELD_NUMBER: builtins.int + LOT_FIELD_NUMBER: builtins.int + NOMINAL_FIELD_NUMBER: builtins.int + CURRENCY_FIELD_NUMBER: builtins.int + MATURITY_DATE_FIELD_NUMBER: builtins.int + SHORT_ENABLED_FLAG_FIELD_NUMBER: builtins.int + API_TRADE_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + BUY_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + SELL_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + LIMIT_ORDER_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + MARKET_ORDER_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + BESTPRICE_ORDER_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + FOR_IIS_FLAG_FIELD_NUMBER: builtins.int + FOR_QUAL_INVESTOR_FLAG_FIELD_NUMBER: builtins.int + TYPE_FIELD_NUMBER: builtins.int + BASIC_ASSETS_FIELD_NUMBER: builtins.int + FORECAST_YIELD_FIELD_NUMBER: builtins.int + YIELD_TO_MATURITY_FIELD_NUMBER: builtins.int + COUPON_VALUE_FIELD_NUMBER: builtins.int + COUPON_PAYMENT_FREQUENCY_FIELD_NUMBER: builtins.int + COUPON_PAYMENT_DATE_FIELD_NUMBER: builtins.int + ACI_VALUE_FIELD_NUMBER: builtins.int + uid: builtins.str + """Уникальный идентификатор инструмента.""" + ticker: builtins.str + """Тикер инструмента.""" + name: builtins.str + """Название инструмента.""" + position_uid: builtins.str + """Уникальный идентификатор позиции.""" + lot: builtins.int + """Количество лотов.""" + currency: builtins.str + """Валюта.""" + short_enabled_flag: builtins.bool + """Признак доступности для операций шорт.""" + api_trade_available_flag: builtins.bool + """Признак доступности торгов по бумаге через API.""" + buy_available_flag: builtins.bool + """Признак доступности для покупки.""" + sell_available_flag: builtins.bool + """Признак доступности для продажи.""" + limit_order_available_flag: builtins.bool + """Признак доступности выставления лимитной заявки по инструменту.""" + market_order_available_flag: builtins.bool + """Признак доступности выставления рыночной заявки по инструменту.""" + bestprice_order_available_flag: builtins.bool + """Признак доступности выставления bestprice заявки по инструменту.""" + for_iis_flag: builtins.bool + """Возможность покупки/продажи на ИИС.""" + for_qual_investor_flag: builtins.bool + """Флаг отображающий доступность торговли инструментом только для квалифицированных инвесторов.""" + type: builtins.str + """Тип актива. Возможные значения: credit_portfolio_dfa, debt_dfa.""" + coupon_payment_frequency: builtins.int + """Количество выплат в год.""" + @property + def min_price_increment(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Шаг цены.""" + + @property + def nominal(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Номинал.""" + + @property + def maturity_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата погашения ЦФА в формате UTC.""" + + @property + def basic_assets(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___DfaResponse.BasicAsset]: + """Базовые активы, входящие в ЦФА.""" + + @property + def forecast_yield(self) -> global___DfaResponse.ForecastYield: + """Прогнозная доходность смарт-портфелей, в виде интервала в %.""" + + @property + def yield_to_maturity(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Доходность к погашению в %.""" + + @property + def coupon_value(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Величина купона.""" + + @property + def coupon_payment_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата выплаты купона.""" + + @property + def aci_value(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Значение НКД (накопленного купонного дохода) на дату.""" + + def __init__( + self, + *, + uid: builtins.str = ..., + ticker: builtins.str = ..., + name: builtins.str = ..., + position_uid: builtins.str = ..., + min_price_increment: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + lot: builtins.int = ..., + nominal: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + currency: builtins.str = ..., + maturity_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + short_enabled_flag: builtins.bool = ..., + api_trade_available_flag: builtins.bool = ..., + buy_available_flag: builtins.bool = ..., + sell_available_flag: builtins.bool = ..., + limit_order_available_flag: builtins.bool = ..., + market_order_available_flag: builtins.bool = ..., + bestprice_order_available_flag: builtins.bool = ..., + for_iis_flag: builtins.bool = ..., + for_qual_investor_flag: builtins.bool = ..., + type: builtins.str = ..., + basic_assets: collections.abc.Iterable[global___DfaResponse.BasicAsset] | None = ..., + forecast_yield: global___DfaResponse.ForecastYield | None = ..., + yield_to_maturity: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + coupon_value: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + coupon_payment_frequency: builtins.int = ..., + coupon_payment_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + aci_value: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["aci_value", b"aci_value", "coupon_payment_date", b"coupon_payment_date", "coupon_value", b"coupon_value", "forecast_yield", b"forecast_yield", "maturity_date", b"maturity_date", "min_price_increment", b"min_price_increment", "nominal", b"nominal", "yield_to_maturity", b"yield_to_maturity"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["aci_value", b"aci_value", "api_trade_available_flag", b"api_trade_available_flag", "basic_assets", b"basic_assets", "bestprice_order_available_flag", b"bestprice_order_available_flag", "buy_available_flag", b"buy_available_flag", "coupon_payment_date", b"coupon_payment_date", "coupon_payment_frequency", b"coupon_payment_frequency", "coupon_value", b"coupon_value", "currency", b"currency", "for_iis_flag", b"for_iis_flag", "for_qual_investor_flag", b"for_qual_investor_flag", "forecast_yield", b"forecast_yield", "limit_order_available_flag", b"limit_order_available_flag", "lot", b"lot", "market_order_available_flag", b"market_order_available_flag", "maturity_date", b"maturity_date", "min_price_increment", b"min_price_increment", "name", b"name", "nominal", b"nominal", "position_uid", b"position_uid", "sell_available_flag", b"sell_available_flag", "short_enabled_flag", b"short_enabled_flag", "ticker", b"ticker", "type", b"type", "uid", b"uid", "yield_to_maturity", b"yield_to_maturity"]) -> None: ... + +global___DfaResponse = DfaResponse + +@typing.final +class DfasResponse(google.protobuf.message.Message): + """Цифровые активы""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENTS_FIELD_NUMBER: builtins.int + @property + def instruments(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___DfaResponse]: + """Массив инструментов.""" + + def __init__( + self, + *, + instruments: collections.abc.Iterable[global___DfaResponse] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["instruments", b"instruments"]) -> None: ... + +global___DfasResponse = DfasResponse diff --git a/invest-python-master/t_tech/invest/grpc/instruments_pb2_grpc.py b/invest-python-master/t_tech/invest/grpc/instruments_pb2_grpc.py new file mode 100644 index 0000000..7f67905 --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/instruments_pb2_grpc.py @@ -0,0 +1,1473 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +from t_tech.invest.grpc import ( + instruments_pb2 as t__tech_dot_invest_dot_grpc_dot_instruments__pb2, +) + + +class InstrumentsServiceStub(object): + """Методы сервиса предназначены для получения:
1. Информации об инструментах.
2. + Расписания торговых сессий.
3. Календаря выплат купонов по облигациям.
4. + Размера гарантийного обеспечения по фьючерсам.
5. Дивидендов по ценной бумаге. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.TradingSchedules = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/TradingSchedules', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.TradingSchedulesRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.TradingSchedulesResponse.FromString, + ) + self.BondBy = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/BondBy', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.BondResponse.FromString, + ) + self.Bonds = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/Bonds', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.BondsResponse.FromString, + ) + self.GetBondCoupons = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetBondCoupons', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetBondCouponsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetBondCouponsResponse.FromString, + ) + self.GetBondEvents = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetBondEvents', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetBondEventsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetBondEventsResponse.FromString, + ) + self.CurrencyBy = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/CurrencyBy', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.CurrencyResponse.FromString, + ) + self.Currencies = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/Currencies', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.CurrenciesResponse.FromString, + ) + self.EtfBy = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/EtfBy', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.EtfResponse.FromString, + ) + self.Etfs = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/Etfs', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.EtfsResponse.FromString, + ) + self.FutureBy = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/FutureBy', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.FutureResponse.FromString, + ) + self.Futures = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/Futures', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.FuturesResponse.FromString, + ) + self.OptionBy = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/OptionBy', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.OptionResponse.FromString, + ) + self.Options = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/Options', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.OptionsResponse.FromString, + ) + self.OptionsBy = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/OptionsBy', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.FilterOptionsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.OptionsResponse.FromString, + ) + self.ShareBy = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/ShareBy', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.ShareResponse.FromString, + ) + self.Shares = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/Shares', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.SharesResponse.FromString, + ) + self.DfaBy = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/DfaBy', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.DfaResponse.FromString, + ) + self.Dfas = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/Dfas', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.DfasRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.DfasResponse.FromString, + ) + self.Indicatives = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/Indicatives', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.IndicativesRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.IndicativesResponse.FromString, + ) + self.GetAccruedInterests = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetAccruedInterests', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetAccruedInterestsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetAccruedInterestsResponse.FromString, + ) + self.GetFuturesMargin = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetFuturesMargin', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetFuturesMarginRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetFuturesMarginResponse.FromString, + ) + self.GetInstrumentBy = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetInstrumentBy', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentResponse.FromString, + ) + self.GetDividends = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetDividends', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetDividendsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetDividendsResponse.FromString, + ) + self.GetAssetBy = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetAssetBy', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.AssetRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.AssetResponse.FromString, + ) + self.GetAssets = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetAssets', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.AssetsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.AssetsResponse.FromString, + ) + self.GetFavorites = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetFavorites', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetFavoritesRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetFavoritesResponse.FromString, + ) + self.EditFavorites = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/EditFavorites', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.EditFavoritesRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.EditFavoritesResponse.FromString, + ) + self.CreateFavoriteGroup = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/CreateFavoriteGroup', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.CreateFavoriteGroupRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.CreateFavoriteGroupResponse.FromString, + ) + self.DeleteFavoriteGroup = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/DeleteFavoriteGroup', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.DeleteFavoriteGroupRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.DeleteFavoriteGroupResponse.FromString, + ) + self.GetFavoriteGroups = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetFavoriteGroups', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetFavoriteGroupsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetFavoriteGroupsResponse.FromString, + ) + self.GetCountries = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetCountries', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetCountriesRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetCountriesResponse.FromString, + ) + self.FindInstrument = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/FindInstrument', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.FindInstrumentRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.FindInstrumentResponse.FromString, + ) + self.GetBrands = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetBrands', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetBrandsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetBrandsResponse.FromString, + ) + self.GetBrandBy = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetBrandBy', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetBrandRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.Brand.FromString, + ) + self.GetAssetFundamentals = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetAssetFundamentals', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetAssetFundamentalsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetAssetFundamentalsResponse.FromString, + ) + self.GetAssetReports = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetAssetReports', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetAssetReportsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetAssetReportsResponse.FromString, + ) + self.GetConsensusForecasts = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetConsensusForecasts', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetConsensusForecastsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetConsensusForecastsResponse.FromString, + ) + self.GetForecastBy = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetForecastBy', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetForecastRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetForecastResponse.FromString, + ) + self.GetRiskRates = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetRiskRates', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.RiskRatesRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.RiskRatesResponse.FromString, + ) + self.GetInsiderDeals = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetInsiderDeals', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetInsiderDealsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetInsiderDealsResponse.FromString, + ) + self.StructuredNoteBy = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/StructuredNoteBy', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.StructuredNoteResponse.FromString, + ) + self.StructuredNotes = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.InstrumentsService/StructuredNotes', + request_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.StructuredNotesResponse.FromString, + ) + + +class InstrumentsServiceServicer(object): + """Методы сервиса предназначены для получения:
1. Информации об инструментах.
2. + Расписания торговых сессий.
3. Календаря выплат купонов по облигациям.
4. + Размера гарантийного обеспечения по фьючерсам.
5. Дивидендов по ценной бумаге. + """ + + def TradingSchedules(self, request, context): + """TradingSchedules — расписания торговых площадок + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def BondBy(self, request, context): + """BondBy — получить облигацию по ее идентификатору + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def Bonds(self, request, context): + """Bonds — список облигаций + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetBondCoupons(self, request, context): + """GetBondCoupons — график выплат купонов по облигации + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetBondEvents(self, request, context): + """GetBondEvents — события по облигации + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def CurrencyBy(self, request, context): + """CurrencyBy — получить валюту по ее идентификатору + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def Currencies(self, request, context): + """Currencies — список валют + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def EtfBy(self, request, context): + """EtfBy — получить инвестиционный фонд по его идентификатору + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def Etfs(self, request, context): + """Etfs — список инвестиционных фондов + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def FutureBy(self, request, context): + """FutureBy — получить фьючерс по его идентификатору + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def Futures(self, request, context): + """Futures — список фьючерсов + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def OptionBy(self, request, context): + """OptionBy — получить опцион по его идентификатору + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def Options(self, request, context): + """Deprecated Options — список опционов + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def OptionsBy(self, request, context): + """OptionsBy — список опционов + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def ShareBy(self, request, context): + """ShareBy — получить акцию по ее идентификатору + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def Shares(self, request, context): + """Shares — список акций + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def DfaBy(self, request, context): + """DfaBy — получить цифровой актив по ее идентификатору + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def Dfas(self, request, context): + """Dfas — список цифровых активов + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def Indicatives(self, request, context): + """Indicatives — индикативные инструменты — индексы, товары и другие + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetAccruedInterests(self, request, context): + """GetAccruedInterests — накопленный купонный доход по облигации + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetFuturesMargin(self, request, context): + """GetFuturesMargin — размера гарантийного обеспечения по фьючерсам + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetInstrumentBy(self, request, context): + """GetInstrumentBy — основная информация об инструменте + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetDividends(self, request, context): + """GetDividends — события выплаты дивидендов по инструменту + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetAssetBy(self, request, context): + """GetAssetBy — получить актив по его идентификатору + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetAssets(self, request, context): + """GetAssets — список активов + Метод работает для всех инструментов, кроме срочных — фьючерсов и опционов + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetFavorites(self, request, context): + """GetFavorites — получить список избранных инструментов + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def EditFavorites(self, request, context): + """EditFavorites — отредактировать список избранных инструментов + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def CreateFavoriteGroup(self, request, context): + """CreateFavoriteGroup — создать новую группу избранных инструментов + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def DeleteFavoriteGroup(self, request, context): + """DeleteFavoriteGroup — удалить группу избранных инструментов + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetFavoriteGroups(self, request, context): + """GetFavoriteGroups — список групп избранных инструментов + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetCountries(self, request, context): + """GetCountries — список стран + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def FindInstrument(self, request, context): + """FindInstrument — найти инструмент + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetBrands(self, request, context): + """GetBrands — список брендов + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetBrandBy(self, request, context): + """GetBrandBy — получить бренд по его идентификатору + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetAssetFundamentals(self, request, context): + """GetAssetFundamentals — фундаментальные показатели по активу + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetAssetReports(self, request, context): + """GetAssetReports — расписания выхода отчетностей эмитентов + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetConsensusForecasts(self, request, context): + """GetConsensusForecasts — мнения аналитиков по инструменту + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetForecastBy(self, request, context): + """GetForecastBy — прогнозы инвестдомов по инструменту + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetRiskRates(self, request, context): + """GetRiskRates — ставки риска по инструменту + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetInsiderDeals(self, request, context): + """GetInsiderDeals — сделки инсайдеров по инструментам + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def StructuredNoteBy(self, request, context): + """StructuredNoteBy — получить структурную ноту по ее идентификатору + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def StructuredNotes(self, request, context): + """StructuredNotes — список структурных нот + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_InstrumentsServiceServicer_to_server(servicer, server): + rpc_method_handlers = { + 'TradingSchedules': grpc.unary_unary_rpc_method_handler( + servicer.TradingSchedules, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.TradingSchedulesRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.TradingSchedulesResponse.SerializeToString, + ), + 'BondBy': grpc.unary_unary_rpc_method_handler( + servicer.BondBy, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.BondResponse.SerializeToString, + ), + 'Bonds': grpc.unary_unary_rpc_method_handler( + servicer.Bonds, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.BondsResponse.SerializeToString, + ), + 'GetBondCoupons': grpc.unary_unary_rpc_method_handler( + servicer.GetBondCoupons, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetBondCouponsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetBondCouponsResponse.SerializeToString, + ), + 'GetBondEvents': grpc.unary_unary_rpc_method_handler( + servicer.GetBondEvents, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetBondEventsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetBondEventsResponse.SerializeToString, + ), + 'CurrencyBy': grpc.unary_unary_rpc_method_handler( + servicer.CurrencyBy, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.CurrencyResponse.SerializeToString, + ), + 'Currencies': grpc.unary_unary_rpc_method_handler( + servicer.Currencies, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.CurrenciesResponse.SerializeToString, + ), + 'EtfBy': grpc.unary_unary_rpc_method_handler( + servicer.EtfBy, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.EtfResponse.SerializeToString, + ), + 'Etfs': grpc.unary_unary_rpc_method_handler( + servicer.Etfs, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.EtfsResponse.SerializeToString, + ), + 'FutureBy': grpc.unary_unary_rpc_method_handler( + servicer.FutureBy, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.FutureResponse.SerializeToString, + ), + 'Futures': grpc.unary_unary_rpc_method_handler( + servicer.Futures, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.FuturesResponse.SerializeToString, + ), + 'OptionBy': grpc.unary_unary_rpc_method_handler( + servicer.OptionBy, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.OptionResponse.SerializeToString, + ), + 'Options': grpc.unary_unary_rpc_method_handler( + servicer.Options, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.OptionsResponse.SerializeToString, + ), + 'OptionsBy': grpc.unary_unary_rpc_method_handler( + servicer.OptionsBy, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.FilterOptionsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.OptionsResponse.SerializeToString, + ), + 'ShareBy': grpc.unary_unary_rpc_method_handler( + servicer.ShareBy, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.ShareResponse.SerializeToString, + ), + 'Shares': grpc.unary_unary_rpc_method_handler( + servicer.Shares, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.SharesResponse.SerializeToString, + ), + 'DfaBy': grpc.unary_unary_rpc_method_handler( + servicer.DfaBy, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.DfaResponse.SerializeToString, + ), + 'Dfas': grpc.unary_unary_rpc_method_handler( + servicer.Dfas, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.DfasRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.DfasResponse.SerializeToString, + ), + 'Indicatives': grpc.unary_unary_rpc_method_handler( + servicer.Indicatives, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.IndicativesRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.IndicativesResponse.SerializeToString, + ), + 'GetAccruedInterests': grpc.unary_unary_rpc_method_handler( + servicer.GetAccruedInterests, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetAccruedInterestsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetAccruedInterestsResponse.SerializeToString, + ), + 'GetFuturesMargin': grpc.unary_unary_rpc_method_handler( + servicer.GetFuturesMargin, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetFuturesMarginRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetFuturesMarginResponse.SerializeToString, + ), + 'GetInstrumentBy': grpc.unary_unary_rpc_method_handler( + servicer.GetInstrumentBy, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentResponse.SerializeToString, + ), + 'GetDividends': grpc.unary_unary_rpc_method_handler( + servicer.GetDividends, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetDividendsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetDividendsResponse.SerializeToString, + ), + 'GetAssetBy': grpc.unary_unary_rpc_method_handler( + servicer.GetAssetBy, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.AssetRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.AssetResponse.SerializeToString, + ), + 'GetAssets': grpc.unary_unary_rpc_method_handler( + servicer.GetAssets, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.AssetsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.AssetsResponse.SerializeToString, + ), + 'GetFavorites': grpc.unary_unary_rpc_method_handler( + servicer.GetFavorites, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetFavoritesRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetFavoritesResponse.SerializeToString, + ), + 'EditFavorites': grpc.unary_unary_rpc_method_handler( + servicer.EditFavorites, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.EditFavoritesRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.EditFavoritesResponse.SerializeToString, + ), + 'CreateFavoriteGroup': grpc.unary_unary_rpc_method_handler( + servicer.CreateFavoriteGroup, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.CreateFavoriteGroupRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.CreateFavoriteGroupResponse.SerializeToString, + ), + 'DeleteFavoriteGroup': grpc.unary_unary_rpc_method_handler( + servicer.DeleteFavoriteGroup, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.DeleteFavoriteGroupRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.DeleteFavoriteGroupResponse.SerializeToString, + ), + 'GetFavoriteGroups': grpc.unary_unary_rpc_method_handler( + servicer.GetFavoriteGroups, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetFavoriteGroupsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetFavoriteGroupsResponse.SerializeToString, + ), + 'GetCountries': grpc.unary_unary_rpc_method_handler( + servicer.GetCountries, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetCountriesRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetCountriesResponse.SerializeToString, + ), + 'FindInstrument': grpc.unary_unary_rpc_method_handler( + servicer.FindInstrument, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.FindInstrumentRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.FindInstrumentResponse.SerializeToString, + ), + 'GetBrands': grpc.unary_unary_rpc_method_handler( + servicer.GetBrands, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetBrandsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetBrandsResponse.SerializeToString, + ), + 'GetBrandBy': grpc.unary_unary_rpc_method_handler( + servicer.GetBrandBy, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetBrandRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.Brand.SerializeToString, + ), + 'GetAssetFundamentals': grpc.unary_unary_rpc_method_handler( + servicer.GetAssetFundamentals, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetAssetFundamentalsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetAssetFundamentalsResponse.SerializeToString, + ), + 'GetAssetReports': grpc.unary_unary_rpc_method_handler( + servicer.GetAssetReports, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetAssetReportsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetAssetReportsResponse.SerializeToString, + ), + 'GetConsensusForecasts': grpc.unary_unary_rpc_method_handler( + servicer.GetConsensusForecasts, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetConsensusForecastsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetConsensusForecastsResponse.SerializeToString, + ), + 'GetForecastBy': grpc.unary_unary_rpc_method_handler( + servicer.GetForecastBy, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetForecastRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetForecastResponse.SerializeToString, + ), + 'GetRiskRates': grpc.unary_unary_rpc_method_handler( + servicer.GetRiskRates, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.RiskRatesRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.RiskRatesResponse.SerializeToString, + ), + 'GetInsiderDeals': grpc.unary_unary_rpc_method_handler( + servicer.GetInsiderDeals, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetInsiderDealsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetInsiderDealsResponse.SerializeToString, + ), + 'StructuredNoteBy': grpc.unary_unary_rpc_method_handler( + servicer.StructuredNoteBy, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.StructuredNoteResponse.SerializeToString, + ), + 'StructuredNotes': grpc.unary_unary_rpc_method_handler( + servicer.StructuredNotes, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_instruments__pb2.StructuredNotesResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'tinkoff.public.invest.api.contract.v1.InstrumentsService', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class InstrumentsService(object): + """Методы сервиса предназначены для получения:
1. Информации об инструментах.
2. + Расписания торговых сессий.
3. Календаря выплат купонов по облигациям.
4. + Размера гарантийного обеспечения по фьючерсам.
5. Дивидендов по ценной бумаге. + """ + + @staticmethod + def TradingSchedules(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/TradingSchedules', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.TradingSchedulesRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.TradingSchedulesResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def BondBy(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/BondBy', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.BondResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def Bonds(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/Bonds', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.BondsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetBondCoupons(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetBondCoupons', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetBondCouponsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetBondCouponsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetBondEvents(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetBondEvents', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetBondEventsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetBondEventsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def CurrencyBy(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/CurrencyBy', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.CurrencyResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def Currencies(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/Currencies', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.CurrenciesResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def EtfBy(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/EtfBy', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.EtfResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def Etfs(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/Etfs', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.EtfsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def FutureBy(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/FutureBy', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.FutureResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def Futures(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/Futures', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.FuturesResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def OptionBy(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/OptionBy', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.OptionResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def Options(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/Options', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.OptionsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def OptionsBy(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/OptionsBy', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.FilterOptionsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.OptionsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def ShareBy(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/ShareBy', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.ShareResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def Shares(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/Shares', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.SharesResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def DfaBy(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/DfaBy', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.DfaResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def Dfas(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/Dfas', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.DfasRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.DfasResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def Indicatives(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/Indicatives', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.IndicativesRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.IndicativesResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetAccruedInterests(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetAccruedInterests', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetAccruedInterestsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetAccruedInterestsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetFuturesMargin(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetFuturesMargin', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetFuturesMarginRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetFuturesMarginResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetInstrumentBy(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetInstrumentBy', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetDividends(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetDividends', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetDividendsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetDividendsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetAssetBy(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetAssetBy', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.AssetRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.AssetResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetAssets(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetAssets', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.AssetsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.AssetsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetFavorites(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetFavorites', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetFavoritesRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetFavoritesResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def EditFavorites(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/EditFavorites', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.EditFavoritesRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.EditFavoritesResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def CreateFavoriteGroup(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/CreateFavoriteGroup', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.CreateFavoriteGroupRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.CreateFavoriteGroupResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def DeleteFavoriteGroup(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/DeleteFavoriteGroup', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.DeleteFavoriteGroupRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.DeleteFavoriteGroupResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetFavoriteGroups(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetFavoriteGroups', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetFavoriteGroupsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetFavoriteGroupsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetCountries(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetCountries', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetCountriesRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetCountriesResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def FindInstrument(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/FindInstrument', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.FindInstrumentRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.FindInstrumentResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetBrands(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetBrands', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetBrandsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetBrandsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetBrandBy(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetBrandBy', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetBrandRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.Brand.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetAssetFundamentals(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetAssetFundamentals', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetAssetFundamentalsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetAssetFundamentalsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetAssetReports(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetAssetReports', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetAssetReportsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetAssetReportsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetConsensusForecasts(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetConsensusForecasts', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetConsensusForecastsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetConsensusForecastsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetForecastBy(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetForecastBy', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetForecastRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetForecastResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetRiskRates(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetRiskRates', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.RiskRatesRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.RiskRatesResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetInsiderDeals(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/GetInsiderDeals', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetInsiderDealsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.GetInsiderDealsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def StructuredNoteBy(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/StructuredNoteBy', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.StructuredNoteResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def StructuredNotes(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.InstrumentsService/StructuredNotes', + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.InstrumentsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_instruments__pb2.StructuredNotesResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/invest-python-master/t_tech/invest/grpc/marketdata_pb2.py b/invest-python-master/t_tech/invest/grpc/marketdata_pb2.py new file mode 100644 index 0000000..cd1446c --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/marketdata_pb2.py @@ -0,0 +1,225 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: t_tech/invest/grpc/marketdata.proto +# Protobuf Python Version: 4.25.1 +"""Generated protocol buffer code.""" +from google.protobuf import ( + descriptor as _descriptor, + descriptor_pool as _descriptor_pool, + symbol_database as _symbol_database, +) +from google.protobuf.internal import builder as _builder + +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 + +from t_tech.invest.grpc import common_pb2 as t__tech_dot_invest_dot_grpc_dot_common__pb2 +from t_tech.invest.grpc.google.api import ( + field_behavior_pb2 as t__tech_dot_invest_dot_grpc_dot_google_dot_api_dot_field__behavior__pb2, +) + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#t_tech/invest/grpc/marketdata.proto\x12%tinkoff.public.invest.api.contract.v1\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1ft_tech/invest/grpc/common.proto\x1a\x32t_tech/invest/grpc/google/api/field_behavior.proto\"\x8b\x06\n\x11MarketDataRequest\x12\x63\n\x19subscribe_candles_request\x18\x01 \x01(\x0b\x32>.tinkoff.public.invest.api.contract.v1.SubscribeCandlesRequestH\x00\x12h\n\x1csubscribe_order_book_request\x18\x02 \x01(\x0b\x32@.tinkoff.public.invest.api.contract.v1.SubscribeOrderBookRequestH\x00\x12\x61\n\x18subscribe_trades_request\x18\x03 \x01(\x0b\x32=.tinkoff.public.invest.api.contract.v1.SubscribeTradesRequestH\x00\x12]\n\x16subscribe_info_request\x18\x04 \x01(\x0b\x32;.tinkoff.public.invest.api.contract.v1.SubscribeInfoRequestH\x00\x12h\n\x1csubscribe_last_price_request\x18\x05 \x01(\x0b\x32@.tinkoff.public.invest.api.contract.v1.SubscribeLastPriceRequestH\x00\x12Y\n\x14get_my_subscriptions\x18\x06 \x01(\x0b\x32\x39.tinkoff.public.invest.api.contract.v1.GetMySubscriptionsH\x00\x12\x42\n\x04ping\x18\x07 \x01(\x0b\x32\x32.tinkoff.public.invest.api.contract.v1.PingRequestH\x00\x12Q\n\rping_settings\x18\x0f \x01(\x0b\x32\x38.tinkoff.public.invest.api.contract.v1.PingDelaySettingsH\x00\x42\t\n\x07payload\"\xe5\x04\n!MarketDataServerSideStreamRequest\x12\x61\n\x19subscribe_candles_request\x18\x01 \x01(\x0b\x32>.tinkoff.public.invest.api.contract.v1.SubscribeCandlesRequest\x12\x66\n\x1csubscribe_order_book_request\x18\x02 \x01(\x0b\x32@.tinkoff.public.invest.api.contract.v1.SubscribeOrderBookRequest\x12_\n\x18subscribe_trades_request\x18\x03 \x01(\x0b\x32=.tinkoff.public.invest.api.contract.v1.SubscribeTradesRequest\x12[\n\x16subscribe_info_request\x18\x04 \x01(\x0b\x32;.tinkoff.public.invest.api.contract.v1.SubscribeInfoRequest\x12\x66\n\x1csubscribe_last_price_request\x18\x05 \x01(\x0b\x32@.tinkoff.public.invest.api.contract.v1.SubscribeLastPriceRequest\x12O\n\rping_settings\x18\x0f \x01(\x0b\x32\x38.tinkoff.public.invest.api.contract.v1.PingDelaySettings\"\x8e\x08\n\x12MarketDataResponse\x12\x65\n\x1asubscribe_candles_response\x18\x01 \x01(\x0b\x32?.tinkoff.public.invest.api.contract.v1.SubscribeCandlesResponseH\x00\x12j\n\x1dsubscribe_order_book_response\x18\x02 \x01(\x0b\x32\x41.tinkoff.public.invest.api.contract.v1.SubscribeOrderBookResponseH\x00\x12\x63\n\x19subscribe_trades_response\x18\x03 \x01(\x0b\x32>.tinkoff.public.invest.api.contract.v1.SubscribeTradesResponseH\x00\x12_\n\x17subscribe_info_response\x18\x04 \x01(\x0b\x32<.tinkoff.public.invest.api.contract.v1.SubscribeInfoResponseH\x00\x12?\n\x06\x63\x61ndle\x18\x05 \x01(\x0b\x32-.tinkoff.public.invest.api.contract.v1.CandleH\x00\x12=\n\x05trade\x18\x06 \x01(\x0b\x32,.tinkoff.public.invest.api.contract.v1.TradeH\x00\x12\x45\n\torderbook\x18\x07 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.OrderBookH\x00\x12N\n\x0etrading_status\x18\x08 \x01(\x0b\x32\x34.tinkoff.public.invest.api.contract.v1.TradingStatusH\x00\x12;\n\x04ping\x18\t \x01(\x0b\x32+.tinkoff.public.invest.api.contract.v1.PingH\x00\x12j\n\x1dsubscribe_last_price_response\x18\n \x01(\x0b\x32\x41.tinkoff.public.invest.api.contract.v1.SubscribeLastPriceResponseH\x00\x12\x46\n\nlast_price\x18\x0b \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.LastPriceH\x00\x12L\n\ropen_interest\x18\x0c \x01(\x0b\x32\x33.tinkoff.public.invest.api.contract.v1.OpenInterestH\x00\x42\t\n\x07payload\"\xd5\x02\n\x17SubscribeCandlesRequest\x12V\n\x13subscription_action\x18\x01 \x01(\x0e\x32\x39.tinkoff.public.invest.api.contract.v1.SubscriptionAction\x12L\n\x0binstruments\x18\x02 \x03(\x0b\x32\x37.tinkoff.public.invest.api.contract.v1.CandleInstrument\x12\x15\n\rwaiting_close\x18\x03 \x01(\x08\x12\x66\n\x12\x63\x61ndle_source_type\x18\t \x01(\x0e\x32\x45.tinkoff.public.invest.api.contract.v1.GetCandlesRequest.CandleSourceH\x00\x88\x01\x01\x42\x15\n\x13_candle_source_type\"\x8a\x01\n\x10\x43\x61ndleInstrument\x12\x10\n\x04\x66igi\x18\x01 \x01(\tB\x02\x18\x01\x12M\n\x08interval\x18\x02 \x01(\x0e\x32;.tinkoff.public.invest.api.contract.v1.SubscriptionInterval\x12\x15\n\rinstrument_id\x18\x03 \x01(\t\"\x89\x01\n\x18SubscribeCandlesResponse\x12\x13\n\x0btracking_id\x18\x01 \x01(\t\x12X\n\x15\x63\x61ndles_subscriptions\x18\x02 \x03(\x0b\x32\x39.tinkoff.public.invest.api.contract.v1.CandleSubscription\"\x9f\x04\n\x12\x43\x61ndleSubscription\x12\x0c\n\x04\x66igi\x18\x01 \x01(\t\x12M\n\x08interval\x18\x02 \x01(\x0e\x32;.tinkoff.public.invest.api.contract.v1.SubscriptionInterval\x12V\n\x13subscription_status\x18\x03 \x01(\x0e\x32\x39.tinkoff.public.invest.api.contract.v1.SubscriptionStatus\x12\x16\n\x0einstrument_uid\x18\x04 \x01(\t\x12\x15\n\rwaiting_close\x18\x05 \x01(\x08\x12\x11\n\tstream_id\x18\x06 \x01(\t\x12\x17\n\x0fsubscription_id\x18\x07 \x01(\t\x12V\n\x13subscription_action\x18\x08 \x01(\x0e\x32\x39.tinkoff.public.invest.api.contract.v1.SubscriptionAction\x12\x66\n\x12\x63\x61ndle_source_type\x18\t \x01(\x0e\x32\x45.tinkoff.public.invest.api.contract.v1.GetCandlesRequest.CandleSourceH\x00\x88\x01\x01\x12\x0e\n\x06ticker\x18\n \x01(\t\x12\x12\n\nclass_code\x18\x0b \x01(\tB\x15\n\x13_candle_source_type\"\xc4\x01\n\x19SubscribeOrderBookRequest\x12V\n\x13subscription_action\x18\x01 \x01(\x0e\x32\x39.tinkoff.public.invest.api.contract.v1.SubscriptionAction\x12O\n\x0binstruments\x18\x02 \x03(\x0b\x32:.tinkoff.public.invest.api.contract.v1.OrderBookInstrument\"\x9c\x01\n\x13OrderBookInstrument\x12\x10\n\x04\x66igi\x18\x01 \x01(\tB\x02\x18\x01\x12\r\n\x05\x64\x65pth\x18\x02 \x01(\x05\x12\x15\n\rinstrument_id\x18\x03 \x01(\t\x12M\n\x0forder_book_type\x18\x04 \x01(\x0e\x32\x34.tinkoff.public.invest.api.contract.v1.OrderBookType\"\x91\x01\n\x1aSubscribeOrderBookResponse\x12\x13\n\x0btracking_id\x18\x01 \x01(\t\x12^\n\x18order_book_subscriptions\x18\x02 \x03(\x0b\x32<.tinkoff.public.invest.api.contract.v1.OrderBookSubscription\"\x9b\x03\n\x15OrderBookSubscription\x12\x0c\n\x04\x66igi\x18\x01 \x01(\t\x12\r\n\x05\x64\x65pth\x18\x02 \x01(\x05\x12V\n\x13subscription_status\x18\x03 \x01(\x0e\x32\x39.tinkoff.public.invest.api.contract.v1.SubscriptionStatus\x12\x16\n\x0einstrument_uid\x18\x04 \x01(\t\x12\x11\n\tstream_id\x18\x05 \x01(\t\x12\x17\n\x0fsubscription_id\x18\x06 \x01(\t\x12M\n\x0forder_book_type\x18\x07 \x01(\x0e\x32\x34.tinkoff.public.invest.api.contract.v1.OrderBookType\x12V\n\x13subscription_action\x18\x08 \x01(\x0e\x32\x39.tinkoff.public.invest.api.contract.v1.SubscriptionAction\x12\x0e\n\x06ticker\x18\t \x01(\t\x12\x12\n\nclass_code\x18\n \x01(\t\"\xa7\x02\n\x16SubscribeTradesRequest\x12V\n\x13subscription_action\x18\x01 \x01(\x0e\x32\x39.tinkoff.public.invest.api.contract.v1.SubscriptionAction\x12K\n\x0binstruments\x18\x02 \x03(\x0b\x32\x36.tinkoff.public.invest.api.contract.v1.TradeInstrument\x12L\n\x0ctrade_source\x18\x03 \x01(\x0e\x32\x36.tinkoff.public.invest.api.contract.v1.TradeSourceType\x12\x1a\n\x12with_open_interest\x18\x04 \x01(\x08\":\n\x0fTradeInstrument\x12\x10\n\x04\x66igi\x18\x01 \x01(\tB\x02\x18\x01\x12\x15\n\rinstrument_id\x18\x02 \x01(\t\"\xd3\x01\n\x17SubscribeTradesResponse\x12\x13\n\x0btracking_id\x18\x01 \x01(\t\x12U\n\x13trade_subscriptions\x18\x02 \x03(\x0b\x32\x38.tinkoff.public.invest.api.contract.v1.TradeSubscription\x12L\n\x0ctrade_source\x18\x03 \x01(\x0e\x32\x36.tinkoff.public.invest.api.contract.v1.TradeSourceType\"\xd5\x02\n\x11TradeSubscription\x12\x0c\n\x04\x66igi\x18\x01 \x01(\t\x12V\n\x13subscription_status\x18\x02 \x01(\x0e\x32\x39.tinkoff.public.invest.api.contract.v1.SubscriptionStatus\x12\x16\n\x0einstrument_uid\x18\x03 \x01(\t\x12\x11\n\tstream_id\x18\x04 \x01(\t\x12\x17\n\x0fsubscription_id\x18\x05 \x01(\t\x12\x1a\n\x12with_open_interest\x18\x06 \x01(\x08\x12V\n\x13subscription_action\x18\x07 \x01(\x0e\x32\x39.tinkoff.public.invest.api.contract.v1.SubscriptionAction\x12\x0e\n\x06ticker\x18\x08 \x01(\t\x12\x12\n\nclass_code\x18\t \x01(\t\"\xba\x01\n\x14SubscribeInfoRequest\x12V\n\x13subscription_action\x18\x01 \x01(\x0e\x32\x39.tinkoff.public.invest.api.contract.v1.SubscriptionAction\x12J\n\x0binstruments\x18\x02 \x03(\x0b\x32\x35.tinkoff.public.invest.api.contract.v1.InfoInstrument\"9\n\x0eInfoInstrument\x12\x10\n\x04\x66igi\x18\x01 \x01(\tB\x02\x18\x01\x12\x15\n\rinstrument_id\x18\x02 \x01(\t\"\x81\x01\n\x15SubscribeInfoResponse\x12\x13\n\x0btracking_id\x18\x01 \x01(\t\x12S\n\x12info_subscriptions\x18\x02 \x03(\x0b\x32\x37.tinkoff.public.invest.api.contract.v1.InfoSubscription\"\xb8\x02\n\x10InfoSubscription\x12\x0c\n\x04\x66igi\x18\x01 \x01(\t\x12V\n\x13subscription_status\x18\x02 \x01(\x0e\x32\x39.tinkoff.public.invest.api.contract.v1.SubscriptionStatus\x12\x16\n\x0einstrument_uid\x18\x03 \x01(\t\x12\x11\n\tstream_id\x18\x04 \x01(\t\x12\x17\n\x0fsubscription_id\x18\x05 \x01(\t\x12V\n\x13subscription_action\x18\x06 \x01(\x0e\x32\x39.tinkoff.public.invest.api.contract.v1.SubscriptionAction\x12\x0e\n\x06ticker\x18\x07 \x01(\t\x12\x12\n\nclass_code\x18\x08 \x01(\t\"\xc4\x01\n\x19SubscribeLastPriceRequest\x12V\n\x13subscription_action\x18\x01 \x01(\x0e\x32\x39.tinkoff.public.invest.api.contract.v1.SubscriptionAction\x12O\n\x0binstruments\x18\x02 \x03(\x0b\x32:.tinkoff.public.invest.api.contract.v1.LastPriceInstrument\">\n\x13LastPriceInstrument\x12\x10\n\x04\x66igi\x18\x01 \x01(\tB\x02\x18\x01\x12\x15\n\rinstrument_id\x18\x02 \x01(\t\"\x91\x01\n\x1aSubscribeLastPriceResponse\x12\x13\n\x0btracking_id\x18\x01 \x01(\t\x12^\n\x18last_price_subscriptions\x18\x02 \x03(\x0b\x32<.tinkoff.public.invest.api.contract.v1.LastPriceSubscription\"\xbd\x02\n\x15LastPriceSubscription\x12\x0c\n\x04\x66igi\x18\x01 \x01(\t\x12V\n\x13subscription_status\x18\x02 \x01(\x0e\x32\x39.tinkoff.public.invest.api.contract.v1.SubscriptionStatus\x12\x16\n\x0einstrument_uid\x18\x03 \x01(\t\x12\x11\n\tstream_id\x18\x04 \x01(\t\x12\x17\n\x0fsubscription_id\x18\x05 \x01(\t\x12V\n\x13subscription_action\x18\x06 \x01(\x0e\x32\x39.tinkoff.public.invest.api.contract.v1.SubscriptionAction\x12\x0e\n\x06ticker\x18\x07 \x01(\t\x12\x12\n\nclass_code\x18\x08 \x01(\t\"\x88\x05\n\x06\x43\x61ndle\x12\x0c\n\x04\x66igi\x18\x01 \x01(\t\x12M\n\x08interval\x18\x02 \x01(\x0e\x32;.tinkoff.public.invest.api.contract.v1.SubscriptionInterval\x12>\n\x04open\x18\x03 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12>\n\x04high\x18\x04 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12=\n\x03low\x18\x05 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12?\n\x05\x63lose\x18\x06 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x0e\n\x06volume\x18\x07 \x01(\x03\x12(\n\x04time\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x31\n\rlast_trade_ts\x18\t \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x16\n\x0einstrument_uid\x18\n \x01(\t\x12\x0e\n\x06ticker\x18\x0b \x01(\t\x12\x12\n\nclass_code\x18\x0c \x01(\t\x12\x12\n\nvolume_buy\x18\r \x01(\x03\x12\x13\n\x0bvolume_sell\x18\x0e \x01(\x03\x12O\n\x12\x63\x61ndle_source_type\x18\x13 \x01(\x0e\x32\x33.tinkoff.public.invest.api.contract.v1.CandleSource\"\xf6\x03\n\tOrderBook\x12\x0c\n\x04\x66igi\x18\x01 \x01(\t\x12\r\n\x05\x64\x65pth\x18\x02 \x01(\x05\x12\x15\n\ris_consistent\x18\x03 \x01(\x08\x12:\n\x04\x62ids\x18\x04 \x03(\x0b\x32,.tinkoff.public.invest.api.contract.v1.Order\x12:\n\x04\x61sks\x18\x05 \x03(\x0b\x32,.tinkoff.public.invest.api.contract.v1.Order\x12(\n\x04time\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x42\n\x08limit_up\x18\x07 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x44\n\nlimit_down\x18\x08 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x16\n\x0einstrument_uid\x18\t \x01(\t\x12M\n\x0forder_book_type\x18\n \x01(\x0e\x32\x34.tinkoff.public.invest.api.contract.v1.OrderBookType\x12\x0e\n\x06ticker\x18\x0b \x01(\t\x12\x12\n\nclass_code\x18\x0c \x01(\t\"Z\n\x05Order\x12?\n\x05price\x18\x01 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x10\n\x08quantity\x18\x02 \x01(\x03\"\xe6\x02\n\x05Trade\x12\x0c\n\x04\x66igi\x18\x01 \x01(\t\x12H\n\tdirection\x18\x02 \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.TradeDirection\x12?\n\x05price\x18\x03 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x10\n\x08quantity\x18\x04 \x01(\x03\x12(\n\x04time\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x16\n\x0einstrument_uid\x18\x06 \x01(\t\x12L\n\x0ctrade_source\x18\x07 \x01(\x0e\x32\x36.tinkoff.public.invest.api.contract.v1.TradeSourceType\x12\x0e\n\x06ticker\x18\x08 \x01(\t\x12\x12\n\nclass_code\x18\t \x01(\t\"\xa2\x02\n\rTradingStatus\x12\x0c\n\x04\x66igi\x18\x01 \x01(\t\x12T\n\x0etrading_status\x18\x02 \x01(\x0e\x32<.tinkoff.public.invest.api.contract.v1.SecurityTradingStatus\x12(\n\x04time\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\"\n\x1alimit_order_available_flag\x18\x04 \x01(\x08\x12#\n\x1bmarket_order_available_flag\x18\x05 \x01(\x08\x12\x16\n\x0einstrument_uid\x18\x06 \x01(\t\x12\x0e\n\x06ticker\x18\x07 \x01(\t\x12\x12\n\nclass_code\x18\x08 \x01(\t\"\x99\x04\n\x11GetCandlesRequest\x12\x15\n\x04\x66igi\x18\x01 \x01(\tB\x02\x18\x01H\x00\x88\x01\x01\x12.\n\x04\x66rom\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x04\xe2\x41\x01\x02\x12,\n\x02to\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x04\xe2\x41\x01\x02\x12M\n\x08interval\x18\x04 \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.CandleIntervalB\x04\xe2\x41\x01\x02\x12\x1a\n\rinstrument_id\x18\x05 \x01(\tH\x01\x88\x01\x01\x12\x66\n\x12\x63\x61ndle_source_type\x18\x07 \x01(\x0e\x32\x45.tinkoff.public.invest.api.contract.v1.GetCandlesRequest.CandleSourceH\x02\x88\x01\x01\x12\x12\n\x05limit\x18\n \x01(\x05H\x03\x88\x01\x01\"l\n\x0c\x43\x61ndleSource\x12\x1d\n\x19\x43\x41NDLE_SOURCE_UNSPECIFIED\x10\x00\x12\x1a\n\x16\x43\x41NDLE_SOURCE_EXCHANGE\x10\x01\x12!\n\x1d\x43\x41NDLE_SOURCE_INCLUDE_WEEKEND\x10\x03\x42\x07\n\x05_figiB\x10\n\x0e_instrument_idB\x15\n\x13_candle_source_typeB\x08\n\x06_limit\"\\\n\x12GetCandlesResponse\x12\x46\n\x07\x63\x61ndles\x18\x01 \x03(\x0b\x32\x35.tinkoff.public.invest.api.contract.v1.HistoricCandle\"\xd4\x03\n\x0eHistoricCandle\x12>\n\x04open\x18\x01 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12>\n\x04high\x18\x02 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12=\n\x03low\x18\x03 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12?\n\x05\x63lose\x18\x04 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x0e\n\x06volume\x18\x05 \x01(\x03\x12(\n\x04time\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x13\n\x0bis_complete\x18\x07 \x01(\x08\x12J\n\rcandle_source\x18\t \x01(\x0e\x32\x33.tinkoff.public.invest.api.contract.v1.CandleSource\x12\x12\n\nvolume_buy\x18\n \x01(\x03\x12\x13\n\x0bvolume_sell\x18\x0b \x01(\x03\"\xfd\x01\n\x14GetLastPricesRequest\x12\x10\n\x04\x66igi\x18\x01 \x03(\tB\x02\x18\x01\x12\x15\n\rinstrument_id\x18\x02 \x03(\t\x12M\n\x0flast_price_type\x18\x03 \x01(\x0e\x32\x34.tinkoff.public.invest.api.contract.v1.LastPriceType\x12W\n\x11instrument_status\x18\t \x01(\x0e\x32\x37.tinkoff.public.invest.api.contract.v1.InstrumentStatusH\x00\x88\x01\x01\x42\x14\n\x12_instrument_status\"^\n\x15GetLastPricesResponse\x12\x45\n\x0blast_prices\x18\x01 \x03(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.LastPrice\"\x8f\x02\n\tLastPrice\x12\x0c\n\x04\x66igi\x18\x01 \x01(\t\x12?\n\x05price\x18\x02 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12(\n\x04time\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0e\n\x06ticker\x18\t \x01(\t\x12\x12\n\nclass_code\x18\n \x01(\t\x12\x16\n\x0einstrument_uid\x18\x0b \x01(\t\x12M\n\x0flast_price_type\x18\x0c \x01(\x0e\x32\x34.tinkoff.public.invest.api.contract.v1.LastPriceType\"\x8b\x01\n\x0cOpenInterest\x12\x16\n\x0einstrument_uid\x18\x01 \x01(\t\x12(\n\x04time\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x15\n\ropen_interest\x18\x03 \x01(\x03\x12\x0e\n\x06ticker\x18\x04 \x01(\t\x12\x12\n\nclass_code\x18\x05 \x01(\t\"x\n\x13GetOrderBookRequest\x12\x15\n\x04\x66igi\x18\x01 \x01(\tB\x02\x18\x01H\x00\x88\x01\x01\x12\x13\n\x05\x64\x65pth\x18\x02 \x01(\x05\x42\x04\xe2\x41\x01\x02\x12\x1a\n\rinstrument_id\x18\x03 \x01(\tH\x01\x88\x01\x01\x42\x07\n\x05_figiB\x10\n\x0e_instrument_id\"\x97\x05\n\x14GetOrderBookResponse\x12\x0c\n\x04\x66igi\x18\x01 \x01(\t\x12\r\n\x05\x64\x65pth\x18\x02 \x01(\x05\x12:\n\x04\x62ids\x18\x03 \x03(\x0b\x32,.tinkoff.public.invest.api.contract.v1.Order\x12:\n\x04\x61sks\x18\x04 \x03(\x0b\x32,.tinkoff.public.invest.api.contract.v1.Order\x12\x44\n\nlast_price\x18\x05 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x45\n\x0b\x63lose_price\x18\x06 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x42\n\x08limit_up\x18\x07 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x44\n\nlimit_down\x18\x08 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x16\n\x0einstrument_uid\x18\t \x01(\t\x12\x0e\n\x06ticker\x18\n \x01(\t\x12\x12\n\nclass_code\x18\x0b \x01(\t\x12\x31\n\rlast_price_ts\x18\x15 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x32\n\x0e\x63lose_price_ts\x18\x16 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x30\n\x0corderbook_ts\x18\x17 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"g\n\x17GetTradingStatusRequest\x12\x15\n\x04\x66igi\x18\x01 \x01(\tB\x02\x18\x01H\x00\x88\x01\x01\x12\x1a\n\rinstrument_id\x18\x02 \x01(\tH\x01\x88\x01\x01\x42\x07\n\x05_figiB\x10\n\x0e_instrument_id\"2\n\x19GetTradingStatusesRequest\x12\x15\n\rinstrument_id\x18\x01 \x03(\t\"w\n\x1aGetTradingStatusesResponse\x12Y\n\x10trading_statuses\x18\x01 \x03(\x0b\x32?.tinkoff.public.invest.api.contract.v1.GetTradingStatusResponse\"\xe6\x02\n\x18GetTradingStatusResponse\x12\x0c\n\x04\x66igi\x18\x01 \x01(\t\x12T\n\x0etrading_status\x18\x02 \x01(\x0e\x32<.tinkoff.public.invest.api.contract.v1.SecurityTradingStatus\x12\"\n\x1alimit_order_available_flag\x18\x03 \x01(\x08\x12#\n\x1bmarket_order_available_flag\x18\x04 \x01(\x08\x12 \n\x18\x61pi_trade_available_flag\x18\x05 \x01(\x08\x12\x16\n\x0einstrument_uid\x18\x06 \x01(\t\x12&\n\x1e\x62\x65stprice_order_available_flag\x18\x08 \x01(\x08\x12\x17\n\x0fonly_best_price\x18\t \x01(\x08\x12\x0e\n\x06ticker\x18\n \x01(\t\x12\x12\n\nclass_code\x18\x0b \x01(\t\"\x90\x02\n\x14GetLastTradesRequest\x12\x15\n\x04\x66igi\x18\x01 \x01(\tB\x02\x18\x01H\x00\x88\x01\x01\x12.\n\x04\x66rom\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x04\xe2\x41\x01\x02\x12,\n\x02to\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x04\xe2\x41\x01\x02\x12\x1a\n\rinstrument_id\x18\x04 \x01(\tH\x01\x88\x01\x01\x12L\n\x0ctrade_source\x18\x05 \x01(\x0e\x32\x36.tinkoff.public.invest.api.contract.v1.TradeSourceTypeB\x07\n\x05_figiB\x10\n\x0e_instrument_id\"U\n\x15GetLastTradesResponse\x12<\n\x06trades\x18\x01 \x03(\x0b\x32,.tinkoff.public.invest.api.contract.v1.Trade\"\x14\n\x12GetMySubscriptions\"\xe5\x01\n\x15GetClosePricesRequest\x12]\n\x0binstruments\x18\x01 \x03(\x0b\x32\x42.tinkoff.public.invest.api.contract.v1.InstrumentClosePriceRequestB\x04\xe2\x41\x01\x02\x12W\n\x11instrument_status\x18\t \x01(\x0e\x32\x37.tinkoff.public.invest.api.contract.v1.InstrumentStatusH\x00\x88\x01\x01\x42\x14\n\x12_instrument_status\"4\n\x1bInstrumentClosePriceRequest\x12\x15\n\rinstrument_id\x18\x01 \x01(\t\"s\n\x16GetClosePricesResponse\x12Y\n\x0c\x63lose_prices\x18\x01 \x03(\x0b\x32\x43.tinkoff.public.invest.api.contract.v1.InstrumentClosePriceResponse\"\xe4\x02\n\x1cInstrumentClosePriceResponse\x12\x0c\n\x04\x66igi\x18\x01 \x01(\t\x12\x16\n\x0einstrument_uid\x18\x02 \x01(\t\x12\x0e\n\x06ticker\x18\x03 \x01(\t\x12\x12\n\nclass_code\x18\x04 \x01(\t\x12?\n\x05price\x18\x0b \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12O\n\x15\x65vening_session_price\x18\x0c \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12(\n\x04time\x18\x15 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12>\n\x1a\x65vening_session_price_time\x18\x17 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\xf4\x0c\n\x16GetTechAnalysisRequest\x12i\n\x0eindicator_type\x18\x01 \x01(\x0e\x32K.tinkoff.public.invest.api.contract.v1.GetTechAnalysisRequest.IndicatorTypeB\x04\xe2\x41\x01\x02\x12\x1c\n\x0einstrument_uid\x18\x02 \x01(\tB\x04\xe2\x41\x01\x02\x12.\n\x04\x66rom\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x04\xe2\x41\x01\x02\x12,\n\x02to\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x04\xe2\x41\x01\x02\x12g\n\x08interval\x18\x05 \x01(\x0e\x32O.tinkoff.public.invest.api.contract.v1.GetTechAnalysisRequest.IndicatorIntervalB\x04\xe2\x41\x01\x02\x12\x66\n\rtype_of_price\x18\x06 \x01(\x0e\x32I.tinkoff.public.invest.api.contract.v1.GetTechAnalysisRequest.TypeOfPriceB\x04\xe2\x41\x01\x02\x12\x0e\n\x06length\x18\x07 \x01(\x05\x12Z\n\tdeviation\x18\x08 \x01(\x0b\x32G.tinkoff.public.invest.api.contract.v1.GetTechAnalysisRequest.Deviation\x12Z\n\tsmoothing\x18\t \x01(\x0b\x32G.tinkoff.public.invest.api.contract.v1.GetTechAnalysisRequest.Smoothing\x1aO\n\tSmoothing\x12\x13\n\x0b\x66\x61st_length\x18\x01 \x01(\x05\x12\x13\n\x0bslow_length\x18\x02 \x01(\x05\x12\x18\n\x10signal_smoothing\x18\x03 \x01(\x05\x1a[\n\tDeviation\x12N\n\x14\x64\x65viation_multiplier\x18\x01 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\"\xdb\x03\n\x11IndicatorInterval\x12\"\n\x1eINDICATOR_INTERVAL_UNSPECIFIED\x10\x00\x12!\n\x1dINDICATOR_INTERVAL_ONE_MINUTE\x10\x01\x12#\n\x1fINDICATOR_INTERVAL_FIVE_MINUTES\x10\x02\x12&\n\"INDICATOR_INTERVAL_FIFTEEN_MINUTES\x10\x03\x12\x1f\n\x1bINDICATOR_INTERVAL_ONE_HOUR\x10\x04\x12\x1e\n\x1aINDICATOR_INTERVAL_ONE_DAY\x10\x05\x12\x1c\n\x18INDICATOR_INTERVAL_2_MIN\x10\x06\x12\x1c\n\x18INDICATOR_INTERVAL_3_MIN\x10\x07\x12\x1d\n\x19INDICATOR_INTERVAL_10_MIN\x10\x08\x12\x1d\n\x19INDICATOR_INTERVAL_30_MIN\x10\t\x12\x1d\n\x19INDICATOR_INTERVAL_2_HOUR\x10\n\x12\x1d\n\x19INDICATOR_INTERVAL_4_HOUR\x10\x0b\x12\x1b\n\x17INDICATOR_INTERVAL_WEEK\x10\x0c\x12\x1c\n\x18INDICATOR_INTERVAL_MONTH\x10\r\"\xa3\x01\n\x0bTypeOfPrice\x12\x1d\n\x19TYPE_OF_PRICE_UNSPECIFIED\x10\x00\x12\x17\n\x13TYPE_OF_PRICE_CLOSE\x10\x01\x12\x16\n\x12TYPE_OF_PRICE_OPEN\x10\x02\x12\x16\n\x12TYPE_OF_PRICE_HIGH\x10\x03\x12\x15\n\x11TYPE_OF_PRICE_LOW\x10\x04\x12\x15\n\x11TYPE_OF_PRICE_AVG\x10\x05\"\xa7\x01\n\rIndicatorType\x12\x1e\n\x1aINDICATOR_TYPE_UNSPECIFIED\x10\x00\x12\x15\n\x11INDICATOR_TYPE_BB\x10\x01\x12\x16\n\x12INDICATOR_TYPE_EMA\x10\x02\x12\x16\n\x12INDICATOR_TYPE_RSI\x10\x03\x12\x17\n\x13INDICATOR_TYPE_MACD\x10\x04\x12\x16\n\x12INDICATOR_TYPE_SMA\x10\x05\"\xfc\x04\n\x17GetTechAnalysisResponse\x12m\n\x14technical_indicators\x18\x01 \x03(\x0b\x32O.tinkoff.public.invest.api.contract.v1.GetTechAnalysisResponse.TechAnalysisItem\x1a\xf1\x03\n\x10TechAnalysisItem\x12-\n\ttimestamp\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12J\n\x0bmiddle_band\x18\x02 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationH\x00\x88\x01\x01\x12I\n\nupper_band\x18\x03 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationH\x01\x88\x01\x01\x12I\n\nlower_band\x18\x04 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationH\x02\x88\x01\x01\x12\x45\n\x06signal\x18\x05 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationH\x03\x88\x01\x01\x12\x43\n\x04macd\x18\x06 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationH\x04\x88\x01\x01\x42\x0e\n\x0c_middle_bandB\r\n\x0b_upper_bandB\r\n\x0b_lower_bandB\t\n\x07_signalB\x07\n\x05_macd\"w\n\x16GetMarketValuesRequest\x12\x15\n\rinstrument_id\x18\x01 \x03(\t\x12\x46\n\x06values\x18\x02 \x03(\x0e\x32\x36.tinkoff.public.invest.api.contract.v1.MarketValueType\"l\n\x17GetMarketValuesResponse\x12Q\n\x0binstruments\x18\x01 \x03(\x0b\x32<.tinkoff.public.invest.api.contract.v1.MarketValueInstrument\"\x97\x01\n\x15MarketValueInstrument\x12\x16\n\x0einstrument_uid\x18\x01 \x01(\t\x12\x42\n\x06values\x18\x02 \x03(\x0b\x32\x32.tinkoff.public.invest.api.contract.v1.MarketValue\x12\x0e\n\x06ticker\x18\x03 \x01(\t\x12\x12\n\nclass_code\x18\x04 \x01(\t\"\xe9\x01\n\x0bMarketValue\x12I\n\x04type\x18\x01 \x01(\x0e\x32\x36.tinkoff.public.invest.api.contract.v1.MarketValueTypeH\x00\x88\x01\x01\x12\x44\n\x05value\x18\x02 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationH\x01\x88\x01\x01\x12-\n\x04time\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x02\x88\x01\x01\x42\x07\n\x05_typeB\x08\n\x06_valueB\x07\n\x05_time*\x81\x01\n\x12SubscriptionAction\x12#\n\x1fSUBSCRIPTION_ACTION_UNSPECIFIED\x10\x00\x12!\n\x1dSUBSCRIPTION_ACTION_SUBSCRIBE\x10\x01\x12#\n\x1fSUBSCRIPTION_ACTION_UNSUBSCRIBE\x10\x02*\x88\x04\n\x14SubscriptionInterval\x12%\n!SUBSCRIPTION_INTERVAL_UNSPECIFIED\x10\x00\x12$\n SUBSCRIPTION_INTERVAL_ONE_MINUTE\x10\x01\x12&\n\"SUBSCRIPTION_INTERVAL_FIVE_MINUTES\x10\x02\x12)\n%SUBSCRIPTION_INTERVAL_FIFTEEN_MINUTES\x10\x03\x12\"\n\x1eSUBSCRIPTION_INTERVAL_ONE_HOUR\x10\x04\x12!\n\x1dSUBSCRIPTION_INTERVAL_ONE_DAY\x10\x05\x12\x1f\n\x1bSUBSCRIPTION_INTERVAL_2_MIN\x10\x06\x12\x1f\n\x1bSUBSCRIPTION_INTERVAL_3_MIN\x10\x07\x12 \n\x1cSUBSCRIPTION_INTERVAL_10_MIN\x10\x08\x12 \n\x1cSUBSCRIPTION_INTERVAL_30_MIN\x10\t\x12 \n\x1cSUBSCRIPTION_INTERVAL_2_HOUR\x10\n\x12 \n\x1cSUBSCRIPTION_INTERVAL_4_HOUR\x10\x0b\x12\x1e\n\x1aSUBSCRIPTION_INTERVAL_WEEK\x10\x0c\x12\x1f\n\x1bSUBSCRIPTION_INTERVAL_MONTH\x10\r*\xf0\x03\n\x12SubscriptionStatus\x12#\n\x1fSUBSCRIPTION_STATUS_UNSPECIFIED\x10\x00\x12\x1f\n\x1bSUBSCRIPTION_STATUS_SUCCESS\x10\x01\x12,\n(SUBSCRIPTION_STATUS_INSTRUMENT_NOT_FOUND\x10\x02\x12\x36\n2SUBSCRIPTION_STATUS_SUBSCRIPTION_ACTION_IS_INVALID\x10\x03\x12(\n$SUBSCRIPTION_STATUS_DEPTH_IS_INVALID\x10\x04\x12+\n\'SUBSCRIPTION_STATUS_INTERVAL_IS_INVALID\x10\x05\x12)\n%SUBSCRIPTION_STATUS_LIMIT_IS_EXCEEDED\x10\x06\x12&\n\"SUBSCRIPTION_STATUS_INTERNAL_ERROR\x10\x07\x12)\n%SUBSCRIPTION_STATUS_TOO_MANY_REQUESTS\x10\x08\x12.\n*SUBSCRIPTION_STATUS_SUBSCRIPTION_NOT_FOUND\x10\t\x12)\n%SUBSCRIPTION_STATUS_SOURCE_IS_INVALID\x10\n*y\n\x0fTradeSourceType\x12\x1c\n\x18TRADE_SOURCE_UNSPECIFIED\x10\x00\x12\x19\n\x15TRADE_SOURCE_EXCHANGE\x10\x01\x12\x17\n\x13TRADE_SOURCE_DEALER\x10\x02\x12\x14\n\x10TRADE_SOURCE_ALL\x10\x03*d\n\x0eTradeDirection\x12\x1f\n\x1bTRADE_DIRECTION_UNSPECIFIED\x10\x00\x12\x17\n\x13TRADE_DIRECTION_BUY\x10\x01\x12\x18\n\x14TRADE_DIRECTION_SELL\x10\x02*\xe4\x03\n\x0e\x43\x61ndleInterval\x12\x1f\n\x1b\x43\x41NDLE_INTERVAL_UNSPECIFIED\x10\x00\x12\x19\n\x15\x43\x41NDLE_INTERVAL_1_MIN\x10\x01\x12\x19\n\x15\x43\x41NDLE_INTERVAL_5_MIN\x10\x02\x12\x1a\n\x16\x43\x41NDLE_INTERVAL_15_MIN\x10\x03\x12\x18\n\x14\x43\x41NDLE_INTERVAL_HOUR\x10\x04\x12\x17\n\x13\x43\x41NDLE_INTERVAL_DAY\x10\x05\x12\x19\n\x15\x43\x41NDLE_INTERVAL_2_MIN\x10\x06\x12\x19\n\x15\x43\x41NDLE_INTERVAL_3_MIN\x10\x07\x12\x1a\n\x16\x43\x41NDLE_INTERVAL_10_MIN\x10\x08\x12\x1a\n\x16\x43\x41NDLE_INTERVAL_30_MIN\x10\t\x12\x1a\n\x16\x43\x41NDLE_INTERVAL_2_HOUR\x10\n\x12\x1a\n\x16\x43\x41NDLE_INTERVAL_4_HOUR\x10\x0b\x12\x18\n\x14\x43\x41NDLE_INTERVAL_WEEK\x10\x0c\x12\x19\n\x15\x43\x41NDLE_INTERVAL_MONTH\x10\r\x12\x19\n\x15\x43\x41NDLE_INTERVAL_5_SEC\x10\x0e\x12\x1a\n\x16\x43\x41NDLE_INTERVAL_10_SEC\x10\x0f\x12\x1a\n\x16\x43\x41NDLE_INTERVAL_30_SEC\x10\x10*k\n\x0c\x43\x61ndleSource\x12\x1d\n\x19\x43\x41NDLE_SOURCE_UNSPECIFIED\x10\x00\x12\x1a\n\x16\x43\x41NDLE_SOURCE_EXCHANGE\x10\x01\x12 \n\x1c\x43\x41NDLE_SOURCE_DEALER_WEEKEND\x10\x02*\xac\x02\n\x0fMarketValueType\x12 \n\x1cINSTRUMENT_VALUE_UNSPECIFIED\x10\x00\x12\x1f\n\x1bINSTRUMENT_VALUE_LAST_PRICE\x10\x01\x12&\n\"INSTRUMENT_VALUE_LAST_PRICE_DEALER\x10\x02\x12 \n\x1cINSTRUMENT_VALUE_CLOSE_PRICE\x10\x03\x12*\n&INSTRUMENT_VALUE_EVENING_SESSION_PRICE\x10\x04\x12\"\n\x1eINSTRUMENT_VALUE_OPEN_INTEREST\x10\x05\x12 \n\x1cINSTRUMENT_VALUE_THEOR_PRICE\x10\x06\x12\x1a\n\x16INSTRUMENT_VALUE_YIELD\x10\x07*\x7f\n\rOrderBookType\x12\x1e\n\x1aORDERBOOK_TYPE_UNSPECIFIED\x10\x00\x12\x1b\n\x17ORDERBOOK_TYPE_EXCHANGE\x10\x01\x12\x19\n\x15ORDERBOOK_TYPE_DEALER\x10\x02\x12\x16\n\x12ORDERBOOK_TYPE_ALL\x10\x03*[\n\rLastPriceType\x12\x1a\n\x16LAST_PRICE_UNSPECIFIED\x10\x00\x12\x17\n\x13LAST_PRICE_EXCHANGE\x10\x01\x12\x15\n\x11LAST_PRICE_DEALER\x10\x02\x32\xa3\n\n\x11MarketDataService\x12\x81\x01\n\nGetCandles\x12\x38.tinkoff.public.invest.api.contract.v1.GetCandlesRequest\x1a\x39.tinkoff.public.invest.api.contract.v1.GetCandlesResponse\x12\x8a\x01\n\rGetLastPrices\x12;.tinkoff.public.invest.api.contract.v1.GetLastPricesRequest\x1a<.tinkoff.public.invest.api.contract.v1.GetLastPricesResponse\x12\x87\x01\n\x0cGetOrderBook\x12:.tinkoff.public.invest.api.contract.v1.GetOrderBookRequest\x1a;.tinkoff.public.invest.api.contract.v1.GetOrderBookResponse\x12\x93\x01\n\x10GetTradingStatus\x12>.tinkoff.public.invest.api.contract.v1.GetTradingStatusRequest\x1a?.tinkoff.public.invest.api.contract.v1.GetTradingStatusResponse\x12\x99\x01\n\x12GetTradingStatuses\x12@.tinkoff.public.invest.api.contract.v1.GetTradingStatusesRequest\x1a\x41.tinkoff.public.invest.api.contract.v1.GetTradingStatusesResponse\x12\x8a\x01\n\rGetLastTrades\x12;.tinkoff.public.invest.api.contract.v1.GetLastTradesRequest\x1a<.tinkoff.public.invest.api.contract.v1.GetLastTradesResponse\x12\x8d\x01\n\x0eGetClosePrices\x12<.tinkoff.public.invest.api.contract.v1.GetClosePricesRequest\x1a=.tinkoff.public.invest.api.contract.v1.GetClosePricesResponse\x12\x90\x01\n\x0fGetTechAnalysis\x12=.tinkoff.public.invest.api.contract.v1.GetTechAnalysisRequest\x1a>.tinkoff.public.invest.api.contract.v1.GetTechAnalysisResponse\x12\x90\x01\n\x0fGetMarketValues\x12=.tinkoff.public.invest.api.contract.v1.GetMarketValuesRequest\x1a>.tinkoff.public.invest.api.contract.v1.GetMarketValuesResponse2\xcd\x02\n\x17MarketDataStreamService\x12\x8b\x01\n\x10MarketDataStream\x12\x38.tinkoff.public.invest.api.contract.v1.MarketDataRequest\x1a\x39.tinkoff.public.invest.api.contract.v1.MarketDataResponse(\x01\x30\x01\x12\xa3\x01\n\x1aMarketDataServerSideStream\x12H.tinkoff.public.invest.api.contract.v1.MarketDataServerSideStreamRequest\x1a\x39.tinkoff.public.invest.api.contract.v1.MarketDataResponse0\x01\x42\x61\n\x1cru.tinkoff.piapi.contract.v1P\x01Z\x0c./;investapi\xa2\x02\x05TIAPI\xaa\x02\x14Tinkoff.InvestApi.V1\xca\x02\x11Tinkoff\\Invest\\V1b\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 't_tech.invest.grpc.marketdata_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\034ru.tinkoff.piapi.contract.v1P\001Z\014./;investapi\242\002\005TIAPI\252\002\024Tinkoff.InvestApi.V1\312\002\021Tinkoff\\Invest\\V1' + _globals['_CANDLEINSTRUMENT'].fields_by_name['figi']._options = None + _globals['_CANDLEINSTRUMENT'].fields_by_name['figi']._serialized_options = b'\030\001' + _globals['_ORDERBOOKINSTRUMENT'].fields_by_name['figi']._options = None + _globals['_ORDERBOOKINSTRUMENT'].fields_by_name['figi']._serialized_options = b'\030\001' + _globals['_TRADEINSTRUMENT'].fields_by_name['figi']._options = None + _globals['_TRADEINSTRUMENT'].fields_by_name['figi']._serialized_options = b'\030\001' + _globals['_INFOINSTRUMENT'].fields_by_name['figi']._options = None + _globals['_INFOINSTRUMENT'].fields_by_name['figi']._serialized_options = b'\030\001' + _globals['_LASTPRICEINSTRUMENT'].fields_by_name['figi']._options = None + _globals['_LASTPRICEINSTRUMENT'].fields_by_name['figi']._serialized_options = b'\030\001' + _globals['_GETCANDLESREQUEST'].fields_by_name['figi']._options = None + _globals['_GETCANDLESREQUEST'].fields_by_name['figi']._serialized_options = b'\030\001' + _globals['_GETCANDLESREQUEST'].fields_by_name['from']._options = None + _globals['_GETCANDLESREQUEST'].fields_by_name['from']._serialized_options = b'\342A\001\002' + _globals['_GETCANDLESREQUEST'].fields_by_name['to']._options = None + _globals['_GETCANDLESREQUEST'].fields_by_name['to']._serialized_options = b'\342A\001\002' + _globals['_GETCANDLESREQUEST'].fields_by_name['interval']._options = None + _globals['_GETCANDLESREQUEST'].fields_by_name['interval']._serialized_options = b'\342A\001\002' + _globals['_GETLASTPRICESREQUEST'].fields_by_name['figi']._options = None + _globals['_GETLASTPRICESREQUEST'].fields_by_name['figi']._serialized_options = b'\030\001' + _globals['_GETORDERBOOKREQUEST'].fields_by_name['figi']._options = None + _globals['_GETORDERBOOKREQUEST'].fields_by_name['figi']._serialized_options = b'\030\001' + _globals['_GETORDERBOOKREQUEST'].fields_by_name['depth']._options = None + _globals['_GETORDERBOOKREQUEST'].fields_by_name['depth']._serialized_options = b'\342A\001\002' + _globals['_GETTRADINGSTATUSREQUEST'].fields_by_name['figi']._options = None + _globals['_GETTRADINGSTATUSREQUEST'].fields_by_name['figi']._serialized_options = b'\030\001' + _globals['_GETLASTTRADESREQUEST'].fields_by_name['figi']._options = None + _globals['_GETLASTTRADESREQUEST'].fields_by_name['figi']._serialized_options = b'\030\001' + _globals['_GETLASTTRADESREQUEST'].fields_by_name['from']._options = None + _globals['_GETLASTTRADESREQUEST'].fields_by_name['from']._serialized_options = b'\342A\001\002' + _globals['_GETLASTTRADESREQUEST'].fields_by_name['to']._options = None + _globals['_GETLASTTRADESREQUEST'].fields_by_name['to']._serialized_options = b'\342A\001\002' + _globals['_GETCLOSEPRICESREQUEST'].fields_by_name['instruments']._options = None + _globals['_GETCLOSEPRICESREQUEST'].fields_by_name['instruments']._serialized_options = b'\342A\001\002' + _globals['_GETTECHANALYSISREQUEST'].fields_by_name['indicator_type']._options = None + _globals['_GETTECHANALYSISREQUEST'].fields_by_name['indicator_type']._serialized_options = b'\342A\001\002' + _globals['_GETTECHANALYSISREQUEST'].fields_by_name['instrument_uid']._options = None + _globals['_GETTECHANALYSISREQUEST'].fields_by_name['instrument_uid']._serialized_options = b'\342A\001\002' + _globals['_GETTECHANALYSISREQUEST'].fields_by_name['from']._options = None + _globals['_GETTECHANALYSISREQUEST'].fields_by_name['from']._serialized_options = b'\342A\001\002' + _globals['_GETTECHANALYSISREQUEST'].fields_by_name['to']._options = None + _globals['_GETTECHANALYSISREQUEST'].fields_by_name['to']._serialized_options = b'\342A\001\002' + _globals['_GETTECHANALYSISREQUEST'].fields_by_name['interval']._options = None + _globals['_GETTECHANALYSISREQUEST'].fields_by_name['interval']._serialized_options = b'\342A\001\002' + _globals['_GETTECHANALYSISREQUEST'].fields_by_name['type_of_price']._options = None + _globals['_GETTECHANALYSISREQUEST'].fields_by_name['type_of_price']._serialized_options = b'\342A\001\002' + _globals['_SUBSCRIPTIONACTION']._serialized_start=16332 + _globals['_SUBSCRIPTIONACTION']._serialized_end=16461 + _globals['_SUBSCRIPTIONINTERVAL']._serialized_start=16464 + _globals['_SUBSCRIPTIONINTERVAL']._serialized_end=16984 + _globals['_SUBSCRIPTIONSTATUS']._serialized_start=16987 + _globals['_SUBSCRIPTIONSTATUS']._serialized_end=17483 + _globals['_TRADESOURCETYPE']._serialized_start=17485 + _globals['_TRADESOURCETYPE']._serialized_end=17606 + _globals['_TRADEDIRECTION']._serialized_start=17608 + _globals['_TRADEDIRECTION']._serialized_end=17708 + _globals['_CANDLEINTERVAL']._serialized_start=17711 + _globals['_CANDLEINTERVAL']._serialized_end=18195 + _globals['_CANDLESOURCE']._serialized_start=18197 + _globals['_CANDLESOURCE']._serialized_end=18304 + _globals['_MARKETVALUETYPE']._serialized_start=18307 + _globals['_MARKETVALUETYPE']._serialized_end=18607 + _globals['_ORDERBOOKTYPE']._serialized_start=18609 + _globals['_ORDERBOOKTYPE']._serialized_end=18736 + _globals['_LASTPRICETYPE']._serialized_start=18738 + _globals['_LASTPRICETYPE']._serialized_end=18829 + _globals['_MARKETDATAREQUEST']._serialized_start=197 + _globals['_MARKETDATAREQUEST']._serialized_end=976 + _globals['_MARKETDATASERVERSIDESTREAMREQUEST']._serialized_start=979 + _globals['_MARKETDATASERVERSIDESTREAMREQUEST']._serialized_end=1592 + _globals['_MARKETDATARESPONSE']._serialized_start=1595 + _globals['_MARKETDATARESPONSE']._serialized_end=2633 + _globals['_SUBSCRIBECANDLESREQUEST']._serialized_start=2636 + _globals['_SUBSCRIBECANDLESREQUEST']._serialized_end=2977 + _globals['_CANDLEINSTRUMENT']._serialized_start=2980 + _globals['_CANDLEINSTRUMENT']._serialized_end=3118 + _globals['_SUBSCRIBECANDLESRESPONSE']._serialized_start=3121 + _globals['_SUBSCRIBECANDLESRESPONSE']._serialized_end=3258 + _globals['_CANDLESUBSCRIPTION']._serialized_start=3261 + _globals['_CANDLESUBSCRIPTION']._serialized_end=3804 + _globals['_SUBSCRIBEORDERBOOKREQUEST']._serialized_start=3807 + _globals['_SUBSCRIBEORDERBOOKREQUEST']._serialized_end=4003 + _globals['_ORDERBOOKINSTRUMENT']._serialized_start=4006 + _globals['_ORDERBOOKINSTRUMENT']._serialized_end=4162 + _globals['_SUBSCRIBEORDERBOOKRESPONSE']._serialized_start=4165 + _globals['_SUBSCRIBEORDERBOOKRESPONSE']._serialized_end=4310 + _globals['_ORDERBOOKSUBSCRIPTION']._serialized_start=4313 + _globals['_ORDERBOOKSUBSCRIPTION']._serialized_end=4724 + _globals['_SUBSCRIBETRADESREQUEST']._serialized_start=4727 + _globals['_SUBSCRIBETRADESREQUEST']._serialized_end=5022 + _globals['_TRADEINSTRUMENT']._serialized_start=5024 + _globals['_TRADEINSTRUMENT']._serialized_end=5082 + _globals['_SUBSCRIBETRADESRESPONSE']._serialized_start=5085 + _globals['_SUBSCRIBETRADESRESPONSE']._serialized_end=5296 + _globals['_TRADESUBSCRIPTION']._serialized_start=5299 + _globals['_TRADESUBSCRIPTION']._serialized_end=5640 + _globals['_SUBSCRIBEINFOREQUEST']._serialized_start=5643 + _globals['_SUBSCRIBEINFOREQUEST']._serialized_end=5829 + _globals['_INFOINSTRUMENT']._serialized_start=5831 + _globals['_INFOINSTRUMENT']._serialized_end=5888 + _globals['_SUBSCRIBEINFORESPONSE']._serialized_start=5891 + _globals['_SUBSCRIBEINFORESPONSE']._serialized_end=6020 + _globals['_INFOSUBSCRIPTION']._serialized_start=6023 + _globals['_INFOSUBSCRIPTION']._serialized_end=6335 + _globals['_SUBSCRIBELASTPRICEREQUEST']._serialized_start=6338 + _globals['_SUBSCRIBELASTPRICEREQUEST']._serialized_end=6534 + _globals['_LASTPRICEINSTRUMENT']._serialized_start=6536 + _globals['_LASTPRICEINSTRUMENT']._serialized_end=6598 + _globals['_SUBSCRIBELASTPRICERESPONSE']._serialized_start=6601 + _globals['_SUBSCRIBELASTPRICERESPONSE']._serialized_end=6746 + _globals['_LASTPRICESUBSCRIPTION']._serialized_start=6749 + _globals['_LASTPRICESUBSCRIPTION']._serialized_end=7066 + _globals['_CANDLE']._serialized_start=7069 + _globals['_CANDLE']._serialized_end=7717 + _globals['_ORDERBOOK']._serialized_start=7720 + _globals['_ORDERBOOK']._serialized_end=8222 + _globals['_ORDER']._serialized_start=8224 + _globals['_ORDER']._serialized_end=8314 + _globals['_TRADE']._serialized_start=8317 + _globals['_TRADE']._serialized_end=8675 + _globals['_TRADINGSTATUS']._serialized_start=8678 + _globals['_TRADINGSTATUS']._serialized_end=8968 + _globals['_GETCANDLESREQUEST']._serialized_start=8971 + _globals['_GETCANDLESREQUEST']._serialized_end=9508 + _globals['_GETCANDLESREQUEST_CANDLESOURCE']._serialized_start=9340 + _globals['_GETCANDLESREQUEST_CANDLESOURCE']._serialized_end=9448 + _globals['_GETCANDLESRESPONSE']._serialized_start=9510 + _globals['_GETCANDLESRESPONSE']._serialized_end=9602 + _globals['_HISTORICCANDLE']._serialized_start=9605 + _globals['_HISTORICCANDLE']._serialized_end=10073 + _globals['_GETLASTPRICESREQUEST']._serialized_start=10076 + _globals['_GETLASTPRICESREQUEST']._serialized_end=10329 + _globals['_GETLASTPRICESRESPONSE']._serialized_start=10331 + _globals['_GETLASTPRICESRESPONSE']._serialized_end=10425 + _globals['_LASTPRICE']._serialized_start=10428 + _globals['_LASTPRICE']._serialized_end=10699 + _globals['_OPENINTEREST']._serialized_start=10702 + _globals['_OPENINTEREST']._serialized_end=10841 + _globals['_GETORDERBOOKREQUEST']._serialized_start=10843 + _globals['_GETORDERBOOKREQUEST']._serialized_end=10963 + _globals['_GETORDERBOOKRESPONSE']._serialized_start=10966 + _globals['_GETORDERBOOKRESPONSE']._serialized_end=11629 + _globals['_GETTRADINGSTATUSREQUEST']._serialized_start=11631 + _globals['_GETTRADINGSTATUSREQUEST']._serialized_end=11734 + _globals['_GETTRADINGSTATUSESREQUEST']._serialized_start=11736 + _globals['_GETTRADINGSTATUSESREQUEST']._serialized_end=11786 + _globals['_GETTRADINGSTATUSESRESPONSE']._serialized_start=11788 + _globals['_GETTRADINGSTATUSESRESPONSE']._serialized_end=11907 + _globals['_GETTRADINGSTATUSRESPONSE']._serialized_start=11910 + _globals['_GETTRADINGSTATUSRESPONSE']._serialized_end=12268 + _globals['_GETLASTTRADESREQUEST']._serialized_start=12271 + _globals['_GETLASTTRADESREQUEST']._serialized_end=12543 + _globals['_GETLASTTRADESRESPONSE']._serialized_start=12545 + _globals['_GETLASTTRADESRESPONSE']._serialized_end=12630 + _globals['_GETMYSUBSCRIPTIONS']._serialized_start=12632 + _globals['_GETMYSUBSCRIPTIONS']._serialized_end=12652 + _globals['_GETCLOSEPRICESREQUEST']._serialized_start=12655 + _globals['_GETCLOSEPRICESREQUEST']._serialized_end=12884 + _globals['_INSTRUMENTCLOSEPRICEREQUEST']._serialized_start=12886 + _globals['_INSTRUMENTCLOSEPRICEREQUEST']._serialized_end=12938 + _globals['_GETCLOSEPRICESRESPONSE']._serialized_start=12940 + _globals['_GETCLOSEPRICESRESPONSE']._serialized_end=13055 + _globals['_INSTRUMENTCLOSEPRICERESPONSE']._serialized_start=13058 + _globals['_INSTRUMENTCLOSEPRICERESPONSE']._serialized_end=13414 + _globals['_GETTECHANALYSISREQUEST']._serialized_start=13417 + _globals['_GETTECHANALYSISREQUEST']._serialized_end=15069 + _globals['_GETTECHANALYSISREQUEST_SMOOTHING']._serialized_start=14083 + _globals['_GETTECHANALYSISREQUEST_SMOOTHING']._serialized_end=14162 + _globals['_GETTECHANALYSISREQUEST_DEVIATION']._serialized_start=14164 + _globals['_GETTECHANALYSISREQUEST_DEVIATION']._serialized_end=14255 + _globals['_GETTECHANALYSISREQUEST_INDICATORINTERVAL']._serialized_start=14258 + _globals['_GETTECHANALYSISREQUEST_INDICATORINTERVAL']._serialized_end=14733 + _globals['_GETTECHANALYSISREQUEST_TYPEOFPRICE']._serialized_start=14736 + _globals['_GETTECHANALYSISREQUEST_TYPEOFPRICE']._serialized_end=14899 + _globals['_GETTECHANALYSISREQUEST_INDICATORTYPE']._serialized_start=14902 + _globals['_GETTECHANALYSISREQUEST_INDICATORTYPE']._serialized_end=15069 + _globals['_GETTECHANALYSISRESPONSE']._serialized_start=15072 + _globals['_GETTECHANALYSISRESPONSE']._serialized_end=15708 + _globals['_GETTECHANALYSISRESPONSE_TECHANALYSISITEM']._serialized_start=15211 + _globals['_GETTECHANALYSISRESPONSE_TECHANALYSISITEM']._serialized_end=15708 + _globals['_GETMARKETVALUESREQUEST']._serialized_start=15710 + _globals['_GETMARKETVALUESREQUEST']._serialized_end=15829 + _globals['_GETMARKETVALUESRESPONSE']._serialized_start=15831 + _globals['_GETMARKETVALUESRESPONSE']._serialized_end=15939 + _globals['_MARKETVALUEINSTRUMENT']._serialized_start=15942 + _globals['_MARKETVALUEINSTRUMENT']._serialized_end=16093 + _globals['_MARKETVALUE']._serialized_start=16096 + _globals['_MARKETVALUE']._serialized_end=16329 + _globals['_MARKETDATASERVICE']._serialized_start=18832 + _globals['_MARKETDATASERVICE']._serialized_end=20147 + _globals['_MARKETDATASTREAMSERVICE']._serialized_start=20150 + _globals['_MARKETDATASTREAMSERVICE']._serialized_end=20483 +# @@protoc_insertion_point(module_scope) diff --git a/invest-python-master/t_tech/invest/grpc/marketdata_pb2.pyi b/invest-python-master/t_tech/invest/grpc/marketdata_pb2.pyi new file mode 100644 index 0000000..c6a8bbb --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/marketdata_pb2.pyi @@ -0,0 +1,2679 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" + +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.internal.enum_type_wrapper +import google.protobuf.message +import google.protobuf.timestamp_pb2 +import sys +import t_tech.invest.grpc.common_pb2 +import typing + +if sys.version_info >= (3, 10): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +class _SubscriptionAction: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _SubscriptionActionEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_SubscriptionAction.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + SUBSCRIPTION_ACTION_UNSPECIFIED: _SubscriptionAction.ValueType # 0 + """Статус подписки не определен.""" + SUBSCRIPTION_ACTION_SUBSCRIBE: _SubscriptionAction.ValueType # 1 + """Подписаться.""" + SUBSCRIPTION_ACTION_UNSUBSCRIBE: _SubscriptionAction.ValueType # 2 + """Отписаться.""" + +class SubscriptionAction(_SubscriptionAction, metaclass=_SubscriptionActionEnumTypeWrapper): + """Тип операции со списком подписок.""" + +SUBSCRIPTION_ACTION_UNSPECIFIED: SubscriptionAction.ValueType # 0 +"""Статус подписки не определен.""" +SUBSCRIPTION_ACTION_SUBSCRIBE: SubscriptionAction.ValueType # 1 +"""Подписаться.""" +SUBSCRIPTION_ACTION_UNSUBSCRIBE: SubscriptionAction.ValueType # 2 +"""Отписаться.""" +global___SubscriptionAction = SubscriptionAction + +class _SubscriptionInterval: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _SubscriptionIntervalEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_SubscriptionInterval.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + SUBSCRIPTION_INTERVAL_UNSPECIFIED: _SubscriptionInterval.ValueType # 0 + """Интервал свечи не определен.""" + SUBSCRIPTION_INTERVAL_ONE_MINUTE: _SubscriptionInterval.ValueType # 1 + """Минутные свечи.""" + SUBSCRIPTION_INTERVAL_FIVE_MINUTES: _SubscriptionInterval.ValueType # 2 + """Пятиминутные свечи.""" + SUBSCRIPTION_INTERVAL_FIFTEEN_MINUTES: _SubscriptionInterval.ValueType # 3 + """Пятнадцатиминутные свечи.""" + SUBSCRIPTION_INTERVAL_ONE_HOUR: _SubscriptionInterval.ValueType # 4 + """Часовые свечи.""" + SUBSCRIPTION_INTERVAL_ONE_DAY: _SubscriptionInterval.ValueType # 5 + """Дневные свечи.""" + SUBSCRIPTION_INTERVAL_2_MIN: _SubscriptionInterval.ValueType # 6 + """Двухминутные свечи.""" + SUBSCRIPTION_INTERVAL_3_MIN: _SubscriptionInterval.ValueType # 7 + """Трехминутные свечи.""" + SUBSCRIPTION_INTERVAL_10_MIN: _SubscriptionInterval.ValueType # 8 + """Десятиминутные свечи.""" + SUBSCRIPTION_INTERVAL_30_MIN: _SubscriptionInterval.ValueType # 9 + """Тридцатиминутные свечи.""" + SUBSCRIPTION_INTERVAL_2_HOUR: _SubscriptionInterval.ValueType # 10 + """Двухчасовые свечи.""" + SUBSCRIPTION_INTERVAL_4_HOUR: _SubscriptionInterval.ValueType # 11 + """Четырехчасовые свечи.""" + SUBSCRIPTION_INTERVAL_WEEK: _SubscriptionInterval.ValueType # 12 + """Недельные свечи.""" + SUBSCRIPTION_INTERVAL_MONTH: _SubscriptionInterval.ValueType # 13 + """Месячные свечи.""" + +class SubscriptionInterval(_SubscriptionInterval, metaclass=_SubscriptionIntervalEnumTypeWrapper): + """Интервал свечи.""" + +SUBSCRIPTION_INTERVAL_UNSPECIFIED: SubscriptionInterval.ValueType # 0 +"""Интервал свечи не определен.""" +SUBSCRIPTION_INTERVAL_ONE_MINUTE: SubscriptionInterval.ValueType # 1 +"""Минутные свечи.""" +SUBSCRIPTION_INTERVAL_FIVE_MINUTES: SubscriptionInterval.ValueType # 2 +"""Пятиминутные свечи.""" +SUBSCRIPTION_INTERVAL_FIFTEEN_MINUTES: SubscriptionInterval.ValueType # 3 +"""Пятнадцатиминутные свечи.""" +SUBSCRIPTION_INTERVAL_ONE_HOUR: SubscriptionInterval.ValueType # 4 +"""Часовые свечи.""" +SUBSCRIPTION_INTERVAL_ONE_DAY: SubscriptionInterval.ValueType # 5 +"""Дневные свечи.""" +SUBSCRIPTION_INTERVAL_2_MIN: SubscriptionInterval.ValueType # 6 +"""Двухминутные свечи.""" +SUBSCRIPTION_INTERVAL_3_MIN: SubscriptionInterval.ValueType # 7 +"""Трехминутные свечи.""" +SUBSCRIPTION_INTERVAL_10_MIN: SubscriptionInterval.ValueType # 8 +"""Десятиминутные свечи.""" +SUBSCRIPTION_INTERVAL_30_MIN: SubscriptionInterval.ValueType # 9 +"""Тридцатиминутные свечи.""" +SUBSCRIPTION_INTERVAL_2_HOUR: SubscriptionInterval.ValueType # 10 +"""Двухчасовые свечи.""" +SUBSCRIPTION_INTERVAL_4_HOUR: SubscriptionInterval.ValueType # 11 +"""Четырехчасовые свечи.""" +SUBSCRIPTION_INTERVAL_WEEK: SubscriptionInterval.ValueType # 12 +"""Недельные свечи.""" +SUBSCRIPTION_INTERVAL_MONTH: SubscriptionInterval.ValueType # 13 +"""Месячные свечи.""" +global___SubscriptionInterval = SubscriptionInterval + +class _SubscriptionStatus: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _SubscriptionStatusEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_SubscriptionStatus.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + SUBSCRIPTION_STATUS_UNSPECIFIED: _SubscriptionStatus.ValueType # 0 + """Статус подписки не определен.""" + SUBSCRIPTION_STATUS_SUCCESS: _SubscriptionStatus.ValueType # 1 + """Успешно.""" + SUBSCRIPTION_STATUS_INSTRUMENT_NOT_FOUND: _SubscriptionStatus.ValueType # 2 + """Инструмент не найден.""" + SUBSCRIPTION_STATUS_SUBSCRIPTION_ACTION_IS_INVALID: _SubscriptionStatus.ValueType # 3 + """Некорректный статус подписки. [Список возможных значений](./marketdata#subscriptionaction).""" + SUBSCRIPTION_STATUS_DEPTH_IS_INVALID: _SubscriptionStatus.ValueType # 4 + """Некорректная глубина стакана. Доступные значения — 1, 10, 20, 30, 40, 50.""" + SUBSCRIPTION_STATUS_INTERVAL_IS_INVALID: _SubscriptionStatus.ValueType # 5 + """Некорректный интервал свечей. [Список возможных значений](./marketdata#subscriptioninterval).""" + SUBSCRIPTION_STATUS_LIMIT_IS_EXCEEDED: _SubscriptionStatus.ValueType # 6 + """Превышен лимит на общее количество подписок в рамках стрима. [Лимитная политика](./limits/).""" + SUBSCRIPTION_STATUS_INTERNAL_ERROR: _SubscriptionStatus.ValueType # 7 + """Внутренняя ошибка сервиса.""" + SUBSCRIPTION_STATUS_TOO_MANY_REQUESTS: _SubscriptionStatus.ValueType # 8 + """Превышен лимит на количество запросов на подписки в течение установленного отрезка времени.""" + SUBSCRIPTION_STATUS_SUBSCRIPTION_NOT_FOUND: _SubscriptionStatus.ValueType # 9 + """Активная подписка не найдена. Ошибка может возникнуть только при отписке от несуществующей подписки.""" + SUBSCRIPTION_STATUS_SOURCE_IS_INVALID: _SubscriptionStatus.ValueType # 10 + """Указан некорректный источник.""" + +class SubscriptionStatus(_SubscriptionStatus, metaclass=_SubscriptionStatusEnumTypeWrapper): + """Результат подписки.""" + +SUBSCRIPTION_STATUS_UNSPECIFIED: SubscriptionStatus.ValueType # 0 +"""Статус подписки не определен.""" +SUBSCRIPTION_STATUS_SUCCESS: SubscriptionStatus.ValueType # 1 +"""Успешно.""" +SUBSCRIPTION_STATUS_INSTRUMENT_NOT_FOUND: SubscriptionStatus.ValueType # 2 +"""Инструмент не найден.""" +SUBSCRIPTION_STATUS_SUBSCRIPTION_ACTION_IS_INVALID: SubscriptionStatus.ValueType # 3 +"""Некорректный статус подписки. [Список возможных значений](./marketdata#subscriptionaction).""" +SUBSCRIPTION_STATUS_DEPTH_IS_INVALID: SubscriptionStatus.ValueType # 4 +"""Некорректная глубина стакана. Доступные значения — 1, 10, 20, 30, 40, 50.""" +SUBSCRIPTION_STATUS_INTERVAL_IS_INVALID: SubscriptionStatus.ValueType # 5 +"""Некорректный интервал свечей. [Список возможных значений](./marketdata#subscriptioninterval).""" +SUBSCRIPTION_STATUS_LIMIT_IS_EXCEEDED: SubscriptionStatus.ValueType # 6 +"""Превышен лимит на общее количество подписок в рамках стрима. [Лимитная политика](./limits/).""" +SUBSCRIPTION_STATUS_INTERNAL_ERROR: SubscriptionStatus.ValueType # 7 +"""Внутренняя ошибка сервиса.""" +SUBSCRIPTION_STATUS_TOO_MANY_REQUESTS: SubscriptionStatus.ValueType # 8 +"""Превышен лимит на количество запросов на подписки в течение установленного отрезка времени.""" +SUBSCRIPTION_STATUS_SUBSCRIPTION_NOT_FOUND: SubscriptionStatus.ValueType # 9 +"""Активная подписка не найдена. Ошибка может возникнуть только при отписке от несуществующей подписки.""" +SUBSCRIPTION_STATUS_SOURCE_IS_INVALID: SubscriptionStatus.ValueType # 10 +"""Указан некорректный источник.""" +global___SubscriptionStatus = SubscriptionStatus + +class _TradeSourceType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _TradeSourceTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_TradeSourceType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + TRADE_SOURCE_UNSPECIFIED: _TradeSourceType.ValueType # 0 + """Тип источника сделки не определён.""" + TRADE_SOURCE_EXCHANGE: _TradeSourceType.ValueType # 1 + """Биржевые сделки.""" + TRADE_SOURCE_DEALER: _TradeSourceType.ValueType # 2 + """Сделки дилера.""" + TRADE_SOURCE_ALL: _TradeSourceType.ValueType # 3 + """Все сделки.""" + +class TradeSourceType(_TradeSourceType, metaclass=_TradeSourceTypeEnumTypeWrapper): + """Типы источников сделок.""" + +TRADE_SOURCE_UNSPECIFIED: TradeSourceType.ValueType # 0 +"""Тип источника сделки не определён.""" +TRADE_SOURCE_EXCHANGE: TradeSourceType.ValueType # 1 +"""Биржевые сделки.""" +TRADE_SOURCE_DEALER: TradeSourceType.ValueType # 2 +"""Сделки дилера.""" +TRADE_SOURCE_ALL: TradeSourceType.ValueType # 3 +"""Все сделки.""" +global___TradeSourceType = TradeSourceType + +class _TradeDirection: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _TradeDirectionEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_TradeDirection.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + TRADE_DIRECTION_UNSPECIFIED: _TradeDirection.ValueType # 0 + """Направление сделки не определено.""" + TRADE_DIRECTION_BUY: _TradeDirection.ValueType # 1 + """Покупка.""" + TRADE_DIRECTION_SELL: _TradeDirection.ValueType # 2 + """Продажа.""" + +class TradeDirection(_TradeDirection, metaclass=_TradeDirectionEnumTypeWrapper): + """Направление сделки.""" + +TRADE_DIRECTION_UNSPECIFIED: TradeDirection.ValueType # 0 +"""Направление сделки не определено.""" +TRADE_DIRECTION_BUY: TradeDirection.ValueType # 1 +"""Покупка.""" +TRADE_DIRECTION_SELL: TradeDirection.ValueType # 2 +"""Продажа.""" +global___TradeDirection = TradeDirection + +class _CandleInterval: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _CandleIntervalEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_CandleInterval.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + CANDLE_INTERVAL_UNSPECIFIED: _CandleInterval.ValueType # 0 + """Интервал не определен.""" + CANDLE_INTERVAL_1_MIN: _CandleInterval.ValueType # 1 + """От 1 минуты до 1 дня. Максимальное значение `limit` — 2400.""" + CANDLE_INTERVAL_5_MIN: _CandleInterval.ValueType # 2 + """От 5 минут до недели. Максимальное значение `limit` — 2400.""" + CANDLE_INTERVAL_15_MIN: _CandleInterval.ValueType # 3 + """От 15 минут до 3 недель. Максимальное значение `limit` — 2400.""" + CANDLE_INTERVAL_HOUR: _CandleInterval.ValueType # 4 + """От 1 часа до 3 месяцев. Максимальное значение `limit` — 2400.""" + CANDLE_INTERVAL_DAY: _CandleInterval.ValueType # 5 + """От 1 дня до 6 лет. Максимальное значение `limit` — 2400.""" + CANDLE_INTERVAL_2_MIN: _CandleInterval.ValueType # 6 + """От 2 минут до 1 дня. Максимальное значение `limit` — 1200.""" + CANDLE_INTERVAL_3_MIN: _CandleInterval.ValueType # 7 + """От 3 минут до 1 дня. Максимальное значение `limit` — 750.""" + CANDLE_INTERVAL_10_MIN: _CandleInterval.ValueType # 8 + """От 10 минут до недели. Максимальное значение `limit` — 1200.""" + CANDLE_INTERVAL_30_MIN: _CandleInterval.ValueType # 9 + """От 30 минут до 3 недель. Максимальное значение `limit` — 1200.""" + CANDLE_INTERVAL_2_HOUR: _CandleInterval.ValueType # 10 + """От 2 часов до 3 месяцев. Максимальное значение `limit` — 2400.""" + CANDLE_INTERVAL_4_HOUR: _CandleInterval.ValueType # 11 + """От 4 часов до 3 месяцев. Максимальное значение `limit` — 700.""" + CANDLE_INTERVAL_WEEK: _CandleInterval.ValueType # 12 + """От 1 недели до 5 лет. Максимальное значение `limit` — 300.""" + CANDLE_INTERVAL_MONTH: _CandleInterval.ValueType # 13 + """От 1 месяца до 10 лет. Максимальное значение `limit` — 120.""" + CANDLE_INTERVAL_5_SEC: _CandleInterval.ValueType # 14 + """От 5 секунд до 200 минут. Максимальное значение `limit` — 2500.""" + CANDLE_INTERVAL_10_SEC: _CandleInterval.ValueType # 15 + """От 10 секунд до 200 минут. Максимальное значение `limit` — 1250.""" + CANDLE_INTERVAL_30_SEC: _CandleInterval.ValueType # 16 + """От 30 секунд до 20 часов. Максимальное значение `limit` — 2500.""" + +class CandleInterval(_CandleInterval, metaclass=_CandleIntervalEnumTypeWrapper): + """Интервал свечей. Максимальное значение интервала приведено ориентировочно, может отличаться в большую сторону в зависимости от параметров запроса.""" + +CANDLE_INTERVAL_UNSPECIFIED: CandleInterval.ValueType # 0 +"""Интервал не определен.""" +CANDLE_INTERVAL_1_MIN: CandleInterval.ValueType # 1 +"""От 1 минуты до 1 дня. Максимальное значение `limit` — 2400.""" +CANDLE_INTERVAL_5_MIN: CandleInterval.ValueType # 2 +"""От 5 минут до недели. Максимальное значение `limit` — 2400.""" +CANDLE_INTERVAL_15_MIN: CandleInterval.ValueType # 3 +"""От 15 минут до 3 недель. Максимальное значение `limit` — 2400.""" +CANDLE_INTERVAL_HOUR: CandleInterval.ValueType # 4 +"""От 1 часа до 3 месяцев. Максимальное значение `limit` — 2400.""" +CANDLE_INTERVAL_DAY: CandleInterval.ValueType # 5 +"""От 1 дня до 6 лет. Максимальное значение `limit` — 2400.""" +CANDLE_INTERVAL_2_MIN: CandleInterval.ValueType # 6 +"""От 2 минут до 1 дня. Максимальное значение `limit` — 1200.""" +CANDLE_INTERVAL_3_MIN: CandleInterval.ValueType # 7 +"""От 3 минут до 1 дня. Максимальное значение `limit` — 750.""" +CANDLE_INTERVAL_10_MIN: CandleInterval.ValueType # 8 +"""От 10 минут до недели. Максимальное значение `limit` — 1200.""" +CANDLE_INTERVAL_30_MIN: CandleInterval.ValueType # 9 +"""От 30 минут до 3 недель. Максимальное значение `limit` — 1200.""" +CANDLE_INTERVAL_2_HOUR: CandleInterval.ValueType # 10 +"""От 2 часов до 3 месяцев. Максимальное значение `limit` — 2400.""" +CANDLE_INTERVAL_4_HOUR: CandleInterval.ValueType # 11 +"""От 4 часов до 3 месяцев. Максимальное значение `limit` — 700.""" +CANDLE_INTERVAL_WEEK: CandleInterval.ValueType # 12 +"""От 1 недели до 5 лет. Максимальное значение `limit` — 300.""" +CANDLE_INTERVAL_MONTH: CandleInterval.ValueType # 13 +"""От 1 месяца до 10 лет. Максимальное значение `limit` — 120.""" +CANDLE_INTERVAL_5_SEC: CandleInterval.ValueType # 14 +"""От 5 секунд до 200 минут. Максимальное значение `limit` — 2500.""" +CANDLE_INTERVAL_10_SEC: CandleInterval.ValueType # 15 +"""От 10 секунд до 200 минут. Максимальное значение `limit` — 1250.""" +CANDLE_INTERVAL_30_SEC: CandleInterval.ValueType # 16 +"""От 30 секунд до 20 часов. Максимальное значение `limit` — 2500.""" +global___CandleInterval = CandleInterval + +class _CandleSource: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _CandleSourceEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_CandleSource.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + CANDLE_SOURCE_UNSPECIFIED: _CandleSource.ValueType # 0 + """Источник свечей не определен.""" + CANDLE_SOURCE_EXCHANGE: _CandleSource.ValueType # 1 + """Биржевые свечи.""" + CANDLE_SOURCE_DEALER_WEEKEND: _CandleSource.ValueType # 2 + """Свечи дилера в результате торговли по выходным.""" + +class CandleSource(_CandleSource, metaclass=_CandleSourceEnumTypeWrapper): ... + +CANDLE_SOURCE_UNSPECIFIED: CandleSource.ValueType # 0 +"""Источник свечей не определен.""" +CANDLE_SOURCE_EXCHANGE: CandleSource.ValueType # 1 +"""Биржевые свечи.""" +CANDLE_SOURCE_DEALER_WEEKEND: CandleSource.ValueType # 2 +"""Свечи дилера в результате торговли по выходным.""" +global___CandleSource = CandleSource + +class _MarketValueType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _MarketValueTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_MarketValueType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + INSTRUMENT_VALUE_UNSPECIFIED: _MarketValueType.ValueType # 0 + """Не определен.""" + INSTRUMENT_VALUE_LAST_PRICE: _MarketValueType.ValueType # 1 + """Последняя биржевая цена.""" + INSTRUMENT_VALUE_LAST_PRICE_DEALER: _MarketValueType.ValueType # 2 + """Последняя цена дилера.""" + INSTRUMENT_VALUE_CLOSE_PRICE: _MarketValueType.ValueType # 3 + """Цена закрытия.""" + INSTRUMENT_VALUE_EVENING_SESSION_PRICE: _MarketValueType.ValueType # 4 + """Цена последней сделки с вечерней сессии.""" + INSTRUMENT_VALUE_OPEN_INTEREST: _MarketValueType.ValueType # 5 + """Открытый интерес, возвращается только для фьючерсов.""" + INSTRUMENT_VALUE_THEOR_PRICE: _MarketValueType.ValueType # 6 + """Теоретическая цена, возвращается только для опционов.""" + INSTRUMENT_VALUE_YIELD: _MarketValueType.ValueType # 7 + """Доходность""" + +class MarketValueType(_MarketValueType, metaclass=_MarketValueTypeEnumTypeWrapper): ... + +INSTRUMENT_VALUE_UNSPECIFIED: MarketValueType.ValueType # 0 +"""Не определен.""" +INSTRUMENT_VALUE_LAST_PRICE: MarketValueType.ValueType # 1 +"""Последняя биржевая цена.""" +INSTRUMENT_VALUE_LAST_PRICE_DEALER: MarketValueType.ValueType # 2 +"""Последняя цена дилера.""" +INSTRUMENT_VALUE_CLOSE_PRICE: MarketValueType.ValueType # 3 +"""Цена закрытия.""" +INSTRUMENT_VALUE_EVENING_SESSION_PRICE: MarketValueType.ValueType # 4 +"""Цена последней сделки с вечерней сессии.""" +INSTRUMENT_VALUE_OPEN_INTEREST: MarketValueType.ValueType # 5 +"""Открытый интерес, возвращается только для фьючерсов.""" +INSTRUMENT_VALUE_THEOR_PRICE: MarketValueType.ValueType # 6 +"""Теоретическая цена, возвращается только для опционов.""" +INSTRUMENT_VALUE_YIELD: MarketValueType.ValueType # 7 +"""Доходность""" +global___MarketValueType = MarketValueType + +class _OrderBookType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _OrderBookTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_OrderBookType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + ORDERBOOK_TYPE_UNSPECIFIED: _OrderBookType.ValueType # 0 + """Не определен.""" + ORDERBOOK_TYPE_EXCHANGE: _OrderBookType.ValueType # 1 + """Биржевой стакан.""" + ORDERBOOK_TYPE_DEALER: _OrderBookType.ValueType # 2 + """Стакан дилера.""" + ORDERBOOK_TYPE_ALL: _OrderBookType.ValueType # 3 + """Стакан биржевой и дилера.""" + +class OrderBookType(_OrderBookType, metaclass=_OrderBookTypeEnumTypeWrapper): ... + +ORDERBOOK_TYPE_UNSPECIFIED: OrderBookType.ValueType # 0 +"""Не определен.""" +ORDERBOOK_TYPE_EXCHANGE: OrderBookType.ValueType # 1 +"""Биржевой стакан.""" +ORDERBOOK_TYPE_DEALER: OrderBookType.ValueType # 2 +"""Стакан дилера.""" +ORDERBOOK_TYPE_ALL: OrderBookType.ValueType # 3 +"""Стакан биржевой и дилера.""" +global___OrderBookType = OrderBookType + +class _LastPriceType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _LastPriceTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_LastPriceType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + LAST_PRICE_UNSPECIFIED: _LastPriceType.ValueType # 0 + """Не определен.""" + LAST_PRICE_EXCHANGE: _LastPriceType.ValueType # 1 + """Цена биржи.""" + LAST_PRICE_DEALER: _LastPriceType.ValueType # 2 + """Цена дилера""" + +class LastPriceType(_LastPriceType, metaclass=_LastPriceTypeEnumTypeWrapper): + """Тип последней цены""" + +LAST_PRICE_UNSPECIFIED: LastPriceType.ValueType # 0 +"""Не определен.""" +LAST_PRICE_EXCHANGE: LastPriceType.ValueType # 1 +"""Цена биржи.""" +LAST_PRICE_DEALER: LastPriceType.ValueType # 2 +"""Цена дилера""" +global___LastPriceType = LastPriceType + +@typing.final +class MarketDataRequest(google.protobuf.message.Message): + """Запрос подписки или отписки на определенные биржевые данные.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SUBSCRIBE_CANDLES_REQUEST_FIELD_NUMBER: builtins.int + SUBSCRIBE_ORDER_BOOK_REQUEST_FIELD_NUMBER: builtins.int + SUBSCRIBE_TRADES_REQUEST_FIELD_NUMBER: builtins.int + SUBSCRIBE_INFO_REQUEST_FIELD_NUMBER: builtins.int + SUBSCRIBE_LAST_PRICE_REQUEST_FIELD_NUMBER: builtins.int + GET_MY_SUBSCRIPTIONS_FIELD_NUMBER: builtins.int + PING_FIELD_NUMBER: builtins.int + PING_SETTINGS_FIELD_NUMBER: builtins.int + @property + def subscribe_candles_request(self) -> global___SubscribeCandlesRequest: + """Запрос подписки на свечи.""" + + @property + def subscribe_order_book_request(self) -> global___SubscribeOrderBookRequest: + """Запрос подписки на стаканы.""" + + @property + def subscribe_trades_request(self) -> global___SubscribeTradesRequest: + """Запрос подписки на ленту обезличенных сделок.""" + + @property + def subscribe_info_request(self) -> global___SubscribeInfoRequest: + """Запрос подписки на торговые статусы инструментов.""" + + @property + def subscribe_last_price_request(self) -> global___SubscribeLastPriceRequest: + """Запрос подписки на цены последних сделок.""" + + @property + def get_my_subscriptions(self) -> global___GetMySubscriptions: + """Запрос своих подписок.""" + + @property + def ping(self) -> t_tech.invest.grpc.common_pb2.PingRequest: + """Запрос проверки активности соединения.""" + + @property + def ping_settings(self) -> t_tech.invest.grpc.common_pb2.PingDelaySettings: + """Запрос настройки пинга.""" + + def __init__( + self, + *, + subscribe_candles_request: global___SubscribeCandlesRequest | None = ..., + subscribe_order_book_request: global___SubscribeOrderBookRequest | None = ..., + subscribe_trades_request: global___SubscribeTradesRequest | None = ..., + subscribe_info_request: global___SubscribeInfoRequest | None = ..., + subscribe_last_price_request: global___SubscribeLastPriceRequest | None = ..., + get_my_subscriptions: global___GetMySubscriptions | None = ..., + ping: t_tech.invest.grpc.common_pb2.PingRequest | None = ..., + ping_settings: t_tech.invest.grpc.common_pb2.PingDelaySettings | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["get_my_subscriptions", b"get_my_subscriptions", "payload", b"payload", "ping", b"ping", "ping_settings", b"ping_settings", "subscribe_candles_request", b"subscribe_candles_request", "subscribe_info_request", b"subscribe_info_request", "subscribe_last_price_request", b"subscribe_last_price_request", "subscribe_order_book_request", b"subscribe_order_book_request", "subscribe_trades_request", b"subscribe_trades_request"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["get_my_subscriptions", b"get_my_subscriptions", "payload", b"payload", "ping", b"ping", "ping_settings", b"ping_settings", "subscribe_candles_request", b"subscribe_candles_request", "subscribe_info_request", b"subscribe_info_request", "subscribe_last_price_request", b"subscribe_last_price_request", "subscribe_order_book_request", b"subscribe_order_book_request", "subscribe_trades_request", b"subscribe_trades_request"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["payload", b"payload"]) -> typing.Literal["subscribe_candles_request", "subscribe_order_book_request", "subscribe_trades_request", "subscribe_info_request", "subscribe_last_price_request", "get_my_subscriptions", "ping", "ping_settings"] | None: ... + +global___MarketDataRequest = MarketDataRequest + +@typing.final +class MarketDataServerSideStreamRequest(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SUBSCRIBE_CANDLES_REQUEST_FIELD_NUMBER: builtins.int + SUBSCRIBE_ORDER_BOOK_REQUEST_FIELD_NUMBER: builtins.int + SUBSCRIBE_TRADES_REQUEST_FIELD_NUMBER: builtins.int + SUBSCRIBE_INFO_REQUEST_FIELD_NUMBER: builtins.int + SUBSCRIBE_LAST_PRICE_REQUEST_FIELD_NUMBER: builtins.int + PING_SETTINGS_FIELD_NUMBER: builtins.int + @property + def subscribe_candles_request(self) -> global___SubscribeCandlesRequest: + """Запрос подписки на свечи.""" + + @property + def subscribe_order_book_request(self) -> global___SubscribeOrderBookRequest: + """Запрос подписки на стаканы.""" + + @property + def subscribe_trades_request(self) -> global___SubscribeTradesRequest: + """Запрос подписки на ленту обезличенных сделок.""" + + @property + def subscribe_info_request(self) -> global___SubscribeInfoRequest: + """Запрос подписки на торговые статусы инструментов.""" + + @property + def subscribe_last_price_request(self) -> global___SubscribeLastPriceRequest: + """Запрос подписки на цены последних сделок.""" + + @property + def ping_settings(self) -> t_tech.invest.grpc.common_pb2.PingDelaySettings: + """Запрос настройки пинга.""" + + def __init__( + self, + *, + subscribe_candles_request: global___SubscribeCandlesRequest | None = ..., + subscribe_order_book_request: global___SubscribeOrderBookRequest | None = ..., + subscribe_trades_request: global___SubscribeTradesRequest | None = ..., + subscribe_info_request: global___SubscribeInfoRequest | None = ..., + subscribe_last_price_request: global___SubscribeLastPriceRequest | None = ..., + ping_settings: t_tech.invest.grpc.common_pb2.PingDelaySettings | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["ping_settings", b"ping_settings", "subscribe_candles_request", b"subscribe_candles_request", "subscribe_info_request", b"subscribe_info_request", "subscribe_last_price_request", b"subscribe_last_price_request", "subscribe_order_book_request", b"subscribe_order_book_request", "subscribe_trades_request", b"subscribe_trades_request"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["ping_settings", b"ping_settings", "subscribe_candles_request", b"subscribe_candles_request", "subscribe_info_request", b"subscribe_info_request", "subscribe_last_price_request", b"subscribe_last_price_request", "subscribe_order_book_request", b"subscribe_order_book_request", "subscribe_trades_request", b"subscribe_trades_request"]) -> None: ... + +global___MarketDataServerSideStreamRequest = MarketDataServerSideStreamRequest + +@typing.final +class MarketDataResponse(google.protobuf.message.Message): + """Пакет биржевой информации по подписке.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SUBSCRIBE_CANDLES_RESPONSE_FIELD_NUMBER: builtins.int + SUBSCRIBE_ORDER_BOOK_RESPONSE_FIELD_NUMBER: builtins.int + SUBSCRIBE_TRADES_RESPONSE_FIELD_NUMBER: builtins.int + SUBSCRIBE_INFO_RESPONSE_FIELD_NUMBER: builtins.int + CANDLE_FIELD_NUMBER: builtins.int + TRADE_FIELD_NUMBER: builtins.int + ORDERBOOK_FIELD_NUMBER: builtins.int + TRADING_STATUS_FIELD_NUMBER: builtins.int + PING_FIELD_NUMBER: builtins.int + SUBSCRIBE_LAST_PRICE_RESPONSE_FIELD_NUMBER: builtins.int + LAST_PRICE_FIELD_NUMBER: builtins.int + OPEN_INTEREST_FIELD_NUMBER: builtins.int + @property + def subscribe_candles_response(self) -> global___SubscribeCandlesResponse: + """Результат подписки на свечи.""" + + @property + def subscribe_order_book_response(self) -> global___SubscribeOrderBookResponse: + """Результат подписки на стаканы.""" + + @property + def subscribe_trades_response(self) -> global___SubscribeTradesResponse: + """Результат подписки на поток обезличенных сделок.""" + + @property + def subscribe_info_response(self) -> global___SubscribeInfoResponse: + """Результат подписки на торговые статусы инструментов.""" + + @property + def candle(self) -> global___Candle: + """Свеча.""" + + @property + def trade(self) -> global___Trade: + """Сделки.""" + + @property + def orderbook(self) -> global___OrderBook: + """Стакан.""" + + @property + def trading_status(self) -> global___TradingStatus: + """Торговый статус.""" + + @property + def ping(self) -> t_tech.invest.grpc.common_pb2.Ping: + """Проверка активности стрима.""" + + @property + def subscribe_last_price_response(self) -> global___SubscribeLastPriceResponse: + """Результат подписки на цены последние сделок по инструментам.""" + + @property + def last_price(self) -> global___LastPrice: + """Цена последней сделки.""" + + @property + def open_interest(self) -> global___OpenInterest: + """Открытый интерес.""" + + def __init__( + self, + *, + subscribe_candles_response: global___SubscribeCandlesResponse | None = ..., + subscribe_order_book_response: global___SubscribeOrderBookResponse | None = ..., + subscribe_trades_response: global___SubscribeTradesResponse | None = ..., + subscribe_info_response: global___SubscribeInfoResponse | None = ..., + candle: global___Candle | None = ..., + trade: global___Trade | None = ..., + orderbook: global___OrderBook | None = ..., + trading_status: global___TradingStatus | None = ..., + ping: t_tech.invest.grpc.common_pb2.Ping | None = ..., + subscribe_last_price_response: global___SubscribeLastPriceResponse | None = ..., + last_price: global___LastPrice | None = ..., + open_interest: global___OpenInterest | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["candle", b"candle", "last_price", b"last_price", "open_interest", b"open_interest", "orderbook", b"orderbook", "payload", b"payload", "ping", b"ping", "subscribe_candles_response", b"subscribe_candles_response", "subscribe_info_response", b"subscribe_info_response", "subscribe_last_price_response", b"subscribe_last_price_response", "subscribe_order_book_response", b"subscribe_order_book_response", "subscribe_trades_response", b"subscribe_trades_response", "trade", b"trade", "trading_status", b"trading_status"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["candle", b"candle", "last_price", b"last_price", "open_interest", b"open_interest", "orderbook", b"orderbook", "payload", b"payload", "ping", b"ping", "subscribe_candles_response", b"subscribe_candles_response", "subscribe_info_response", b"subscribe_info_response", "subscribe_last_price_response", b"subscribe_last_price_response", "subscribe_order_book_response", b"subscribe_order_book_response", "subscribe_trades_response", b"subscribe_trades_response", "trade", b"trade", "trading_status", b"trading_status"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["payload", b"payload"]) -> typing.Literal["subscribe_candles_response", "subscribe_order_book_response", "subscribe_trades_response", "subscribe_info_response", "candle", "trade", "orderbook", "trading_status", "ping", "subscribe_last_price_response", "last_price", "open_interest"] | None: ... + +global___MarketDataResponse = MarketDataResponse + +@typing.final +class SubscribeCandlesRequest(google.protobuf.message.Message): + """subscribeCandles | Изменения статуса подписки на свечи.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SUBSCRIPTION_ACTION_FIELD_NUMBER: builtins.int + INSTRUMENTS_FIELD_NUMBER: builtins.int + WAITING_CLOSE_FIELD_NUMBER: builtins.int + CANDLE_SOURCE_TYPE_FIELD_NUMBER: builtins.int + subscription_action: global___SubscriptionAction.ValueType + """Изменение статуса подписки.""" + waiting_close: builtins.bool + """Флаг ожидания закрытия временного интервала для отправки свечи.""" + candle_source_type: global___GetCandlesRequest.CandleSource.ValueType + """Источник свечей.""" + @property + def instruments(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___CandleInstrument]: + """Массив инструментов для подписки на свечи.""" + + def __init__( + self, + *, + subscription_action: global___SubscriptionAction.ValueType = ..., + instruments: collections.abc.Iterable[global___CandleInstrument] | None = ..., + waiting_close: builtins.bool = ..., + candle_source_type: global___GetCandlesRequest.CandleSource.ValueType | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_candle_source_type", b"_candle_source_type", "candle_source_type", b"candle_source_type"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_candle_source_type", b"_candle_source_type", "candle_source_type", b"candle_source_type", "instruments", b"instruments", "subscription_action", b"subscription_action", "waiting_close", b"waiting_close"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_candle_source_type", b"_candle_source_type"]) -> typing.Literal["candle_source_type"] | None: ... + +global___SubscribeCandlesRequest = SubscribeCandlesRequest + +@typing.final +class CandleInstrument(google.protobuf.message.Message): + """Запрос изменения статус подписки на свечи.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + INTERVAL_FIELD_NUMBER: builtins.int + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + figi: builtins.str + """Deprecated FIGI-идентификатор инструмента. Используйте `instrument_id`.""" + interval: global___SubscriptionInterval.ValueType + """Интервал свечей. Двухчасовые и четырехчасовые свечи в стриме отсчитываются с 0:00 по UTC.""" + instrument_id: builtins.str + """Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`.""" + def __init__( + self, + *, + figi: builtins.str = ..., + interval: global___SubscriptionInterval.ValueType = ..., + instrument_id: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["figi", b"figi", "instrument_id", b"instrument_id", "interval", b"interval"]) -> None: ... + +global___CandleInstrument = CandleInstrument + +@typing.final +class SubscribeCandlesResponse(google.protobuf.message.Message): + """Результат изменения статус подписки на свечи.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TRACKING_ID_FIELD_NUMBER: builtins.int + CANDLES_SUBSCRIPTIONS_FIELD_NUMBER: builtins.int + tracking_id: builtins.str + """Уникальный идентификатор запроса. [Подробнее](./grpc#tracking-id).""" + @property + def candles_subscriptions(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___CandleSubscription]: + """Массив статусов подписки на свечи.""" + + def __init__( + self, + *, + tracking_id: builtins.str = ..., + candles_subscriptions: collections.abc.Iterable[global___CandleSubscription] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["candles_subscriptions", b"candles_subscriptions", "tracking_id", b"tracking_id"]) -> None: ... + +global___SubscribeCandlesResponse = SubscribeCandlesResponse + +@typing.final +class CandleSubscription(google.protobuf.message.Message): + """Статус подписки на свечи.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + INTERVAL_FIELD_NUMBER: builtins.int + SUBSCRIPTION_STATUS_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + WAITING_CLOSE_FIELD_NUMBER: builtins.int + STREAM_ID_FIELD_NUMBER: builtins.int + SUBSCRIPTION_ID_FIELD_NUMBER: builtins.int + SUBSCRIPTION_ACTION_FIELD_NUMBER: builtins.int + CANDLE_SOURCE_TYPE_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI-идентификатор инструмента.""" + interval: global___SubscriptionInterval.ValueType + """Интервал свечей.""" + subscription_status: global___SubscriptionStatus.ValueType + """Статус подписки.""" + instrument_uid: builtins.str + """UID инструмента.""" + waiting_close: builtins.bool + """Флаг ожидания закрытия временного интервала для отправки свечи.""" + stream_id: builtins.str + """Идентификатор открытого соединения.""" + subscription_id: builtins.str + """Идентификатор подписки в формате `UUID`.""" + subscription_action: global___SubscriptionAction.ValueType + """Действие подписки.""" + candle_source_type: global___GetCandlesRequest.CandleSource.ValueType + """Источник свечей.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + def __init__( + self, + *, + figi: builtins.str = ..., + interval: global___SubscriptionInterval.ValueType = ..., + subscription_status: global___SubscriptionStatus.ValueType = ..., + instrument_uid: builtins.str = ..., + waiting_close: builtins.bool = ..., + stream_id: builtins.str = ..., + subscription_id: builtins.str = ..., + subscription_action: global___SubscriptionAction.ValueType = ..., + candle_source_type: global___GetCandlesRequest.CandleSource.ValueType | None = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_candle_source_type", b"_candle_source_type", "candle_source_type", b"candle_source_type"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_candle_source_type", b"_candle_source_type", "candle_source_type", b"candle_source_type", "class_code", b"class_code", "figi", b"figi", "instrument_uid", b"instrument_uid", "interval", b"interval", "stream_id", b"stream_id", "subscription_action", b"subscription_action", "subscription_id", b"subscription_id", "subscription_status", b"subscription_status", "ticker", b"ticker", "waiting_close", b"waiting_close"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_candle_source_type", b"_candle_source_type"]) -> typing.Literal["candle_source_type"] | None: ... + +global___CandleSubscription = CandleSubscription + +@typing.final +class SubscribeOrderBookRequest(google.protobuf.message.Message): + """Запрос на изменение статуса подписки на стаканы.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SUBSCRIPTION_ACTION_FIELD_NUMBER: builtins.int + INSTRUMENTS_FIELD_NUMBER: builtins.int + subscription_action: global___SubscriptionAction.ValueType + """Изменение статуса подписки.""" + @property + def instruments(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___OrderBookInstrument]: + """Массив инструментов для подписки на стаканы.""" + + def __init__( + self, + *, + subscription_action: global___SubscriptionAction.ValueType = ..., + instruments: collections.abc.Iterable[global___OrderBookInstrument] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["instruments", b"instruments", "subscription_action", b"subscription_action"]) -> None: ... + +global___SubscribeOrderBookRequest = SubscribeOrderBookRequest + +@typing.final +class OrderBookInstrument(google.protobuf.message.Message): + """Запрос подписки на стаканы.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + DEPTH_FIELD_NUMBER: builtins.int + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + ORDER_BOOK_TYPE_FIELD_NUMBER: builtins.int + figi: builtins.str + """Deprecated FIGI-идентификатор инструмента. Используйте `instrument_id`.""" + depth: builtins.int + """Глубина стакана.""" + instrument_id: builtins.str + """Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`.""" + order_book_type: global___OrderBookType.ValueType + """Тип стакана. Значение по умолчанию — `ORDERBOOK_TYPE_ALL`, стакан биржевой и дилера.""" + def __init__( + self, + *, + figi: builtins.str = ..., + depth: builtins.int = ..., + instrument_id: builtins.str = ..., + order_book_type: global___OrderBookType.ValueType = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["depth", b"depth", "figi", b"figi", "instrument_id", b"instrument_id", "order_book_type", b"order_book_type"]) -> None: ... + +global___OrderBookInstrument = OrderBookInstrument + +@typing.final +class SubscribeOrderBookResponse(google.protobuf.message.Message): + """Результат изменения статуса подписки на стаканы.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TRACKING_ID_FIELD_NUMBER: builtins.int + ORDER_BOOK_SUBSCRIPTIONS_FIELD_NUMBER: builtins.int + tracking_id: builtins.str + """Уникальный идентификатор запроса. [Подробнее](./grpc#tracking-id).""" + @property + def order_book_subscriptions(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___OrderBookSubscription]: + """Массив статусов подписки на стаканы.""" + + def __init__( + self, + *, + tracking_id: builtins.str = ..., + order_book_subscriptions: collections.abc.Iterable[global___OrderBookSubscription] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["order_book_subscriptions", b"order_book_subscriptions", "tracking_id", b"tracking_id"]) -> None: ... + +global___SubscribeOrderBookResponse = SubscribeOrderBookResponse + +@typing.final +class OrderBookSubscription(google.protobuf.message.Message): + """Статус подписки.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + DEPTH_FIELD_NUMBER: builtins.int + SUBSCRIPTION_STATUS_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + STREAM_ID_FIELD_NUMBER: builtins.int + SUBSCRIPTION_ID_FIELD_NUMBER: builtins.int + ORDER_BOOK_TYPE_FIELD_NUMBER: builtins.int + SUBSCRIPTION_ACTION_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI-идентификатор инструмента.""" + depth: builtins.int + """Глубина стакана.""" + subscription_status: global___SubscriptionStatus.ValueType + """Статус подписки.""" + instrument_uid: builtins.str + """UID инструмента.""" + stream_id: builtins.str + """Идентификатор открытого соединения.""" + subscription_id: builtins.str + """Идентификатор подписки в формате `UUID`.""" + order_book_type: global___OrderBookType.ValueType + """Тип стакана.""" + subscription_action: global___SubscriptionAction.ValueType + """Действие подписки.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + def __init__( + self, + *, + figi: builtins.str = ..., + depth: builtins.int = ..., + subscription_status: global___SubscriptionStatus.ValueType = ..., + instrument_uid: builtins.str = ..., + stream_id: builtins.str = ..., + subscription_id: builtins.str = ..., + order_book_type: global___OrderBookType.ValueType = ..., + subscription_action: global___SubscriptionAction.ValueType = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["class_code", b"class_code", "depth", b"depth", "figi", b"figi", "instrument_uid", b"instrument_uid", "order_book_type", b"order_book_type", "stream_id", b"stream_id", "subscription_action", b"subscription_action", "subscription_id", b"subscription_id", "subscription_status", b"subscription_status", "ticker", b"ticker"]) -> None: ... + +global___OrderBookSubscription = OrderBookSubscription + +@typing.final +class SubscribeTradesRequest(google.protobuf.message.Message): + """Изменение статуса подписки на поток обезличенных сделок.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SUBSCRIPTION_ACTION_FIELD_NUMBER: builtins.int + INSTRUMENTS_FIELD_NUMBER: builtins.int + TRADE_SOURCE_FIELD_NUMBER: builtins.int + WITH_OPEN_INTEREST_FIELD_NUMBER: builtins.int + subscription_action: global___SubscriptionAction.ValueType + """Изменение статуса подписки.""" + trade_source: global___TradeSourceType.ValueType + """Тип источника сделок. Значение по умолчанию — `TRADE_SOURCE_ALL`, все сделки.""" + with_open_interest: builtins.bool + """Флаг открытого интереса. **true** - в стриме дополнительно передается информация об открытом интересе для фьючерсов""" + @property + def instruments(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___TradeInstrument]: + """Массив инструментов для подписки на поток обезличенных сделок.""" + + def __init__( + self, + *, + subscription_action: global___SubscriptionAction.ValueType = ..., + instruments: collections.abc.Iterable[global___TradeInstrument] | None = ..., + trade_source: global___TradeSourceType.ValueType = ..., + with_open_interest: builtins.bool = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["instruments", b"instruments", "subscription_action", b"subscription_action", "trade_source", b"trade_source", "with_open_interest", b"with_open_interest"]) -> None: ... + +global___SubscribeTradesRequest = SubscribeTradesRequest + +@typing.final +class TradeInstrument(google.protobuf.message.Message): + """Запрос подписки на поток обезличенных сделок.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + figi: builtins.str + """Deprecated FIGI-идентификатор инструмента. Используйте instrument_id`.""" + instrument_id: builtins.str + """Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`.""" + def __init__( + self, + *, + figi: builtins.str = ..., + instrument_id: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["figi", b"figi", "instrument_id", b"instrument_id"]) -> None: ... + +global___TradeInstrument = TradeInstrument + +@typing.final +class SubscribeTradesResponse(google.protobuf.message.Message): + """Результат изменения статуса подписки на поток обезличенных сделок.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TRACKING_ID_FIELD_NUMBER: builtins.int + TRADE_SUBSCRIPTIONS_FIELD_NUMBER: builtins.int + TRADE_SOURCE_FIELD_NUMBER: builtins.int + tracking_id: builtins.str + """Уникальный идентификатор запроса. [Подробнее](./grpc#tracking-id).""" + trade_source: global___TradeSourceType.ValueType + """Тип источника сделок.""" + @property + def trade_subscriptions(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___TradeSubscription]: + """Массив статусов подписки на поток сделок.""" + + def __init__( + self, + *, + tracking_id: builtins.str = ..., + trade_subscriptions: collections.abc.Iterable[global___TradeSubscription] | None = ..., + trade_source: global___TradeSourceType.ValueType = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["tracking_id", b"tracking_id", "trade_source", b"trade_source", "trade_subscriptions", b"trade_subscriptions"]) -> None: ... + +global___SubscribeTradesResponse = SubscribeTradesResponse + +@typing.final +class TradeSubscription(google.protobuf.message.Message): + """Статус подписки.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + SUBSCRIPTION_STATUS_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + STREAM_ID_FIELD_NUMBER: builtins.int + SUBSCRIPTION_ID_FIELD_NUMBER: builtins.int + WITH_OPEN_INTEREST_FIELD_NUMBER: builtins.int + SUBSCRIPTION_ACTION_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI-идентификатор инструмента.""" + subscription_status: global___SubscriptionStatus.ValueType + """Статус подписки.""" + instrument_uid: builtins.str + """UID инструмента.""" + stream_id: builtins.str + """Идентификатор открытого соединения.""" + subscription_id: builtins.str + """Идентификатор подписки в формате UUID.""" + with_open_interest: builtins.bool + """Флаг открытого интереса. **true** - в стриме дополнительно передается информация об открытом интересе для фьючерсов""" + subscription_action: global___SubscriptionAction.ValueType + """Действие подписки.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + def __init__( + self, + *, + figi: builtins.str = ..., + subscription_status: global___SubscriptionStatus.ValueType = ..., + instrument_uid: builtins.str = ..., + stream_id: builtins.str = ..., + subscription_id: builtins.str = ..., + with_open_interest: builtins.bool = ..., + subscription_action: global___SubscriptionAction.ValueType = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["class_code", b"class_code", "figi", b"figi", "instrument_uid", b"instrument_uid", "stream_id", b"stream_id", "subscription_action", b"subscription_action", "subscription_id", b"subscription_id", "subscription_status", b"subscription_status", "ticker", b"ticker", "with_open_interest", b"with_open_interest"]) -> None: ... + +global___TradeSubscription = TradeSubscription + +@typing.final +class SubscribeInfoRequest(google.protobuf.message.Message): + """Изменение статуса подписки на торговый статус инструмента.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SUBSCRIPTION_ACTION_FIELD_NUMBER: builtins.int + INSTRUMENTS_FIELD_NUMBER: builtins.int + subscription_action: global___SubscriptionAction.ValueType + """Изменение статуса подписки.""" + @property + def instruments(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___InfoInstrument]: + """Массив инструментов для подписки на торговый статус.""" + + def __init__( + self, + *, + subscription_action: global___SubscriptionAction.ValueType = ..., + instruments: collections.abc.Iterable[global___InfoInstrument] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["instruments", b"instruments", "subscription_action", b"subscription_action"]) -> None: ... + +global___SubscribeInfoRequest = SubscribeInfoRequest + +@typing.final +class InfoInstrument(google.protobuf.message.Message): + """Запрос подписки на торговый статус.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + figi: builtins.str + """Deprecated FIGI-идентификатор инструмента. Используйте instrument_id`.""" + instrument_id: builtins.str + """Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`.""" + def __init__( + self, + *, + figi: builtins.str = ..., + instrument_id: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["figi", b"figi", "instrument_id", b"instrument_id"]) -> None: ... + +global___InfoInstrument = InfoInstrument + +@typing.final +class SubscribeInfoResponse(google.protobuf.message.Message): + """Результат изменения статуса подписки на торговый статус.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TRACKING_ID_FIELD_NUMBER: builtins.int + INFO_SUBSCRIPTIONS_FIELD_NUMBER: builtins.int + tracking_id: builtins.str + """Уникальный идентификатор запроса. [Подробнее](./grpc#tracking-id).""" + @property + def info_subscriptions(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___InfoSubscription]: + """Массив статусов подписки на торговый статус.""" + + def __init__( + self, + *, + tracking_id: builtins.str = ..., + info_subscriptions: collections.abc.Iterable[global___InfoSubscription] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["info_subscriptions", b"info_subscriptions", "tracking_id", b"tracking_id"]) -> None: ... + +global___SubscribeInfoResponse = SubscribeInfoResponse + +@typing.final +class InfoSubscription(google.protobuf.message.Message): + """Статус подписки.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + SUBSCRIPTION_STATUS_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + STREAM_ID_FIELD_NUMBER: builtins.int + SUBSCRIPTION_ID_FIELD_NUMBER: builtins.int + SUBSCRIPTION_ACTION_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI-идентификатор инструмента.""" + subscription_status: global___SubscriptionStatus.ValueType + """Статус подписки.""" + instrument_uid: builtins.str + """UID инструмента.""" + stream_id: builtins.str + """Идентификатор открытого соединения.""" + subscription_id: builtins.str + """Идентификатор подписки в формате UUID.""" + subscription_action: global___SubscriptionAction.ValueType + """Действие подписки.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + def __init__( + self, + *, + figi: builtins.str = ..., + subscription_status: global___SubscriptionStatus.ValueType = ..., + instrument_uid: builtins.str = ..., + stream_id: builtins.str = ..., + subscription_id: builtins.str = ..., + subscription_action: global___SubscriptionAction.ValueType = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["class_code", b"class_code", "figi", b"figi", "instrument_uid", b"instrument_uid", "stream_id", b"stream_id", "subscription_action", b"subscription_action", "subscription_id", b"subscription_id", "subscription_status", b"subscription_status", "ticker", b"ticker"]) -> None: ... + +global___InfoSubscription = InfoSubscription + +@typing.final +class SubscribeLastPriceRequest(google.protobuf.message.Message): + """Изменение статуса подписки на цену последней сделки по инструменту.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SUBSCRIPTION_ACTION_FIELD_NUMBER: builtins.int + INSTRUMENTS_FIELD_NUMBER: builtins.int + subscription_action: global___SubscriptionAction.ValueType + """Изменение статуса подписки.""" + @property + def instruments(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___LastPriceInstrument]: + """Массив инструментов для подписки на цену последней сделки.""" + + def __init__( + self, + *, + subscription_action: global___SubscriptionAction.ValueType = ..., + instruments: collections.abc.Iterable[global___LastPriceInstrument] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["instruments", b"instruments", "subscription_action", b"subscription_action"]) -> None: ... + +global___SubscribeLastPriceRequest = SubscribeLastPriceRequest + +@typing.final +class LastPriceInstrument(google.protobuf.message.Message): + """Запрос подписки на последнюю цену.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + figi: builtins.str + """Deprecated FIGI-идентификатор инструмента. Используйте instrument_id`.""" + instrument_id: builtins.str + """Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`.""" + def __init__( + self, + *, + figi: builtins.str = ..., + instrument_id: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["figi", b"figi", "instrument_id", b"instrument_id"]) -> None: ... + +global___LastPriceInstrument = LastPriceInstrument + +@typing.final +class SubscribeLastPriceResponse(google.protobuf.message.Message): + """Результат изменения статуса подписки на цену последней сделки.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TRACKING_ID_FIELD_NUMBER: builtins.int + LAST_PRICE_SUBSCRIPTIONS_FIELD_NUMBER: builtins.int + tracking_id: builtins.str + """Уникальный идентификатор запроса. [Подробнее](./grpc#tracking-id).""" + @property + def last_price_subscriptions(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___LastPriceSubscription]: + """Массив статусов подписки на цену последней сделки.""" + + def __init__( + self, + *, + tracking_id: builtins.str = ..., + last_price_subscriptions: collections.abc.Iterable[global___LastPriceSubscription] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["last_price_subscriptions", b"last_price_subscriptions", "tracking_id", b"tracking_id"]) -> None: ... + +global___SubscribeLastPriceResponse = SubscribeLastPriceResponse + +@typing.final +class LastPriceSubscription(google.protobuf.message.Message): + """Статус подписки на цену последней сделки.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + SUBSCRIPTION_STATUS_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + STREAM_ID_FIELD_NUMBER: builtins.int + SUBSCRIPTION_ID_FIELD_NUMBER: builtins.int + SUBSCRIPTION_ACTION_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI-идентификатор инструмента.""" + subscription_status: global___SubscriptionStatus.ValueType + """Статус подписки.""" + instrument_uid: builtins.str + """UID инструмента.""" + stream_id: builtins.str + """Идентификатор открытого соединения.""" + subscription_id: builtins.str + """Идентификатор подписки в формате `UUID`.""" + subscription_action: global___SubscriptionAction.ValueType + """Действие подписки.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + def __init__( + self, + *, + figi: builtins.str = ..., + subscription_status: global___SubscriptionStatus.ValueType = ..., + instrument_uid: builtins.str = ..., + stream_id: builtins.str = ..., + subscription_id: builtins.str = ..., + subscription_action: global___SubscriptionAction.ValueType = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["class_code", b"class_code", "figi", b"figi", "instrument_uid", b"instrument_uid", "stream_id", b"stream_id", "subscription_action", b"subscription_action", "subscription_id", b"subscription_id", "subscription_status", b"subscription_status", "ticker", b"ticker"]) -> None: ... + +global___LastPriceSubscription = LastPriceSubscription + +@typing.final +class Candle(google.protobuf.message.Message): + """Пакет свечей в рамках стрима.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + INTERVAL_FIELD_NUMBER: builtins.int + OPEN_FIELD_NUMBER: builtins.int + HIGH_FIELD_NUMBER: builtins.int + LOW_FIELD_NUMBER: builtins.int + CLOSE_FIELD_NUMBER: builtins.int + VOLUME_FIELD_NUMBER: builtins.int + TIME_FIELD_NUMBER: builtins.int + LAST_TRADE_TS_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + VOLUME_BUY_FIELD_NUMBER: builtins.int + VOLUME_SELL_FIELD_NUMBER: builtins.int + CANDLE_SOURCE_TYPE_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI-идентификатор инструмента.""" + interval: global___SubscriptionInterval.ValueType + """Интервал свечи.""" + volume: builtins.int + """Объем сделок в лотах.""" + instrument_uid: builtins.str + """UID инструмента.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + volume_buy: builtins.int + """Объем торгов на покупку.""" + volume_sell: builtins.int + """Объём торгов на продажу.""" + candle_source_type: global___CandleSource.ValueType + """Источник свечей.""" + @property + def open(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Цена открытия за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15).""" + + @property + def high(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Максимальная цена за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15).""" + + @property + def low(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Минимальная цена за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15).""" + + @property + def close(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Цена закрытия за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15).""" + + @property + def time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время начала интервала свечи по UTC.""" + + @property + def last_trade_ts(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время последней сделки, вошедшей в свечу по UTC.""" + + def __init__( + self, + *, + figi: builtins.str = ..., + interval: global___SubscriptionInterval.ValueType = ..., + open: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + high: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + low: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + close: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + volume: builtins.int = ..., + time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + last_trade_ts: google.protobuf.timestamp_pb2.Timestamp | None = ..., + instrument_uid: builtins.str = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + volume_buy: builtins.int = ..., + volume_sell: builtins.int = ..., + candle_source_type: global___CandleSource.ValueType = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["close", b"close", "high", b"high", "last_trade_ts", b"last_trade_ts", "low", b"low", "open", b"open", "time", b"time"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["candle_source_type", b"candle_source_type", "class_code", b"class_code", "close", b"close", "figi", b"figi", "high", b"high", "instrument_uid", b"instrument_uid", "interval", b"interval", "last_trade_ts", b"last_trade_ts", "low", b"low", "open", b"open", "ticker", b"ticker", "time", b"time", "volume", b"volume", "volume_buy", b"volume_buy", "volume_sell", b"volume_sell"]) -> None: ... + +global___Candle = Candle + +@typing.final +class OrderBook(google.protobuf.message.Message): + """Пакет стаканов в рамках стрима.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + DEPTH_FIELD_NUMBER: builtins.int + IS_CONSISTENT_FIELD_NUMBER: builtins.int + BIDS_FIELD_NUMBER: builtins.int + ASKS_FIELD_NUMBER: builtins.int + TIME_FIELD_NUMBER: builtins.int + LIMIT_UP_FIELD_NUMBER: builtins.int + LIMIT_DOWN_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + ORDER_BOOK_TYPE_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI-идентификатор инструмента.""" + depth: builtins.int + """Глубина стакана.""" + is_consistent: builtins.bool + """Флаг консистентности стакана. **false** — не все заявки попали в стакан из-за сетевых задержек или нарушения порядка доставки.""" + instrument_uid: builtins.str + """UID инструмента.""" + order_book_type: global___OrderBookType.ValueType + """Тип стакана.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + @property + def bids(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Order]: + """Массив предложений.""" + + @property + def asks(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Order]: + """Массив спроса.""" + + @property + def time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время формирования стакана в часовом поясе UTC по времени биржи.""" + + @property + def limit_up(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Верхний лимит цены за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15).""" + + @property + def limit_down(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Нижний лимит цены за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15).""" + + def __init__( + self, + *, + figi: builtins.str = ..., + depth: builtins.int = ..., + is_consistent: builtins.bool = ..., + bids: collections.abc.Iterable[global___Order] | None = ..., + asks: collections.abc.Iterable[global___Order] | None = ..., + time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + limit_up: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + limit_down: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + instrument_uid: builtins.str = ..., + order_book_type: global___OrderBookType.ValueType = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["limit_down", b"limit_down", "limit_up", b"limit_up", "time", b"time"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["asks", b"asks", "bids", b"bids", "class_code", b"class_code", "depth", b"depth", "figi", b"figi", "instrument_uid", b"instrument_uid", "is_consistent", b"is_consistent", "limit_down", b"limit_down", "limit_up", b"limit_up", "order_book_type", b"order_book_type", "ticker", b"ticker", "time", b"time"]) -> None: ... + +global___OrderBook = OrderBook + +@typing.final +class Order(google.protobuf.message.Message): + """Массив предложений/спроса.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PRICE_FIELD_NUMBER: builtins.int + QUANTITY_FIELD_NUMBER: builtins.int + quantity: builtins.int + """Количество в лотах.""" + @property + def price(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Цена за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15).""" + + def __init__( + self, + *, + price: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + quantity: builtins.int = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["price", b"price"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["price", b"price", "quantity", b"quantity"]) -> None: ... + +global___Order = Order + +@typing.final +class Trade(google.protobuf.message.Message): + """Информация о сделке.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + DIRECTION_FIELD_NUMBER: builtins.int + PRICE_FIELD_NUMBER: builtins.int + QUANTITY_FIELD_NUMBER: builtins.int + TIME_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + TRADE_SOURCE_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI-идентификатор инструмента.""" + direction: global___TradeDirection.ValueType + """Направление сделки.""" + quantity: builtins.int + """Количество лотов.""" + instrument_uid: builtins.str + """UID инструмента.""" + trade_source: global___TradeSourceType.ValueType + """Тип источника сделки.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + @property + def price(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Цена за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15).""" + + @property + def time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время сделки в часовом поясе UTC по времени биржи.""" + + def __init__( + self, + *, + figi: builtins.str = ..., + direction: global___TradeDirection.ValueType = ..., + price: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + quantity: builtins.int = ..., + time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + instrument_uid: builtins.str = ..., + trade_source: global___TradeSourceType.ValueType = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["price", b"price", "time", b"time"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["class_code", b"class_code", "direction", b"direction", "figi", b"figi", "instrument_uid", b"instrument_uid", "price", b"price", "quantity", b"quantity", "ticker", b"ticker", "time", b"time", "trade_source", b"trade_source"]) -> None: ... + +global___Trade = Trade + +@typing.final +class TradingStatus(google.protobuf.message.Message): + """Пакет изменения торгового статуса.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + TRADING_STATUS_FIELD_NUMBER: builtins.int + TIME_FIELD_NUMBER: builtins.int + LIMIT_ORDER_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + MARKET_ORDER_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI-идентификатор инструмента.""" + trading_status: t_tech.invest.grpc.common_pb2.SecurityTradingStatus.ValueType + """Статус торговли инструментом.""" + limit_order_available_flag: builtins.bool + """Признак доступности выставления лимитной заявки по инструменту.""" + market_order_available_flag: builtins.bool + """Признак доступности выставления рыночной заявки по инструменту.""" + instrument_uid: builtins.str + """UID инструмента.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + @property + def time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время изменения торгового статуса по UTC.""" + + def __init__( + self, + *, + figi: builtins.str = ..., + trading_status: t_tech.invest.grpc.common_pb2.SecurityTradingStatus.ValueType = ..., + time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + limit_order_available_flag: builtins.bool = ..., + market_order_available_flag: builtins.bool = ..., + instrument_uid: builtins.str = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["time", b"time"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["class_code", b"class_code", "figi", b"figi", "instrument_uid", b"instrument_uid", "limit_order_available_flag", b"limit_order_available_flag", "market_order_available_flag", b"market_order_available_flag", "ticker", b"ticker", "time", b"time", "trading_status", b"trading_status"]) -> None: ... + +global___TradingStatus = TradingStatus + +@typing.final +class GetCandlesRequest(google.protobuf.message.Message): + """Запрос исторических свечей.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _CandleSource: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _CandleSourceEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[GetCandlesRequest._CandleSource.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + CANDLE_SOURCE_UNSPECIFIED: GetCandlesRequest._CandleSource.ValueType # 0 + """Все свечи.""" + CANDLE_SOURCE_EXCHANGE: GetCandlesRequest._CandleSource.ValueType # 1 + """Биржевые свечи.""" + CANDLE_SOURCE_INCLUDE_WEEKEND: GetCandlesRequest._CandleSource.ValueType # 3 + """Все свечи с учетом торговли по выходным.""" + + class CandleSource(_CandleSource, metaclass=_CandleSourceEnumTypeWrapper): ... + CANDLE_SOURCE_UNSPECIFIED: GetCandlesRequest.CandleSource.ValueType # 0 + """Все свечи.""" + CANDLE_SOURCE_EXCHANGE: GetCandlesRequest.CandleSource.ValueType # 1 + """Биржевые свечи.""" + CANDLE_SOURCE_INCLUDE_WEEKEND: GetCandlesRequest.CandleSource.ValueType # 3 + """Все свечи с учетом торговли по выходным.""" + + FIGI_FIELD_NUMBER: builtins.int + FROM_FIELD_NUMBER: builtins.int + TO_FIELD_NUMBER: builtins.int + INTERVAL_FIELD_NUMBER: builtins.int + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + CANDLE_SOURCE_TYPE_FIELD_NUMBER: builtins.int + LIMIT_FIELD_NUMBER: builtins.int + figi: builtins.str + """Deprecated FIGI-идентификатор инструмента. Используйте `instrument_id`.""" + interval: global___CandleInterval.ValueType + """Интервал запрошенных свечей.""" + instrument_id: builtins.str + """Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`.""" + candle_source_type: global___GetCandlesRequest.CandleSource.ValueType + """Тип источника свечи.""" + limit: builtins.int + """Максимальное количество свечей в ответе.""" + @property + def to(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Окончание запрашиваемого периода по UTC.""" + + def __init__( + self, + *, + figi: builtins.str | None = ..., + to: google.protobuf.timestamp_pb2.Timestamp | None = ..., + interval: global___CandleInterval.ValueType = ..., + instrument_id: builtins.str | None = ..., + candle_source_type: global___GetCandlesRequest.CandleSource.ValueType | None = ..., + limit: builtins.int | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_candle_source_type", b"_candle_source_type", "_figi", b"_figi", "_instrument_id", b"_instrument_id", "_limit", b"_limit", "candle_source_type", b"candle_source_type", "figi", b"figi", "from", b"from", "instrument_id", b"instrument_id", "limit", b"limit", "to", b"to"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_candle_source_type", b"_candle_source_type", "_figi", b"_figi", "_instrument_id", b"_instrument_id", "_limit", b"_limit", "candle_source_type", b"candle_source_type", "figi", b"figi", "from", b"from", "instrument_id", b"instrument_id", "interval", b"interval", "limit", b"limit", "to", b"to"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_candle_source_type", b"_candle_source_type"]) -> typing.Literal["candle_source_type"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_figi", b"_figi"]) -> typing.Literal["figi"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_instrument_id", b"_instrument_id"]) -> typing.Literal["instrument_id"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_limit", b"_limit"]) -> typing.Literal["limit"] | None: ... + +global___GetCandlesRequest = GetCandlesRequest + +@typing.final +class GetCandlesResponse(google.protobuf.message.Message): + """Список свечей.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + CANDLES_FIELD_NUMBER: builtins.int + @property + def candles(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___HistoricCandle]: + """Массив свечей.""" + + def __init__( + self, + *, + candles: collections.abc.Iterable[global___HistoricCandle] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["candles", b"candles"]) -> None: ... + +global___GetCandlesResponse = GetCandlesResponse + +@typing.final +class HistoricCandle(google.protobuf.message.Message): + """Информация о свече.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + OPEN_FIELD_NUMBER: builtins.int + HIGH_FIELD_NUMBER: builtins.int + LOW_FIELD_NUMBER: builtins.int + CLOSE_FIELD_NUMBER: builtins.int + VOLUME_FIELD_NUMBER: builtins.int + TIME_FIELD_NUMBER: builtins.int + IS_COMPLETE_FIELD_NUMBER: builtins.int + CANDLE_SOURCE_FIELD_NUMBER: builtins.int + VOLUME_BUY_FIELD_NUMBER: builtins.int + VOLUME_SELL_FIELD_NUMBER: builtins.int + volume: builtins.int + """Объем торгов в лотах.""" + is_complete: builtins.bool + """Признак завершенности свечи. **false** — свеча за текущие интервал еще сформирована не полностью.""" + candle_source: global___CandleSource.ValueType + """Тип источника свечи""" + volume_buy: builtins.int + """Объем торгов на покупку.""" + volume_sell: builtins.int + """Объём торгов на продажу.""" + @property + def open(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Цена открытия за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15).""" + + @property + def high(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Максимальная цена за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15).""" + + @property + def low(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Минимальная цена за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15).""" + + @property + def close(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Цена закрытия за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15).""" + + @property + def time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время свечи в часовом поясе UTC.""" + + def __init__( + self, + *, + open: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + high: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + low: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + close: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + volume: builtins.int = ..., + time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + is_complete: builtins.bool = ..., + candle_source: global___CandleSource.ValueType = ..., + volume_buy: builtins.int = ..., + volume_sell: builtins.int = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["close", b"close", "high", b"high", "low", b"low", "open", b"open", "time", b"time"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["candle_source", b"candle_source", "close", b"close", "high", b"high", "is_complete", b"is_complete", "low", b"low", "open", b"open", "time", b"time", "volume", b"volume", "volume_buy", b"volume_buy", "volume_sell", b"volume_sell"]) -> None: ... + +global___HistoricCandle = HistoricCandle + +@typing.final +class GetLastPricesRequest(google.protobuf.message.Message): + """Запрос получения цен последних сделок.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + LAST_PRICE_TYPE_FIELD_NUMBER: builtins.int + INSTRUMENT_STATUS_FIELD_NUMBER: builtins.int + last_price_type: global___LastPriceType.ValueType + """Тип запрашиваемой последней цены.""" + instrument_status: t_tech.invest.grpc.common_pb2.InstrumentStatus.ValueType + """Статус запрашиваемых инструментов. [Возможные значения](#instrumentstatus).""" + @property + def figi(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Deprecated FIGI-идентификатор инструмента. Используйте `instrument_id`.""" + + @property + def instrument_id(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Массив идентификаторов инструмента. Принимает значения `figi`, `instrument_uid` или `ticker + '_' + class_code`.""" + + def __init__( + self, + *, + figi: collections.abc.Iterable[builtins.str] | None = ..., + instrument_id: collections.abc.Iterable[builtins.str] | None = ..., + last_price_type: global___LastPriceType.ValueType = ..., + instrument_status: t_tech.invest.grpc.common_pb2.InstrumentStatus.ValueType | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_instrument_status", b"_instrument_status", "instrument_status", b"instrument_status"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_instrument_status", b"_instrument_status", "figi", b"figi", "instrument_id", b"instrument_id", "instrument_status", b"instrument_status", "last_price_type", b"last_price_type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_instrument_status", b"_instrument_status"]) -> typing.Literal["instrument_status"] | None: ... + +global___GetLastPricesRequest = GetLastPricesRequest + +@typing.final +class GetLastPricesResponse(google.protobuf.message.Message): + """Список цен последних сделок.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + LAST_PRICES_FIELD_NUMBER: builtins.int + @property + def last_prices(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___LastPrice]: + """Массив цен последних сделок.""" + + def __init__( + self, + *, + last_prices: collections.abc.Iterable[global___LastPrice] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["last_prices", b"last_prices"]) -> None: ... + +global___GetLastPricesResponse = GetLastPricesResponse + +@typing.final +class LastPrice(google.protobuf.message.Message): + """Информация о цене последней сделки.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + PRICE_FIELD_NUMBER: builtins.int + TIME_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + LAST_PRICE_TYPE_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI инструмента.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + instrument_uid: builtins.str + """UID инструмента.""" + last_price_type: global___LastPriceType.ValueType + """Тип последней цены.""" + @property + def price(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Цена последней сделки за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15).""" + + @property + def time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время получения последней цены в часовом поясе UTC по времени биржи.""" + + def __init__( + self, + *, + figi: builtins.str = ..., + price: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + instrument_uid: builtins.str = ..., + last_price_type: global___LastPriceType.ValueType = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["price", b"price", "time", b"time"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["class_code", b"class_code", "figi", b"figi", "instrument_uid", b"instrument_uid", "last_price_type", b"last_price_type", "price", b"price", "ticker", b"ticker", "time", b"time"]) -> None: ... + +global___LastPrice = LastPrice + +@typing.final +class OpenInterest(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + TIME_FIELD_NUMBER: builtins.int + OPEN_INTEREST_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + instrument_uid: builtins.str + """UID инструмента.""" + open_interest: builtins.int + """Открытый интерес.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + @property + def time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время получения открытого интереса в часовом поясе UTC по времени биржи.""" + + def __init__( + self, + *, + instrument_uid: builtins.str = ..., + time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + open_interest: builtins.int = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["time", b"time"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["class_code", b"class_code", "instrument_uid", b"instrument_uid", "open_interest", b"open_interest", "ticker", b"ticker", "time", b"time"]) -> None: ... + +global___OpenInterest = OpenInterest + +@typing.final +class GetOrderBookRequest(google.protobuf.message.Message): + """Запрос стакана.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + DEPTH_FIELD_NUMBER: builtins.int + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + figi: builtins.str + """Deprecated FIGI-идентификатор инструмента. Используйте `instrument_id`.""" + depth: builtins.int + """Глубина стакана.""" + instrument_id: builtins.str + """Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`.""" + def __init__( + self, + *, + figi: builtins.str | None = ..., + depth: builtins.int = ..., + instrument_id: builtins.str | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_figi", b"_figi", "_instrument_id", b"_instrument_id", "figi", b"figi", "instrument_id", b"instrument_id"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_figi", b"_figi", "_instrument_id", b"_instrument_id", "depth", b"depth", "figi", b"figi", "instrument_id", b"instrument_id"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_figi", b"_figi"]) -> typing.Literal["figi"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_instrument_id", b"_instrument_id"]) -> typing.Literal["instrument_id"] | None: ... + +global___GetOrderBookRequest = GetOrderBookRequest + +@typing.final +class GetOrderBookResponse(google.protobuf.message.Message): + """Информация о стакане.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + DEPTH_FIELD_NUMBER: builtins.int + BIDS_FIELD_NUMBER: builtins.int + ASKS_FIELD_NUMBER: builtins.int + LAST_PRICE_FIELD_NUMBER: builtins.int + CLOSE_PRICE_FIELD_NUMBER: builtins.int + LIMIT_UP_FIELD_NUMBER: builtins.int + LIMIT_DOWN_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + LAST_PRICE_TS_FIELD_NUMBER: builtins.int + CLOSE_PRICE_TS_FIELD_NUMBER: builtins.int + ORDERBOOK_TS_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI-идентификатор инструмента.""" + depth: builtins.int + """Глубина стакана.""" + instrument_uid: builtins.str + """UID инструмента.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + @property + def bids(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Order]: + """Множество пар значений на покупку.""" + + @property + def asks(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Order]: + """Множество пар значений на продажу.""" + + @property + def last_price(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Цена последней сделки за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15).""" + + @property + def close_price(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Цена закрытия за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15).""" + + @property + def limit_up(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Верхний лимит цены за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15).""" + + @property + def limit_down(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Нижний лимит цены за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента. [Подробнее про перевод цен в валюту](./faq_marketdata/#_15).""" + + @property + def last_price_ts(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время получения цены последней сделки.""" + + @property + def close_price_ts(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время получения цены закрытия.""" + + @property + def orderbook_ts(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время формирования стакана на бирже.""" + + def __init__( + self, + *, + figi: builtins.str = ..., + depth: builtins.int = ..., + bids: collections.abc.Iterable[global___Order] | None = ..., + asks: collections.abc.Iterable[global___Order] | None = ..., + last_price: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + close_price: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + limit_up: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + limit_down: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + instrument_uid: builtins.str = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + last_price_ts: google.protobuf.timestamp_pb2.Timestamp | None = ..., + close_price_ts: google.protobuf.timestamp_pb2.Timestamp | None = ..., + orderbook_ts: google.protobuf.timestamp_pb2.Timestamp | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["close_price", b"close_price", "close_price_ts", b"close_price_ts", "last_price", b"last_price", "last_price_ts", b"last_price_ts", "limit_down", b"limit_down", "limit_up", b"limit_up", "orderbook_ts", b"orderbook_ts"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["asks", b"asks", "bids", b"bids", "class_code", b"class_code", "close_price", b"close_price", "close_price_ts", b"close_price_ts", "depth", b"depth", "figi", b"figi", "instrument_uid", b"instrument_uid", "last_price", b"last_price", "last_price_ts", b"last_price_ts", "limit_down", b"limit_down", "limit_up", b"limit_up", "orderbook_ts", b"orderbook_ts", "ticker", b"ticker"]) -> None: ... + +global___GetOrderBookResponse = GetOrderBookResponse + +@typing.final +class GetTradingStatusRequest(google.protobuf.message.Message): + """Запрос получения торгового статуса.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + figi: builtins.str + """Deprecated FIGI-идентификатор инструмента. Используйте `instrument_id`.""" + instrument_id: builtins.str + """Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`""" + def __init__( + self, + *, + figi: builtins.str | None = ..., + instrument_id: builtins.str | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_figi", b"_figi", "_instrument_id", b"_instrument_id", "figi", b"figi", "instrument_id", b"instrument_id"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_figi", b"_figi", "_instrument_id", b"_instrument_id", "figi", b"figi", "instrument_id", b"instrument_id"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_figi", b"_figi"]) -> typing.Literal["figi"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_instrument_id", b"_instrument_id"]) -> typing.Literal["instrument_id"] | None: ... + +global___GetTradingStatusRequest = GetTradingStatusRequest + +@typing.final +class GetTradingStatusesRequest(google.protobuf.message.Message): + """Запрос получения торгового статуса.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + @property + def instrument_id(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`""" + + def __init__( + self, + *, + instrument_id: collections.abc.Iterable[builtins.str] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["instrument_id", b"instrument_id"]) -> None: ... + +global___GetTradingStatusesRequest = GetTradingStatusesRequest + +@typing.final +class GetTradingStatusesResponse(google.protobuf.message.Message): + """Информация о торговом статусе.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TRADING_STATUSES_FIELD_NUMBER: builtins.int + @property + def trading_statuses(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___GetTradingStatusResponse]: + """Массив информации о торговых статусах.""" + + def __init__( + self, + *, + trading_statuses: collections.abc.Iterable[global___GetTradingStatusResponse] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["trading_statuses", b"trading_statuses"]) -> None: ... + +global___GetTradingStatusesResponse = GetTradingStatusesResponse + +@typing.final +class GetTradingStatusResponse(google.protobuf.message.Message): + """Информация о торговом статусе.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + TRADING_STATUS_FIELD_NUMBER: builtins.int + LIMIT_ORDER_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + MARKET_ORDER_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + API_TRADE_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + BESTPRICE_ORDER_AVAILABLE_FLAG_FIELD_NUMBER: builtins.int + ONLY_BEST_PRICE_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI-идентификатор инструмента.""" + trading_status: t_tech.invest.grpc.common_pb2.SecurityTradingStatus.ValueType + """Статус торговли инструментом.""" + limit_order_available_flag: builtins.bool + """Признак доступности выставления лимитной заявки по инструменту.""" + market_order_available_flag: builtins.bool + """Признак доступности выставления рыночной заявки по инструменту.""" + api_trade_available_flag: builtins.bool + """Признак доступности торгов через API.""" + instrument_uid: builtins.str + """UID инструмента.""" + bestprice_order_available_flag: builtins.bool + """Признак доступности завяки по лучшей цене.""" + only_best_price: builtins.bool + """Признак доступности только заявки по лучшей цене.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + def __init__( + self, + *, + figi: builtins.str = ..., + trading_status: t_tech.invest.grpc.common_pb2.SecurityTradingStatus.ValueType = ..., + limit_order_available_flag: builtins.bool = ..., + market_order_available_flag: builtins.bool = ..., + api_trade_available_flag: builtins.bool = ..., + instrument_uid: builtins.str = ..., + bestprice_order_available_flag: builtins.bool = ..., + only_best_price: builtins.bool = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["api_trade_available_flag", b"api_trade_available_flag", "bestprice_order_available_flag", b"bestprice_order_available_flag", "class_code", b"class_code", "figi", b"figi", "instrument_uid", b"instrument_uid", "limit_order_available_flag", b"limit_order_available_flag", "market_order_available_flag", b"market_order_available_flag", "only_best_price", b"only_best_price", "ticker", b"ticker", "trading_status", b"trading_status"]) -> None: ... + +global___GetTradingStatusResponse = GetTradingStatusResponse + +@typing.final +class GetLastTradesRequest(google.protobuf.message.Message): + """Запрос обезличенных сделок за последний час.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + FROM_FIELD_NUMBER: builtins.int + TO_FIELD_NUMBER: builtins.int + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + TRADE_SOURCE_FIELD_NUMBER: builtins.int + figi: builtins.str + """Deprecated FIGI-идентификатор инструмента. Используйте `instrument_id`.""" + instrument_id: builtins.str + """Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`""" + trade_source: global___TradeSourceType.ValueType + """Тип источника сделок. Значение по умолчанию — `TRADE_SOURCE_ALL`, все сделки.""" + @property + def to(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Окончание запрашиваемого периода по UTC.""" + + def __init__( + self, + *, + figi: builtins.str | None = ..., + to: google.protobuf.timestamp_pb2.Timestamp | None = ..., + instrument_id: builtins.str | None = ..., + trade_source: global___TradeSourceType.ValueType = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_figi", b"_figi", "_instrument_id", b"_instrument_id", "figi", b"figi", "from", b"from", "instrument_id", b"instrument_id", "to", b"to"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_figi", b"_figi", "_instrument_id", b"_instrument_id", "figi", b"figi", "from", b"from", "instrument_id", b"instrument_id", "to", b"to", "trade_source", b"trade_source"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_figi", b"_figi"]) -> typing.Literal["figi"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_instrument_id", b"_instrument_id"]) -> typing.Literal["instrument_id"] | None: ... + +global___GetLastTradesRequest = GetLastTradesRequest + +@typing.final +class GetLastTradesResponse(google.protobuf.message.Message): + """Обезличенных сделок за последний час.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TRADES_FIELD_NUMBER: builtins.int + @property + def trades(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Trade]: + """Массив сделок.""" + + def __init__( + self, + *, + trades: collections.abc.Iterable[global___Trade] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["trades", b"trades"]) -> None: ... + +global___GetLastTradesResponse = GetLastTradesResponse + +@typing.final +class GetMySubscriptions(google.protobuf.message.Message): + """Запрос активных подписок. Возвращает по одному сообщению на каждый тип активных подписок — `SubscribeLastPriceResponse`, `SubscribeInfoResponse`, `SubscribeTradesResponse`, `SubscribeOrderBookResponse`, `SubscribeCandlesResponse`.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + def __init__( + self, + ) -> None: ... + +global___GetMySubscriptions = GetMySubscriptions + +@typing.final +class GetClosePricesRequest(google.protobuf.message.Message): + """Запрос цен закрытия торговой сессии по инструментам.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENTS_FIELD_NUMBER: builtins.int + INSTRUMENT_STATUS_FIELD_NUMBER: builtins.int + instrument_status: t_tech.invest.grpc.common_pb2.InstrumentStatus.ValueType + """Статус запрашиваемых инструментов. [Возможные значения](#instrumentstatus).""" + @property + def instruments(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___InstrumentClosePriceRequest]: + """Массив по инструментам.""" + + def __init__( + self, + *, + instruments: collections.abc.Iterable[global___InstrumentClosePriceRequest] | None = ..., + instrument_status: t_tech.invest.grpc.common_pb2.InstrumentStatus.ValueType | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_instrument_status", b"_instrument_status", "instrument_status", b"instrument_status"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_instrument_status", b"_instrument_status", "instrument_status", b"instrument_status", "instruments", b"instruments"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_instrument_status", b"_instrument_status"]) -> typing.Literal["instrument_status"] | None: ... + +global___GetClosePricesRequest = GetClosePricesRequest + +@typing.final +class InstrumentClosePriceRequest(google.protobuf.message.Message): + """Запрос цен закрытия торговой сессии по инструменту.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + instrument_id: builtins.str + """Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`""" + def __init__( + self, + *, + instrument_id: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["instrument_id", b"instrument_id"]) -> None: ... + +global___InstrumentClosePriceRequest = InstrumentClosePriceRequest + +@typing.final +class GetClosePricesResponse(google.protobuf.message.Message): + """Цены закрытия торговой сессии по инструментам.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + CLOSE_PRICES_FIELD_NUMBER: builtins.int + @property + def close_prices(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___InstrumentClosePriceResponse]: + """Массив по инструментам.""" + + def __init__( + self, + *, + close_prices: collections.abc.Iterable[global___InstrumentClosePriceResponse] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["close_prices", b"close_prices"]) -> None: ... + +global___GetClosePricesResponse = GetClosePricesResponse + +@typing.final +class InstrumentClosePriceResponse(google.protobuf.message.Message): + """Цена закрытия торговой сессии по инструменту.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + PRICE_FIELD_NUMBER: builtins.int + EVENING_SESSION_PRICE_FIELD_NUMBER: builtins.int + TIME_FIELD_NUMBER: builtins.int + EVENING_SESSION_PRICE_TIME_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI инструмента.""" + instrument_uid: builtins.str + """UID инструмента.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + @property + def price(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Цена закрытия торговой сессии.""" + + @property + def evening_session_price(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Цена последней сделки с вечерней сессии. Цена публикуется биржей по торговым дням и в нерабочие дни не обновляется.""" + + @property + def time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата совершения торгов.""" + + @property + def evening_session_price_time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата цены закрытия вечерней сессии.""" + + def __init__( + self, + *, + figi: builtins.str = ..., + instrument_uid: builtins.str = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + price: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + evening_session_price: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + evening_session_price_time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["evening_session_price", b"evening_session_price", "evening_session_price_time", b"evening_session_price_time", "price", b"price", "time", b"time"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["class_code", b"class_code", "evening_session_price", b"evening_session_price", "evening_session_price_time", b"evening_session_price_time", "figi", b"figi", "instrument_uid", b"instrument_uid", "price", b"price", "ticker", b"ticker", "time", b"time"]) -> None: ... + +global___InstrumentClosePriceResponse = InstrumentClosePriceResponse + +@typing.final +class GetTechAnalysisRequest(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _IndicatorInterval: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _IndicatorIntervalEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[GetTechAnalysisRequest._IndicatorInterval.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + INDICATOR_INTERVAL_UNSPECIFIED: GetTechAnalysisRequest._IndicatorInterval.ValueType # 0 + """Интервал не определен.""" + INDICATOR_INTERVAL_ONE_MINUTE: GetTechAnalysisRequest._IndicatorInterval.ValueType # 1 + """1 минута.""" + INDICATOR_INTERVAL_FIVE_MINUTES: GetTechAnalysisRequest._IndicatorInterval.ValueType # 2 + """5 минут.""" + INDICATOR_INTERVAL_FIFTEEN_MINUTES: GetTechAnalysisRequest._IndicatorInterval.ValueType # 3 + """15 минут.""" + INDICATOR_INTERVAL_ONE_HOUR: GetTechAnalysisRequest._IndicatorInterval.ValueType # 4 + """1 час.""" + INDICATOR_INTERVAL_ONE_DAY: GetTechAnalysisRequest._IndicatorInterval.ValueType # 5 + """1 день.""" + INDICATOR_INTERVAL_2_MIN: GetTechAnalysisRequest._IndicatorInterval.ValueType # 6 + """2 минуты.""" + INDICATOR_INTERVAL_3_MIN: GetTechAnalysisRequest._IndicatorInterval.ValueType # 7 + """3 минуты.""" + INDICATOR_INTERVAL_10_MIN: GetTechAnalysisRequest._IndicatorInterval.ValueType # 8 + """10 минут.""" + INDICATOR_INTERVAL_30_MIN: GetTechAnalysisRequest._IndicatorInterval.ValueType # 9 + """30 минут.""" + INDICATOR_INTERVAL_2_HOUR: GetTechAnalysisRequest._IndicatorInterval.ValueType # 10 + """2 часа.""" + INDICATOR_INTERVAL_4_HOUR: GetTechAnalysisRequest._IndicatorInterval.ValueType # 11 + """4 часа.""" + INDICATOR_INTERVAL_WEEK: GetTechAnalysisRequest._IndicatorInterval.ValueType # 12 + """Неделя.""" + INDICATOR_INTERVAL_MONTH: GetTechAnalysisRequest._IndicatorInterval.ValueType # 13 + """Месяц.""" + + class IndicatorInterval(_IndicatorInterval, metaclass=_IndicatorIntervalEnumTypeWrapper): + """Интервал свечи.""" + + INDICATOR_INTERVAL_UNSPECIFIED: GetTechAnalysisRequest.IndicatorInterval.ValueType # 0 + """Интервал не определен.""" + INDICATOR_INTERVAL_ONE_MINUTE: GetTechAnalysisRequest.IndicatorInterval.ValueType # 1 + """1 минута.""" + INDICATOR_INTERVAL_FIVE_MINUTES: GetTechAnalysisRequest.IndicatorInterval.ValueType # 2 + """5 минут.""" + INDICATOR_INTERVAL_FIFTEEN_MINUTES: GetTechAnalysisRequest.IndicatorInterval.ValueType # 3 + """15 минут.""" + INDICATOR_INTERVAL_ONE_HOUR: GetTechAnalysisRequest.IndicatorInterval.ValueType # 4 + """1 час.""" + INDICATOR_INTERVAL_ONE_DAY: GetTechAnalysisRequest.IndicatorInterval.ValueType # 5 + """1 день.""" + INDICATOR_INTERVAL_2_MIN: GetTechAnalysisRequest.IndicatorInterval.ValueType # 6 + """2 минуты.""" + INDICATOR_INTERVAL_3_MIN: GetTechAnalysisRequest.IndicatorInterval.ValueType # 7 + """3 минуты.""" + INDICATOR_INTERVAL_10_MIN: GetTechAnalysisRequest.IndicatorInterval.ValueType # 8 + """10 минут.""" + INDICATOR_INTERVAL_30_MIN: GetTechAnalysisRequest.IndicatorInterval.ValueType # 9 + """30 минут.""" + INDICATOR_INTERVAL_2_HOUR: GetTechAnalysisRequest.IndicatorInterval.ValueType # 10 + """2 часа.""" + INDICATOR_INTERVAL_4_HOUR: GetTechAnalysisRequest.IndicatorInterval.ValueType # 11 + """4 часа.""" + INDICATOR_INTERVAL_WEEK: GetTechAnalysisRequest.IndicatorInterval.ValueType # 12 + """Неделя.""" + INDICATOR_INTERVAL_MONTH: GetTechAnalysisRequest.IndicatorInterval.ValueType # 13 + """Месяц.""" + + class _TypeOfPrice: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _TypeOfPriceEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[GetTechAnalysisRequest._TypeOfPrice.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + TYPE_OF_PRICE_UNSPECIFIED: GetTechAnalysisRequest._TypeOfPrice.ValueType # 0 + """Не указано.""" + TYPE_OF_PRICE_CLOSE: GetTechAnalysisRequest._TypeOfPrice.ValueType # 1 + """Цена закрытия.""" + TYPE_OF_PRICE_OPEN: GetTechAnalysisRequest._TypeOfPrice.ValueType # 2 + """Цена открытия.""" + TYPE_OF_PRICE_HIGH: GetTechAnalysisRequest._TypeOfPrice.ValueType # 3 + """Максимальное значение за выбранный интервал.""" + TYPE_OF_PRICE_LOW: GetTechAnalysisRequest._TypeOfPrice.ValueType # 4 + """Минимальное значение за выбранный интервал.""" + TYPE_OF_PRICE_AVG: GetTechAnalysisRequest._TypeOfPrice.ValueType # 5 + """Среднее значение по показателям [ (close + open + high + low) / 4 ].""" + + class TypeOfPrice(_TypeOfPrice, metaclass=_TypeOfPriceEnumTypeWrapper): ... + TYPE_OF_PRICE_UNSPECIFIED: GetTechAnalysisRequest.TypeOfPrice.ValueType # 0 + """Не указано.""" + TYPE_OF_PRICE_CLOSE: GetTechAnalysisRequest.TypeOfPrice.ValueType # 1 + """Цена закрытия.""" + TYPE_OF_PRICE_OPEN: GetTechAnalysisRequest.TypeOfPrice.ValueType # 2 + """Цена открытия.""" + TYPE_OF_PRICE_HIGH: GetTechAnalysisRequest.TypeOfPrice.ValueType # 3 + """Максимальное значение за выбранный интервал.""" + TYPE_OF_PRICE_LOW: GetTechAnalysisRequest.TypeOfPrice.ValueType # 4 + """Минимальное значение за выбранный интервал.""" + TYPE_OF_PRICE_AVG: GetTechAnalysisRequest.TypeOfPrice.ValueType # 5 + """Среднее значение по показателям [ (close + open + high + low) / 4 ].""" + + class _IndicatorType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _IndicatorTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[GetTechAnalysisRequest._IndicatorType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + INDICATOR_TYPE_UNSPECIFIED: GetTechAnalysisRequest._IndicatorType.ValueType # 0 + """Не определен.""" + INDICATOR_TYPE_BB: GetTechAnalysisRequest._IndicatorType.ValueType # 1 + """Bollinger Bands — линия Боллинжера.""" + INDICATOR_TYPE_EMA: GetTechAnalysisRequest._IndicatorType.ValueType # 2 + """Exponential Moving Average — EMA, экспоненциальная скользящая средняя.""" + INDICATOR_TYPE_RSI: GetTechAnalysisRequest._IndicatorType.ValueType # 3 + """Relative Strength Index — индекс относительной силы.""" + INDICATOR_TYPE_MACD: GetTechAnalysisRequest._IndicatorType.ValueType # 4 + """Moving Average Convergence/Divergence — схождение/расхождение скользящих средних.""" + INDICATOR_TYPE_SMA: GetTechAnalysisRequest._IndicatorType.ValueType # 5 + """Simple Moving Average — простое скользящее среднее.""" + + class IndicatorType(_IndicatorType, metaclass=_IndicatorTypeEnumTypeWrapper): ... + INDICATOR_TYPE_UNSPECIFIED: GetTechAnalysisRequest.IndicatorType.ValueType # 0 + """Не определен.""" + INDICATOR_TYPE_BB: GetTechAnalysisRequest.IndicatorType.ValueType # 1 + """Bollinger Bands — линия Боллинжера.""" + INDICATOR_TYPE_EMA: GetTechAnalysisRequest.IndicatorType.ValueType # 2 + """Exponential Moving Average — EMA, экспоненциальная скользящая средняя.""" + INDICATOR_TYPE_RSI: GetTechAnalysisRequest.IndicatorType.ValueType # 3 + """Relative Strength Index — индекс относительной силы.""" + INDICATOR_TYPE_MACD: GetTechAnalysisRequest.IndicatorType.ValueType # 4 + """Moving Average Convergence/Divergence — схождение/расхождение скользящих средних.""" + INDICATOR_TYPE_SMA: GetTechAnalysisRequest.IndicatorType.ValueType # 5 + """Simple Moving Average — простое скользящее среднее.""" + + @typing.final + class Smoothing(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FAST_LENGTH_FIELD_NUMBER: builtins.int + SLOW_LENGTH_FIELD_NUMBER: builtins.int + SIGNAL_SMOOTHING_FIELD_NUMBER: builtins.int + fast_length: builtins.int + """Короткий период сглаживания для первой экспоненциальной скользящей средней (EMA).""" + slow_length: builtins.int + """Длинный период сглаживания для второй экспоненциальной скользящей средней (EMA).""" + signal_smoothing: builtins.int + """Период сглаживания для третьей экспоненциальной скользящей средней (EMA)""" + def __init__( + self, + *, + fast_length: builtins.int = ..., + slow_length: builtins.int = ..., + signal_smoothing: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["fast_length", b"fast_length", "signal_smoothing", b"signal_smoothing", "slow_length", b"slow_length"]) -> None: ... + + @typing.final + class Deviation(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + DEVIATION_MULTIPLIER_FIELD_NUMBER: builtins.int + @property + def deviation_multiplier(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Количество стандартных отклонений, на которые отступают верхняя и нижняя границы.""" + + def __init__( + self, + *, + deviation_multiplier: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["deviation_multiplier", b"deviation_multiplier"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["deviation_multiplier", b"deviation_multiplier"]) -> None: ... + + INDICATOR_TYPE_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + FROM_FIELD_NUMBER: builtins.int + TO_FIELD_NUMBER: builtins.int + INTERVAL_FIELD_NUMBER: builtins.int + TYPE_OF_PRICE_FIELD_NUMBER: builtins.int + LENGTH_FIELD_NUMBER: builtins.int + DEVIATION_FIELD_NUMBER: builtins.int + SMOOTHING_FIELD_NUMBER: builtins.int + indicator_type: global___GetTechAnalysisRequest.IndicatorType.ValueType + """Тип технического индикатора.""" + instrument_uid: builtins.str + """UID инструмента.""" + interval: global___GetTechAnalysisRequest.IndicatorInterval.ValueType + """Интервал, за который рассчитывается индикатор.""" + type_of_price: global___GetTechAnalysisRequest.TypeOfPrice.ValueType + """Тип цены, который используется при расчете индикатора.""" + length: builtins.int + """Торговый период, за который рассчитывается индикатор.""" + @property + def to(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Окончание запрашиваемого периода по UTC.""" + + @property + def deviation(self) -> global___GetTechAnalysisRequest.Deviation: + """Параметры отклонения.""" + + @property + def smoothing(self) -> global___GetTechAnalysisRequest.Smoothing: + """Параметры сглаживания.""" + + def __init__( + self, + *, + indicator_type: global___GetTechAnalysisRequest.IndicatorType.ValueType = ..., + instrument_uid: builtins.str = ..., + to: google.protobuf.timestamp_pb2.Timestamp | None = ..., + interval: global___GetTechAnalysisRequest.IndicatorInterval.ValueType = ..., + type_of_price: global___GetTechAnalysisRequest.TypeOfPrice.ValueType = ..., + length: builtins.int = ..., + deviation: global___GetTechAnalysisRequest.Deviation | None = ..., + smoothing: global___GetTechAnalysisRequest.Smoothing | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["deviation", b"deviation", "from", b"from", "smoothing", b"smoothing", "to", b"to"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["deviation", b"deviation", "from", b"from", "indicator_type", b"indicator_type", "instrument_uid", b"instrument_uid", "interval", b"interval", "length", b"length", "smoothing", b"smoothing", "to", b"to", "type_of_price", b"type_of_price"]) -> None: ... + +global___GetTechAnalysisRequest = GetTechAnalysisRequest + +@typing.final +class GetTechAnalysisResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing.final + class TechAnalysisItem(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TIMESTAMP_FIELD_NUMBER: builtins.int + MIDDLE_BAND_FIELD_NUMBER: builtins.int + UPPER_BAND_FIELD_NUMBER: builtins.int + LOWER_BAND_FIELD_NUMBER: builtins.int + SIGNAL_FIELD_NUMBER: builtins.int + MACD_FIELD_NUMBER: builtins.int + @property + def timestamp(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Временная метка по UTC, для которой были рассчитаны значения индикатора.""" + + @property + def middle_band(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Значение простого скользящего среднего (средней линии).""" + + @property + def upper_band(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Значение верхней линии Боллинджера.""" + + @property + def lower_band(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Значение нижней линии Боллинджера.""" + + @property + def signal(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Значение сигнальной линии.""" + + @property + def macd(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Значение линии MACD.""" + + def __init__( + self, + *, + timestamp: google.protobuf.timestamp_pb2.Timestamp | None = ..., + middle_band: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + upper_band: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + lower_band: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + signal: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + macd: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_lower_band", b"_lower_band", "_macd", b"_macd", "_middle_band", b"_middle_band", "_signal", b"_signal", "_upper_band", b"_upper_band", "lower_band", b"lower_band", "macd", b"macd", "middle_band", b"middle_band", "signal", b"signal", "timestamp", b"timestamp", "upper_band", b"upper_band"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_lower_band", b"_lower_band", "_macd", b"_macd", "_middle_band", b"_middle_band", "_signal", b"_signal", "_upper_band", b"_upper_band", "lower_band", b"lower_band", "macd", b"macd", "middle_band", b"middle_band", "signal", b"signal", "timestamp", b"timestamp", "upper_band", b"upper_band"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_lower_band", b"_lower_band"]) -> typing.Literal["lower_band"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_macd", b"_macd"]) -> typing.Literal["macd"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_middle_band", b"_middle_band"]) -> typing.Literal["middle_band"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_signal", b"_signal"]) -> typing.Literal["signal"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_upper_band", b"_upper_band"]) -> typing.Literal["upper_band"] | None: ... + + TECHNICAL_INDICATORS_FIELD_NUMBER: builtins.int + @property + def technical_indicators(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___GetTechAnalysisResponse.TechAnalysisItem]: + """Массив значений результатов технического анализа.""" + + def __init__( + self, + *, + technical_indicators: collections.abc.Iterable[global___GetTechAnalysisResponse.TechAnalysisItem] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["technical_indicators", b"technical_indicators"]) -> None: ... + +global___GetTechAnalysisResponse = GetTechAnalysisResponse + +@typing.final +class GetMarketValuesRequest(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + VALUES_FIELD_NUMBER: builtins.int + @property + def instrument_id(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Массив идентификаторов инструментов. Принимает значения `figi`, `instrument_uid` или `ticker + '_' + class_code`.""" + + @property + def values(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[global___MarketValueType.ValueType]: + """Массив запрашиваемых параметров.""" + + def __init__( + self, + *, + instrument_id: collections.abc.Iterable[builtins.str] | None = ..., + values: collections.abc.Iterable[global___MarketValueType.ValueType] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["instrument_id", b"instrument_id", "values", b"values"]) -> None: ... + +global___GetMarketValuesRequest = GetMarketValuesRequest + +@typing.final +class GetMarketValuesResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENTS_FIELD_NUMBER: builtins.int + @property + def instruments(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___MarketValueInstrument]: + """Массив значений параметров.""" + + def __init__( + self, + *, + instruments: collections.abc.Iterable[global___MarketValueInstrument] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["instruments", b"instruments"]) -> None: ... + +global___GetMarketValuesResponse = GetMarketValuesResponse + +@typing.final +class MarketValueInstrument(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + VALUES_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + instrument_uid: builtins.str + """Идентификатор инструмента.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + @property + def values(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___MarketValue]: + """Массив параметров инструмента.""" + + def __init__( + self, + *, + instrument_uid: builtins.str = ..., + values: collections.abc.Iterable[global___MarketValue] | None = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["class_code", b"class_code", "instrument_uid", b"instrument_uid", "ticker", b"ticker", "values", b"values"]) -> None: ... + +global___MarketValueInstrument = MarketValueInstrument + +@typing.final +class MarketValue(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TYPE_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + TIME_FIELD_NUMBER: builtins.int + type: global___MarketValueType.ValueType + """Тип параметра.""" + @property + def value(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Значение.""" + + @property + def time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата и время.""" + + def __init__( + self, + *, + type: global___MarketValueType.ValueType | None = ..., + value: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_time", b"_time", "_type", b"_type", "_value", b"_value", "time", b"time", "type", b"type", "value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_time", b"_time", "_type", b"_type", "_value", b"_value", "time", b"time", "type", b"type", "value", b"value"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_time", b"_time"]) -> typing.Literal["time"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_type", b"_type"]) -> typing.Literal["type"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_value", b"_value"]) -> typing.Literal["value"] | None: ... + +global___MarketValue = MarketValue diff --git a/invest-python-master/t_tech/invest/grpc/marketdata_pb2_grpc.py b/invest-python-master/t_tech/invest/grpc/marketdata_pb2_grpc.py new file mode 100644 index 0000000..45a69b0 --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/marketdata_pb2_grpc.py @@ -0,0 +1,441 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +from t_tech.invest.grpc import ( + marketdata_pb2 as t__tech_dot_invest_dot_grpc_dot_marketdata__pb2, +) + + +class MarketDataServiceStub(object): + """Сервис для получения биржевой информации:
1. Свечи.
2. Стаканы.
3. Торговые статусы.
4. Лента сделок. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.GetCandles = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.MarketDataService/GetCandles', + request_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetCandlesRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetCandlesResponse.FromString, + ) + self.GetLastPrices = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.MarketDataService/GetLastPrices', + request_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetLastPricesRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetLastPricesResponse.FromString, + ) + self.GetOrderBook = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.MarketDataService/GetOrderBook', + request_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetOrderBookRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetOrderBookResponse.FromString, + ) + self.GetTradingStatus = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.MarketDataService/GetTradingStatus', + request_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTradingStatusRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTradingStatusResponse.FromString, + ) + self.GetTradingStatuses = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.MarketDataService/GetTradingStatuses', + request_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTradingStatusesRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTradingStatusesResponse.FromString, + ) + self.GetLastTrades = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.MarketDataService/GetLastTrades', + request_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetLastTradesRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetLastTradesResponse.FromString, + ) + self.GetClosePrices = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.MarketDataService/GetClosePrices', + request_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetClosePricesRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetClosePricesResponse.FromString, + ) + self.GetTechAnalysis = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.MarketDataService/GetTechAnalysis', + request_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTechAnalysisRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTechAnalysisResponse.FromString, + ) + self.GetMarketValues = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.MarketDataService/GetMarketValues', + request_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetMarketValuesRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetMarketValuesResponse.FromString, + ) + + +class MarketDataServiceServicer(object): + """Сервис для получения биржевой информации:
1. Свечи.
2. Стаканы.
3. Торговые статусы.
4. Лента сделок. + """ + + def GetCandles(self, request, context): + """GetCandles — исторические свечи по инструменту + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetLastPrices(self, request, context): + """GetLastPrices — цены последних сделок по инструментам + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetOrderBook(self, request, context): + """GetOrderBook — стакан по инструменту + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetTradingStatus(self, request, context): + """GetTradingStatus — статус торгов по инструменту + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetTradingStatuses(self, request, context): + """GetTradingStatuses — статус торгов по инструментам + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetLastTrades(self, request, context): + """GetLastTrades — обезличенные сделки + Обезличенные сделки по инструменту. Метод гарантирует получение информации за последний час. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetClosePrices(self, request, context): + """GetClosePrices — цены закрытия торговой сессии по инструментам + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetTechAnalysis(self, request, context): + """GetTechAnalysis — технические индикаторы по инструменту + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetMarketValues(self, request, context): + """GetMarketValues — рыночные данные по инструментам + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_MarketDataServiceServicer_to_server(servicer, server): + rpc_method_handlers = { + 'GetCandles': grpc.unary_unary_rpc_method_handler( + servicer.GetCandles, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetCandlesRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetCandlesResponse.SerializeToString, + ), + 'GetLastPrices': grpc.unary_unary_rpc_method_handler( + servicer.GetLastPrices, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetLastPricesRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetLastPricesResponse.SerializeToString, + ), + 'GetOrderBook': grpc.unary_unary_rpc_method_handler( + servicer.GetOrderBook, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetOrderBookRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetOrderBookResponse.SerializeToString, + ), + 'GetTradingStatus': grpc.unary_unary_rpc_method_handler( + servicer.GetTradingStatus, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTradingStatusRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTradingStatusResponse.SerializeToString, + ), + 'GetTradingStatuses': grpc.unary_unary_rpc_method_handler( + servicer.GetTradingStatuses, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTradingStatusesRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTradingStatusesResponse.SerializeToString, + ), + 'GetLastTrades': grpc.unary_unary_rpc_method_handler( + servicer.GetLastTrades, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetLastTradesRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetLastTradesResponse.SerializeToString, + ), + 'GetClosePrices': grpc.unary_unary_rpc_method_handler( + servicer.GetClosePrices, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetClosePricesRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetClosePricesResponse.SerializeToString, + ), + 'GetTechAnalysis': grpc.unary_unary_rpc_method_handler( + servicer.GetTechAnalysis, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTechAnalysisRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTechAnalysisResponse.SerializeToString, + ), + 'GetMarketValues': grpc.unary_unary_rpc_method_handler( + servicer.GetMarketValues, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetMarketValuesRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetMarketValuesResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'tinkoff.public.invest.api.contract.v1.MarketDataService', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class MarketDataService(object): + """Сервис для получения биржевой информации:
1. Свечи.
2. Стаканы.
3. Торговые статусы.
4. Лента сделок. + """ + + @staticmethod + def GetCandles(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.MarketDataService/GetCandles', + t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetCandlesRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetCandlesResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetLastPrices(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.MarketDataService/GetLastPrices', + t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetLastPricesRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetLastPricesResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetOrderBook(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.MarketDataService/GetOrderBook', + t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetOrderBookRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetOrderBookResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetTradingStatus(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.MarketDataService/GetTradingStatus', + t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTradingStatusRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTradingStatusResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetTradingStatuses(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.MarketDataService/GetTradingStatuses', + t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTradingStatusesRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTradingStatusesResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetLastTrades(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.MarketDataService/GetLastTrades', + t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetLastTradesRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetLastTradesResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetClosePrices(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.MarketDataService/GetClosePrices', + t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetClosePricesRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetClosePricesResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetTechAnalysis(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.MarketDataService/GetTechAnalysis', + t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTechAnalysisRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTechAnalysisResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetMarketValues(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.MarketDataService/GetMarketValues', + t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetMarketValuesRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetMarketValuesResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + +class MarketDataStreamServiceStub(object): + """Missing associated documentation comment in .proto file.""" + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.MarketDataStream = channel.stream_stream( + '/tinkoff.public.invest.api.contract.v1.MarketDataStreamService/MarketDataStream', + request_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.MarketDataRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.MarketDataResponse.FromString, + ) + self.MarketDataServerSideStream = channel.unary_stream( + '/tinkoff.public.invest.api.contract.v1.MarketDataStreamService/MarketDataServerSideStream', + request_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.MarketDataServerSideStreamRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.MarketDataResponse.FromString, + ) + + +class MarketDataStreamServiceServicer(object): + """Missing associated documentation comment in .proto file.""" + + def MarketDataStream(self, request_iterator, context): + """MarketDataStream — bidirectional стрим предоставления биржевой информации + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def MarketDataServerSideStream(self, request, context): + """MarketDataServerSideStream — server-side стрим предоставления биржевой информации + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_MarketDataStreamServiceServicer_to_server(servicer, server): + rpc_method_handlers = { + 'MarketDataStream': grpc.stream_stream_rpc_method_handler( + servicer.MarketDataStream, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.MarketDataRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.MarketDataResponse.SerializeToString, + ), + 'MarketDataServerSideStream': grpc.unary_stream_rpc_method_handler( + servicer.MarketDataServerSideStream, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.MarketDataServerSideStreamRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.MarketDataResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'tinkoff.public.invest.api.contract.v1.MarketDataStreamService', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class MarketDataStreamService(object): + """Missing associated documentation comment in .proto file.""" + + @staticmethod + def MarketDataStream(request_iterator, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.stream_stream(request_iterator, target, '/tinkoff.public.invest.api.contract.v1.MarketDataStreamService/MarketDataStream', + t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.MarketDataRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.MarketDataResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def MarketDataServerSideStream(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_stream(request, target, '/tinkoff.public.invest.api.contract.v1.MarketDataStreamService/MarketDataServerSideStream', + t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.MarketDataServerSideStreamRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.MarketDataResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/invest-python-master/t_tech/invest/grpc/operations_pb2.py b/invest-python-master/t_tech/invest/grpc/operations_pb2.py new file mode 100644 index 0000000..9bde821 --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/operations_pb2.py @@ -0,0 +1,177 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: t_tech/invest/grpc/operations.proto +# Protobuf Python Version: 4.25.1 +"""Generated protocol buffer code.""" +from google.protobuf import ( + descriptor as _descriptor, + descriptor_pool as _descriptor_pool, + symbol_database as _symbol_database, +) +from google.protobuf.internal import builder as _builder + +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 + +from t_tech.invest.grpc import common_pb2 as t__tech_dot_invest_dot_grpc_dot_common__pb2 +from t_tech.invest.grpc.google.api import ( + field_behavior_pb2 as t__tech_dot_invest_dot_grpc_dot_google_dot_api_dot_field__behavior__pb2, +) + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#t_tech/invest/grpc/operations.proto\x12%tinkoff.public.invest.api.contract.v1\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1ft_tech/invest/grpc/common.proto\x1a\x32t_tech/invest/grpc/google/api/field_behavior.proto\"\x8a\x02\n\x11OperationsRequest\x12\x18\n\naccount_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\x12-\n\x04\x66rom\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x00\x88\x01\x01\x12+\n\x02to\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x01\x88\x01\x01\x12I\n\x05state\x18\x04 \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.OperationStateH\x02\x88\x01\x01\x12\x11\n\x04\x66igi\x18\x05 \x01(\tH\x03\x88\x01\x01\x42\x07\n\x05_fromB\x05\n\x03_toB\x08\n\x06_stateB\x07\n\x05_figi\"Z\n\x12OperationsResponse\x12\x44\n\noperations\x18\x01 \x03(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Operation\"\xc5\x05\n\tOperation\x12\n\n\x02id\x18\x01 \x01(\t\x12\x1b\n\x13parent_operation_id\x18\x02 \x01(\t\x12\x10\n\x08\x63urrency\x18\x03 \x01(\t\x12\x42\n\x07payment\x18\x04 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12@\n\x05price\x18\x05 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x44\n\x05state\x18\x06 \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.OperationState\x12\x10\n\x08quantity\x18\x07 \x01(\x03\x12\x15\n\rquantity_rest\x18\x08 \x01(\x03\x12\x0c\n\x04\x66igi\x18\t \x01(\t\x12\x17\n\x0finstrument_type\x18\n \x01(\t\x12(\n\x04\x64\x61te\x18\x0b \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0c\n\x04type\x18\x0c \x01(\t\x12L\n\x0eoperation_type\x18\r \x01(\x0e\x32\x34.tinkoff.public.invest.api.contract.v1.OperationType\x12\x45\n\x06trades\x18\x0e \x03(\x0b\x32\x35.tinkoff.public.invest.api.contract.v1.OperationTrade\x12\x11\n\tasset_uid\x18\x10 \x01(\t\x12\x14\n\x0cposition_uid\x18\x11 \x01(\t\x12\x16\n\x0einstrument_uid\x18\x12 \x01(\t\x12S\n\x10\x63hild_operations\x18\x13 \x03(\x0b\x32\x39.tinkoff.public.invest.api.contract.v1.ChildOperationItem\"\xa5\x01\n\x0eOperationTrade\x12\x10\n\x08trade_id\x18\x01 \x01(\t\x12-\n\tdate_time\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x10\n\x08quantity\x18\x03 \x01(\x03\x12@\n\x05price\x18\x04 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\"\xc7\x01\n\x10PortfolioRequest\x12\x18\n\naccount_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\x12^\n\x08\x63urrency\x18\x02 \x01(\x0e\x32G.tinkoff.public.invest.api.contract.v1.PortfolioRequest.CurrencyRequestH\x00\x88\x01\x01\",\n\x0f\x43urrencyRequest\x12\x07\n\x03RUB\x10\x00\x12\x07\n\x03USD\x10\x01\x12\x07\n\x03\x45UR\x10\x02\x42\x0b\n\t_currency\"\x80\t\n\x11PortfolioResponse\x12N\n\x13total_amount_shares\x18\x01 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12M\n\x12total_amount_bonds\x18\x02 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12K\n\x10total_amount_etf\x18\x03 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12R\n\x17total_amount_currencies\x18\x04 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12O\n\x14total_amount_futures\x18\x05 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12H\n\x0e\x65xpected_yield\x18\x06 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12K\n\tpositions\x18\x07 \x03(\x0b\x32\x38.tinkoff.public.invest.api.contract.v1.PortfolioPosition\x12\x12\n\naccount_id\x18\x08 \x01(\t\x12O\n\x14total_amount_options\x18\t \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12J\n\x0ftotal_amount_sp\x18\n \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12Q\n\x16total_amount_portfolio\x18\x0b \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12Z\n\x11virtual_positions\x18\x0c \x03(\x0b\x32?.tinkoff.public.invest.api.contract.v1.VirtualPortfolioPosition\x12\x46\n\x0b\x64\x61ily_yield\x18\x0f \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12N\n\x14\x64\x61ily_yield_relative\x18\x10 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12K\n\x10total_amount_dfa\x18\x11 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\",\n\x10PositionsRequest\x12\x18\n\naccount_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\"\xb5\x03\n\x11PositionsResponse\x12@\n\x05money\x18\x01 \x03(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x42\n\x07\x62locked\x18\x02 \x03(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12N\n\nsecurities\x18\x03 \x03(\x0b\x32:.tinkoff.public.invest.api.contract.v1.PositionsSecurities\x12\"\n\x1alimits_loading_in_progress\x18\x04 \x01(\x08\x12H\n\x07\x66utures\x18\x05 \x03(\x0b\x32\x37.tinkoff.public.invest.api.contract.v1.PositionsFutures\x12H\n\x07options\x18\x06 \x03(\x0b\x32\x37.tinkoff.public.invest.api.contract.v1.PositionsOptions\x12\x12\n\naccount_id\x18\x0f \x01(\t\"1\n\x15WithdrawLimitsRequest\x12\x18\n\naccount_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\"\xec\x01\n\x16WithdrawLimitsResponse\x12@\n\x05money\x18\x01 \x03(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x42\n\x07\x62locked\x18\x02 \x03(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12L\n\x11\x62locked_guarantee\x18\x03 \x03(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\"\xb4\x08\n\x11PortfolioPosition\x12\x0c\n\x04\x66igi\x18\x01 \x01(\t\x12\x17\n\x0finstrument_type\x18\x02 \x01(\t\x12\x42\n\x08quantity\x18\x03 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12Q\n\x16\x61verage_position_price\x18\x04 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12H\n\x0e\x65xpected_yield\x18\x05 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x46\n\x0b\x63urrent_nkd\x18\x06 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12W\n\x19\x61verage_position_price_pt\x18\x07 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationB\x02\x18\x01\x12H\n\rcurrent_price\x18\x08 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12V\n\x1b\x61verage_position_price_fifo\x18\t \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12K\n\rquantity_lots\x18\n \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationB\x02\x18\x01\x12\x0f\n\x07\x62locked\x18\x15 \x01(\x08\x12\x46\n\x0c\x62locked_lots\x18\x16 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x14\n\x0cposition_uid\x18\x18 \x01(\t\x12\x16\n\x0einstrument_uid\x18\x19 \x01(\t\x12\x45\n\nvar_margin\x18\x1a \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12M\n\x13\x65xpected_yield_fifo\x18\x1b \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x46\n\x0b\x64\x61ily_yield\x18\x1f \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x0e\n\x06ticker\x18 \x01(\t\x12\x12\n\nclass_code\x18! \x01(\t\"\xde\x05\n\x18VirtualPortfolioPosition\x12\x14\n\x0cposition_uid\x18\x01 \x01(\t\x12\x16\n\x0einstrument_uid\x18\x02 \x01(\t\x12\x0c\n\x04\x66igi\x18\x03 \x01(\t\x12\x17\n\x0finstrument_type\x18\x04 \x01(\t\x12\x42\n\x08quantity\x18\x05 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12Q\n\x16\x61verage_position_price\x18\x06 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12H\n\x0e\x65xpected_yield\x18\x07 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12M\n\x13\x65xpected_yield_fifo\x18\x08 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12/\n\x0b\x65xpire_date\x18\t \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12H\n\rcurrent_price\x18\n \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12V\n\x1b\x61verage_position_price_fifo\x18\x0b \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x46\n\x0b\x64\x61ily_yield\x18\x1f \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x0e\n\x06ticker\x18 \x01(\t\x12\x12\n\nclass_code\x18! \x01(\t\"\xca\x01\n\x13PositionsSecurities\x12\x0c\n\x04\x66igi\x18\x01 \x01(\t\x12\x0f\n\x07\x62locked\x18\x02 \x01(\x03\x12\x0f\n\x07\x62\x61lance\x18\x03 \x01(\x03\x12\x14\n\x0cposition_uid\x18\x04 \x01(\t\x12\x16\n\x0einstrument_uid\x18\x05 \x01(\t\x12\x0e\n\x06ticker\x18\x06 \x01(\t\x12\x12\n\nclass_code\x18\x07 \x01(\t\x12\x18\n\x10\x65xchange_blocked\x18\x0b \x01(\x08\x12\x17\n\x0finstrument_type\x18\x10 \x01(\t\"\x94\x01\n\x10PositionsFutures\x12\x0c\n\x04\x66igi\x18\x01 \x01(\t\x12\x0f\n\x07\x62locked\x18\x02 \x01(\x03\x12\x0f\n\x07\x62\x61lance\x18\x03 \x01(\x03\x12\x14\n\x0cposition_uid\x18\x04 \x01(\t\x12\x16\n\x0einstrument_uid\x18\x05 \x01(\t\x12\x0e\n\x06ticker\x18\x06 \x01(\t\x12\x12\n\nclass_code\x18\x07 \x01(\t\"\x86\x01\n\x10PositionsOptions\x12\x14\n\x0cposition_uid\x18\x01 \x01(\t\x12\x16\n\x0einstrument_uid\x18\x02 \x01(\t\x12\x0e\n\x06ticker\x18\x03 \x01(\t\x12\x12\n\nclass_code\x18\x04 \x01(\t\x12\x0f\n\x07\x62locked\x18\x0b \x01(\x03\x12\x0f\n\x07\x62\x61lance\x18\x15 \x01(\x03\"\xf2\x01\n\x13\x42rokerReportRequest\x12l\n\x1egenerate_broker_report_request\x18\x01 \x01(\x0b\x32\x42.tinkoff.public.invest.api.contract.v1.GenerateBrokerReportRequestH\x00\x12\x62\n\x19get_broker_report_request\x18\x02 \x01(\x0b\x32=.tinkoff.public.invest.api.contract.v1.GetBrokerReportRequestH\x00\x42\t\n\x07payload\"\xf7\x01\n\x14\x42rokerReportResponse\x12n\n\x1fgenerate_broker_report_response\x18\x01 \x01(\x0b\x32\x43.tinkoff.public.invest.api.contract.v1.GenerateBrokerReportResponseH\x00\x12\x64\n\x1aget_broker_report_response\x18\x02 \x01(\x0b\x32>.tinkoff.public.invest.api.contract.v1.GetBrokerReportResponseH\x00\x42\t\n\x07payload\"\x95\x01\n\x1bGenerateBrokerReportRequest\x12\x18\n\naccount_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\x12.\n\x04\x66rom\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x04\xe2\x41\x01\x02\x12,\n\x02to\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x04\xe2\x41\x01\x02\"/\n\x1cGenerateBrokerReportResponse\x12\x0f\n\x07task_id\x18\x01 \x01(\t\"K\n\x16GetBrokerReportRequest\x12\x15\n\x07task_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\x12\x11\n\x04page\x18\x02 \x01(\x05H\x00\x88\x01\x01\x42\x07\n\x05_page\"\xac\x01\n\x17GetBrokerReportResponse\x12J\n\rbroker_report\x18\x01 \x03(\x0b\x32\x33.tinkoff.public.invest.api.contract.v1.BrokerReport\x12\x12\n\nitemsCount\x18\x02 \x01(\x05\x12\x12\n\npagesCount\x18\x03 \x01(\x05\x12\x0c\n\x04page\x18\x04 \x01(\x05\x12\x0f\n\x07task_id\x18\x05 \x01(\t\"\xda\x08\n\x0c\x42rokerReport\x12\x10\n\x08trade_id\x18\x01 \x01(\t\x12\x10\n\x08order_id\x18\x02 \x01(\t\x12\x0c\n\x04\x66igi\x18\x03 \x01(\t\x12\x14\n\x0c\x65xecute_sign\x18\x04 \x01(\t\x12\x32\n\x0etrade_datetime\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x10\n\x08\x65xchange\x18\x06 \x01(\t\x12\x12\n\nclass_code\x18\x07 \x01(\t\x12\x11\n\tdirection\x18\x08 \x01(\t\x12\x0c\n\x04name\x18\t \x01(\t\x12\x0e\n\x06ticker\x18\n \x01(\t\x12@\n\x05price\x18\x0b \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x10\n\x08quantity\x18\x0c \x01(\x03\x12G\n\x0corder_amount\x18\r \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x43\n\taci_value\x18\x0e \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12M\n\x12total_order_amount\x18\x0f \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12L\n\x11\x62roker_commission\x18\x10 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12N\n\x13\x65xchange_commission\x18\x11 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12W\n\x1c\x65xchange_clearing_commission\x18\x12 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x43\n\trepo_rate\x18\x13 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\r\n\x05party\x18\x14 \x01(\t\x12\x34\n\x10\x63lear_value_date\x18\x15 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x32\n\x0esec_value_date\x18\x16 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x15\n\rbroker_status\x18\x17 \x01(\t\x12\x1f\n\x17separate_agreement_type\x18\x18 \x01(\t\x12!\n\x19separate_agreement_number\x18\x19 \x01(\t\x12\x1f\n\x17separate_agreement_date\x18\x1a \x01(\t\x12\x15\n\rdelivery_type\x18\x1b \x01(\t\"\xa8\x02\n GetDividendsForeignIssuerRequest\x12\x80\x01\n\"generate_div_foreign_issuer_report\x18\x01 \x01(\x0b\x32R.tinkoff.public.invest.api.contract.v1.GenerateDividendsForeignIssuerReportRequestH\x00\x12v\n\x1dget_div_foreign_issuer_report\x18\x02 \x01(\x0b\x32M.tinkoff.public.invest.api.contract.v1.GetDividendsForeignIssuerReportRequestH\x00\x42\t\n\x07payload\"\xb0\x02\n!GetDividendsForeignIssuerResponse\x12\x8a\x01\n+generate_div_foreign_issuer_report_response\x18\x01 \x01(\x0b\x32S.tinkoff.public.invest.api.contract.v1.GenerateDividendsForeignIssuerReportResponseH\x00\x12s\n\x19\x64iv_foreign_issuer_report\x18\x02 \x01(\x0b\x32N.tinkoff.public.invest.api.contract.v1.GetDividendsForeignIssuerReportResponseH\x00\x42\t\n\x07payload\"\xa5\x01\n+GenerateDividendsForeignIssuerReportRequest\x12\x18\n\naccount_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\x12.\n\x04\x66rom\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x04\xe2\x41\x01\x02\x12,\n\x02to\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x04\xe2\x41\x01\x02\"[\n&GetDividendsForeignIssuerReportRequest\x12\x15\n\x07task_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\x12\x11\n\x04page\x18\x02 \x01(\x05H\x00\x88\x01\x01\x42\x07\n\x05_page\"?\n,GenerateDividendsForeignIssuerReportResponse\x12\x0f\n\x07task_id\x18\x01 \x01(\t\"\xcd\x01\n\'GetDividendsForeignIssuerReportResponse\x12l\n\x1f\x64ividends_foreign_issuer_report\x18\x01 \x03(\x0b\x32\x43.tinkoff.public.invest.api.contract.v1.DividendsForeignIssuerReport\x12\x12\n\nitemsCount\x18\x02 \x01(\x05\x12\x12\n\npagesCount\x18\x03 \x01(\x05\x12\x0c\n\x04page\x18\x04 \x01(\x05\"\xc9\x04\n\x1c\x44ividendsForeignIssuerReport\x12/\n\x0brecord_date\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x30\n\x0cpayment_date\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x15\n\rsecurity_name\x18\x03 \x01(\t\x12\x0c\n\x04isin\x18\x04 \x01(\t\x12\x16\n\x0eissuer_country\x18\x05 \x01(\t\x12\x10\n\x08quantity\x18\x06 \x01(\x03\x12\x42\n\x08\x64ividend\x18\x07 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12M\n\x13\x65xternal_commission\x18\x08 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12H\n\x0e\x64ividend_gross\x18\t \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12=\n\x03tax\x18\n \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12I\n\x0f\x64ividend_amount\x18\x0b \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x10\n\x08\x63urrency\x18\x0c \x01(\t\"{\n\x16PortfolioStreamRequest\x12\x10\n\x08\x61\x63\x63ounts\x18\x01 \x03(\t\x12O\n\rping_settings\x18\x0f \x01(\x0b\x32\x38.tinkoff.public.invest.api.contract.v1.PingDelaySettings\"\x8d\x02\n\x17PortfolioStreamResponse\x12[\n\rsubscriptions\x18\x01 \x01(\x0b\x32\x42.tinkoff.public.invest.api.contract.v1.PortfolioSubscriptionResultH\x00\x12M\n\tportfolio\x18\x02 \x01(\x0b\x32\x38.tinkoff.public.invest.api.contract.v1.PortfolioResponseH\x00\x12;\n\x04ping\x18\x03 \x01(\x0b\x32+.tinkoff.public.invest.api.contract.v1.PingH\x00\x42\t\n\x07payload\"\x99\x01\n\x1bPortfolioSubscriptionResult\x12R\n\x08\x61\x63\x63ounts\x18\x01 \x03(\x0b\x32@.tinkoff.public.invest.api.contract.v1.AccountSubscriptionStatus\x12\x13\n\x0btracking_id\x18\x07 \x01(\t\x12\x11\n\tstream_id\x18\x08 \x01(\t\"\x90\x01\n\x19\x41\x63\x63ountSubscriptionStatus\x12\x12\n\naccount_id\x18\x01 \x01(\t\x12_\n\x13subscription_status\x18\x06 \x01(\x0e\x32\x42.tinkoff.public.invest.api.contract.v1.PortfolioSubscriptionStatus\"\xd6\x04\n\x1cGetOperationsByCursorRequest\x12\x18\n\naccount_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\x12\x1a\n\rinstrument_id\x18\x02 \x01(\tH\x00\x88\x01\x01\x12-\n\x04\x66rom\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x01\x88\x01\x01\x12+\n\x02to\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x02\x88\x01\x01\x12\x13\n\x06\x63ursor\x18\x0b \x01(\tH\x03\x88\x01\x01\x12\x12\n\x05limit\x18\x0c \x01(\x05H\x04\x88\x01\x01\x12M\n\x0foperation_types\x18\r \x03(\x0e\x32\x34.tinkoff.public.invest.api.contract.v1.OperationType\x12I\n\x05state\x18\x0e \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.OperationStateH\x05\x88\x01\x01\x12 \n\x13without_commissions\x18\x0f \x01(\x08H\x06\x88\x01\x01\x12\x1b\n\x0ewithout_trades\x18\x10 \x01(\x08H\x07\x88\x01\x01\x12\x1f\n\x12without_overnights\x18\x11 \x01(\x08H\x08\x88\x01\x01\x42\x10\n\x0e_instrument_idB\x07\n\x05_fromB\x05\n\x03_toB\t\n\x07_cursorB\x08\n\x06_limitB\x08\n\x06_stateB\x16\n\x14_without_commissionsB\x11\n\x0f_without_tradesB\x15\n\x13_without_overnights\"\x8b\x01\n\x1dGetOperationsByCursorResponse\x12\x10\n\x08has_next\x18\x01 \x01(\x08\x12\x13\n\x0bnext_cursor\x18\x02 \x01(\t\x12\x43\n\x05items\x18\x06 \x03(\x0b\x32\x34.tinkoff.public.invest.api.contract.v1.OperationItem\"\xea\t\n\rOperationItem\x12\x0e\n\x06\x63ursor\x18\x01 \x01(\t\x12\x19\n\x11\x62roker_account_id\x18\x06 \x01(\t\x12\n\n\x02id\x18\x10 \x01(\t\x12\x1b\n\x13parent_operation_id\x18\x11 \x01(\t\x12\x0c\n\x04name\x18\x12 \x01(\t\x12(\n\x04\x64\x61te\x18\x15 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x42\n\x04type\x18\x16 \x01(\x0e\x32\x34.tinkoff.public.invest.api.contract.v1.OperationType\x12\x13\n\x0b\x64\x65scription\x18\x17 \x01(\t\x12\x44\n\x05state\x18\x18 \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.OperationState\x12\x16\n\x0einstrument_uid\x18\x1f \x01(\t\x12\x0c\n\x04\x66igi\x18 \x01(\t\x12\x17\n\x0finstrument_type\x18! \x01(\t\x12N\n\x0finstrument_kind\x18\" \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.InstrumentType\x12\x14\n\x0cposition_uid\x18# \x01(\t\x12\x0e\n\x06ticker\x18$ \x01(\t\x12\x12\n\nclass_code\x18% \x01(\t\x12\x42\n\x07payment\x18) \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12@\n\x05price\x18* \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x45\n\ncommission\x18+ \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12@\n\x05yield\x18, \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12H\n\x0eyield_relative\x18- \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x46\n\x0b\x61\x63\x63rued_int\x18. \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x10\n\x08quantity\x18\x33 \x01(\x03\x12\x15\n\rquantity_rest\x18\x34 \x01(\x03\x12\x15\n\rquantity_done\x18\x35 \x01(\x03\x12\x34\n\x10\x63\x61ncel_date_time\x18\x38 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x15\n\rcancel_reason\x18\x39 \x01(\t\x12O\n\x0btrades_info\x18= \x01(\x0b\x32:.tinkoff.public.invest.api.contract.v1.OperationItemTrades\x12\x11\n\tasset_uid\x18@ \x01(\t\x12S\n\x10\x63hild_operations\x18\x41 \x03(\x0b\x32\x39.tinkoff.public.invest.api.contract.v1.ChildOperationItem\"`\n\x13OperationItemTrades\x12I\n\x06trades\x18\x06 \x03(\x0b\x32\x39.tinkoff.public.invest.api.contract.v1.OperationItemTrade\"\xab\x02\n\x12OperationItemTrade\x12\x0b\n\x03num\x18\x01 \x01(\t\x12(\n\x04\x64\x61te\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x10\n\x08quantity\x18\x0b \x01(\x03\x12@\n\x05price\x18\x10 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12@\n\x05yield\x18\x15 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12H\n\x0eyield_relative\x18\x16 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\"\x9b\x01\n\x16PositionsStreamRequest\x12\x10\n\x08\x61\x63\x63ounts\x18\x01 \x03(\t\x12\x1e\n\x16with_initial_positions\x18\x03 \x01(\x08\x12O\n\rping_settings\x18\x0f \x01(\x0b\x32\x38.tinkoff.public.invest.api.contract.v1.PingDelaySettings\"\xde\x02\n\x17PositionsStreamResponse\x12[\n\rsubscriptions\x18\x01 \x01(\x0b\x32\x42.tinkoff.public.invest.api.contract.v1.PositionsSubscriptionResultH\x00\x12G\n\x08position\x18\x02 \x01(\x0b\x32\x33.tinkoff.public.invest.api.contract.v1.PositionDataH\x00\x12;\n\x04ping\x18\x03 \x01(\x0b\x32+.tinkoff.public.invest.api.contract.v1.PingH\x00\x12U\n\x11initial_positions\x18\x05 \x01(\x0b\x32\x38.tinkoff.public.invest.api.contract.v1.PositionsResponseH\x00\x42\t\n\x07payload\"\x9b\x01\n\x1bPositionsSubscriptionResult\x12T\n\x08\x61\x63\x63ounts\x18\x01 \x03(\x0b\x32\x42.tinkoff.public.invest.api.contract.v1.PositionsSubscriptionStatus\x12\x13\n\x0btracking_id\x18\x07 \x01(\t\x12\x11\n\tstream_id\x18\x08 \x01(\t\"\x99\x01\n\x1bPositionsSubscriptionStatus\x12\x12\n\naccount_id\x18\x01 \x01(\t\x12\x66\n\x13subscription_status\x18\x06 \x01(\x0e\x32I.tinkoff.public.invest.api.contract.v1.PositionsAccountSubscriptionStatus\"\xf6\x02\n\x0cPositionData\x12\x12\n\naccount_id\x18\x01 \x01(\t\x12\x44\n\x05money\x18\x02 \x03(\x0b\x32\x35.tinkoff.public.invest.api.contract.v1.PositionsMoney\x12N\n\nsecurities\x18\x03 \x03(\x0b\x32:.tinkoff.public.invest.api.contract.v1.PositionsSecurities\x12H\n\x07\x66utures\x18\x04 \x03(\x0b\x32\x37.tinkoff.public.invest.api.contract.v1.PositionsFutures\x12H\n\x07options\x18\x05 \x03(\x0b\x32\x37.tinkoff.public.invest.api.contract.v1.PositionsOptions\x12(\n\x04\x64\x61te\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\xa6\x01\n\x0ePositionsMoney\x12J\n\x0f\x61vailable_value\x18\x01 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12H\n\rblocked_value\x18\x02 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\"p\n\x12\x43hildOperationItem\x12\x16\n\x0einstrument_uid\x18\x01 \x01(\t\x12\x42\n\x07payment\x18\x02 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\"|\n\x17OperationsStreamRequest\x12\x10\n\x08\x61\x63\x63ounts\x18\x01 \x03(\t\x12O\n\rping_settings\x18\x0f \x01(\x0b\x32\x38.tinkoff.public.invest.api.contract.v1.PingDelaySettings\"\x8b\x02\n\x18OperationsStreamResponse\x12\\\n\rsubscriptions\x18\x01 \x01(\x0b\x32\x43.tinkoff.public.invest.api.contract.v1.OperationsSubscriptionResultH\x00\x12I\n\toperation\x18\x02 \x01(\x0b\x32\x34.tinkoff.public.invest.api.contract.v1.OperationDataH\x00\x12;\n\x04ping\x18\x03 \x01(\x0b\x32+.tinkoff.public.invest.api.contract.v1.PingH\x00\x42\t\n\x07payload\"\xc1\x01\n\x1cOperationsSubscriptionResult\x12\x10\n\x08\x61\x63\x63ounts\x18\x01 \x03(\t\x12g\n\x13subscription_status\x18\x02 \x01(\x0e\x32J.tinkoff.public.invest.api.contract.v1.OperationsAccountSubscriptionStatus\x12\x13\n\x0btracking_id\x18\x07 \x01(\t\x12\x11\n\tstream_id\x18\x08 \x01(\t\"\xa2\x04\n\rOperationData\x12\x19\n\x11\x62roker_account_id\x18\x01 \x01(\t\x12\n\n\x02id\x18\x02 \x01(\t\x12\x1b\n\x13parent_operation_id\x18\x03 \x01(\t\x12\x0c\n\x04name\x18\x04 \x01(\t\x12(\n\x04\x64\x61te\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x42\n\x04type\x18\x06 \x01(\x0e\x32\x34.tinkoff.public.invest.api.contract.v1.OperationType\x12\x44\n\x05state\x18\x07 \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.OperationState\x12\x16\n\x0einstrument_uid\x18\x08 \x01(\t\x12\x0c\n\x04\x66igi\x18\t \x01(\t\x12\x17\n\x0finstrument_type\x18\n \x01(\t\x12N\n\x0finstrument_kind\x18\x0b \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.InstrumentType\x12\x14\n\x0cposition_uid\x18\x0c \x01(\t\x12\x0e\n\x06ticker\x18\r \x01(\t\x12\x12\n\nclass_code\x18\x0e \x01(\t\x12\x42\n\x07payment\x18\x0f \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue*\x8b\x01\n\x0eOperationState\x12\x1f\n\x1bOPERATION_STATE_UNSPECIFIED\x10\x00\x12\x1c\n\x18OPERATION_STATE_EXECUTED\x10\x01\x12\x1c\n\x18OPERATION_STATE_CANCELED\x10\x02\x12\x1c\n\x18OPERATION_STATE_PROGRESS\x10\x03*\xdd\x11\n\rOperationType\x12\x1e\n\x1aOPERATION_TYPE_UNSPECIFIED\x10\x00\x12\x18\n\x14OPERATION_TYPE_INPUT\x10\x01\x12\x1b\n\x17OPERATION_TYPE_BOND_TAX\x10\x02\x12$\n OPERATION_TYPE_OUTPUT_SECURITIES\x10\x03\x12\x1c\n\x18OPERATION_TYPE_OVERNIGHT\x10\x04\x12\x16\n\x12OPERATION_TYPE_TAX\x10\x05\x12&\n\"OPERATION_TYPE_BOND_REPAYMENT_FULL\x10\x06\x12\x1c\n\x18OPERATION_TYPE_SELL_CARD\x10\x07\x12\x1f\n\x1bOPERATION_TYPE_DIVIDEND_TAX\x10\x08\x12\x19\n\x15OPERATION_TYPE_OUTPUT\x10\t\x12!\n\x1dOPERATION_TYPE_BOND_REPAYMENT\x10\n\x12!\n\x1dOPERATION_TYPE_TAX_CORRECTION\x10\x0b\x12\x1e\n\x1aOPERATION_TYPE_SERVICE_FEE\x10\x0c\x12\x1e\n\x1aOPERATION_TYPE_BENEFIT_TAX\x10\r\x12\x1d\n\x19OPERATION_TYPE_MARGIN_FEE\x10\x0e\x12\x16\n\x12OPERATION_TYPE_BUY\x10\x0f\x12\x1b\n\x17OPERATION_TYPE_BUY_CARD\x10\x10\x12#\n\x1fOPERATION_TYPE_INPUT_SECURITIES\x10\x11\x12\x1e\n\x1aOPERATION_TYPE_SELL_MARGIN\x10\x12\x12\x1d\n\x19OPERATION_TYPE_BROKER_FEE\x10\x13\x12\x1d\n\x19OPERATION_TYPE_BUY_MARGIN\x10\x14\x12\x1b\n\x17OPERATION_TYPE_DIVIDEND\x10\x15\x12\x17\n\x13OPERATION_TYPE_SELL\x10\x16\x12\x19\n\x15OPERATION_TYPE_COUPON\x10\x17\x12\x1e\n\x1aOPERATION_TYPE_SUCCESS_FEE\x10\x18\x12$\n OPERATION_TYPE_DIVIDEND_TRANSFER\x10\x19\x12%\n!OPERATION_TYPE_ACCRUING_VARMARGIN\x10\x1a\x12(\n$OPERATION_TYPE_WRITING_OFF_VARMARGIN\x10\x1b\x12\x1f\n\x1bOPERATION_TYPE_DELIVERY_BUY\x10\x1c\x12 \n\x1cOPERATION_TYPE_DELIVERY_SELL\x10\x1d\x12\x1d\n\x19OPERATION_TYPE_TRACK_MFEE\x10\x1e\x12\x1d\n\x19OPERATION_TYPE_TRACK_PFEE\x10\x1f\x12\"\n\x1eOPERATION_TYPE_TAX_PROGRESSIVE\x10 \x12\'\n#OPERATION_TYPE_BOND_TAX_PROGRESSIVE\x10!\x12+\n\'OPERATION_TYPE_DIVIDEND_TAX_PROGRESSIVE\x10\"\x12*\n&OPERATION_TYPE_BENEFIT_TAX_PROGRESSIVE\x10#\x12-\n)OPERATION_TYPE_TAX_CORRECTION_PROGRESSIVE\x10$\x12\'\n#OPERATION_TYPE_TAX_REPO_PROGRESSIVE\x10%\x12\x1b\n\x17OPERATION_TYPE_TAX_REPO\x10&\x12 \n\x1cOPERATION_TYPE_TAX_REPO_HOLD\x10\'\x12\"\n\x1eOPERATION_TYPE_TAX_REPO_REFUND\x10(\x12,\n(OPERATION_TYPE_TAX_REPO_HOLD_PROGRESSIVE\x10)\x12.\n*OPERATION_TYPE_TAX_REPO_REFUND_PROGRESSIVE\x10*\x12\x1a\n\x16OPERATION_TYPE_DIV_EXT\x10+\x12(\n$OPERATION_TYPE_TAX_CORRECTION_COUPON\x10,\x12\x1b\n\x17OPERATION_TYPE_CASH_FEE\x10-\x12\x1a\n\x16OPERATION_TYPE_OUT_FEE\x10.\x12!\n\x1dOPERATION_TYPE_OUT_STAMP_DUTY\x10/\x12\x1f\n\x1bOPERATION_TYPE_OUTPUT_SWIFT\x10\x32\x12\x1e\n\x1aOPERATION_TYPE_INPUT_SWIFT\x10\x33\x12#\n\x1fOPERATION_TYPE_OUTPUT_ACQUIRING\x10\x35\x12\"\n\x1eOPERATION_TYPE_INPUT_ACQUIRING\x10\x36\x12!\n\x1dOPERATION_TYPE_OUTPUT_PENALTY\x10\x37\x12\x1d\n\x19OPERATION_TYPE_ADVICE_FEE\x10\x38\x12\x1f\n\x1bOPERATION_TYPE_TRANS_IIS_BS\x10\x39\x12\x1e\n\x1aOPERATION_TYPE_TRANS_BS_BS\x10:\x12\x1c\n\x18OPERATION_TYPE_OUT_MULTI\x10;\x12\x1c\n\x18OPERATION_TYPE_INP_MULTI\x10<\x12!\n\x1dOPERATION_TYPE_OVER_PLACEMENT\x10=\x12\x1b\n\x17OPERATION_TYPE_OVER_COM\x10>\x12\x1e\n\x1aOPERATION_TYPE_OVER_INCOME\x10?\x12$\n OPERATION_TYPE_OPTION_EXPIRATION\x10@\x12$\n OPERATION_TYPE_FUTURE_EXPIRATION\x10\x41\x12\x1c\n\x18OPERATION_TYPE_OTHER_FEE\x10\x42\x12\x18\n\x14OPERATION_TYPE_OTHER\x10\x43\x12!\n\x1dOPERATION_TYPE_DFA_REDEMPTION\x10\x44\x12 \n\x1cOPERATION_TYPE_PRIMARY_ORDER\x10\x45*\xde\x01\n\x1bPortfolioSubscriptionStatus\x12-\n)PORTFOLIO_SUBSCRIPTION_STATUS_UNSPECIFIED\x10\x00\x12)\n%PORTFOLIO_SUBSCRIPTION_STATUS_SUCCESS\x10\x01\x12\x33\n/PORTFOLIO_SUBSCRIPTION_STATUS_ACCOUNT_NOT_FOUND\x10\x02\x12\x30\n,PORTFOLIO_SUBSCRIPTION_STATUS_INTERNAL_ERROR\x10\x03*\xe5\x01\n\"PositionsAccountSubscriptionStatus\x12-\n)POSITIONS_SUBSCRIPTION_STATUS_UNSPECIFIED\x10\x00\x12)\n%POSITIONS_SUBSCRIPTION_STATUS_SUCCESS\x10\x01\x12\x33\n/POSITIONS_SUBSCRIPTION_STATUS_ACCOUNT_NOT_FOUND\x10\x02\x12\x30\n,POSITIONS_SUBSCRIPTION_STATUS_INTERNAL_ERROR\x10\x03*\xea\x01\n#OperationsAccountSubscriptionStatus\x12.\n*OPERATIONS_SUBSCRIPTION_STATUS_UNSPECIFIED\x10\x00\x12*\n&OPERATIONS_SUBSCRIPTION_STATUS_SUCCESS\x10\x01\x12\x34\n0OPERATIONS_SUBSCRIPTION_STATUS_ACCOUNT_NOT_FOUND\x10\x02\x12\x31\n-OPERATIONS_SUBSCRIPTION_STATUS_INTERNAL_ERROR\x10\x03\x32\x98\x08\n\x11OperationsService\x12\x84\x01\n\rGetOperations\x12\x38.tinkoff.public.invest.api.contract.v1.OperationsRequest\x1a\x39.tinkoff.public.invest.api.contract.v1.OperationsResponse\x12\x81\x01\n\x0cGetPortfolio\x12\x37.tinkoff.public.invest.api.contract.v1.PortfolioRequest\x1a\x38.tinkoff.public.invest.api.contract.v1.PortfolioResponse\x12\x81\x01\n\x0cGetPositions\x12\x37.tinkoff.public.invest.api.contract.v1.PositionsRequest\x1a\x38.tinkoff.public.invest.api.contract.v1.PositionsResponse\x12\x90\x01\n\x11GetWithdrawLimits\x12<.tinkoff.public.invest.api.contract.v1.WithdrawLimitsRequest\x1a=.tinkoff.public.invest.api.contract.v1.WithdrawLimitsResponse\x12\x8a\x01\n\x0fGetBrokerReport\x12:.tinkoff.public.invest.api.contract.v1.BrokerReportRequest\x1a;.tinkoff.public.invest.api.contract.v1.BrokerReportResponse\x12\xae\x01\n\x19GetDividendsForeignIssuer\x12G.tinkoff.public.invest.api.contract.v1.GetDividendsForeignIssuerRequest\x1aH.tinkoff.public.invest.api.contract.v1.GetDividendsForeignIssuerResponse\x12\xa2\x01\n\x15GetOperationsByCursor\x12\x43.tinkoff.public.invest.api.contract.v1.GetOperationsByCursorRequest\x1a\x44.tinkoff.public.invest.api.contract.v1.GetOperationsByCursorResponse2\xdb\x03\n\x17OperationsStreamService\x12\x92\x01\n\x0fPortfolioStream\x12=.tinkoff.public.invest.api.contract.v1.PortfolioStreamRequest\x1a>.tinkoff.public.invest.api.contract.v1.PortfolioStreamResponse0\x01\x12\x92\x01\n\x0fPositionsStream\x12=.tinkoff.public.invest.api.contract.v1.PositionsStreamRequest\x1a>.tinkoff.public.invest.api.contract.v1.PositionsStreamResponse0\x01\x12\x95\x01\n\x10OperationsStream\x12>.tinkoff.public.invest.api.contract.v1.OperationsStreamRequest\x1a?.tinkoff.public.invest.api.contract.v1.OperationsStreamResponse0\x01\x42\x61\n\x1cru.tinkoff.piapi.contract.v1P\x01Z\x0c./;investapi\xa2\x02\x05TIAPI\xaa\x02\x14Tinkoff.InvestApi.V1\xca\x02\x11Tinkoff\\Invest\\V1b\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 't_tech.invest.grpc.operations_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\034ru.tinkoff.piapi.contract.v1P\001Z\014./;investapi\242\002\005TIAPI\252\002\024Tinkoff.InvestApi.V1\312\002\021Tinkoff\\Invest\\V1' + _globals['_OPERATIONSREQUEST'].fields_by_name['account_id']._options = None + _globals['_OPERATIONSREQUEST'].fields_by_name['account_id']._serialized_options = b'\342A\001\002' + _globals['_PORTFOLIOREQUEST'].fields_by_name['account_id']._options = None + _globals['_PORTFOLIOREQUEST'].fields_by_name['account_id']._serialized_options = b'\342A\001\002' + _globals['_POSITIONSREQUEST'].fields_by_name['account_id']._options = None + _globals['_POSITIONSREQUEST'].fields_by_name['account_id']._serialized_options = b'\342A\001\002' + _globals['_WITHDRAWLIMITSREQUEST'].fields_by_name['account_id']._options = None + _globals['_WITHDRAWLIMITSREQUEST'].fields_by_name['account_id']._serialized_options = b'\342A\001\002' + _globals['_PORTFOLIOPOSITION'].fields_by_name['average_position_price_pt']._options = None + _globals['_PORTFOLIOPOSITION'].fields_by_name['average_position_price_pt']._serialized_options = b'\030\001' + _globals['_PORTFOLIOPOSITION'].fields_by_name['quantity_lots']._options = None + _globals['_PORTFOLIOPOSITION'].fields_by_name['quantity_lots']._serialized_options = b'\030\001' + _globals['_GENERATEBROKERREPORTREQUEST'].fields_by_name['account_id']._options = None + _globals['_GENERATEBROKERREPORTREQUEST'].fields_by_name['account_id']._serialized_options = b'\342A\001\002' + _globals['_GENERATEBROKERREPORTREQUEST'].fields_by_name['from']._options = None + _globals['_GENERATEBROKERREPORTREQUEST'].fields_by_name['from']._serialized_options = b'\342A\001\002' + _globals['_GENERATEBROKERREPORTREQUEST'].fields_by_name['to']._options = None + _globals['_GENERATEBROKERREPORTREQUEST'].fields_by_name['to']._serialized_options = b'\342A\001\002' + _globals['_GETBROKERREPORTREQUEST'].fields_by_name['task_id']._options = None + _globals['_GETBROKERREPORTREQUEST'].fields_by_name['task_id']._serialized_options = b'\342A\001\002' + _globals['_GENERATEDIVIDENDSFOREIGNISSUERREPORTREQUEST'].fields_by_name['account_id']._options = None + _globals['_GENERATEDIVIDENDSFOREIGNISSUERREPORTREQUEST'].fields_by_name['account_id']._serialized_options = b'\342A\001\002' + _globals['_GENERATEDIVIDENDSFOREIGNISSUERREPORTREQUEST'].fields_by_name['from']._options = None + _globals['_GENERATEDIVIDENDSFOREIGNISSUERREPORTREQUEST'].fields_by_name['from']._serialized_options = b'\342A\001\002' + _globals['_GENERATEDIVIDENDSFOREIGNISSUERREPORTREQUEST'].fields_by_name['to']._options = None + _globals['_GENERATEDIVIDENDSFOREIGNISSUERREPORTREQUEST'].fields_by_name['to']._serialized_options = b'\342A\001\002' + _globals['_GETDIVIDENDSFOREIGNISSUERREPORTREQUEST'].fields_by_name['task_id']._options = None + _globals['_GETDIVIDENDSFOREIGNISSUERREPORTREQUEST'].fields_by_name['task_id']._serialized_options = b'\342A\001\002' + _globals['_GETOPERATIONSBYCURSORREQUEST'].fields_by_name['account_id']._options = None + _globals['_GETOPERATIONSBYCURSORREQUEST'].fields_by_name['account_id']._serialized_options = b'\342A\001\002' + _globals['_OPERATIONSTATE']._serialized_start=15403 + _globals['_OPERATIONSTATE']._serialized_end=15542 + _globals['_OPERATIONTYPE']._serialized_start=15545 + _globals['_OPERATIONTYPE']._serialized_end=17814 + _globals['_PORTFOLIOSUBSCRIPTIONSTATUS']._serialized_start=17817 + _globals['_PORTFOLIOSUBSCRIPTIONSTATUS']._serialized_end=18039 + _globals['_POSITIONSACCOUNTSUBSCRIPTIONSTATUS']._serialized_start=18042 + _globals['_POSITIONSACCOUNTSUBSCRIPTIONSTATUS']._serialized_end=18271 + _globals['_OPERATIONSACCOUNTSUBSCRIPTIONSTATUS']._serialized_start=18274 + _globals['_OPERATIONSACCOUNTSUBSCRIPTIONSTATUS']._serialized_end=18508 + _globals['_OPERATIONSREQUEST']._serialized_start=197 + _globals['_OPERATIONSREQUEST']._serialized_end=463 + _globals['_OPERATIONSRESPONSE']._serialized_start=465 + _globals['_OPERATIONSRESPONSE']._serialized_end=555 + _globals['_OPERATION']._serialized_start=558 + _globals['_OPERATION']._serialized_end=1267 + _globals['_OPERATIONTRADE']._serialized_start=1270 + _globals['_OPERATIONTRADE']._serialized_end=1435 + _globals['_PORTFOLIOREQUEST']._serialized_start=1438 + _globals['_PORTFOLIOREQUEST']._serialized_end=1637 + _globals['_PORTFOLIOREQUEST_CURRENCYREQUEST']._serialized_start=1580 + _globals['_PORTFOLIOREQUEST_CURRENCYREQUEST']._serialized_end=1624 + _globals['_PORTFOLIORESPONSE']._serialized_start=1640 + _globals['_PORTFOLIORESPONSE']._serialized_end=2792 + _globals['_POSITIONSREQUEST']._serialized_start=2794 + _globals['_POSITIONSREQUEST']._serialized_end=2838 + _globals['_POSITIONSRESPONSE']._serialized_start=2841 + _globals['_POSITIONSRESPONSE']._serialized_end=3278 + _globals['_WITHDRAWLIMITSREQUEST']._serialized_start=3280 + _globals['_WITHDRAWLIMITSREQUEST']._serialized_end=3329 + _globals['_WITHDRAWLIMITSRESPONSE']._serialized_start=3332 + _globals['_WITHDRAWLIMITSRESPONSE']._serialized_end=3568 + _globals['_PORTFOLIOPOSITION']._serialized_start=3571 + _globals['_PORTFOLIOPOSITION']._serialized_end=4647 + _globals['_VIRTUALPORTFOLIOPOSITION']._serialized_start=4650 + _globals['_VIRTUALPORTFOLIOPOSITION']._serialized_end=5384 + _globals['_POSITIONSSECURITIES']._serialized_start=5387 + _globals['_POSITIONSSECURITIES']._serialized_end=5589 + _globals['_POSITIONSFUTURES']._serialized_start=5592 + _globals['_POSITIONSFUTURES']._serialized_end=5740 + _globals['_POSITIONSOPTIONS']._serialized_start=5743 + _globals['_POSITIONSOPTIONS']._serialized_end=5877 + _globals['_BROKERREPORTREQUEST']._serialized_start=5880 + _globals['_BROKERREPORTREQUEST']._serialized_end=6122 + _globals['_BROKERREPORTRESPONSE']._serialized_start=6125 + _globals['_BROKERREPORTRESPONSE']._serialized_end=6372 + _globals['_GENERATEBROKERREPORTREQUEST']._serialized_start=6375 + _globals['_GENERATEBROKERREPORTREQUEST']._serialized_end=6524 + _globals['_GENERATEBROKERREPORTRESPONSE']._serialized_start=6526 + _globals['_GENERATEBROKERREPORTRESPONSE']._serialized_end=6573 + _globals['_GETBROKERREPORTREQUEST']._serialized_start=6575 + _globals['_GETBROKERREPORTREQUEST']._serialized_end=6650 + _globals['_GETBROKERREPORTRESPONSE']._serialized_start=6653 + _globals['_GETBROKERREPORTRESPONSE']._serialized_end=6825 + _globals['_BROKERREPORT']._serialized_start=6828 + _globals['_BROKERREPORT']._serialized_end=7942 + _globals['_GETDIVIDENDSFOREIGNISSUERREQUEST']._serialized_start=7945 + _globals['_GETDIVIDENDSFOREIGNISSUERREQUEST']._serialized_end=8241 + _globals['_GETDIVIDENDSFOREIGNISSUERRESPONSE']._serialized_start=8244 + _globals['_GETDIVIDENDSFOREIGNISSUERRESPONSE']._serialized_end=8548 + _globals['_GENERATEDIVIDENDSFOREIGNISSUERREPORTREQUEST']._serialized_start=8551 + _globals['_GENERATEDIVIDENDSFOREIGNISSUERREPORTREQUEST']._serialized_end=8716 + _globals['_GETDIVIDENDSFOREIGNISSUERREPORTREQUEST']._serialized_start=8718 + _globals['_GETDIVIDENDSFOREIGNISSUERREPORTREQUEST']._serialized_end=8809 + _globals['_GENERATEDIVIDENDSFOREIGNISSUERREPORTRESPONSE']._serialized_start=8811 + _globals['_GENERATEDIVIDENDSFOREIGNISSUERREPORTRESPONSE']._serialized_end=8874 + _globals['_GETDIVIDENDSFOREIGNISSUERREPORTRESPONSE']._serialized_start=8877 + _globals['_GETDIVIDENDSFOREIGNISSUERREPORTRESPONSE']._serialized_end=9082 + _globals['_DIVIDENDSFOREIGNISSUERREPORT']._serialized_start=9085 + _globals['_DIVIDENDSFOREIGNISSUERREPORT']._serialized_end=9670 + _globals['_PORTFOLIOSTREAMREQUEST']._serialized_start=9672 + _globals['_PORTFOLIOSTREAMREQUEST']._serialized_end=9795 + _globals['_PORTFOLIOSTREAMRESPONSE']._serialized_start=9798 + _globals['_PORTFOLIOSTREAMRESPONSE']._serialized_end=10067 + _globals['_PORTFOLIOSUBSCRIPTIONRESULT']._serialized_start=10070 + _globals['_PORTFOLIOSUBSCRIPTIONRESULT']._serialized_end=10223 + _globals['_ACCOUNTSUBSCRIPTIONSTATUS']._serialized_start=10226 + _globals['_ACCOUNTSUBSCRIPTIONSTATUS']._serialized_end=10370 + _globals['_GETOPERATIONSBYCURSORREQUEST']._serialized_start=10373 + _globals['_GETOPERATIONSBYCURSORREQUEST']._serialized_end=10971 + _globals['_GETOPERATIONSBYCURSORRESPONSE']._serialized_start=10974 + _globals['_GETOPERATIONSBYCURSORRESPONSE']._serialized_end=11113 + _globals['_OPERATIONITEM']._serialized_start=11116 + _globals['_OPERATIONITEM']._serialized_end=12374 + _globals['_OPERATIONITEMTRADES']._serialized_start=12376 + _globals['_OPERATIONITEMTRADES']._serialized_end=12472 + _globals['_OPERATIONITEMTRADE']._serialized_start=12475 + _globals['_OPERATIONITEMTRADE']._serialized_end=12774 + _globals['_POSITIONSSTREAMREQUEST']._serialized_start=12777 + _globals['_POSITIONSSTREAMREQUEST']._serialized_end=12932 + _globals['_POSITIONSSTREAMRESPONSE']._serialized_start=12935 + _globals['_POSITIONSSTREAMRESPONSE']._serialized_end=13285 + _globals['_POSITIONSSUBSCRIPTIONRESULT']._serialized_start=13288 + _globals['_POSITIONSSUBSCRIPTIONRESULT']._serialized_end=13443 + _globals['_POSITIONSSUBSCRIPTIONSTATUS']._serialized_start=13446 + _globals['_POSITIONSSUBSCRIPTIONSTATUS']._serialized_end=13599 + _globals['_POSITIONDATA']._serialized_start=13602 + _globals['_POSITIONDATA']._serialized_end=13976 + _globals['_POSITIONSMONEY']._serialized_start=13979 + _globals['_POSITIONSMONEY']._serialized_end=14145 + _globals['_CHILDOPERATIONITEM']._serialized_start=14147 + _globals['_CHILDOPERATIONITEM']._serialized_end=14259 + _globals['_OPERATIONSSTREAMREQUEST']._serialized_start=14261 + _globals['_OPERATIONSSTREAMREQUEST']._serialized_end=14385 + _globals['_OPERATIONSSTREAMRESPONSE']._serialized_start=14388 + _globals['_OPERATIONSSTREAMRESPONSE']._serialized_end=14655 + _globals['_OPERATIONSSUBSCRIPTIONRESULT']._serialized_start=14658 + _globals['_OPERATIONSSUBSCRIPTIONRESULT']._serialized_end=14851 + _globals['_OPERATIONDATA']._serialized_start=14854 + _globals['_OPERATIONDATA']._serialized_end=15400 + _globals['_OPERATIONSSERVICE']._serialized_start=18511 + _globals['_OPERATIONSSERVICE']._serialized_end=19559 + _globals['_OPERATIONSSTREAMSERVICE']._serialized_start=19562 + _globals['_OPERATIONSSTREAMSERVICE']._serialized_end=20037 +# @@protoc_insertion_point(module_scope) diff --git a/invest-python-master/t_tech/invest/grpc/operations_pb2.pyi b/invest-python-master/t_tech/invest/grpc/operations_pb2.pyi new file mode 100644 index 0000000..8bdec67 --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/operations_pb2.pyi @@ -0,0 +1,2531 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" + +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.internal.enum_type_wrapper +import google.protobuf.message +import google.protobuf.timestamp_pb2 +import sys +import t_tech.invest.grpc.common_pb2 +import typing + +if sys.version_info >= (3, 10): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +class _OperationState: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _OperationStateEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_OperationState.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + OPERATION_STATE_UNSPECIFIED: _OperationState.ValueType # 0 + """Статус операции не определен.""" + OPERATION_STATE_EXECUTED: _OperationState.ValueType # 1 + """Исполнена частично или полностью.""" + OPERATION_STATE_CANCELED: _OperationState.ValueType # 2 + """Отменена.""" + OPERATION_STATE_PROGRESS: _OperationState.ValueType # 3 + """Исполняется.""" + +class OperationState(_OperationState, metaclass=_OperationStateEnumTypeWrapper): + """Статус запрашиваемых операций.""" + +OPERATION_STATE_UNSPECIFIED: OperationState.ValueType # 0 +"""Статус операции не определен.""" +OPERATION_STATE_EXECUTED: OperationState.ValueType # 1 +"""Исполнена частично или полностью.""" +OPERATION_STATE_CANCELED: OperationState.ValueType # 2 +"""Отменена.""" +OPERATION_STATE_PROGRESS: OperationState.ValueType # 3 +"""Исполняется.""" +global___OperationState = OperationState + +class _OperationType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _OperationTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_OperationType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + OPERATION_TYPE_UNSPECIFIED: _OperationType.ValueType # 0 + """Тип операции не определен.""" + OPERATION_TYPE_INPUT: _OperationType.ValueType # 1 + """Пополнение брокерского счета.""" + OPERATION_TYPE_BOND_TAX: _OperationType.ValueType # 2 + """Удержание НДФЛ по купонам.""" + OPERATION_TYPE_OUTPUT_SECURITIES: _OperationType.ValueType # 3 + """Вывод ЦБ.""" + OPERATION_TYPE_OVERNIGHT: _OperationType.ValueType # 4 + """Доход по сделке РЕПО овернайт.""" + OPERATION_TYPE_TAX: _OperationType.ValueType # 5 + """Удержание налога.""" + OPERATION_TYPE_BOND_REPAYMENT_FULL: _OperationType.ValueType # 6 + """Полное погашение облигаций.""" + OPERATION_TYPE_SELL_CARD: _OperationType.ValueType # 7 + """Продажа ЦБ с карты.""" + OPERATION_TYPE_DIVIDEND_TAX: _OperationType.ValueType # 8 + """Удержание налога по дивидендам.""" + OPERATION_TYPE_OUTPUT: _OperationType.ValueType # 9 + """Вывод денежных средств.""" + OPERATION_TYPE_BOND_REPAYMENT: _OperationType.ValueType # 10 + """Частичное погашение облигаций.""" + OPERATION_TYPE_TAX_CORRECTION: _OperationType.ValueType # 11 + """Корректировка налога.""" + OPERATION_TYPE_SERVICE_FEE: _OperationType.ValueType # 12 + """Удержание комиссии за обслуживание брокерского счета.""" + OPERATION_TYPE_BENEFIT_TAX: _OperationType.ValueType # 13 + """Удержание налога за материальную выгоду.""" + OPERATION_TYPE_MARGIN_FEE: _OperationType.ValueType # 14 + """Удержание комиссии за непокрытую позицию.""" + OPERATION_TYPE_BUY: _OperationType.ValueType # 15 + """Покупка ЦБ.""" + OPERATION_TYPE_BUY_CARD: _OperationType.ValueType # 16 + """Покупка ЦБ с карты.""" + OPERATION_TYPE_INPUT_SECURITIES: _OperationType.ValueType # 17 + """Перевод ценных бумаг из другого депозитария.""" + OPERATION_TYPE_SELL_MARGIN: _OperationType.ValueType # 18 + """Продажа в результате Margin-call.""" + OPERATION_TYPE_BROKER_FEE: _OperationType.ValueType # 19 + """Удержание комиссии за операцию.""" + OPERATION_TYPE_BUY_MARGIN: _OperationType.ValueType # 20 + """Покупка в результате Margin-call.""" + OPERATION_TYPE_DIVIDEND: _OperationType.ValueType # 21 + """Выплата дивидендов.""" + OPERATION_TYPE_SELL: _OperationType.ValueType # 22 + """Продажа ЦБ.""" + OPERATION_TYPE_COUPON: _OperationType.ValueType # 23 + """Выплата купонов.""" + OPERATION_TYPE_SUCCESS_FEE: _OperationType.ValueType # 24 + """Удержание комиссии SuccessFee.""" + OPERATION_TYPE_DIVIDEND_TRANSFER: _OperationType.ValueType # 25 + """Передача дивидендного дохода.""" + OPERATION_TYPE_ACCRUING_VARMARGIN: _OperationType.ValueType # 26 + """Зачисление вариационной маржи.""" + OPERATION_TYPE_WRITING_OFF_VARMARGIN: _OperationType.ValueType # 27 + """Списание вариационной маржи.""" + OPERATION_TYPE_DELIVERY_BUY: _OperationType.ValueType # 28 + """Покупка в рамках экспирации фьючерсного контракта.""" + OPERATION_TYPE_DELIVERY_SELL: _OperationType.ValueType # 29 + """Продажа в рамках экспирации фьючерсного контракта.""" + OPERATION_TYPE_TRACK_MFEE: _OperationType.ValueType # 30 + """Комиссия за управление по счету автоследования.""" + OPERATION_TYPE_TRACK_PFEE: _OperationType.ValueType # 31 + """Комиссия за результат по счету автоследования.""" + OPERATION_TYPE_TAX_PROGRESSIVE: _OperationType.ValueType # 32 + """Удержание налога по ставке 15%.""" + OPERATION_TYPE_BOND_TAX_PROGRESSIVE: _OperationType.ValueType # 33 + """Удержание налога по купонам по ставке 15%.""" + OPERATION_TYPE_DIVIDEND_TAX_PROGRESSIVE: _OperationType.ValueType # 34 + """Удержание налога по дивидендам по ставке 15%.""" + OPERATION_TYPE_BENEFIT_TAX_PROGRESSIVE: _OperationType.ValueType # 35 + """Удержание налога за материальную выгоду по ставке 15%.""" + OPERATION_TYPE_TAX_CORRECTION_PROGRESSIVE: _OperationType.ValueType # 36 + """Корректировка налога по ставке 15%.""" + OPERATION_TYPE_TAX_REPO_PROGRESSIVE: _OperationType.ValueType # 37 + """Удержание налога за возмещение по сделкам РЕПО по ставке 15%.""" + OPERATION_TYPE_TAX_REPO: _OperationType.ValueType # 38 + """Удержание налога за возмещение по сделкам РЕПО.""" + OPERATION_TYPE_TAX_REPO_HOLD: _OperationType.ValueType # 39 + """Удержание налога по сделкам РЕПО.""" + OPERATION_TYPE_TAX_REPO_REFUND: _OperationType.ValueType # 40 + """Возврат налога по сделкам РЕПО.""" + OPERATION_TYPE_TAX_REPO_HOLD_PROGRESSIVE: _OperationType.ValueType # 41 + """Удержание налога по сделкам РЕПО по ставке 15%.""" + OPERATION_TYPE_TAX_REPO_REFUND_PROGRESSIVE: _OperationType.ValueType # 42 + """Возврат налога по сделкам РЕПО по ставке 15%.""" + OPERATION_TYPE_DIV_EXT: _OperationType.ValueType # 43 + """Выплата дивидендов на карту.""" + OPERATION_TYPE_TAX_CORRECTION_COUPON: _OperationType.ValueType # 44 + """Корректировка налога по купонам.""" + OPERATION_TYPE_CASH_FEE: _OperationType.ValueType # 45 + """Комиссия за валютный остаток.""" + OPERATION_TYPE_OUT_FEE: _OperationType.ValueType # 46 + """Комиссия за вывод валюты с брокерского счета.""" + OPERATION_TYPE_OUT_STAMP_DUTY: _OperationType.ValueType # 47 + """Гербовый сбор.""" + OPERATION_TYPE_OUTPUT_SWIFT: _OperationType.ValueType # 50 + """ SWIFT-перевод.""" + OPERATION_TYPE_INPUT_SWIFT: _OperationType.ValueType # 51 + """ SWIFT-перевод.""" + OPERATION_TYPE_OUTPUT_ACQUIRING: _OperationType.ValueType # 53 + """ Перевод на карту.""" + OPERATION_TYPE_INPUT_ACQUIRING: _OperationType.ValueType # 54 + """ Перевод с карты.""" + OPERATION_TYPE_OUTPUT_PENALTY: _OperationType.ValueType # 55 + """ Комиссия за вывод средств.""" + OPERATION_TYPE_ADVICE_FEE: _OperationType.ValueType # 56 + """ Списание оплаты за сервис Советов.""" + OPERATION_TYPE_TRANS_IIS_BS: _OperationType.ValueType # 57 + """ Перевод ценных бумаг с ИИС на брокерский счет.""" + OPERATION_TYPE_TRANS_BS_BS: _OperationType.ValueType # 58 + """ Перевод ценных бумаг с одного брокерского счета на другой.""" + OPERATION_TYPE_OUT_MULTI: _OperationType.ValueType # 59 + """ Вывод денежных средств со счета.""" + OPERATION_TYPE_INP_MULTI: _OperationType.ValueType # 60 + """ Пополнение денежных средств со счета.""" + OPERATION_TYPE_OVER_PLACEMENT: _OperationType.ValueType # 61 + """ Размещение биржевого овернайта.""" + OPERATION_TYPE_OVER_COM: _OperationType.ValueType # 62 + """ Списание комиссии.""" + OPERATION_TYPE_OVER_INCOME: _OperationType.ValueType # 63 + """ Доход от оверанайта.""" + OPERATION_TYPE_OPTION_EXPIRATION: _OperationType.ValueType # 64 + """Экспирация опциона.""" + OPERATION_TYPE_FUTURE_EXPIRATION: _OperationType.ValueType # 65 + """Экспирация фьючерса.""" + OPERATION_TYPE_OTHER_FEE: _OperationType.ValueType # 66 + """ Прочие комиссии;""" + OPERATION_TYPE_OTHER: _OperationType.ValueType # 67 + """ Операция по счету;""" + OPERATION_TYPE_DFA_REDEMPTION: _OperationType.ValueType # 68 + """погашение ЦФА-токена;""" + OPERATION_TYPE_PRIMARY_ORDER: _OperationType.ValueType # 69 + """ отмена заявки на первичное размещение по ЦФА;""" + +class OperationType(_OperationType, metaclass=_OperationTypeEnumTypeWrapper): + """Тип операции.""" + +OPERATION_TYPE_UNSPECIFIED: OperationType.ValueType # 0 +"""Тип операции не определен.""" +OPERATION_TYPE_INPUT: OperationType.ValueType # 1 +"""Пополнение брокерского счета.""" +OPERATION_TYPE_BOND_TAX: OperationType.ValueType # 2 +"""Удержание НДФЛ по купонам.""" +OPERATION_TYPE_OUTPUT_SECURITIES: OperationType.ValueType # 3 +"""Вывод ЦБ.""" +OPERATION_TYPE_OVERNIGHT: OperationType.ValueType # 4 +"""Доход по сделке РЕПО овернайт.""" +OPERATION_TYPE_TAX: OperationType.ValueType # 5 +"""Удержание налога.""" +OPERATION_TYPE_BOND_REPAYMENT_FULL: OperationType.ValueType # 6 +"""Полное погашение облигаций.""" +OPERATION_TYPE_SELL_CARD: OperationType.ValueType # 7 +"""Продажа ЦБ с карты.""" +OPERATION_TYPE_DIVIDEND_TAX: OperationType.ValueType # 8 +"""Удержание налога по дивидендам.""" +OPERATION_TYPE_OUTPUT: OperationType.ValueType # 9 +"""Вывод денежных средств.""" +OPERATION_TYPE_BOND_REPAYMENT: OperationType.ValueType # 10 +"""Частичное погашение облигаций.""" +OPERATION_TYPE_TAX_CORRECTION: OperationType.ValueType # 11 +"""Корректировка налога.""" +OPERATION_TYPE_SERVICE_FEE: OperationType.ValueType # 12 +"""Удержание комиссии за обслуживание брокерского счета.""" +OPERATION_TYPE_BENEFIT_TAX: OperationType.ValueType # 13 +"""Удержание налога за материальную выгоду.""" +OPERATION_TYPE_MARGIN_FEE: OperationType.ValueType # 14 +"""Удержание комиссии за непокрытую позицию.""" +OPERATION_TYPE_BUY: OperationType.ValueType # 15 +"""Покупка ЦБ.""" +OPERATION_TYPE_BUY_CARD: OperationType.ValueType # 16 +"""Покупка ЦБ с карты.""" +OPERATION_TYPE_INPUT_SECURITIES: OperationType.ValueType # 17 +"""Перевод ценных бумаг из другого депозитария.""" +OPERATION_TYPE_SELL_MARGIN: OperationType.ValueType # 18 +"""Продажа в результате Margin-call.""" +OPERATION_TYPE_BROKER_FEE: OperationType.ValueType # 19 +"""Удержание комиссии за операцию.""" +OPERATION_TYPE_BUY_MARGIN: OperationType.ValueType # 20 +"""Покупка в результате Margin-call.""" +OPERATION_TYPE_DIVIDEND: OperationType.ValueType # 21 +"""Выплата дивидендов.""" +OPERATION_TYPE_SELL: OperationType.ValueType # 22 +"""Продажа ЦБ.""" +OPERATION_TYPE_COUPON: OperationType.ValueType # 23 +"""Выплата купонов.""" +OPERATION_TYPE_SUCCESS_FEE: OperationType.ValueType # 24 +"""Удержание комиссии SuccessFee.""" +OPERATION_TYPE_DIVIDEND_TRANSFER: OperationType.ValueType # 25 +"""Передача дивидендного дохода.""" +OPERATION_TYPE_ACCRUING_VARMARGIN: OperationType.ValueType # 26 +"""Зачисление вариационной маржи.""" +OPERATION_TYPE_WRITING_OFF_VARMARGIN: OperationType.ValueType # 27 +"""Списание вариационной маржи.""" +OPERATION_TYPE_DELIVERY_BUY: OperationType.ValueType # 28 +"""Покупка в рамках экспирации фьючерсного контракта.""" +OPERATION_TYPE_DELIVERY_SELL: OperationType.ValueType # 29 +"""Продажа в рамках экспирации фьючерсного контракта.""" +OPERATION_TYPE_TRACK_MFEE: OperationType.ValueType # 30 +"""Комиссия за управление по счету автоследования.""" +OPERATION_TYPE_TRACK_PFEE: OperationType.ValueType # 31 +"""Комиссия за результат по счету автоследования.""" +OPERATION_TYPE_TAX_PROGRESSIVE: OperationType.ValueType # 32 +"""Удержание налога по ставке 15%.""" +OPERATION_TYPE_BOND_TAX_PROGRESSIVE: OperationType.ValueType # 33 +"""Удержание налога по купонам по ставке 15%.""" +OPERATION_TYPE_DIVIDEND_TAX_PROGRESSIVE: OperationType.ValueType # 34 +"""Удержание налога по дивидендам по ставке 15%.""" +OPERATION_TYPE_BENEFIT_TAX_PROGRESSIVE: OperationType.ValueType # 35 +"""Удержание налога за материальную выгоду по ставке 15%.""" +OPERATION_TYPE_TAX_CORRECTION_PROGRESSIVE: OperationType.ValueType # 36 +"""Корректировка налога по ставке 15%.""" +OPERATION_TYPE_TAX_REPO_PROGRESSIVE: OperationType.ValueType # 37 +"""Удержание налога за возмещение по сделкам РЕПО по ставке 15%.""" +OPERATION_TYPE_TAX_REPO: OperationType.ValueType # 38 +"""Удержание налога за возмещение по сделкам РЕПО.""" +OPERATION_TYPE_TAX_REPO_HOLD: OperationType.ValueType # 39 +"""Удержание налога по сделкам РЕПО.""" +OPERATION_TYPE_TAX_REPO_REFUND: OperationType.ValueType # 40 +"""Возврат налога по сделкам РЕПО.""" +OPERATION_TYPE_TAX_REPO_HOLD_PROGRESSIVE: OperationType.ValueType # 41 +"""Удержание налога по сделкам РЕПО по ставке 15%.""" +OPERATION_TYPE_TAX_REPO_REFUND_PROGRESSIVE: OperationType.ValueType # 42 +"""Возврат налога по сделкам РЕПО по ставке 15%.""" +OPERATION_TYPE_DIV_EXT: OperationType.ValueType # 43 +"""Выплата дивидендов на карту.""" +OPERATION_TYPE_TAX_CORRECTION_COUPON: OperationType.ValueType # 44 +"""Корректировка налога по купонам.""" +OPERATION_TYPE_CASH_FEE: OperationType.ValueType # 45 +"""Комиссия за валютный остаток.""" +OPERATION_TYPE_OUT_FEE: OperationType.ValueType # 46 +"""Комиссия за вывод валюты с брокерского счета.""" +OPERATION_TYPE_OUT_STAMP_DUTY: OperationType.ValueType # 47 +"""Гербовый сбор.""" +OPERATION_TYPE_OUTPUT_SWIFT: OperationType.ValueType # 50 +""" SWIFT-перевод.""" +OPERATION_TYPE_INPUT_SWIFT: OperationType.ValueType # 51 +""" SWIFT-перевод.""" +OPERATION_TYPE_OUTPUT_ACQUIRING: OperationType.ValueType # 53 +""" Перевод на карту.""" +OPERATION_TYPE_INPUT_ACQUIRING: OperationType.ValueType # 54 +""" Перевод с карты.""" +OPERATION_TYPE_OUTPUT_PENALTY: OperationType.ValueType # 55 +""" Комиссия за вывод средств.""" +OPERATION_TYPE_ADVICE_FEE: OperationType.ValueType # 56 +""" Списание оплаты за сервис Советов.""" +OPERATION_TYPE_TRANS_IIS_BS: OperationType.ValueType # 57 +""" Перевод ценных бумаг с ИИС на брокерский счет.""" +OPERATION_TYPE_TRANS_BS_BS: OperationType.ValueType # 58 +""" Перевод ценных бумаг с одного брокерского счета на другой.""" +OPERATION_TYPE_OUT_MULTI: OperationType.ValueType # 59 +""" Вывод денежных средств со счета.""" +OPERATION_TYPE_INP_MULTI: OperationType.ValueType # 60 +""" Пополнение денежных средств со счета.""" +OPERATION_TYPE_OVER_PLACEMENT: OperationType.ValueType # 61 +""" Размещение биржевого овернайта.""" +OPERATION_TYPE_OVER_COM: OperationType.ValueType # 62 +""" Списание комиссии.""" +OPERATION_TYPE_OVER_INCOME: OperationType.ValueType # 63 +""" Доход от оверанайта.""" +OPERATION_TYPE_OPTION_EXPIRATION: OperationType.ValueType # 64 +"""Экспирация опциона.""" +OPERATION_TYPE_FUTURE_EXPIRATION: OperationType.ValueType # 65 +"""Экспирация фьючерса.""" +OPERATION_TYPE_OTHER_FEE: OperationType.ValueType # 66 +""" Прочие комиссии;""" +OPERATION_TYPE_OTHER: OperationType.ValueType # 67 +""" Операция по счету;""" +OPERATION_TYPE_DFA_REDEMPTION: OperationType.ValueType # 68 +"""погашение ЦФА-токена;""" +OPERATION_TYPE_PRIMARY_ORDER: OperationType.ValueType # 69 +""" отмена заявки на первичное размещение по ЦФА;""" +global___OperationType = OperationType + +class _PortfolioSubscriptionStatus: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _PortfolioSubscriptionStatusEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_PortfolioSubscriptionStatus.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + PORTFOLIO_SUBSCRIPTION_STATUS_UNSPECIFIED: _PortfolioSubscriptionStatus.ValueType # 0 + """Тип не определен.""" + PORTFOLIO_SUBSCRIPTION_STATUS_SUCCESS: _PortfolioSubscriptionStatus.ValueType # 1 + """Успешно.""" + PORTFOLIO_SUBSCRIPTION_STATUS_ACCOUNT_NOT_FOUND: _PortfolioSubscriptionStatus.ValueType # 2 + """Счет не найден или недостаточно прав.""" + PORTFOLIO_SUBSCRIPTION_STATUS_INTERNAL_ERROR: _PortfolioSubscriptionStatus.ValueType # 3 + """Произошла ошибка.""" + +class PortfolioSubscriptionStatus(_PortfolioSubscriptionStatus, metaclass=_PortfolioSubscriptionStatusEnumTypeWrapper): + """Результат подписки.""" + +PORTFOLIO_SUBSCRIPTION_STATUS_UNSPECIFIED: PortfolioSubscriptionStatus.ValueType # 0 +"""Тип не определен.""" +PORTFOLIO_SUBSCRIPTION_STATUS_SUCCESS: PortfolioSubscriptionStatus.ValueType # 1 +"""Успешно.""" +PORTFOLIO_SUBSCRIPTION_STATUS_ACCOUNT_NOT_FOUND: PortfolioSubscriptionStatus.ValueType # 2 +"""Счет не найден или недостаточно прав.""" +PORTFOLIO_SUBSCRIPTION_STATUS_INTERNAL_ERROR: PortfolioSubscriptionStatus.ValueType # 3 +"""Произошла ошибка.""" +global___PortfolioSubscriptionStatus = PortfolioSubscriptionStatus + +class _PositionsAccountSubscriptionStatus: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _PositionsAccountSubscriptionStatusEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_PositionsAccountSubscriptionStatus.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + POSITIONS_SUBSCRIPTION_STATUS_UNSPECIFIED: _PositionsAccountSubscriptionStatus.ValueType # 0 + """Тип не определен.""" + POSITIONS_SUBSCRIPTION_STATUS_SUCCESS: _PositionsAccountSubscriptionStatus.ValueType # 1 + """Успешно.""" + POSITIONS_SUBSCRIPTION_STATUS_ACCOUNT_NOT_FOUND: _PositionsAccountSubscriptionStatus.ValueType # 2 + """Счет не найден или недостаточно прав.""" + POSITIONS_SUBSCRIPTION_STATUS_INTERNAL_ERROR: _PositionsAccountSubscriptionStatus.ValueType # 3 + """Произошла ошибка.""" + +class PositionsAccountSubscriptionStatus(_PositionsAccountSubscriptionStatus, metaclass=_PositionsAccountSubscriptionStatusEnumTypeWrapper): + """Результат подписки.""" + +POSITIONS_SUBSCRIPTION_STATUS_UNSPECIFIED: PositionsAccountSubscriptionStatus.ValueType # 0 +"""Тип не определен.""" +POSITIONS_SUBSCRIPTION_STATUS_SUCCESS: PositionsAccountSubscriptionStatus.ValueType # 1 +"""Успешно.""" +POSITIONS_SUBSCRIPTION_STATUS_ACCOUNT_NOT_FOUND: PositionsAccountSubscriptionStatus.ValueType # 2 +"""Счет не найден или недостаточно прав.""" +POSITIONS_SUBSCRIPTION_STATUS_INTERNAL_ERROR: PositionsAccountSubscriptionStatus.ValueType # 3 +"""Произошла ошибка.""" +global___PositionsAccountSubscriptionStatus = PositionsAccountSubscriptionStatus + +class _OperationsAccountSubscriptionStatus: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _OperationsAccountSubscriptionStatusEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_OperationsAccountSubscriptionStatus.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + OPERATIONS_SUBSCRIPTION_STATUS_UNSPECIFIED: _OperationsAccountSubscriptionStatus.ValueType # 0 + """Тип не определен.""" + OPERATIONS_SUBSCRIPTION_STATUS_SUCCESS: _OperationsAccountSubscriptionStatus.ValueType # 1 + """Успешно.""" + OPERATIONS_SUBSCRIPTION_STATUS_ACCOUNT_NOT_FOUND: _OperationsAccountSubscriptionStatus.ValueType # 2 + """Счет не найден или недостаточно прав.""" + OPERATIONS_SUBSCRIPTION_STATUS_INTERNAL_ERROR: _OperationsAccountSubscriptionStatus.ValueType # 3 + """Произошла ошибка.""" + +class OperationsAccountSubscriptionStatus(_OperationsAccountSubscriptionStatus, metaclass=_OperationsAccountSubscriptionStatusEnumTypeWrapper): + """Результат подписки.""" + +OPERATIONS_SUBSCRIPTION_STATUS_UNSPECIFIED: OperationsAccountSubscriptionStatus.ValueType # 0 +"""Тип не определен.""" +OPERATIONS_SUBSCRIPTION_STATUS_SUCCESS: OperationsAccountSubscriptionStatus.ValueType # 1 +"""Успешно.""" +OPERATIONS_SUBSCRIPTION_STATUS_ACCOUNT_NOT_FOUND: OperationsAccountSubscriptionStatus.ValueType # 2 +"""Счет не найден или недостаточно прав.""" +OPERATIONS_SUBSCRIPTION_STATUS_INTERNAL_ERROR: OperationsAccountSubscriptionStatus.ValueType # 3 +"""Произошла ошибка.""" +global___OperationsAccountSubscriptionStatus = OperationsAccountSubscriptionStatus + +@typing.final +class OperationsRequest(google.protobuf.message.Message): + """Запрос получения списка операций по счету.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNT_ID_FIELD_NUMBER: builtins.int + FROM_FIELD_NUMBER: builtins.int + TO_FIELD_NUMBER: builtins.int + STATE_FIELD_NUMBER: builtins.int + FIGI_FIELD_NUMBER: builtins.int + account_id: builtins.str + """Идентификатор счета клиента.""" + state: global___OperationState.ValueType + """Статус запрашиваемых операций.""" + figi: builtins.str + """FIGI-идентификатор инструмента для фильтрации.""" + @property + def to(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Окончание периода по UTC.""" + + def __init__( + self, + *, + account_id: builtins.str = ..., + to: google.protobuf.timestamp_pb2.Timestamp | None = ..., + state: global___OperationState.ValueType | None = ..., + figi: builtins.str | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_figi", b"_figi", "_from", b"_from", "_state", b"_state", "_to", b"_to", "figi", b"figi", "from", b"from", "state", b"state", "to", b"to"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_figi", b"_figi", "_from", b"_from", "_state", b"_state", "_to", b"_to", "account_id", b"account_id", "figi", b"figi", "from", b"from", "state", b"state", "to", b"to"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_figi", b"_figi"]) -> typing.Literal["figi"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_from", b"_from"]) -> typing.Literal["from"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_state", b"_state"]) -> typing.Literal["state"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_to", b"_to"]) -> typing.Literal["to"] | None: ... + +global___OperationsRequest = OperationsRequest + +@typing.final +class OperationsResponse(google.protobuf.message.Message): + """Список операций.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + OPERATIONS_FIELD_NUMBER: builtins.int + @property + def operations(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Operation]: + """Массив операций.""" + + def __init__( + self, + *, + operations: collections.abc.Iterable[global___Operation] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["operations", b"operations"]) -> None: ... + +global___OperationsResponse = OperationsResponse + +@typing.final +class Operation(google.protobuf.message.Message): + """Данные по операции.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ID_FIELD_NUMBER: builtins.int + PARENT_OPERATION_ID_FIELD_NUMBER: builtins.int + CURRENCY_FIELD_NUMBER: builtins.int + PAYMENT_FIELD_NUMBER: builtins.int + PRICE_FIELD_NUMBER: builtins.int + STATE_FIELD_NUMBER: builtins.int + QUANTITY_FIELD_NUMBER: builtins.int + QUANTITY_REST_FIELD_NUMBER: builtins.int + FIGI_FIELD_NUMBER: builtins.int + INSTRUMENT_TYPE_FIELD_NUMBER: builtins.int + DATE_FIELD_NUMBER: builtins.int + TYPE_FIELD_NUMBER: builtins.int + OPERATION_TYPE_FIELD_NUMBER: builtins.int + TRADES_FIELD_NUMBER: builtins.int + ASSET_UID_FIELD_NUMBER: builtins.int + POSITION_UID_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + CHILD_OPERATIONS_FIELD_NUMBER: builtins.int + id: builtins.str + """Идентификатор операции.""" + parent_operation_id: builtins.str + """Идентификатор родительской операции.""" + currency: builtins.str + """Валюта операции.""" + state: global___OperationState.ValueType + """Статус операции.""" + quantity: builtins.int + """Количество единиц инструмента.""" + quantity_rest: builtins.int + """Неисполненный остаток по сделке.""" + figi: builtins.str + """FIGI-идентификатор инструмента, связанного с операцией.""" + instrument_type: builtins.str + """Тип инструмента. Возможные значения:

`bond` — облигация;
`share` — акция;
`currency` — валюта;
`etf` — фонд;
`futures` — фьючерс.""" + type: builtins.str + """Текстовое описание типа операции.""" + operation_type: global___OperationType.ValueType + """Тип операции.""" + asset_uid: builtins.str + """Идентификатор актива""" + position_uid: builtins.str + """Уникальный идентификатор позиции.""" + instrument_uid: builtins.str + """Уникальный идентификатор инструмента.""" + @property + def payment(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Сумма операции.""" + + @property + def price(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Цена операции за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента.""" + + @property + def date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата и время операции в формате часовом поясе UTC.""" + + @property + def trades(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___OperationTrade]: + """Массив сделок.""" + + @property + def child_operations(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___ChildOperationItem]: + """Массив дочерних операций.""" + + def __init__( + self, + *, + id: builtins.str = ..., + parent_operation_id: builtins.str = ..., + currency: builtins.str = ..., + payment: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + price: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + state: global___OperationState.ValueType = ..., + quantity: builtins.int = ..., + quantity_rest: builtins.int = ..., + figi: builtins.str = ..., + instrument_type: builtins.str = ..., + date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + type: builtins.str = ..., + operation_type: global___OperationType.ValueType = ..., + trades: collections.abc.Iterable[global___OperationTrade] | None = ..., + asset_uid: builtins.str = ..., + position_uid: builtins.str = ..., + instrument_uid: builtins.str = ..., + child_operations: collections.abc.Iterable[global___ChildOperationItem] | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["date", b"date", "payment", b"payment", "price", b"price"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["asset_uid", b"asset_uid", "child_operations", b"child_operations", "currency", b"currency", "date", b"date", "figi", b"figi", "id", b"id", "instrument_type", b"instrument_type", "instrument_uid", b"instrument_uid", "operation_type", b"operation_type", "parent_operation_id", b"parent_operation_id", "payment", b"payment", "position_uid", b"position_uid", "price", b"price", "quantity", b"quantity", "quantity_rest", b"quantity_rest", "state", b"state", "trades", b"trades", "type", b"type"]) -> None: ... + +global___Operation = Operation + +@typing.final +class OperationTrade(google.protobuf.message.Message): + """Сделка по операции.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TRADE_ID_FIELD_NUMBER: builtins.int + DATE_TIME_FIELD_NUMBER: builtins.int + QUANTITY_FIELD_NUMBER: builtins.int + PRICE_FIELD_NUMBER: builtins.int + trade_id: builtins.str + """Идентификатор сделки.""" + quantity: builtins.int + """Количество инструментов.""" + @property + def date_time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата и время сделки по UTC.""" + + @property + def price(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Цена за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента.""" + + def __init__( + self, + *, + trade_id: builtins.str = ..., + date_time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + quantity: builtins.int = ..., + price: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["date_time", b"date_time", "price", b"price"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["date_time", b"date_time", "price", b"price", "quantity", b"quantity", "trade_id", b"trade_id"]) -> None: ... + +global___OperationTrade = OperationTrade + +@typing.final +class PortfolioRequest(google.protobuf.message.Message): + """Запрос получения текущего портфеля по счету.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _CurrencyRequest: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _CurrencyRequestEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[PortfolioRequest._CurrencyRequest.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + RUB: PortfolioRequest._CurrencyRequest.ValueType # 0 + """Рубли""" + USD: PortfolioRequest._CurrencyRequest.ValueType # 1 + """Доллары""" + EUR: PortfolioRequest._CurrencyRequest.ValueType # 2 + """Евро""" + + class CurrencyRequest(_CurrencyRequest, metaclass=_CurrencyRequestEnumTypeWrapper): ... + RUB: PortfolioRequest.CurrencyRequest.ValueType # 0 + """Рубли""" + USD: PortfolioRequest.CurrencyRequest.ValueType # 1 + """Доллары""" + EUR: PortfolioRequest.CurrencyRequest.ValueType # 2 + """Евро""" + + ACCOUNT_ID_FIELD_NUMBER: builtins.int + CURRENCY_FIELD_NUMBER: builtins.int + account_id: builtins.str + """Идентификатор счета пользователя.""" + currency: global___PortfolioRequest.CurrencyRequest.ValueType + """Валюта, в которой нужно рассчитать портфель.""" + def __init__( + self, + *, + account_id: builtins.str = ..., + currency: global___PortfolioRequest.CurrencyRequest.ValueType | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_currency", b"_currency", "currency", b"currency"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_currency", b"_currency", "account_id", b"account_id", "currency", b"currency"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_currency", b"_currency"]) -> typing.Literal["currency"] | None: ... + +global___PortfolioRequest = PortfolioRequest + +@typing.final +class PortfolioResponse(google.protobuf.message.Message): + """Текущий портфель по счету.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TOTAL_AMOUNT_SHARES_FIELD_NUMBER: builtins.int + TOTAL_AMOUNT_BONDS_FIELD_NUMBER: builtins.int + TOTAL_AMOUNT_ETF_FIELD_NUMBER: builtins.int + TOTAL_AMOUNT_CURRENCIES_FIELD_NUMBER: builtins.int + TOTAL_AMOUNT_FUTURES_FIELD_NUMBER: builtins.int + EXPECTED_YIELD_FIELD_NUMBER: builtins.int + POSITIONS_FIELD_NUMBER: builtins.int + ACCOUNT_ID_FIELD_NUMBER: builtins.int + TOTAL_AMOUNT_OPTIONS_FIELD_NUMBER: builtins.int + TOTAL_AMOUNT_SP_FIELD_NUMBER: builtins.int + TOTAL_AMOUNT_PORTFOLIO_FIELD_NUMBER: builtins.int + VIRTUAL_POSITIONS_FIELD_NUMBER: builtins.int + DAILY_YIELD_FIELD_NUMBER: builtins.int + DAILY_YIELD_RELATIVE_FIELD_NUMBER: builtins.int + TOTAL_AMOUNT_DFA_FIELD_NUMBER: builtins.int + account_id: builtins.str + """Идентификатор счета пользователя.""" + @property + def total_amount_shares(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Общая стоимость акций в портфеле.""" + + @property + def total_amount_bonds(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Общая стоимость облигаций в портфеле.""" + + @property + def total_amount_etf(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Общая стоимость фондов в портфеле.""" + + @property + def total_amount_currencies(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Общая стоимость валют в портфеле.""" + + @property + def total_amount_futures(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Общая стоимость фьючерсов в портфеле.""" + + @property + def expected_yield(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Текущая относительная доходность портфеля в %.""" + + @property + def positions(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___PortfolioPosition]: + """Список позиций портфеля.""" + + @property + def total_amount_options(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Общая стоимость опционов в портфеле.""" + + @property + def total_amount_sp(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Общая стоимость структурных нот в портфеле.""" + + @property + def total_amount_portfolio(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Общая стоимость портфеля.""" + + @property + def virtual_positions(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___VirtualPortfolioPosition]: + """Массив виртуальных позиций портфеля.""" + + @property + def daily_yield(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Рассчитанная доходность портфеля за день в рублях.""" + + @property + def daily_yield_relative(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Относительная доходность в день в %.""" + + @property + def total_amount_dfa(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Общая стоимость смарт-активов в портфеле в рублях.""" + + def __init__( + self, + *, + total_amount_shares: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + total_amount_bonds: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + total_amount_etf: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + total_amount_currencies: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + total_amount_futures: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + expected_yield: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + positions: collections.abc.Iterable[global___PortfolioPosition] | None = ..., + account_id: builtins.str = ..., + total_amount_options: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + total_amount_sp: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + total_amount_portfolio: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + virtual_positions: collections.abc.Iterable[global___VirtualPortfolioPosition] | None = ..., + daily_yield: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + daily_yield_relative: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + total_amount_dfa: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["daily_yield", b"daily_yield", "daily_yield_relative", b"daily_yield_relative", "expected_yield", b"expected_yield", "total_amount_bonds", b"total_amount_bonds", "total_amount_currencies", b"total_amount_currencies", "total_amount_dfa", b"total_amount_dfa", "total_amount_etf", b"total_amount_etf", "total_amount_futures", b"total_amount_futures", "total_amount_options", b"total_amount_options", "total_amount_portfolio", b"total_amount_portfolio", "total_amount_shares", b"total_amount_shares", "total_amount_sp", b"total_amount_sp"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["account_id", b"account_id", "daily_yield", b"daily_yield", "daily_yield_relative", b"daily_yield_relative", "expected_yield", b"expected_yield", "positions", b"positions", "total_amount_bonds", b"total_amount_bonds", "total_amount_currencies", b"total_amount_currencies", "total_amount_dfa", b"total_amount_dfa", "total_amount_etf", b"total_amount_etf", "total_amount_futures", b"total_amount_futures", "total_amount_options", b"total_amount_options", "total_amount_portfolio", b"total_amount_portfolio", "total_amount_shares", b"total_amount_shares", "total_amount_sp", b"total_amount_sp", "virtual_positions", b"virtual_positions"]) -> None: ... + +global___PortfolioResponse = PortfolioResponse + +@typing.final +class PositionsRequest(google.protobuf.message.Message): + """Запрос позиций портфеля по счету.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNT_ID_FIELD_NUMBER: builtins.int + account_id: builtins.str + """Идентификатор счета пользователя.""" + def __init__( + self, + *, + account_id: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["account_id", b"account_id"]) -> None: ... + +global___PositionsRequest = PositionsRequest + +@typing.final +class PositionsResponse(google.protobuf.message.Message): + """Список позиций по счету.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + MONEY_FIELD_NUMBER: builtins.int + BLOCKED_FIELD_NUMBER: builtins.int + SECURITIES_FIELD_NUMBER: builtins.int + LIMITS_LOADING_IN_PROGRESS_FIELD_NUMBER: builtins.int + FUTURES_FIELD_NUMBER: builtins.int + OPTIONS_FIELD_NUMBER: builtins.int + ACCOUNT_ID_FIELD_NUMBER: builtins.int + limits_loading_in_progress: builtins.bool + """Признак идущей выгрузки лимитов в данный момент.""" + account_id: builtins.str + """Идентификатор счёта пользователя.""" + @property + def money(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[t_tech.invest.grpc.common_pb2.MoneyValue]: + """Массив валютных позиций портфеля.""" + + @property + def blocked(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[t_tech.invest.grpc.common_pb2.MoneyValue]: + """Массив заблокированных валютных позиций портфеля.""" + + @property + def securities(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___PositionsSecurities]: + """Список ценно-бумажных позиций портфеля.""" + + @property + def futures(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___PositionsFutures]: + """Список фьючерсов портфеля.""" + + @property + def options(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___PositionsOptions]: + """Список опционов портфеля.""" + + def __init__( + self, + *, + money: collections.abc.Iterable[t_tech.invest.grpc.common_pb2.MoneyValue] | None = ..., + blocked: collections.abc.Iterable[t_tech.invest.grpc.common_pb2.MoneyValue] | None = ..., + securities: collections.abc.Iterable[global___PositionsSecurities] | None = ..., + limits_loading_in_progress: builtins.bool = ..., + futures: collections.abc.Iterable[global___PositionsFutures] | None = ..., + options: collections.abc.Iterable[global___PositionsOptions] | None = ..., + account_id: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["account_id", b"account_id", "blocked", b"blocked", "futures", b"futures", "limits_loading_in_progress", b"limits_loading_in_progress", "money", b"money", "options", b"options", "securities", b"securities"]) -> None: ... + +global___PositionsResponse = PositionsResponse + +@typing.final +class WithdrawLimitsRequest(google.protobuf.message.Message): + """Запрос доступного остатка для вывода.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNT_ID_FIELD_NUMBER: builtins.int + account_id: builtins.str + """Идентификатор счета пользователя.""" + def __init__( + self, + *, + account_id: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["account_id", b"account_id"]) -> None: ... + +global___WithdrawLimitsRequest = WithdrawLimitsRequest + +@typing.final +class WithdrawLimitsResponse(google.protobuf.message.Message): + """Доступный остаток для вывода.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + MONEY_FIELD_NUMBER: builtins.int + BLOCKED_FIELD_NUMBER: builtins.int + BLOCKED_GUARANTEE_FIELD_NUMBER: builtins.int + @property + def money(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[t_tech.invest.grpc.common_pb2.MoneyValue]: + """Массив валютных позиций портфеля.""" + + @property + def blocked(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[t_tech.invest.grpc.common_pb2.MoneyValue]: + """Массив заблокированных валютных позиций портфеля.""" + + @property + def blocked_guarantee(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[t_tech.invest.grpc.common_pb2.MoneyValue]: + """Заблокировано под гарантийное обеспечение фьючерсов.""" + + def __init__( + self, + *, + money: collections.abc.Iterable[t_tech.invest.grpc.common_pb2.MoneyValue] | None = ..., + blocked: collections.abc.Iterable[t_tech.invest.grpc.common_pb2.MoneyValue] | None = ..., + blocked_guarantee: collections.abc.Iterable[t_tech.invest.grpc.common_pb2.MoneyValue] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["blocked", b"blocked", "blocked_guarantee", b"blocked_guarantee", "money", b"money"]) -> None: ... + +global___WithdrawLimitsResponse = WithdrawLimitsResponse + +@typing.final +class PortfolioPosition(google.protobuf.message.Message): + """Позиции портфеля.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + INSTRUMENT_TYPE_FIELD_NUMBER: builtins.int + QUANTITY_FIELD_NUMBER: builtins.int + AVERAGE_POSITION_PRICE_FIELD_NUMBER: builtins.int + EXPECTED_YIELD_FIELD_NUMBER: builtins.int + CURRENT_NKD_FIELD_NUMBER: builtins.int + AVERAGE_POSITION_PRICE_PT_FIELD_NUMBER: builtins.int + CURRENT_PRICE_FIELD_NUMBER: builtins.int + AVERAGE_POSITION_PRICE_FIFO_FIELD_NUMBER: builtins.int + QUANTITY_LOTS_FIELD_NUMBER: builtins.int + BLOCKED_FIELD_NUMBER: builtins.int + BLOCKED_LOTS_FIELD_NUMBER: builtins.int + POSITION_UID_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + VAR_MARGIN_FIELD_NUMBER: builtins.int + EXPECTED_YIELD_FIFO_FIELD_NUMBER: builtins.int + DAILY_YIELD_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI-идентификатор инструмента.""" + instrument_type: builtins.str + """Тип инструмента.""" + blocked: builtins.bool + """Заблокировано на бирже.""" + position_uid: builtins.str + """Уникальный идентификатор позиции.""" + instrument_uid: builtins.str + """Уникальный идентификатор инструмента.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + @property + def quantity(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Количество инструмента в портфеле в штуках.""" + + @property + def average_position_price(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Средневзвешенная цена позиции. Для пересчета возможна задержка до одной секунды.""" + + @property + def expected_yield(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Текущая рассчитанная доходность позиции.""" + + @property + def current_nkd(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Текущий НКД.""" + + @property + def average_position_price_pt(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Deprecated Средняя цена позиции в пунктах (для фьючерсов). Для пересчета возможна задержка до одной секунды.""" + + @property + def current_price(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Текущая цена за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента.""" + + @property + def average_position_price_fifo(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Средняя цена позиции по методу FIFO. Для пересчета возможна задержка до одной секунды.""" + + @property + def quantity_lots(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Deprecated Количество лотов в портфеле.""" + + @property + def blocked_lots(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Количество бумаг, заблокированных выставленными заявками.""" + + @property + def var_margin(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Вариационная маржа.""" + + @property + def expected_yield_fifo(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Текущая рассчитанная доходность позиции.""" + + @property + def daily_yield(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Рассчитанная доходность портфеля за день.""" + + def __init__( + self, + *, + figi: builtins.str = ..., + instrument_type: builtins.str = ..., + quantity: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + average_position_price: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + expected_yield: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + current_nkd: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + average_position_price_pt: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + current_price: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + average_position_price_fifo: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + quantity_lots: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + blocked: builtins.bool = ..., + blocked_lots: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + position_uid: builtins.str = ..., + instrument_uid: builtins.str = ..., + var_margin: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + expected_yield_fifo: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + daily_yield: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["average_position_price", b"average_position_price", "average_position_price_fifo", b"average_position_price_fifo", "average_position_price_pt", b"average_position_price_pt", "blocked_lots", b"blocked_lots", "current_nkd", b"current_nkd", "current_price", b"current_price", "daily_yield", b"daily_yield", "expected_yield", b"expected_yield", "expected_yield_fifo", b"expected_yield_fifo", "quantity", b"quantity", "quantity_lots", b"quantity_lots", "var_margin", b"var_margin"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["average_position_price", b"average_position_price", "average_position_price_fifo", b"average_position_price_fifo", "average_position_price_pt", b"average_position_price_pt", "blocked", b"blocked", "blocked_lots", b"blocked_lots", "class_code", b"class_code", "current_nkd", b"current_nkd", "current_price", b"current_price", "daily_yield", b"daily_yield", "expected_yield", b"expected_yield", "expected_yield_fifo", b"expected_yield_fifo", "figi", b"figi", "instrument_type", b"instrument_type", "instrument_uid", b"instrument_uid", "position_uid", b"position_uid", "quantity", b"quantity", "quantity_lots", b"quantity_lots", "ticker", b"ticker", "var_margin", b"var_margin"]) -> None: ... + +global___PortfolioPosition = PortfolioPosition + +@typing.final +class VirtualPortfolioPosition(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + POSITION_UID_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + FIGI_FIELD_NUMBER: builtins.int + INSTRUMENT_TYPE_FIELD_NUMBER: builtins.int + QUANTITY_FIELD_NUMBER: builtins.int + AVERAGE_POSITION_PRICE_FIELD_NUMBER: builtins.int + EXPECTED_YIELD_FIELD_NUMBER: builtins.int + EXPECTED_YIELD_FIFO_FIELD_NUMBER: builtins.int + EXPIRE_DATE_FIELD_NUMBER: builtins.int + CURRENT_PRICE_FIELD_NUMBER: builtins.int + AVERAGE_POSITION_PRICE_FIFO_FIELD_NUMBER: builtins.int + DAILY_YIELD_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + position_uid: builtins.str + """Уникальный идентификатор позиции.""" + instrument_uid: builtins.str + """Уникальный идентификатор инструмента.""" + figi: builtins.str + """FIGI-идентификатор инструмента.""" + instrument_type: builtins.str + """Тип инструмента.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + @property + def quantity(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Количество инструмента в портфеле в штуках.""" + + @property + def average_position_price(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Средневзвешенная цена позиции. Для пересчета возможна задержка до одной секунды.""" + + @property + def expected_yield(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Текущая рассчитанная доходность позиции.""" + + @property + def expected_yield_fifo(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Текущая рассчитанная доходность позиции.""" + + @property + def expire_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата, до которой нужно продать виртуальные бумаги. После этой даты виртуальная позиция «сгораетт».""" + + @property + def current_price(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Текущая цена за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента.""" + + @property + def average_position_price_fifo(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Средняя цена позиции по методу FIFO. Для пересчета возможна задержка до одной секунды.""" + + @property + def daily_yield(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Рассчитанная доходность портфеля за день.""" + + def __init__( + self, + *, + position_uid: builtins.str = ..., + instrument_uid: builtins.str = ..., + figi: builtins.str = ..., + instrument_type: builtins.str = ..., + quantity: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + average_position_price: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + expected_yield: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + expected_yield_fifo: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + expire_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + current_price: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + average_position_price_fifo: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + daily_yield: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["average_position_price", b"average_position_price", "average_position_price_fifo", b"average_position_price_fifo", "current_price", b"current_price", "daily_yield", b"daily_yield", "expected_yield", b"expected_yield", "expected_yield_fifo", b"expected_yield_fifo", "expire_date", b"expire_date", "quantity", b"quantity"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["average_position_price", b"average_position_price", "average_position_price_fifo", b"average_position_price_fifo", "class_code", b"class_code", "current_price", b"current_price", "daily_yield", b"daily_yield", "expected_yield", b"expected_yield", "expected_yield_fifo", b"expected_yield_fifo", "expire_date", b"expire_date", "figi", b"figi", "instrument_type", b"instrument_type", "instrument_uid", b"instrument_uid", "position_uid", b"position_uid", "quantity", b"quantity", "ticker", b"ticker"]) -> None: ... + +global___VirtualPortfolioPosition = VirtualPortfolioPosition + +@typing.final +class PositionsSecurities(google.protobuf.message.Message): + """Баланс позиции ценной бумаги.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + BLOCKED_FIELD_NUMBER: builtins.int + BALANCE_FIELD_NUMBER: builtins.int + POSITION_UID_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + EXCHANGE_BLOCKED_FIELD_NUMBER: builtins.int + INSTRUMENT_TYPE_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI-идентификатор бумаги.""" + blocked: builtins.int + """Количество бумаг, заблокированных выставленными заявками.""" + balance: builtins.int + """Текущий незаблокированный баланс.""" + position_uid: builtins.str + """Уникальный идентификатор позиции.""" + instrument_uid: builtins.str + """Уникальный идентификатор инструмента.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + exchange_blocked: builtins.bool + """Заблокировано на бирже.""" + instrument_type: builtins.str + """Тип инструмента.""" + def __init__( + self, + *, + figi: builtins.str = ..., + blocked: builtins.int = ..., + balance: builtins.int = ..., + position_uid: builtins.str = ..., + instrument_uid: builtins.str = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + exchange_blocked: builtins.bool = ..., + instrument_type: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["balance", b"balance", "blocked", b"blocked", "class_code", b"class_code", "exchange_blocked", b"exchange_blocked", "figi", b"figi", "instrument_type", b"instrument_type", "instrument_uid", b"instrument_uid", "position_uid", b"position_uid", "ticker", b"ticker"]) -> None: ... + +global___PositionsSecurities = PositionsSecurities + +@typing.final +class PositionsFutures(google.protobuf.message.Message): + """Баланс фьючерса.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + BLOCKED_FIELD_NUMBER: builtins.int + BALANCE_FIELD_NUMBER: builtins.int + POSITION_UID_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + figi: builtins.str + """FIGI-идентификатор фьючерса.""" + blocked: builtins.int + """Количество бумаг, заблокированных выставленными заявками.""" + balance: builtins.int + """Текущий незаблокированный баланс.""" + position_uid: builtins.str + """Уникальный идентификатор позиции.""" + instrument_uid: builtins.str + """Уникальный идентификатор инструмента.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + def __init__( + self, + *, + figi: builtins.str = ..., + blocked: builtins.int = ..., + balance: builtins.int = ..., + position_uid: builtins.str = ..., + instrument_uid: builtins.str = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["balance", b"balance", "blocked", b"blocked", "class_code", b"class_code", "figi", b"figi", "instrument_uid", b"instrument_uid", "position_uid", b"position_uid", "ticker", b"ticker"]) -> None: ... + +global___PositionsFutures = PositionsFutures + +@typing.final +class PositionsOptions(google.protobuf.message.Message): + """Баланс опциона.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + POSITION_UID_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + BLOCKED_FIELD_NUMBER: builtins.int + BALANCE_FIELD_NUMBER: builtins.int + position_uid: builtins.str + """Уникальный идентификатор позиции опциона.""" + instrument_uid: builtins.str + """Уникальный идентификатор инструмента.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + blocked: builtins.int + """Количество бумаг, заблокированных выставленными заявками.""" + balance: builtins.int + """Текущий незаблокированный баланс.""" + def __init__( + self, + *, + position_uid: builtins.str = ..., + instrument_uid: builtins.str = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + blocked: builtins.int = ..., + balance: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["balance", b"balance", "blocked", b"blocked", "class_code", b"class_code", "instrument_uid", b"instrument_uid", "position_uid", b"position_uid", "ticker", b"ticker"]) -> None: ... + +global___PositionsOptions = PositionsOptions + +@typing.final +class BrokerReportRequest(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + GENERATE_BROKER_REPORT_REQUEST_FIELD_NUMBER: builtins.int + GET_BROKER_REPORT_REQUEST_FIELD_NUMBER: builtins.int + @property + def generate_broker_report_request(self) -> global___GenerateBrokerReportRequest: ... + @property + def get_broker_report_request(self) -> global___GetBrokerReportRequest: ... + def __init__( + self, + *, + generate_broker_report_request: global___GenerateBrokerReportRequest | None = ..., + get_broker_report_request: global___GetBrokerReportRequest | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["generate_broker_report_request", b"generate_broker_report_request", "get_broker_report_request", b"get_broker_report_request", "payload", b"payload"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["generate_broker_report_request", b"generate_broker_report_request", "get_broker_report_request", b"get_broker_report_request", "payload", b"payload"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["payload", b"payload"]) -> typing.Literal["generate_broker_report_request", "get_broker_report_request"] | None: ... + +global___BrokerReportRequest = BrokerReportRequest + +@typing.final +class BrokerReportResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + GENERATE_BROKER_REPORT_RESPONSE_FIELD_NUMBER: builtins.int + GET_BROKER_REPORT_RESPONSE_FIELD_NUMBER: builtins.int + @property + def generate_broker_report_response(self) -> global___GenerateBrokerReportResponse: ... + @property + def get_broker_report_response(self) -> global___GetBrokerReportResponse: ... + def __init__( + self, + *, + generate_broker_report_response: global___GenerateBrokerReportResponse | None = ..., + get_broker_report_response: global___GetBrokerReportResponse | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["generate_broker_report_response", b"generate_broker_report_response", "get_broker_report_response", b"get_broker_report_response", "payload", b"payload"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["generate_broker_report_response", b"generate_broker_report_response", "get_broker_report_response", b"get_broker_report_response", "payload", b"payload"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["payload", b"payload"]) -> typing.Literal["generate_broker_report_response", "get_broker_report_response"] | None: ... + +global___BrokerReportResponse = BrokerReportResponse + +@typing.final +class GenerateBrokerReportRequest(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNT_ID_FIELD_NUMBER: builtins.int + FROM_FIELD_NUMBER: builtins.int + TO_FIELD_NUMBER: builtins.int + account_id: builtins.str + """Идентификатор счета клиента.""" + @property + def to(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Окончание периода по UTC.""" + + def __init__( + self, + *, + account_id: builtins.str = ..., + to: google.protobuf.timestamp_pb2.Timestamp | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["from", b"from", "to", b"to"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["account_id", b"account_id", "from", b"from", "to", b"to"]) -> None: ... + +global___GenerateBrokerReportRequest = GenerateBrokerReportRequest + +@typing.final +class GenerateBrokerReportResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TASK_ID_FIELD_NUMBER: builtins.int + task_id: builtins.str + """Идентификатор задачи формирования брокерского отчета.""" + def __init__( + self, + *, + task_id: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["task_id", b"task_id"]) -> None: ... + +global___GenerateBrokerReportResponse = GenerateBrokerReportResponse + +@typing.final +class GetBrokerReportRequest(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TASK_ID_FIELD_NUMBER: builtins.int + PAGE_FIELD_NUMBER: builtins.int + task_id: builtins.str + """Идентификатор задачи формирования брокерского отчета.""" + page: builtins.int + """Номер страницы отчета, начинается с 1. Значение по умолчанию — 0.""" + def __init__( + self, + *, + task_id: builtins.str = ..., + page: builtins.int | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_page", b"_page", "page", b"page"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_page", b"_page", "page", b"page", "task_id", b"task_id"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_page", b"_page"]) -> typing.Literal["page"] | None: ... + +global___GetBrokerReportRequest = GetBrokerReportRequest + +@typing.final +class GetBrokerReportResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + BROKER_REPORT_FIELD_NUMBER: builtins.int + ITEMSCOUNT_FIELD_NUMBER: builtins.int + PAGESCOUNT_FIELD_NUMBER: builtins.int + PAGE_FIELD_NUMBER: builtins.int + TASK_ID_FIELD_NUMBER: builtins.int + itemsCount: builtins.int + """Количество записей в отчете.""" + pagesCount: builtins.int + """Количество страниц с данными отчета, начинается с 0.""" + page: builtins.int + """Текущая страница, начинается с 0.""" + task_id: builtins.str + """Идентификатор задачи формирования брокерского отчета.""" + @property + def broker_report(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___BrokerReport]: ... + def __init__( + self, + *, + broker_report: collections.abc.Iterable[global___BrokerReport] | None = ..., + itemsCount: builtins.int = ..., + pagesCount: builtins.int = ..., + page: builtins.int = ..., + task_id: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["broker_report", b"broker_report", "itemsCount", b"itemsCount", "page", b"page", "pagesCount", b"pagesCount", "task_id", b"task_id"]) -> None: ... + +global___GetBrokerReportResponse = GetBrokerReportResponse + +@typing.final +class BrokerReport(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TRADE_ID_FIELD_NUMBER: builtins.int + ORDER_ID_FIELD_NUMBER: builtins.int + FIGI_FIELD_NUMBER: builtins.int + EXECUTE_SIGN_FIELD_NUMBER: builtins.int + TRADE_DATETIME_FIELD_NUMBER: builtins.int + EXCHANGE_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + DIRECTION_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + PRICE_FIELD_NUMBER: builtins.int + QUANTITY_FIELD_NUMBER: builtins.int + ORDER_AMOUNT_FIELD_NUMBER: builtins.int + ACI_VALUE_FIELD_NUMBER: builtins.int + TOTAL_ORDER_AMOUNT_FIELD_NUMBER: builtins.int + BROKER_COMMISSION_FIELD_NUMBER: builtins.int + EXCHANGE_COMMISSION_FIELD_NUMBER: builtins.int + EXCHANGE_CLEARING_COMMISSION_FIELD_NUMBER: builtins.int + REPO_RATE_FIELD_NUMBER: builtins.int + PARTY_FIELD_NUMBER: builtins.int + CLEAR_VALUE_DATE_FIELD_NUMBER: builtins.int + SEC_VALUE_DATE_FIELD_NUMBER: builtins.int + BROKER_STATUS_FIELD_NUMBER: builtins.int + SEPARATE_AGREEMENT_TYPE_FIELD_NUMBER: builtins.int + SEPARATE_AGREEMENT_NUMBER_FIELD_NUMBER: builtins.int + SEPARATE_AGREEMENT_DATE_FIELD_NUMBER: builtins.int + DELIVERY_TYPE_FIELD_NUMBER: builtins.int + trade_id: builtins.str + """Номер сделки.""" + order_id: builtins.str + """Номер поручения.""" + figi: builtins.str + """FIGI-идентификаторинструмента.""" + execute_sign: builtins.str + """Признак исполнения.""" + exchange: builtins.str + """Торговая площадка.""" + class_code: builtins.str + """Режим торгов.""" + direction: builtins.str + """Вид сделки.""" + name: builtins.str + """Сокращенное наименование актива.""" + ticker: builtins.str + """Код актива.""" + quantity: builtins.int + """Количество.""" + party: builtins.str + """Контрагент или брокерарокер.""" + broker_status: builtins.str + """Статус брокера.""" + separate_agreement_type: builtins.str + """Тип договора.""" + separate_agreement_number: builtins.str + """Номер договора.""" + separate_agreement_date: builtins.str + """Дата договора.""" + delivery_type: builtins.str + """Тип расчета по сделке.""" + @property + def trade_datetime(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата и время заключения по UTC.""" + + @property + def price(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Цена за единицу.""" + + @property + def order_amount(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Сумма без НКД.""" + + @property + def aci_value(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """НКД.""" + + @property + def total_order_amount(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Сумма сделки.""" + + @property + def broker_commission(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Комиссия брокера.""" + + @property + def exchange_commission(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Комиссия биржи.""" + + @property + def exchange_clearing_commission(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Комиссия клирингового центра.""" + + @property + def repo_rate(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Ставка РЕПО, %.""" + + @property + def clear_value_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата расчетов по UTC.""" + + @property + def sec_value_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата поставки по UTC.""" + + def __init__( + self, + *, + trade_id: builtins.str = ..., + order_id: builtins.str = ..., + figi: builtins.str = ..., + execute_sign: builtins.str = ..., + trade_datetime: google.protobuf.timestamp_pb2.Timestamp | None = ..., + exchange: builtins.str = ..., + class_code: builtins.str = ..., + direction: builtins.str = ..., + name: builtins.str = ..., + ticker: builtins.str = ..., + price: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + quantity: builtins.int = ..., + order_amount: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + aci_value: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + total_order_amount: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + broker_commission: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + exchange_commission: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + exchange_clearing_commission: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + repo_rate: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + party: builtins.str = ..., + clear_value_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + sec_value_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + broker_status: builtins.str = ..., + separate_agreement_type: builtins.str = ..., + separate_agreement_number: builtins.str = ..., + separate_agreement_date: builtins.str = ..., + delivery_type: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["aci_value", b"aci_value", "broker_commission", b"broker_commission", "clear_value_date", b"clear_value_date", "exchange_clearing_commission", b"exchange_clearing_commission", "exchange_commission", b"exchange_commission", "order_amount", b"order_amount", "price", b"price", "repo_rate", b"repo_rate", "sec_value_date", b"sec_value_date", "total_order_amount", b"total_order_amount", "trade_datetime", b"trade_datetime"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["aci_value", b"aci_value", "broker_commission", b"broker_commission", "broker_status", b"broker_status", "class_code", b"class_code", "clear_value_date", b"clear_value_date", "delivery_type", b"delivery_type", "direction", b"direction", "exchange", b"exchange", "exchange_clearing_commission", b"exchange_clearing_commission", "exchange_commission", b"exchange_commission", "execute_sign", b"execute_sign", "figi", b"figi", "name", b"name", "order_amount", b"order_amount", "order_id", b"order_id", "party", b"party", "price", b"price", "quantity", b"quantity", "repo_rate", b"repo_rate", "sec_value_date", b"sec_value_date", "separate_agreement_date", b"separate_agreement_date", "separate_agreement_number", b"separate_agreement_number", "separate_agreement_type", b"separate_agreement_type", "ticker", b"ticker", "total_order_amount", b"total_order_amount", "trade_datetime", b"trade_datetime", "trade_id", b"trade_id"]) -> None: ... + +global___BrokerReport = BrokerReport + +@typing.final +class GetDividendsForeignIssuerRequest(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + GENERATE_DIV_FOREIGN_ISSUER_REPORT_FIELD_NUMBER: builtins.int + GET_DIV_FOREIGN_ISSUER_REPORT_FIELD_NUMBER: builtins.int + @property + def generate_div_foreign_issuer_report(self) -> global___GenerateDividendsForeignIssuerReportRequest: + """Объект запроса формирования отчета.""" + + @property + def get_div_foreign_issuer_report(self) -> global___GetDividendsForeignIssuerReportRequest: + """Объект запроса сформированного отчета.""" + + def __init__( + self, + *, + generate_div_foreign_issuer_report: global___GenerateDividendsForeignIssuerReportRequest | None = ..., + get_div_foreign_issuer_report: global___GetDividendsForeignIssuerReportRequest | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["generate_div_foreign_issuer_report", b"generate_div_foreign_issuer_report", "get_div_foreign_issuer_report", b"get_div_foreign_issuer_report", "payload", b"payload"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["generate_div_foreign_issuer_report", b"generate_div_foreign_issuer_report", "get_div_foreign_issuer_report", b"get_div_foreign_issuer_report", "payload", b"payload"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["payload", b"payload"]) -> typing.Literal["generate_div_foreign_issuer_report", "get_div_foreign_issuer_report"] | None: ... + +global___GetDividendsForeignIssuerRequest = GetDividendsForeignIssuerRequest + +@typing.final +class GetDividendsForeignIssuerResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + GENERATE_DIV_FOREIGN_ISSUER_REPORT_RESPONSE_FIELD_NUMBER: builtins.int + DIV_FOREIGN_ISSUER_REPORT_FIELD_NUMBER: builtins.int + @property + def generate_div_foreign_issuer_report_response(self) -> global___GenerateDividendsForeignIssuerReportResponse: + """Объект результата задачи запуска формирования отчета.""" + + @property + def div_foreign_issuer_report(self) -> global___GetDividendsForeignIssuerReportResponse: + """Отчет «Справка о доходах за пределами РФ».""" + + def __init__( + self, + *, + generate_div_foreign_issuer_report_response: global___GenerateDividendsForeignIssuerReportResponse | None = ..., + div_foreign_issuer_report: global___GetDividendsForeignIssuerReportResponse | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["div_foreign_issuer_report", b"div_foreign_issuer_report", "generate_div_foreign_issuer_report_response", b"generate_div_foreign_issuer_report_response", "payload", b"payload"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["div_foreign_issuer_report", b"div_foreign_issuer_report", "generate_div_foreign_issuer_report_response", b"generate_div_foreign_issuer_report_response", "payload", b"payload"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["payload", b"payload"]) -> typing.Literal["generate_div_foreign_issuer_report_response", "div_foreign_issuer_report"] | None: ... + +global___GetDividendsForeignIssuerResponse = GetDividendsForeignIssuerResponse + +@typing.final +class GenerateDividendsForeignIssuerReportRequest(google.protobuf.message.Message): + """Объект запроса формирования отчета «Справка о доходах за пределами РФ».""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNT_ID_FIELD_NUMBER: builtins.int + FROM_FIELD_NUMBER: builtins.int + TO_FIELD_NUMBER: builtins.int + account_id: builtins.str + """Идентификатор счета клиента.""" + @property + def to(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Окончание периода по UTC. Как правило, можно сформировать отчет по дату на несколько дней меньше текущей. Начало и окончание периода должны быть в рамках одного календарного года.""" + + def __init__( + self, + *, + account_id: builtins.str = ..., + to: google.protobuf.timestamp_pb2.Timestamp | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["from", b"from", "to", b"to"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["account_id", b"account_id", "from", b"from", "to", b"to"]) -> None: ... + +global___GenerateDividendsForeignIssuerReportRequest = GenerateDividendsForeignIssuerReportRequest + +@typing.final +class GetDividendsForeignIssuerReportRequest(google.protobuf.message.Message): + """Объект запроса сформированного отчета «Справка о доходах за пределами РФ».""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TASK_ID_FIELD_NUMBER: builtins.int + PAGE_FIELD_NUMBER: builtins.int + task_id: builtins.str + """Идентификатор задачи формирования отчета.""" + page: builtins.int + """Номер страницы отчета (начинается с 0), значение по умолчанию: 0.""" + def __init__( + self, + *, + task_id: builtins.str = ..., + page: builtins.int | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_page", b"_page", "page", b"page"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_page", b"_page", "page", b"page", "task_id", b"task_id"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_page", b"_page"]) -> typing.Literal["page"] | None: ... + +global___GetDividendsForeignIssuerReportRequest = GetDividendsForeignIssuerReportRequest + +@typing.final +class GenerateDividendsForeignIssuerReportResponse(google.protobuf.message.Message): + """Объект результата задачи запуска формирования отчета «Справка о доходах за пределами РФ».""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TASK_ID_FIELD_NUMBER: builtins.int + task_id: builtins.str + """Идентификатор задачи формирования отчета.""" + def __init__( + self, + *, + task_id: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["task_id", b"task_id"]) -> None: ... + +global___GenerateDividendsForeignIssuerReportResponse = GenerateDividendsForeignIssuerReportResponse + +@typing.final +class GetDividendsForeignIssuerReportResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + DIVIDENDS_FOREIGN_ISSUER_REPORT_FIELD_NUMBER: builtins.int + ITEMSCOUNT_FIELD_NUMBER: builtins.int + PAGESCOUNT_FIELD_NUMBER: builtins.int + PAGE_FIELD_NUMBER: builtins.int + itemsCount: builtins.int + """Количество записей в отчете.""" + pagesCount: builtins.int + """Количество страниц с данными отчета, начинается с 0.""" + page: builtins.int + """Текущая страница, начинается с 0.""" + @property + def dividends_foreign_issuer_report(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___DividendsForeignIssuerReport]: ... + def __init__( + self, + *, + dividends_foreign_issuer_report: collections.abc.Iterable[global___DividendsForeignIssuerReport] | None = ..., + itemsCount: builtins.int = ..., + pagesCount: builtins.int = ..., + page: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["dividends_foreign_issuer_report", b"dividends_foreign_issuer_report", "itemsCount", b"itemsCount", "page", b"page", "pagesCount", b"pagesCount"]) -> None: ... + +global___GetDividendsForeignIssuerReportResponse = GetDividendsForeignIssuerReportResponse + +@typing.final +class DividendsForeignIssuerReport(google.protobuf.message.Message): + """Отчет «Справка о доходах за пределами РФ».""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + RECORD_DATE_FIELD_NUMBER: builtins.int + PAYMENT_DATE_FIELD_NUMBER: builtins.int + SECURITY_NAME_FIELD_NUMBER: builtins.int + ISIN_FIELD_NUMBER: builtins.int + ISSUER_COUNTRY_FIELD_NUMBER: builtins.int + QUANTITY_FIELD_NUMBER: builtins.int + DIVIDEND_FIELD_NUMBER: builtins.int + EXTERNAL_COMMISSION_FIELD_NUMBER: builtins.int + DIVIDEND_GROSS_FIELD_NUMBER: builtins.int + TAX_FIELD_NUMBER: builtins.int + DIVIDEND_AMOUNT_FIELD_NUMBER: builtins.int + CURRENCY_FIELD_NUMBER: builtins.int + security_name: builtins.str + """Наименование ценной бумаги.""" + isin: builtins.str + """ISIN-идентификатор ценной бумаги.""" + issuer_country: builtins.str + """Страна эмитента. Для депозитарных расписок указывается страна эмитента базового актива.""" + quantity: builtins.int + """Количество ценных бумаг.""" + currency: builtins.str + """Валюта.""" + @property + def record_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата фиксации реестра.""" + + @property + def payment_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата выплаты.""" + + @property + def dividend(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Выплаты на одну бумагу""" + + @property + def external_commission(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Комиссия внешних платежных агентов.""" + + @property + def dividend_gross(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Сумма до удержания налога.""" + + @property + def tax(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Сумма налога, удержанного агентом.""" + + @property + def dividend_amount(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Итоговая сумма выплаты.""" + + def __init__( + self, + *, + record_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + payment_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + security_name: builtins.str = ..., + isin: builtins.str = ..., + issuer_country: builtins.str = ..., + quantity: builtins.int = ..., + dividend: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + external_commission: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dividend_gross: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + tax: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + dividend_amount: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + currency: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["dividend", b"dividend", "dividend_amount", b"dividend_amount", "dividend_gross", b"dividend_gross", "external_commission", b"external_commission", "payment_date", b"payment_date", "record_date", b"record_date", "tax", b"tax"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["currency", b"currency", "dividend", b"dividend", "dividend_amount", b"dividend_amount", "dividend_gross", b"dividend_gross", "external_commission", b"external_commission", "isin", b"isin", "issuer_country", b"issuer_country", "payment_date", b"payment_date", "quantity", b"quantity", "record_date", b"record_date", "security_name", b"security_name", "tax", b"tax"]) -> None: ... + +global___DividendsForeignIssuerReport = DividendsForeignIssuerReport + +@typing.final +class PortfolioStreamRequest(google.protobuf.message.Message): + """Запрос установки stream-соединения.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNTS_FIELD_NUMBER: builtins.int + PING_SETTINGS_FIELD_NUMBER: builtins.int + @property + def accounts(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Массив идентификаторов счетов пользователя.""" + + @property + def ping_settings(self) -> t_tech.invest.grpc.common_pb2.PingDelaySettings: + """Запрос настройки пинга.""" + + def __init__( + self, + *, + accounts: collections.abc.Iterable[builtins.str] | None = ..., + ping_settings: t_tech.invest.grpc.common_pb2.PingDelaySettings | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["ping_settings", b"ping_settings"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["accounts", b"accounts", "ping_settings", b"ping_settings"]) -> None: ... + +global___PortfolioStreamRequest = PortfolioStreamRequest + +@typing.final +class PortfolioStreamResponse(google.protobuf.message.Message): + """Информация по позициям и доходностям портфелей.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SUBSCRIPTIONS_FIELD_NUMBER: builtins.int + PORTFOLIO_FIELD_NUMBER: builtins.int + PING_FIELD_NUMBER: builtins.int + @property + def subscriptions(self) -> global___PortfolioSubscriptionResult: + """Объект результата подписки.""" + + @property + def portfolio(self) -> global___PortfolioResponse: + """Объект стриминга портфеля.""" + + @property + def ping(self) -> t_tech.invest.grpc.common_pb2.Ping: + """Проверка активности стрима.""" + + def __init__( + self, + *, + subscriptions: global___PortfolioSubscriptionResult | None = ..., + portfolio: global___PortfolioResponse | None = ..., + ping: t_tech.invest.grpc.common_pb2.Ping | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["payload", b"payload", "ping", b"ping", "portfolio", b"portfolio", "subscriptions", b"subscriptions"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["payload", b"payload", "ping", b"ping", "portfolio", b"portfolio", "subscriptions", b"subscriptions"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["payload", b"payload"]) -> typing.Literal["subscriptions", "portfolio", "ping"] | None: ... + +global___PortfolioStreamResponse = PortfolioStreamResponse + +@typing.final +class PortfolioSubscriptionResult(google.protobuf.message.Message): + """Объект результата подписки.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNTS_FIELD_NUMBER: builtins.int + TRACKING_ID_FIELD_NUMBER: builtins.int + STREAM_ID_FIELD_NUMBER: builtins.int + tracking_id: builtins.str + """Уникальный идентификатор запроса, подробнее: [tracking_id](/invest/intro/developer/protocols/grpc#tracking-id).""" + stream_id: builtins.str + """Идентификатор открытого соединения""" + @property + def accounts(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___AccountSubscriptionStatus]: + """Массив счетов клиента.""" + + def __init__( + self, + *, + accounts: collections.abc.Iterable[global___AccountSubscriptionStatus] | None = ..., + tracking_id: builtins.str = ..., + stream_id: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["accounts", b"accounts", "stream_id", b"stream_id", "tracking_id", b"tracking_id"]) -> None: ... + +global___PortfolioSubscriptionResult = PortfolioSubscriptionResult + +@typing.final +class AccountSubscriptionStatus(google.protobuf.message.Message): + """Счет клиента.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNT_ID_FIELD_NUMBER: builtins.int + SUBSCRIPTION_STATUS_FIELD_NUMBER: builtins.int + account_id: builtins.str + """Идентификатор счета.""" + subscription_status: global___PortfolioSubscriptionStatus.ValueType + """Результат подписки.""" + def __init__( + self, + *, + account_id: builtins.str = ..., + subscription_status: global___PortfolioSubscriptionStatus.ValueType = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["account_id", b"account_id", "subscription_status", b"subscription_status"]) -> None: ... + +global___AccountSubscriptionStatus = AccountSubscriptionStatus + +@typing.final +class GetOperationsByCursorRequest(google.protobuf.message.Message): + """Запрос списка операций по счету с пагинацией.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNT_ID_FIELD_NUMBER: builtins.int + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + FROM_FIELD_NUMBER: builtins.int + TO_FIELD_NUMBER: builtins.int + CURSOR_FIELD_NUMBER: builtins.int + LIMIT_FIELD_NUMBER: builtins.int + OPERATION_TYPES_FIELD_NUMBER: builtins.int + STATE_FIELD_NUMBER: builtins.int + WITHOUT_COMMISSIONS_FIELD_NUMBER: builtins.int + WITHOUT_TRADES_FIELD_NUMBER: builtins.int + WITHOUT_OVERNIGHTS_FIELD_NUMBER: builtins.int + account_id: builtins.str + """Идентификатор счета клиента, обязательный параметр. Остальные параметры опциональны.""" + instrument_id: builtins.str + """Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`.""" + cursor: builtins.str + """Идентификатор элемента, с которого начать формировать ответ.""" + limit: builtins.int + """Лимит количества операций. По умолчанию — `100`, максимальное значение — `1000`.""" + state: global___OperationState.ValueType + """Статус запрашиваемых операций. Возможные значения указаны в `OperationState`.""" + without_commissions: builtins.bool + """Флаг возврата комиссии. По умолчанию — `false`.""" + without_trades: builtins.bool + """Флаг получения ответа без массива сделок.""" + without_overnights: builtins.bool + """Флаг показа overnight операций.""" + @property + def to(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Окончание периода по UTC.""" + + @property + def operation_types(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[global___OperationType.ValueType]: + """Тип операции. Принимает значение из списка `OperationType`.""" + + def __init__( + self, + *, + account_id: builtins.str = ..., + instrument_id: builtins.str | None = ..., + to: google.protobuf.timestamp_pb2.Timestamp | None = ..., + cursor: builtins.str | None = ..., + limit: builtins.int | None = ..., + operation_types: collections.abc.Iterable[global___OperationType.ValueType] | None = ..., + state: global___OperationState.ValueType | None = ..., + without_commissions: builtins.bool | None = ..., + without_trades: builtins.bool | None = ..., + without_overnights: builtins.bool | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_cursor", b"_cursor", "_from", b"_from", "_instrument_id", b"_instrument_id", "_limit", b"_limit", "_state", b"_state", "_to", b"_to", "_without_commissions", b"_without_commissions", "_without_overnights", b"_without_overnights", "_without_trades", b"_without_trades", "cursor", b"cursor", "from", b"from", "instrument_id", b"instrument_id", "limit", b"limit", "state", b"state", "to", b"to", "without_commissions", b"without_commissions", "without_overnights", b"without_overnights", "without_trades", b"without_trades"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_cursor", b"_cursor", "_from", b"_from", "_instrument_id", b"_instrument_id", "_limit", b"_limit", "_state", b"_state", "_to", b"_to", "_without_commissions", b"_without_commissions", "_without_overnights", b"_without_overnights", "_without_trades", b"_without_trades", "account_id", b"account_id", "cursor", b"cursor", "from", b"from", "instrument_id", b"instrument_id", "limit", b"limit", "operation_types", b"operation_types", "state", b"state", "to", b"to", "without_commissions", b"without_commissions", "without_overnights", b"without_overnights", "without_trades", b"without_trades"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_cursor", b"_cursor"]) -> typing.Literal["cursor"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_from", b"_from"]) -> typing.Literal["from"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_instrument_id", b"_instrument_id"]) -> typing.Literal["instrument_id"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_limit", b"_limit"]) -> typing.Literal["limit"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_state", b"_state"]) -> typing.Literal["state"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_to", b"_to"]) -> typing.Literal["to"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_without_commissions", b"_without_commissions"]) -> typing.Literal["without_commissions"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_without_overnights", b"_without_overnights"]) -> typing.Literal["without_overnights"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_without_trades", b"_without_trades"]) -> typing.Literal["without_trades"] | None: ... + +global___GetOperationsByCursorRequest = GetOperationsByCursorRequest + +@typing.final +class GetOperationsByCursorResponse(google.protobuf.message.Message): + """Список операций по счету с пагинацией.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + HAS_NEXT_FIELD_NUMBER: builtins.int + NEXT_CURSOR_FIELD_NUMBER: builtins.int + ITEMS_FIELD_NUMBER: builtins.int + has_next: builtins.bool + """Признак, есть ли следующий элемент.""" + next_cursor: builtins.str + """Следующий курсор.""" + @property + def items(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___OperationItem]: + """Список операций.""" + + def __init__( + self, + *, + has_next: builtins.bool = ..., + next_cursor: builtins.str = ..., + items: collections.abc.Iterable[global___OperationItem] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["has_next", b"has_next", "items", b"items", "next_cursor", b"next_cursor"]) -> None: ... + +global___GetOperationsByCursorResponse = GetOperationsByCursorResponse + +@typing.final +class OperationItem(google.protobuf.message.Message): + """Данные об операции.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + CURSOR_FIELD_NUMBER: builtins.int + BROKER_ACCOUNT_ID_FIELD_NUMBER: builtins.int + ID_FIELD_NUMBER: builtins.int + PARENT_OPERATION_ID_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + DATE_FIELD_NUMBER: builtins.int + TYPE_FIELD_NUMBER: builtins.int + DESCRIPTION_FIELD_NUMBER: builtins.int + STATE_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + FIGI_FIELD_NUMBER: builtins.int + INSTRUMENT_TYPE_FIELD_NUMBER: builtins.int + INSTRUMENT_KIND_FIELD_NUMBER: builtins.int + POSITION_UID_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + PAYMENT_FIELD_NUMBER: builtins.int + PRICE_FIELD_NUMBER: builtins.int + COMMISSION_FIELD_NUMBER: builtins.int + YIELD_FIELD_NUMBER: builtins.int + YIELD_RELATIVE_FIELD_NUMBER: builtins.int + ACCRUED_INT_FIELD_NUMBER: builtins.int + QUANTITY_FIELD_NUMBER: builtins.int + QUANTITY_REST_FIELD_NUMBER: builtins.int + QUANTITY_DONE_FIELD_NUMBER: builtins.int + CANCEL_DATE_TIME_FIELD_NUMBER: builtins.int + CANCEL_REASON_FIELD_NUMBER: builtins.int + TRADES_INFO_FIELD_NUMBER: builtins.int + ASSET_UID_FIELD_NUMBER: builtins.int + CHILD_OPERATIONS_FIELD_NUMBER: builtins.int + cursor: builtins.str + """Курсор.""" + broker_account_id: builtins.str + """Номер счета клиента.""" + id: builtins.str + """Идентификатор операции, может меняться с течением времени.""" + parent_operation_id: builtins.str + """Идентификатор родительской операции. Может измениться, если изменился ID родительской операции.""" + name: builtins.str + """Название операции.""" + type: global___OperationType.ValueType + """Тип операции.""" + description: builtins.str + """Описание операции.""" + state: global___OperationState.ValueType + """Статус поручения.""" + instrument_uid: builtins.str + """Уникальный идентификатор инструмента.""" + figi: builtins.str + """FIGI.""" + instrument_type: builtins.str + """Тип инструмента.""" + instrument_kind: t_tech.invest.grpc.common_pb2.InstrumentType.ValueType + """Тип инструмента.""" + position_uid: builtins.str + """Уникальный идентификатор позиции.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + quantity: builtins.int + """Количество единиц инструмента.""" + quantity_rest: builtins.int + """Неисполненный остаток по сделке.""" + quantity_done: builtins.int + """Исполненный остаток.""" + cancel_reason: builtins.str + """Причина отмены операции.""" + asset_uid: builtins.str + """Идентификатор актива.""" + @property + def date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата поручения.""" + + @property + def payment(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Сумма операции.""" + + @property + def price(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Цена операции за 1 инструмент.""" + + @property + def commission(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Комиссия.""" + + @property + def yield_relative(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Относительная доходность.""" + + @property + def accrued_int(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Накопленный купонный доход.""" + + @property + def cancel_date_time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата и время снятия заявки.""" + + @property + def trades_info(self) -> global___OperationItemTrades: + """Массив сделок.""" + + @property + def child_operations(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___ChildOperationItem]: + """Массив дочерних операций.""" + + def __init__( + self, + *, + cursor: builtins.str = ..., + broker_account_id: builtins.str = ..., + id: builtins.str = ..., + parent_operation_id: builtins.str = ..., + name: builtins.str = ..., + date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + type: global___OperationType.ValueType = ..., + description: builtins.str = ..., + state: global___OperationState.ValueType = ..., + instrument_uid: builtins.str = ..., + figi: builtins.str = ..., + instrument_type: builtins.str = ..., + instrument_kind: t_tech.invest.grpc.common_pb2.InstrumentType.ValueType = ..., + position_uid: builtins.str = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + payment: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + price: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + commission: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + yield_relative: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + accrued_int: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + quantity: builtins.int = ..., + quantity_rest: builtins.int = ..., + quantity_done: builtins.int = ..., + cancel_date_time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + cancel_reason: builtins.str = ..., + trades_info: global___OperationItemTrades | None = ..., + asset_uid: builtins.str = ..., + child_operations: collections.abc.Iterable[global___ChildOperationItem] | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["accrued_int", b"accrued_int", "cancel_date_time", b"cancel_date_time", "commission", b"commission", "date", b"date", "payment", b"payment", "price", b"price", "trades_info", b"trades_info", "yield", b"yield", "yield_relative", b"yield_relative"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["accrued_int", b"accrued_int", "asset_uid", b"asset_uid", "broker_account_id", b"broker_account_id", "cancel_date_time", b"cancel_date_time", "cancel_reason", b"cancel_reason", "child_operations", b"child_operations", "class_code", b"class_code", "commission", b"commission", "cursor", b"cursor", "date", b"date", "description", b"description", "figi", b"figi", "id", b"id", "instrument_kind", b"instrument_kind", "instrument_type", b"instrument_type", "instrument_uid", b"instrument_uid", "name", b"name", "parent_operation_id", b"parent_operation_id", "payment", b"payment", "position_uid", b"position_uid", "price", b"price", "quantity", b"quantity", "quantity_done", b"quantity_done", "quantity_rest", b"quantity_rest", "state", b"state", "ticker", b"ticker", "trades_info", b"trades_info", "type", b"type", "yield", b"yield", "yield_relative", b"yield_relative"]) -> None: ... + +global___OperationItem = OperationItem + +@typing.final +class OperationItemTrades(google.protobuf.message.Message): + """Массив с информацией о сделках.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TRADES_FIELD_NUMBER: builtins.int + @property + def trades(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___OperationItemTrade]: ... + def __init__( + self, + *, + trades: collections.abc.Iterable[global___OperationItemTrade] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["trades", b"trades"]) -> None: ... + +global___OperationItemTrades = OperationItemTrades + +@typing.final +class OperationItemTrade(google.protobuf.message.Message): + """Сделка по операции.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + NUM_FIELD_NUMBER: builtins.int + DATE_FIELD_NUMBER: builtins.int + QUANTITY_FIELD_NUMBER: builtins.int + PRICE_FIELD_NUMBER: builtins.int + YIELD_FIELD_NUMBER: builtins.int + YIELD_RELATIVE_FIELD_NUMBER: builtins.int + num: builtins.str + """Номер сделки.""" + quantity: builtins.int + """Количество в единицах.""" + @property + def date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата сделки.""" + + @property + def price(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Цена.""" + + @property + def yield_relative(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Относительная доходность.""" + + def __init__( + self, + *, + num: builtins.str = ..., + date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + quantity: builtins.int = ..., + price: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + yield_relative: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["date", b"date", "price", b"price", "yield", b"yield", "yield_relative", b"yield_relative"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["date", b"date", "num", b"num", "price", b"price", "quantity", b"quantity", "yield", b"yield", "yield_relative", b"yield_relative"]) -> None: ... + +global___OperationItemTrade = OperationItemTrade + +@typing.final +class PositionsStreamRequest(google.protobuf.message.Message): + """Запрос установки stream-соединения позиций.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNTS_FIELD_NUMBER: builtins.int + WITH_INITIAL_POSITIONS_FIELD_NUMBER: builtins.int + PING_SETTINGS_FIELD_NUMBER: builtins.int + with_initial_positions: builtins.bool + """Получение состояния позиций на момент подключения.""" + @property + def accounts(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Массив идентификаторов счетов пользователя.""" + + @property + def ping_settings(self) -> t_tech.invest.grpc.common_pb2.PingDelaySettings: + """Запрос настройки пинга.""" + + def __init__( + self, + *, + accounts: collections.abc.Iterable[builtins.str] | None = ..., + with_initial_positions: builtins.bool = ..., + ping_settings: t_tech.invest.grpc.common_pb2.PingDelaySettings | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["ping_settings", b"ping_settings"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["accounts", b"accounts", "ping_settings", b"ping_settings", "with_initial_positions", b"with_initial_positions"]) -> None: ... + +global___PositionsStreamRequest = PositionsStreamRequest + +@typing.final +class PositionsStreamResponse(google.protobuf.message.Message): + """Информация по изменению позиций портфеля.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SUBSCRIPTIONS_FIELD_NUMBER: builtins.int + POSITION_FIELD_NUMBER: builtins.int + PING_FIELD_NUMBER: builtins.int + INITIAL_POSITIONS_FIELD_NUMBER: builtins.int + @property + def subscriptions(self) -> global___PositionsSubscriptionResult: + """Объект результата подписки.""" + + @property + def position(self) -> global___PositionData: + """Объект стриминга позиций.""" + + @property + def ping(self) -> t_tech.invest.grpc.common_pb2.Ping: + """Проверка активности стрима.""" + + @property + def initial_positions(self) -> global___PositionsResponse: + """Текущие позиции.""" + + def __init__( + self, + *, + subscriptions: global___PositionsSubscriptionResult | None = ..., + position: global___PositionData | None = ..., + ping: t_tech.invest.grpc.common_pb2.Ping | None = ..., + initial_positions: global___PositionsResponse | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["initial_positions", b"initial_positions", "payload", b"payload", "ping", b"ping", "position", b"position", "subscriptions", b"subscriptions"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["initial_positions", b"initial_positions", "payload", b"payload", "ping", b"ping", "position", b"position", "subscriptions", b"subscriptions"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["payload", b"payload"]) -> typing.Literal["subscriptions", "position", "ping", "initial_positions"] | None: ... + +global___PositionsStreamResponse = PositionsStreamResponse + +@typing.final +class PositionsSubscriptionResult(google.protobuf.message.Message): + """Объект результата подписки.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNTS_FIELD_NUMBER: builtins.int + TRACKING_ID_FIELD_NUMBER: builtins.int + STREAM_ID_FIELD_NUMBER: builtins.int + tracking_id: builtins.str + """Уникальный идентификатор запроса, подробнее: [tracking_id](/invest/intro/developer/protocols/grpc#tracking-id).""" + stream_id: builtins.str + """Идентификатор открытого соединения""" + @property + def accounts(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___PositionsSubscriptionStatus]: + """Массив счетов клиента.""" + + def __init__( + self, + *, + accounts: collections.abc.Iterable[global___PositionsSubscriptionStatus] | None = ..., + tracking_id: builtins.str = ..., + stream_id: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["accounts", b"accounts", "stream_id", b"stream_id", "tracking_id", b"tracking_id"]) -> None: ... + +global___PositionsSubscriptionResult = PositionsSubscriptionResult + +@typing.final +class PositionsSubscriptionStatus(google.protobuf.message.Message): + """Счет клиента.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNT_ID_FIELD_NUMBER: builtins.int + SUBSCRIPTION_STATUS_FIELD_NUMBER: builtins.int + account_id: builtins.str + """Идентификатор счета.""" + subscription_status: global___PositionsAccountSubscriptionStatus.ValueType + """Результат подписки.""" + def __init__( + self, + *, + account_id: builtins.str = ..., + subscription_status: global___PositionsAccountSubscriptionStatus.ValueType = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["account_id", b"account_id", "subscription_status", b"subscription_status"]) -> None: ... + +global___PositionsSubscriptionStatus = PositionsSubscriptionStatus + +@typing.final +class PositionData(google.protobuf.message.Message): + """Данные о позиции портфеля.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNT_ID_FIELD_NUMBER: builtins.int + MONEY_FIELD_NUMBER: builtins.int + SECURITIES_FIELD_NUMBER: builtins.int + FUTURES_FIELD_NUMBER: builtins.int + OPTIONS_FIELD_NUMBER: builtins.int + DATE_FIELD_NUMBER: builtins.int + account_id: builtins.str + """Идентификатор счета.""" + @property + def money(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___PositionsMoney]: + """Массив валютных позиций портфеля.""" + + @property + def securities(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___PositionsSecurities]: + """Список ценно-бумажных позиций портфеля.""" + + @property + def futures(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___PositionsFutures]: + """Список фьючерсов портфеля.""" + + @property + def options(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___PositionsOptions]: + """Список опционов портфеля.""" + + @property + def date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата и время операции в формате UTC.""" + + def __init__( + self, + *, + account_id: builtins.str = ..., + money: collections.abc.Iterable[global___PositionsMoney] | None = ..., + securities: collections.abc.Iterable[global___PositionsSecurities] | None = ..., + futures: collections.abc.Iterable[global___PositionsFutures] | None = ..., + options: collections.abc.Iterable[global___PositionsOptions] | None = ..., + date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["date", b"date"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["account_id", b"account_id", "date", b"date", "futures", b"futures", "money", b"money", "options", b"options", "securities", b"securities"]) -> None: ... + +global___PositionData = PositionData + +@typing.final +class PositionsMoney(google.protobuf.message.Message): + """Валютная позиция портфеля.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + AVAILABLE_VALUE_FIELD_NUMBER: builtins.int + BLOCKED_VALUE_FIELD_NUMBER: builtins.int + @property + def available_value(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Доступное количество валютный позиций.""" + + @property + def blocked_value(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Заблокированное количество валютных позиций.""" + + def __init__( + self, + *, + available_value: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + blocked_value: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["available_value", b"available_value", "blocked_value", b"blocked_value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["available_value", b"available_value", "blocked_value", b"blocked_value"]) -> None: ... + +global___PositionsMoney = PositionsMoney + +@typing.final +class ChildOperationItem(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + PAYMENT_FIELD_NUMBER: builtins.int + instrument_uid: builtins.str + """Уникальный идентификатор инструмента.""" + @property + def payment(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Сумма операции.""" + + def __init__( + self, + *, + instrument_uid: builtins.str = ..., + payment: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["payment", b"payment"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["instrument_uid", b"instrument_uid", "payment", b"payment"]) -> None: ... + +global___ChildOperationItem = ChildOperationItem + +@typing.final +class OperationsStreamRequest(google.protobuf.message.Message): + """Запрос установки stream-соединения операций.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNTS_FIELD_NUMBER: builtins.int + PING_SETTINGS_FIELD_NUMBER: builtins.int + @property + def accounts(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Массив идентификаторов счетов пользователя.""" + + @property + def ping_settings(self) -> t_tech.invest.grpc.common_pb2.PingDelaySettings: + """Запрос настройки пинга.""" + + def __init__( + self, + *, + accounts: collections.abc.Iterable[builtins.str] | None = ..., + ping_settings: t_tech.invest.grpc.common_pb2.PingDelaySettings | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["ping_settings", b"ping_settings"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["accounts", b"accounts", "ping_settings", b"ping_settings"]) -> None: ... + +global___OperationsStreamRequest = OperationsStreamRequest + +@typing.final +class OperationsStreamResponse(google.protobuf.message.Message): + """Информация по операциям.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SUBSCRIPTIONS_FIELD_NUMBER: builtins.int + OPERATION_FIELD_NUMBER: builtins.int + PING_FIELD_NUMBER: builtins.int + @property + def subscriptions(self) -> global___OperationsSubscriptionResult: + """Объект результата подписки.""" + + @property + def operation(self) -> global___OperationData: + """Объект стриминга операций.""" + + @property + def ping(self) -> t_tech.invest.grpc.common_pb2.Ping: + """Проверка активности стрима.""" + + def __init__( + self, + *, + subscriptions: global___OperationsSubscriptionResult | None = ..., + operation: global___OperationData | None = ..., + ping: t_tech.invest.grpc.common_pb2.Ping | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["operation", b"operation", "payload", b"payload", "ping", b"ping", "subscriptions", b"subscriptions"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["operation", b"operation", "payload", b"payload", "ping", b"ping", "subscriptions", b"subscriptions"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["payload", b"payload"]) -> typing.Literal["subscriptions", "operation", "ping"] | None: ... + +global___OperationsStreamResponse = OperationsStreamResponse + +@typing.final +class OperationsSubscriptionResult(google.protobuf.message.Message): + """Объект результата подписки.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNTS_FIELD_NUMBER: builtins.int + SUBSCRIPTION_STATUS_FIELD_NUMBER: builtins.int + TRACKING_ID_FIELD_NUMBER: builtins.int + STREAM_ID_FIELD_NUMBER: builtins.int + subscription_status: global___OperationsAccountSubscriptionStatus.ValueType + """Результат подписки.""" + tracking_id: builtins.str + """Уникальный идентификатор запроса, подробнее: [tracking_id](/invest/intro/developer/protocols/grpc#tracking-id).""" + stream_id: builtins.str + """Идентификатор открытого соединения""" + @property + def accounts(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Массив счетов клиента.""" + + def __init__( + self, + *, + accounts: collections.abc.Iterable[builtins.str] | None = ..., + subscription_status: global___OperationsAccountSubscriptionStatus.ValueType = ..., + tracking_id: builtins.str = ..., + stream_id: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["accounts", b"accounts", "stream_id", b"stream_id", "subscription_status", b"subscription_status", "tracking_id", b"tracking_id"]) -> None: ... + +global___OperationsSubscriptionResult = OperationsSubscriptionResult + +@typing.final +class OperationData(google.protobuf.message.Message): + """Данные об операции.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + BROKER_ACCOUNT_ID_FIELD_NUMBER: builtins.int + ID_FIELD_NUMBER: builtins.int + PARENT_OPERATION_ID_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + DATE_FIELD_NUMBER: builtins.int + TYPE_FIELD_NUMBER: builtins.int + STATE_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + FIGI_FIELD_NUMBER: builtins.int + INSTRUMENT_TYPE_FIELD_NUMBER: builtins.int + INSTRUMENT_KIND_FIELD_NUMBER: builtins.int + POSITION_UID_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + PAYMENT_FIELD_NUMBER: builtins.int + broker_account_id: builtins.str + """Идентификатор счета.""" + id: builtins.str + """Номер поручения.""" + parent_operation_id: builtins.str + """Номер родительского поручения.""" + name: builtins.str + """Название инструмента.""" + type: global___OperationType.ValueType + """Тип операции.""" + state: global___OperationState.ValueType + """Статус поручения.""" + instrument_uid: builtins.str + """Уникальный идентификатор инструмента.""" + figi: builtins.str + """FIGI-идентификатор инструмента.""" + instrument_type: builtins.str + """Тип инструмента.""" + instrument_kind: t_tech.invest.grpc.common_pb2.InstrumentType.ValueType + """Тип инструмента.""" + position_uid: builtins.str + """Идентификатор позиции.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + @property + def date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата.""" + + @property + def payment(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Сумма операции.""" + + def __init__( + self, + *, + broker_account_id: builtins.str = ..., + id: builtins.str = ..., + parent_operation_id: builtins.str = ..., + name: builtins.str = ..., + date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + type: global___OperationType.ValueType = ..., + state: global___OperationState.ValueType = ..., + instrument_uid: builtins.str = ..., + figi: builtins.str = ..., + instrument_type: builtins.str = ..., + instrument_kind: t_tech.invest.grpc.common_pb2.InstrumentType.ValueType = ..., + position_uid: builtins.str = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + payment: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["date", b"date", "payment", b"payment"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["broker_account_id", b"broker_account_id", "class_code", b"class_code", "date", b"date", "figi", b"figi", "id", b"id", "instrument_kind", b"instrument_kind", "instrument_type", b"instrument_type", "instrument_uid", b"instrument_uid", "name", b"name", "parent_operation_id", b"parent_operation_id", "payment", b"payment", "position_uid", b"position_uid", "state", b"state", "ticker", b"ticker", "type", b"type"]) -> None: ... + +global___OperationData = OperationData diff --git a/invest-python-master/t_tech/invest/grpc/operations_pb2_grpc.py b/invest-python-master/t_tech/invest/grpc/operations_pb2_grpc.py new file mode 100644 index 0000000..6cf38f8 --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/operations_pb2_grpc.py @@ -0,0 +1,414 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +from t_tech.invest.grpc import ( + operations_pb2 as t__tech_dot_invest_dot_grpc_dot_operations__pb2, +) + + +class OperationsServiceStub(object): + """С помощью методов сервиса можно получить:

**1**. Список операций по счету.
**2**. + Портфель по счету.
**3**. Позиции ценных бумаг на счете.
**4**. + Доступный остаток для вывода средств.
**5**. Различные отчеты. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.GetOperations = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.OperationsService/GetOperations', + request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsResponse.FromString, + ) + self.GetPortfolio = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.OperationsService/GetPortfolio', + request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioResponse.FromString, + ) + self.GetPositions = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.OperationsService/GetPositions', + request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsResponse.FromString, + ) + self.GetWithdrawLimits = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.OperationsService/GetWithdrawLimits', + request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.WithdrawLimitsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.WithdrawLimitsResponse.FromString, + ) + self.GetBrokerReport = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.OperationsService/GetBrokerReport', + request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.BrokerReportRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.BrokerReportResponse.FromString, + ) + self.GetDividendsForeignIssuer = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.OperationsService/GetDividendsForeignIssuer', + request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetDividendsForeignIssuerRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetDividendsForeignIssuerResponse.FromString, + ) + self.GetOperationsByCursor = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.OperationsService/GetOperationsByCursor', + request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetOperationsByCursorRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetOperationsByCursorResponse.FromString, + ) + + +class OperationsServiceServicer(object): + """С помощью методов сервиса можно получить:

**1**. Список операций по счету.
**2**. + Портфель по счету.
**3**. Позиции ценных бумаг на счете.
**4**. + Доступный остаток для вывода средств.
**5**. Различные отчеты. + """ + + def GetOperations(self, request, context): + """GetOperations — список операций по счету + При работе с методом учитывайте [особенности взаимодействия](/invest/services/operations/operations_problems). + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetPortfolio(self, request, context): + """GetPortfolio — портфель по счету + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetPositions(self, request, context): + """GetPositions — список позиций по счету + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetWithdrawLimits(self, request, context): + """GetWithdrawLimits — доступный остаток для вывода средств + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetBrokerReport(self, request, context): + """GetBrokerReport — брокерский отчет. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetDividendsForeignIssuer(self, request, context): + """GetDividendsForeignIssuer — отчет «Справка о доходах за пределами РФ» + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetOperationsByCursor(self, request, context): + """GetOperationsByCursor — список операций по счету с пагинацией + При работе с методом учитывайте [особенности взаимодействия](/invest/services/operations/operations_problems). + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_OperationsServiceServicer_to_server(servicer, server): + rpc_method_handlers = { + 'GetOperations': grpc.unary_unary_rpc_method_handler( + servicer.GetOperations, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsResponse.SerializeToString, + ), + 'GetPortfolio': grpc.unary_unary_rpc_method_handler( + servicer.GetPortfolio, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioResponse.SerializeToString, + ), + 'GetPositions': grpc.unary_unary_rpc_method_handler( + servicer.GetPositions, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsResponse.SerializeToString, + ), + 'GetWithdrawLimits': grpc.unary_unary_rpc_method_handler( + servicer.GetWithdrawLimits, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.WithdrawLimitsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.WithdrawLimitsResponse.SerializeToString, + ), + 'GetBrokerReport': grpc.unary_unary_rpc_method_handler( + servicer.GetBrokerReport, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.BrokerReportRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.BrokerReportResponse.SerializeToString, + ), + 'GetDividendsForeignIssuer': grpc.unary_unary_rpc_method_handler( + servicer.GetDividendsForeignIssuer, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetDividendsForeignIssuerRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetDividendsForeignIssuerResponse.SerializeToString, + ), + 'GetOperationsByCursor': grpc.unary_unary_rpc_method_handler( + servicer.GetOperationsByCursor, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetOperationsByCursorRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetOperationsByCursorResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'tinkoff.public.invest.api.contract.v1.OperationsService', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class OperationsService(object): + """С помощью методов сервиса можно получить:

**1**. Список операций по счету.
**2**. + Портфель по счету.
**3**. Позиции ценных бумаг на счете.
**4**. + Доступный остаток для вывода средств.
**5**. Различные отчеты. + """ + + @staticmethod + def GetOperations(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OperationsService/GetOperations', + t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetPortfolio(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OperationsService/GetPortfolio', + t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetPositions(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OperationsService/GetPositions', + t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetWithdrawLimits(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OperationsService/GetWithdrawLimits', + t__tech_dot_invest_dot_grpc_dot_operations__pb2.WithdrawLimitsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_operations__pb2.WithdrawLimitsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetBrokerReport(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OperationsService/GetBrokerReport', + t__tech_dot_invest_dot_grpc_dot_operations__pb2.BrokerReportRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_operations__pb2.BrokerReportResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetDividendsForeignIssuer(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OperationsService/GetDividendsForeignIssuer', + t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetDividendsForeignIssuerRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetDividendsForeignIssuerResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetOperationsByCursor(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OperationsService/GetOperationsByCursor', + t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetOperationsByCursorRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetOperationsByCursorResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + +class OperationsStreamServiceStub(object): + """Missing associated documentation comment in .proto file.""" + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.PortfolioStream = channel.unary_stream( + '/tinkoff.public.invest.api.contract.v1.OperationsStreamService/PortfolioStream', + request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioStreamRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioStreamResponse.FromString, + ) + self.PositionsStream = channel.unary_stream( + '/tinkoff.public.invest.api.contract.v1.OperationsStreamService/PositionsStream', + request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsStreamRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsStreamResponse.FromString, + ) + self.OperationsStream = channel.unary_stream( + '/tinkoff.public.invest.api.contract.v1.OperationsStreamService/OperationsStream', + request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsStreamRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsStreamResponse.FromString, + ) + + +class OperationsStreamServiceServicer(object): + """Missing associated documentation comment in .proto file.""" + + def PortfolioStream(self, request, context): + """PortfolioStream — стрим обновлений портфеля + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def PositionsStream(self, request, context): + """PositionsStream — стрим обновлений информации по изменению позиций портфеля + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def OperationsStream(self, request, context): + """OperationsStream — стрим обновлений операций + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_OperationsStreamServiceServicer_to_server(servicer, server): + rpc_method_handlers = { + 'PortfolioStream': grpc.unary_stream_rpc_method_handler( + servicer.PortfolioStream, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioStreamRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioStreamResponse.SerializeToString, + ), + 'PositionsStream': grpc.unary_stream_rpc_method_handler( + servicer.PositionsStream, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsStreamRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsStreamResponse.SerializeToString, + ), + 'OperationsStream': grpc.unary_stream_rpc_method_handler( + servicer.OperationsStream, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsStreamRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsStreamResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'tinkoff.public.invest.api.contract.v1.OperationsStreamService', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class OperationsStreamService(object): + """Missing associated documentation comment in .proto file.""" + + @staticmethod + def PortfolioStream(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_stream(request, target, '/tinkoff.public.invest.api.contract.v1.OperationsStreamService/PortfolioStream', + t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioStreamRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioStreamResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def PositionsStream(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_stream(request, target, '/tinkoff.public.invest.api.contract.v1.OperationsStreamService/PositionsStream', + t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsStreamRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsStreamResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def OperationsStream(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_stream(request, target, '/tinkoff.public.invest.api.contract.v1.OperationsStreamService/OperationsStream', + t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsStreamRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsStreamResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/invest-python-master/t_tech/invest/grpc/orders_pb2.py b/invest-python-master/t_tech/invest/grpc/orders_pb2.py new file mode 100644 index 0000000..56c14bb --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/orders_pb2.py @@ -0,0 +1,161 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: t_tech/invest/grpc/orders.proto +# Protobuf Python Version: 4.25.1 +"""Generated protocol buffer code.""" +from google.protobuf import ( + descriptor as _descriptor, + descriptor_pool as _descriptor_pool, + symbol_database as _symbol_database, +) +from google.protobuf.internal import builder as _builder + +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 + +from t_tech.invest.grpc import common_pb2 as t__tech_dot_invest_dot_grpc_dot_common__pb2 +from t_tech.invest.grpc.google.api import ( + field_behavior_pb2 as t__tech_dot_invest_dot_grpc_dot_google_dot_api_dot_field__behavior__pb2, +) + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1ft_tech/invest/grpc/orders.proto\x12%tinkoff.public.invest.api.contract.v1\x1a\x1ft_tech/invest/grpc/common.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x32t_tech/invest/grpc/google/api/field_behavior.proto\"U\n\x13TradesStreamRequest\x12\x10\n\x08\x61\x63\x63ounts\x18\x01 \x03(\t\x12\x1a\n\rping_delay_ms\x18\x0f \x01(\x05H\x00\x88\x01\x01\x42\x10\n\x0e_ping_delay_ms\"\xff\x01\n\x14TradesStreamResponse\x12J\n\x0corder_trades\x18\x01 \x01(\x0b\x32\x32.tinkoff.public.invest.api.contract.v1.OrderTradesH\x00\x12;\n\x04ping\x18\x02 \x01(\x0b\x32+.tinkoff.public.invest.api.contract.v1.PingH\x00\x12S\n\x0csubscription\x18\x03 \x01(\x0b\x32;.tinkoff.public.invest.api.contract.v1.SubscriptionResponseH\x00\x42\t\n\x07payload\"\x96\x02\n\x0bOrderTrades\x12\x10\n\x08order_id\x18\x01 \x01(\t\x12.\n\ncreated_at\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12H\n\tdirection\x18\x03 \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.OrderDirection\x12\x0c\n\x04\x66igi\x18\x04 \x01(\t\x12\x41\n\x06trades\x18\x05 \x03(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.OrderTrade\x12\x12\n\naccount_id\x18\x06 \x01(\t\x12\x16\n\x0einstrument_uid\x18\x07 \x01(\t\"\xa0\x01\n\nOrderTrade\x12-\n\tdate_time\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12?\n\x05price\x18\x02 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x10\n\x08quantity\x18\x03 \x01(\x03\x12\x10\n\x08trade_id\x18\x04 \x01(\t\"\xb2\x04\n\x10PostOrderRequest\x12\x15\n\x04\x66igi\x18\x01 \x01(\tB\x02\x18\x01H\x00\x88\x01\x01\x12\x16\n\x08quantity\x18\x02 \x01(\x03\x42\x04\xe2\x41\x01\x02\x12\x44\n\x05price\x18\x03 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationH\x01\x88\x01\x01\x12N\n\tdirection\x18\x04 \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.OrderDirectionB\x04\xe2\x41\x01\x02\x12\x18\n\naccount_id\x18\x05 \x01(\tB\x04\xe2\x41\x01\x02\x12J\n\norder_type\x18\x06 \x01(\x0e\x32\x30.tinkoff.public.invest.api.contract.v1.OrderTypeB\x04\xe2\x41\x01\x02\x12\x16\n\x08order_id\x18\x07 \x01(\tB\x04\xe2\x41\x01\x02\x12\x15\n\rinstrument_id\x18\x08 \x01(\t\x12M\n\rtime_in_force\x18\t \x01(\x0e\x32\x36.tinkoff.public.invest.api.contract.v1.TimeInForceType\x12\x44\n\nprice_type\x18\n \x01(\x0e\x32\x30.tinkoff.public.invest.api.contract.v1.PriceType\x12\x1c\n\x14\x63onfirm_margin_trade\x18\x0b \x01(\x08\x42\x07\n\x05_figiB\x08\n\x06_price\"\x8c\t\n\x11PostOrderResponse\x12\x10\n\x08order_id\x18\x01 \x01(\t\x12\x62\n\x17\x65xecution_report_status\x18\x02 \x01(\x0e\x32\x41.tinkoff.public.invest.api.contract.v1.OrderExecutionReportStatus\x12\x16\n\x0elots_requested\x18\x03 \x01(\x03\x12\x15\n\rlots_executed\x18\x04 \x01(\x03\x12N\n\x13initial_order_price\x18\x05 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12O\n\x14\x65xecuted_order_price\x18\x06 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12M\n\x12total_order_amount\x18\x07 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12M\n\x12initial_commission\x18\x08 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12N\n\x13\x65xecuted_commission\x18\t \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x44\n\taci_value\x18\n \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x0c\n\x04\x66igi\x18\x0b \x01(\t\x12H\n\tdirection\x18\x0c \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.OrderDirection\x12Q\n\x16initial_security_price\x18\r \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x44\n\norder_type\x18\x0e \x01(\x0e\x32\x30.tinkoff.public.invest.api.contract.v1.OrderType\x12\x0f\n\x07message\x18\x0f \x01(\t\x12P\n\x16initial_order_price_pt\x18\x10 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x16\n\x0einstrument_uid\x18\x11 \x01(\t\x12\x0e\n\x06ticker\x18\x12 \x01(\t\x12\x12\n\nclass_code\x18\x13 \x01(\t\x12\x18\n\x10order_request_id\x18\x14 \x01(\t\x12S\n\x11response_metadata\x18\xfe\x01 \x01(\x0b\x32\x37.tinkoff.public.invest.api.contract.v1.ResponseMetadata\"\xc8\x04\n\x15PostOrderAsyncRequest\x12\x1b\n\rinstrument_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\x12\x16\n\x08quantity\x18\x02 \x01(\x03\x42\x04\xe2\x41\x01\x02\x12\x44\n\x05price\x18\x03 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationH\x00\x88\x01\x01\x12N\n\tdirection\x18\x04 \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.OrderDirectionB\x04\xe2\x41\x01\x02\x12\x18\n\naccount_id\x18\x05 \x01(\tB\x04\xe2\x41\x01\x02\x12J\n\norder_type\x18\x06 \x01(\x0e\x32\x30.tinkoff.public.invest.api.contract.v1.OrderTypeB\x04\xe2\x41\x01\x02\x12\x16\n\x08order_id\x18\x07 \x01(\tB\x04\xe2\x41\x01\x02\x12R\n\rtime_in_force\x18\x08 \x01(\x0e\x32\x36.tinkoff.public.invest.api.contract.v1.TimeInForceTypeH\x01\x88\x01\x01\x12I\n\nprice_type\x18\t \x01(\x0e\x32\x30.tinkoff.public.invest.api.contract.v1.PriceTypeH\x02\x88\x01\x01\x12\x1c\n\x14\x63onfirm_margin_trade\x18\n \x01(\x08\x42\x08\n\x06_priceB\x10\n\x0e_time_in_forceB\r\n\x0b_price_type\"\xd4\x01\n\x16PostOrderAsyncResponse\x12\x1e\n\x10order_request_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\x12h\n\x17\x65xecution_report_status\x18\x02 \x01(\x0e\x32\x41.tinkoff.public.invest.api.contract.v1.OrderExecutionReportStatusB\x04\xe2\x41\x01\x02\x12\x1c\n\x0ftrade_intent_id\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x12\n\x10_trade_intent_id\"\xa8\x01\n\x12\x43\x61ncelOrderRequest\x12\x18\n\naccount_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\x12\x16\n\x08order_id\x18\x02 \x01(\tB\x04\xe2\x41\x01\x02\x12N\n\rorder_id_type\x18\x03 \x01(\x0e\x32\x32.tinkoff.public.invest.api.contract.v1.OrderIdTypeH\x00\x88\x01\x01\x42\x10\n\x0e_order_id_type\"\x94\x01\n\x13\x43\x61ncelOrderResponse\x12(\n\x04time\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12S\n\x11response_metadata\x18\xfe\x01 \x01(\x0b\x32\x37.tinkoff.public.invest.api.contract.v1.ResponseMetadata\"\xf0\x01\n\x14GetOrderStateRequest\x12\x18\n\naccount_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\x12\x16\n\x08order_id\x18\x02 \x01(\tB\x04\xe2\x41\x01\x02\x12\x44\n\nprice_type\x18\x03 \x01(\x0e\x32\x30.tinkoff.public.invest.api.contract.v1.PriceType\x12N\n\rorder_id_type\x18\x04 \x01(\x0e\x32\x32.tinkoff.public.invest.api.contract.v1.OrderIdTypeH\x00\x88\x01\x01\x42\x10\n\x0e_order_id_type\"\x96\x03\n\x10GetOrdersRequest\x12\x18\n\naccount_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\x12n\n\x10\x61\x64vanced_filters\x18\x02 \x01(\x0b\x32O.tinkoff.public.invest.api.contract.v1.GetOrdersRequest.GetOrdersRequestFiltersH\x00\x88\x01\x01\x1a\xe2\x01\n\x17GetOrdersRequestFilters\x12-\n\x04\x66rom\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x00\x88\x01\x01\x12+\n\x02to\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x01\x88\x01\x01\x12[\n\x10\x65xecution_status\x18\x03 \x03(\x0e\x32\x41.tinkoff.public.invest.api.contract.v1.OrderExecutionReportStatusB\x07\n\x05_fromB\x05\n\x03_toB\x13\n\x11_advanced_filters\"V\n\x11GetOrdersResponse\x12\x41\n\x06orders\x18\x01 \x03(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.OrderState\"\xae\t\n\nOrderState\x12\x10\n\x08order_id\x18\x01 \x01(\t\x12\x62\n\x17\x65xecution_report_status\x18\x02 \x01(\x0e\x32\x41.tinkoff.public.invest.api.contract.v1.OrderExecutionReportStatus\x12\x16\n\x0elots_requested\x18\x03 \x01(\x03\x12\x15\n\rlots_executed\x18\x04 \x01(\x03\x12N\n\x13initial_order_price\x18\x05 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12O\n\x14\x65xecuted_order_price\x18\x06 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12M\n\x12total_order_amount\x18\x07 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12Q\n\x16\x61verage_position_price\x18\x08 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12M\n\x12initial_commission\x18\t \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12N\n\x13\x65xecuted_commission\x18\n \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x0c\n\x04\x66igi\x18\x0b \x01(\t\x12H\n\tdirection\x18\x0c \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.OrderDirection\x12Q\n\x16initial_security_price\x18\r \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x41\n\x06stages\x18\x0e \x03(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.OrderStage\x12M\n\x12service_commission\x18\x0f \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x10\n\x08\x63urrency\x18\x10 \x01(\t\x12\x44\n\norder_type\x18\x11 \x01(\x0e\x32\x30.tinkoff.public.invest.api.contract.v1.OrderType\x12.\n\norder_date\x18\x12 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x16\n\x0einstrument_uid\x18\x13 \x01(\t\x12\x18\n\x10order_request_id\x18\x14 \x01(\t\x12\x0e\n\x06ticker\x18\x15 \x01(\t\x12\x12\n\nclass_code\x18\x16 \x01(\t\"\xa6\x01\n\nOrderStage\x12@\n\x05price\x18\x01 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x10\n\x08quantity\x18\x02 \x01(\x03\x12\x10\n\x08trade_id\x18\x03 \x01(\t\x12\x32\n\x0e\x65xecution_time\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\xa8\x03\n\x13ReplaceOrderRequest\x12\x18\n\naccount_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\x12N\n\rorder_id_type\x18\x05 \x01(\x0e\x32\x32.tinkoff.public.invest.api.contract.v1.OrderIdTypeH\x00\x88\x01\x01\x12\x16\n\x08order_id\x18\x06 \x01(\tB\x04\xe2\x41\x01\x02\x12\x1d\n\x0fidempotency_key\x18\x07 \x01(\tB\x04\xe2\x41\x01\x02\x12\x16\n\x08quantity\x18\x0b \x01(\x03\x42\x04\xe2\x41\x01\x02\x12\x44\n\x05price\x18\x0c \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationH\x01\x88\x01\x01\x12I\n\nprice_type\x18\r \x01(\x0e\x32\x30.tinkoff.public.invest.api.contract.v1.PriceTypeH\x02\x88\x01\x01\x12\x1c\n\x14\x63onfirm_margin_trade\x18\x0e \x01(\x08\x42\x10\n\x0e_order_id_typeB\x08\n\x06_priceB\r\n\x0b_price_type\"\x9a\x01\n\x11GetMaxLotsRequest\x12\x18\n\naccount_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\x12\x1b\n\rinstrument_id\x18\x02 \x01(\tB\x04\xe2\x41\x01\x02\x12\x44\n\x05price\x18\x03 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationH\x00\x88\x01\x01\x42\x08\n\x06_price\"\xe6\x04\n\x12GetMaxLotsResponse\x12\x10\n\x08\x63urrency\x18\x01 \x01(\t\x12[\n\nbuy_limits\x18\x02 \x01(\x0b\x32G.tinkoff.public.invest.api.contract.v1.GetMaxLotsResponse.BuyLimitsView\x12\x62\n\x11\x62uy_margin_limits\x18\x03 \x01(\x0b\x32G.tinkoff.public.invest.api.contract.v1.GetMaxLotsResponse.BuyLimitsView\x12]\n\x0bsell_limits\x18\x04 \x01(\x0b\x32H.tinkoff.public.invest.api.contract.v1.GetMaxLotsResponse.SellLimitsView\x12\x64\n\x12sell_margin_limits\x18\x05 \x01(\x0b\x32H.tinkoff.public.invest.api.contract.v1.GetMaxLotsResponse.SellLimitsView\x1a\x8e\x01\n\rBuyLimitsView\x12J\n\x10\x62uy_money_amount\x18\x01 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12\x14\n\x0c\x62uy_max_lots\x18\x02 \x01(\x03\x12\x1b\n\x13\x62uy_max_market_lots\x18\x03 \x01(\x03\x1a\'\n\x0eSellLimitsView\x12\x15\n\rsell_max_lots\x18\x01 \x01(\x03\"\xde\x01\n\x14GetOrderPriceRequest\x12\x12\n\naccount_id\x18\x01 \x01(\t\x12\x15\n\rinstrument_id\x18\x02 \x01(\t\x12?\n\x05price\x18\x03 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12H\n\tdirection\x18\x0c \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.OrderDirection\x12\x10\n\x08quantity\x18\r \x01(\x03\"\xe3\x07\n\x15GetOrderPriceResponse\x12M\n\x12total_order_amount\x18\x01 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12O\n\x14initial_order_amount\x18\x05 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x16\n\x0elots_requested\x18\x03 \x01(\x03\x12N\n\x13\x65xecuted_commission\x18\x07 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12R\n\x17\x65xecuted_commission_rub\x18\x08 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12M\n\x12service_commission\x18\t \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12J\n\x0f\x64\x65\x61l_commission\x18\n \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\\\n\nextra_bond\x18\x0c \x01(\x0b\x32\x46.tinkoff.public.invest.api.contract.v1.GetOrderPriceResponse.ExtraBondH\x00\x12`\n\x0c\x65xtra_future\x18\r \x01(\x0b\x32H.tinkoff.public.invest.api.contract.v1.GetOrderPriceResponse.ExtraFutureH\x00\x1a\xa4\x01\n\tExtraBond\x12\x44\n\taci_value\x18\x02 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12Q\n\x17nominal_conversion_rate\x18\x03 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x1aX\n\x0b\x45xtraFuture\x12I\n\x0einitial_margin\x18\x02 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValueB\x12\n\x10instrument_extra\"a\n\x17OrderStateStreamRequest\x12\x10\n\x08\x61\x63\x63ounts\x18\x01 \x03(\t\x12\x1e\n\x11ping_delay_millis\x18\x0f \x01(\x05H\x00\x88\x01\x01\x42\x14\n\x12_ping_delay_millis\"\xf3\x01\n\x14SubscriptionResponse\x12\x13\n\x0btracking_id\x18\x01 \x01(\t\x12O\n\x06status\x18\x02 \x01(\x0e\x32?.tinkoff.public.invest.api.contract.v1.ResultSubscriptionStatus\x12\x11\n\tstream_id\x18\x04 \x01(\t\x12\x10\n\x08\x61\x63\x63ounts\x18\x05 \x03(\t\x12\x46\n\x05\x65rror\x18\x07 \x01(\x0b\x32\x32.tinkoff.public.invest.api.contract.v1.ErrorDetailH\x00\x88\x01\x01\x42\x08\n\x06_error\"\xd8\x10\n\x18OrderStateStreamResponse\x12\x61\n\x0border_state\x18\x01 \x01(\x0b\x32J.tinkoff.public.invest.api.contract.v1.OrderStateStreamResponse.OrderStateH\x00\x12;\n\x04ping\x18\x02 \x01(\x0b\x32+.tinkoff.public.invest.api.contract.v1.PingH\x00\x12S\n\x0csubscription\x18\x03 \x01(\x0b\x32;.tinkoff.public.invest.api.contract.v1.SubscriptionResponseH\x00\x1a\xf3\n\n\nOrderState\x12\x10\n\x08order_id\x18\x01 \x01(\t\x12\x1d\n\x10order_request_id\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x0b\x63lient_code\x18\x03 \x01(\t\x12.\n\ncreated_at\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x62\n\x17\x65xecution_report_status\x18\x05 \x01(\x0e\x32\x41.tinkoff.public.invest.api.contract.v1.OrderExecutionReportStatus\x12i\n\x0bstatus_info\x18\x06 \x01(\x0e\x32O.tinkoff.public.invest.api.contract.v1.OrderStateStreamResponse.StatusCauseInfoH\x01\x88\x01\x01\x12\x0e\n\x06ticker\x18\x07 \x01(\t\x12\x12\n\nclass_code\x18\x08 \x01(\t\x12\x10\n\x08lot_size\x18\t \x01(\x05\x12H\n\tdirection\x18\n \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.OrderDirection\x12M\n\rtime_in_force\x18\x0b \x01(\x0e\x32\x36.tinkoff.public.invest.api.contract.v1.TimeInForceType\x12\x44\n\norder_type\x18\x0c \x01(\x0e\x32\x30.tinkoff.public.invest.api.contract.v1.OrderType\x12\x12\n\naccount_id\x18\r \x01(\t\x12\x1c\n\x0etrade_order_id\x18\x0e \x01(\tB\x04\xe2\x41\x01\x02\x12N\n\x13initial_order_price\x18\x16 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x46\n\x0border_price\x18\x17 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x46\n\x06\x61mount\x18\x18 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValueH\x02\x88\x01\x01\x12O\n\x14\x65xecuted_order_price\x18\x19 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x10\n\x08\x63urrency\x18\x1a \x01(\t\x12\x16\n\x0elots_requested\x18\x1b \x01(\x03\x12\x15\n\rlots_executed\x18\x1c \x01(\x03\x12\x11\n\tlots_left\x18\x1d \x01(\x03\x12\x16\n\x0elots_cancelled\x18\x1e \x01(\x03\x12_\n\x06marker\x18\x1f \x01(\x0e\x32J.tinkoff.public.invest.api.contract.v1.OrderStateStreamResponse.MarkerTypeH\x03\x88\x01\x01\x12\x41\n\x06trades\x18! \x03(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.OrderTrade\x12\x33\n\x0f\x63ompletion_time\x18# \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x10\n\x08\x65xchange\x18$ \x01(\t\x12\x16\n\x0einstrument_uid\x18) \x01(\tB\x13\n\x11_order_request_idB\x0e\n\x0c_status_infoB\t\n\x07_amountB\t\n\x07_marker\"\xaf\x01\n\nMarkerType\x12\x12\n\x0eMARKER_UNKNOWN\x10\x00\x12\x11\n\rMARKER_BROKER\x10\x01\x12\x0f\n\x0bMARKER_CHAT\x10\x02\x12\x10\n\x0cMARKER_PAPER\x10\x03\x12\x11\n\rMARKER_MARGIN\x10\x04\x12\x10\n\x0cMARKER_TKBNM\x10\x05\x12\x10\n\x0cMARKER_SHORT\x10\x06\x12\x11\n\rMARKER_SPECMM\x10\x07\x12\r\n\tMARKER_PO\x10\x08\"\x93\x02\n\x0fStatusCauseInfo\x12\x15\n\x11\x43\x41USE_UNSPECIFIED\x10\x00\x12\x1d\n\x19\x43\x41USE_CANCELLED_BY_CLIENT\x10\x0f\x12\x1f\n\x1b\x43\x41USE_CANCELLED_BY_EXCHANGE\x10\x01\x12\'\n#CAUSE_CANCELLED_NOT_ENOUGH_POSITION\x10\x02\x12#\n\x1f\x43\x41USE_CANCELLED_BY_CLIENT_BLOCK\x10\x03\x12\x1c\n\x18\x43\x41USE_REJECTED_BY_BROKER\x10\x04\x12\x1e\n\x1a\x43\x41USE_REJECTED_BY_EXCHANGE\x10\x05\x12\x1d\n\x19\x43\x41USE_CANCELLED_BY_BROKER\x10\x06\x42\t\n\x07payload*d\n\x0eOrderDirection\x12\x1f\n\x1bORDER_DIRECTION_UNSPECIFIED\x10\x00\x12\x17\n\x13ORDER_DIRECTION_BUY\x10\x01\x12\x18\n\x14ORDER_DIRECTION_SELL\x10\x02*n\n\tOrderType\x12\x1a\n\x16ORDER_TYPE_UNSPECIFIED\x10\x00\x12\x14\n\x10ORDER_TYPE_LIMIT\x10\x01\x12\x15\n\x11ORDER_TYPE_MARKET\x10\x02\x12\x18\n\x14ORDER_TYPE_BESTPRICE\x10\x03*\x80\x02\n\x1aOrderExecutionReportStatus\x12\'\n#EXECUTION_REPORT_STATUS_UNSPECIFIED\x10\x00\x12 \n\x1c\x45XECUTION_REPORT_STATUS_FILL\x10\x01\x12$\n EXECUTION_REPORT_STATUS_REJECTED\x10\x02\x12%\n!EXECUTION_REPORT_STATUS_CANCELLED\x10\x03\x12\x1f\n\x1b\x45XECUTION_REPORT_STATUS_NEW\x10\x04\x12)\n%EXECUTION_REPORT_STATUS_PARTIALLYFILL\x10\x05*\x88\x01\n\x0fTimeInForceType\x12\x1d\n\x19TIME_IN_FORCE_UNSPECIFIED\x10\x00\x12\x15\n\x11TIME_IN_FORCE_DAY\x10\x01\x12\x1f\n\x1bTIME_IN_FORCE_FILL_AND_KILL\x10\x02\x12\x1e\n\x1aTIME_IN_FORCE_FILL_OR_KILL\x10\x03*c\n\x0bOrderIdType\x12\x1d\n\x19ORDER_ID_TYPE_UNSPECIFIED\x10\x00\x12\x1a\n\x16ORDER_ID_TYPE_EXCHANGE\x10\x01\x12\x19\n\x15ORDER_ID_TYPE_REQUEST\x10\x02\x32\xb9\x02\n\x13OrdersStreamService\x12\x89\x01\n\x0cTradesStream\x12:.tinkoff.public.invest.api.contract.v1.TradesStreamRequest\x1a;.tinkoff.public.invest.api.contract.v1.TradesStreamResponse0\x01\x12\x95\x01\n\x10OrderStateStream\x12>.tinkoff.public.invest.api.contract.v1.OrderStateStreamRequest\x1a?.tinkoff.public.invest.api.contract.v1.OrderStateStreamResponse0\x01\x32\xbf\x08\n\rOrdersService\x12~\n\tPostOrder\x12\x37.tinkoff.public.invest.api.contract.v1.PostOrderRequest\x1a\x38.tinkoff.public.invest.api.contract.v1.PostOrderResponse\x12\x8d\x01\n\x0ePostOrderAsync\x12<.tinkoff.public.invest.api.contract.v1.PostOrderAsyncRequest\x1a=.tinkoff.public.invest.api.contract.v1.PostOrderAsyncResponse\x12\x84\x01\n\x0b\x43\x61ncelOrder\x12\x39.tinkoff.public.invest.api.contract.v1.CancelOrderRequest\x1a:.tinkoff.public.invest.api.contract.v1.CancelOrderResponse\x12\x7f\n\rGetOrderState\x12;.tinkoff.public.invest.api.contract.v1.GetOrderStateRequest\x1a\x31.tinkoff.public.invest.api.contract.v1.OrderState\x12~\n\tGetOrders\x12\x37.tinkoff.public.invest.api.contract.v1.GetOrdersRequest\x1a\x38.tinkoff.public.invest.api.contract.v1.GetOrdersResponse\x12\x84\x01\n\x0cReplaceOrder\x12:.tinkoff.public.invest.api.contract.v1.ReplaceOrderRequest\x1a\x38.tinkoff.public.invest.api.contract.v1.PostOrderResponse\x12\x81\x01\n\nGetMaxLots\x12\x38.tinkoff.public.invest.api.contract.v1.GetMaxLotsRequest\x1a\x39.tinkoff.public.invest.api.contract.v1.GetMaxLotsResponse\x12\x8a\x01\n\rGetOrderPrice\x12;.tinkoff.public.invest.api.contract.v1.GetOrderPriceRequest\x1a<.tinkoff.public.invest.api.contract.v1.GetOrderPriceResponseBa\n\x1cru.tinkoff.piapi.contract.v1P\x01Z\x0c./;investapi\xa2\x02\x05TIAPI\xaa\x02\x14Tinkoff.InvestApi.V1\xca\x02\x11Tinkoff\\Invest\\V1b\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 't_tech.invest.grpc.orders_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\034ru.tinkoff.piapi.contract.v1P\001Z\014./;investapi\242\002\005TIAPI\252\002\024Tinkoff.InvestApi.V1\312\002\021Tinkoff\\Invest\\V1' + _globals['_POSTORDERREQUEST'].fields_by_name['figi']._options = None + _globals['_POSTORDERREQUEST'].fields_by_name['figi']._serialized_options = b'\030\001' + _globals['_POSTORDERREQUEST'].fields_by_name['quantity']._options = None + _globals['_POSTORDERREQUEST'].fields_by_name['quantity']._serialized_options = b'\342A\001\002' + _globals['_POSTORDERREQUEST'].fields_by_name['direction']._options = None + _globals['_POSTORDERREQUEST'].fields_by_name['direction']._serialized_options = b'\342A\001\002' + _globals['_POSTORDERREQUEST'].fields_by_name['account_id']._options = None + _globals['_POSTORDERREQUEST'].fields_by_name['account_id']._serialized_options = b'\342A\001\002' + _globals['_POSTORDERREQUEST'].fields_by_name['order_type']._options = None + _globals['_POSTORDERREQUEST'].fields_by_name['order_type']._serialized_options = b'\342A\001\002' + _globals['_POSTORDERREQUEST'].fields_by_name['order_id']._options = None + _globals['_POSTORDERREQUEST'].fields_by_name['order_id']._serialized_options = b'\342A\001\002' + _globals['_POSTORDERASYNCREQUEST'].fields_by_name['instrument_id']._options = None + _globals['_POSTORDERASYNCREQUEST'].fields_by_name['instrument_id']._serialized_options = b'\342A\001\002' + _globals['_POSTORDERASYNCREQUEST'].fields_by_name['quantity']._options = None + _globals['_POSTORDERASYNCREQUEST'].fields_by_name['quantity']._serialized_options = b'\342A\001\002' + _globals['_POSTORDERASYNCREQUEST'].fields_by_name['direction']._options = None + _globals['_POSTORDERASYNCREQUEST'].fields_by_name['direction']._serialized_options = b'\342A\001\002' + _globals['_POSTORDERASYNCREQUEST'].fields_by_name['account_id']._options = None + _globals['_POSTORDERASYNCREQUEST'].fields_by_name['account_id']._serialized_options = b'\342A\001\002' + _globals['_POSTORDERASYNCREQUEST'].fields_by_name['order_type']._options = None + _globals['_POSTORDERASYNCREQUEST'].fields_by_name['order_type']._serialized_options = b'\342A\001\002' + _globals['_POSTORDERASYNCREQUEST'].fields_by_name['order_id']._options = None + _globals['_POSTORDERASYNCREQUEST'].fields_by_name['order_id']._serialized_options = b'\342A\001\002' + _globals['_POSTORDERASYNCRESPONSE'].fields_by_name['order_request_id']._options = None + _globals['_POSTORDERASYNCRESPONSE'].fields_by_name['order_request_id']._serialized_options = b'\342A\001\002' + _globals['_POSTORDERASYNCRESPONSE'].fields_by_name['execution_report_status']._options = None + _globals['_POSTORDERASYNCRESPONSE'].fields_by_name['execution_report_status']._serialized_options = b'\342A\001\002' + _globals['_CANCELORDERREQUEST'].fields_by_name['account_id']._options = None + _globals['_CANCELORDERREQUEST'].fields_by_name['account_id']._serialized_options = b'\342A\001\002' + _globals['_CANCELORDERREQUEST'].fields_by_name['order_id']._options = None + _globals['_CANCELORDERREQUEST'].fields_by_name['order_id']._serialized_options = b'\342A\001\002' + _globals['_GETORDERSTATEREQUEST'].fields_by_name['account_id']._options = None + _globals['_GETORDERSTATEREQUEST'].fields_by_name['account_id']._serialized_options = b'\342A\001\002' + _globals['_GETORDERSTATEREQUEST'].fields_by_name['order_id']._options = None + _globals['_GETORDERSTATEREQUEST'].fields_by_name['order_id']._serialized_options = b'\342A\001\002' + _globals['_GETORDERSREQUEST'].fields_by_name['account_id']._options = None + _globals['_GETORDERSREQUEST'].fields_by_name['account_id']._serialized_options = b'\342A\001\002' + _globals['_REPLACEORDERREQUEST'].fields_by_name['account_id']._options = None + _globals['_REPLACEORDERREQUEST'].fields_by_name['account_id']._serialized_options = b'\342A\001\002' + _globals['_REPLACEORDERREQUEST'].fields_by_name['order_id']._options = None + _globals['_REPLACEORDERREQUEST'].fields_by_name['order_id']._serialized_options = b'\342A\001\002' + _globals['_REPLACEORDERREQUEST'].fields_by_name['idempotency_key']._options = None + _globals['_REPLACEORDERREQUEST'].fields_by_name['idempotency_key']._serialized_options = b'\342A\001\002' + _globals['_REPLACEORDERREQUEST'].fields_by_name['quantity']._options = None + _globals['_REPLACEORDERREQUEST'].fields_by_name['quantity']._serialized_options = b'\342A\001\002' + _globals['_GETMAXLOTSREQUEST'].fields_by_name['account_id']._options = None + _globals['_GETMAXLOTSREQUEST'].fields_by_name['account_id']._serialized_options = b'\342A\001\002' + _globals['_GETMAXLOTSREQUEST'].fields_by_name['instrument_id']._options = None + _globals['_GETMAXLOTSREQUEST'].fields_by_name['instrument_id']._serialized_options = b'\342A\001\002' + _globals['_ORDERSTATESTREAMRESPONSE_ORDERSTATE'].fields_by_name['trade_order_id']._options = None + _globals['_ORDERSTATESTREAMRESPONSE_ORDERSTATE'].fields_by_name['trade_order_id']._serialized_options = b'\342A\001\002' + _globals['_ORDERDIRECTION']._serialized_start=10855 + _globals['_ORDERDIRECTION']._serialized_end=10955 + _globals['_ORDERTYPE']._serialized_start=10957 + _globals['_ORDERTYPE']._serialized_end=11067 + _globals['_ORDEREXECUTIONREPORTSTATUS']._serialized_start=11070 + _globals['_ORDEREXECUTIONREPORTSTATUS']._serialized_end=11326 + _globals['_TIMEINFORCETYPE']._serialized_start=11329 + _globals['_TIMEINFORCETYPE']._serialized_end=11465 + _globals['_ORDERIDTYPE']._serialized_start=11467 + _globals['_ORDERIDTYPE']._serialized_end=11566 + _globals['_TRADESSTREAMREQUEST']._serialized_start=192 + _globals['_TRADESSTREAMREQUEST']._serialized_end=277 + _globals['_TRADESSTREAMRESPONSE']._serialized_start=280 + _globals['_TRADESSTREAMRESPONSE']._serialized_end=535 + _globals['_ORDERTRADES']._serialized_start=538 + _globals['_ORDERTRADES']._serialized_end=816 + _globals['_ORDERTRADE']._serialized_start=819 + _globals['_ORDERTRADE']._serialized_end=979 + _globals['_POSTORDERREQUEST']._serialized_start=982 + _globals['_POSTORDERREQUEST']._serialized_end=1544 + _globals['_POSTORDERRESPONSE']._serialized_start=1547 + _globals['_POSTORDERRESPONSE']._serialized_end=2711 + _globals['_POSTORDERASYNCREQUEST']._serialized_start=2714 + _globals['_POSTORDERASYNCREQUEST']._serialized_end=3298 + _globals['_POSTORDERASYNCRESPONSE']._serialized_start=3301 + _globals['_POSTORDERASYNCRESPONSE']._serialized_end=3513 + _globals['_CANCELORDERREQUEST']._serialized_start=3516 + _globals['_CANCELORDERREQUEST']._serialized_end=3684 + _globals['_CANCELORDERRESPONSE']._serialized_start=3687 + _globals['_CANCELORDERRESPONSE']._serialized_end=3835 + _globals['_GETORDERSTATEREQUEST']._serialized_start=3838 + _globals['_GETORDERSTATEREQUEST']._serialized_end=4078 + _globals['_GETORDERSREQUEST']._serialized_start=4081 + _globals['_GETORDERSREQUEST']._serialized_end=4487 + _globals['_GETORDERSREQUEST_GETORDERSREQUESTFILTERS']._serialized_start=4240 + _globals['_GETORDERSREQUEST_GETORDERSREQUESTFILTERS']._serialized_end=4466 + _globals['_GETORDERSRESPONSE']._serialized_start=4489 + _globals['_GETORDERSRESPONSE']._serialized_end=4575 + _globals['_ORDERSTATE']._serialized_start=4578 + _globals['_ORDERSTATE']._serialized_end=5776 + _globals['_ORDERSTAGE']._serialized_start=5779 + _globals['_ORDERSTAGE']._serialized_end=5945 + _globals['_REPLACEORDERREQUEST']._serialized_start=5948 + _globals['_REPLACEORDERREQUEST']._serialized_end=6372 + _globals['_GETMAXLOTSREQUEST']._serialized_start=6375 + _globals['_GETMAXLOTSREQUEST']._serialized_end=6529 + _globals['_GETMAXLOTSRESPONSE']._serialized_start=6532 + _globals['_GETMAXLOTSRESPONSE']._serialized_end=7146 + _globals['_GETMAXLOTSRESPONSE_BUYLIMITSVIEW']._serialized_start=6963 + _globals['_GETMAXLOTSRESPONSE_BUYLIMITSVIEW']._serialized_end=7105 + _globals['_GETMAXLOTSRESPONSE_SELLLIMITSVIEW']._serialized_start=7107 + _globals['_GETMAXLOTSRESPONSE_SELLLIMITSVIEW']._serialized_end=7146 + _globals['_GETORDERPRICEREQUEST']._serialized_start=7149 + _globals['_GETORDERPRICEREQUEST']._serialized_end=7371 + _globals['_GETORDERPRICERESPONSE']._serialized_start=7374 + _globals['_GETORDERPRICERESPONSE']._serialized_end=8369 + _globals['_GETORDERPRICERESPONSE_EXTRABOND']._serialized_start=8095 + _globals['_GETORDERPRICERESPONSE_EXTRABOND']._serialized_end=8259 + _globals['_GETORDERPRICERESPONSE_EXTRAFUTURE']._serialized_start=8261 + _globals['_GETORDERPRICERESPONSE_EXTRAFUTURE']._serialized_end=8349 + _globals['_ORDERSTATESTREAMREQUEST']._serialized_start=8371 + _globals['_ORDERSTATESTREAMREQUEST']._serialized_end=8468 + _globals['_SUBSCRIPTIONRESPONSE']._serialized_start=8471 + _globals['_SUBSCRIPTIONRESPONSE']._serialized_end=8714 + _globals['_ORDERSTATESTREAMRESPONSE']._serialized_start=8717 + _globals['_ORDERSTATESTREAMRESPONSE']._serialized_end=10853 + _globals['_ORDERSTATESTREAMRESPONSE_ORDERSTATE']._serialized_start=8991 + _globals['_ORDERSTATESTREAMRESPONSE_ORDERSTATE']._serialized_end=10386 + _globals['_ORDERSTATESTREAMRESPONSE_MARKERTYPE']._serialized_start=10389 + _globals['_ORDERSTATESTREAMRESPONSE_MARKERTYPE']._serialized_end=10564 + _globals['_ORDERSTATESTREAMRESPONSE_STATUSCAUSEINFO']._serialized_start=10567 + _globals['_ORDERSTATESTREAMRESPONSE_STATUSCAUSEINFO']._serialized_end=10842 + _globals['_ORDERSSTREAMSERVICE']._serialized_start=11569 + _globals['_ORDERSSTREAMSERVICE']._serialized_end=11882 + _globals['_ORDERSSERVICE']._serialized_start=11885 + _globals['_ORDERSSERVICE']._serialized_end=12972 +# @@protoc_insertion_point(module_scope) diff --git a/invest-python-master/t_tech/invest/grpc/orders_pb2.pyi b/invest-python-master/t_tech/invest/grpc/orders_pb2.pyi new file mode 100644 index 0000000..db7eee2 --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/orders_pb2.pyi @@ -0,0 +1,1542 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" + +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.internal.enum_type_wrapper +import google.protobuf.message +import google.protobuf.timestamp_pb2 +import sys +import t_tech.invest.grpc.common_pb2 +import typing + +if sys.version_info >= (3, 10): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +class _OrderDirection: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _OrderDirectionEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_OrderDirection.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + ORDER_DIRECTION_UNSPECIFIED: _OrderDirection.ValueType # 0 + """Значение не указано""" + ORDER_DIRECTION_BUY: _OrderDirection.ValueType # 1 + """Покупка""" + ORDER_DIRECTION_SELL: _OrderDirection.ValueType # 2 + """Продажа""" + +class OrderDirection(_OrderDirection, metaclass=_OrderDirectionEnumTypeWrapper): + """Направление операции.""" + +ORDER_DIRECTION_UNSPECIFIED: OrderDirection.ValueType # 0 +"""Значение не указано""" +ORDER_DIRECTION_BUY: OrderDirection.ValueType # 1 +"""Покупка""" +ORDER_DIRECTION_SELL: OrderDirection.ValueType # 2 +"""Продажа""" +global___OrderDirection = OrderDirection + +class _OrderType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _OrderTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_OrderType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + ORDER_TYPE_UNSPECIFIED: _OrderType.ValueType # 0 + """Значение не указано""" + ORDER_TYPE_LIMIT: _OrderType.ValueType # 1 + """Лимитная""" + ORDER_TYPE_MARKET: _OrderType.ValueType # 2 + """Рыночная""" + ORDER_TYPE_BESTPRICE: _OrderType.ValueType # 3 + """Лучшая цена""" + +class OrderType(_OrderType, metaclass=_OrderTypeEnumTypeWrapper): + """Тип заявки.""" + +ORDER_TYPE_UNSPECIFIED: OrderType.ValueType # 0 +"""Значение не указано""" +ORDER_TYPE_LIMIT: OrderType.ValueType # 1 +"""Лимитная""" +ORDER_TYPE_MARKET: OrderType.ValueType # 2 +"""Рыночная""" +ORDER_TYPE_BESTPRICE: OrderType.ValueType # 3 +"""Лучшая цена""" +global___OrderType = OrderType + +class _OrderExecutionReportStatus: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _OrderExecutionReportStatusEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_OrderExecutionReportStatus.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + EXECUTION_REPORT_STATUS_UNSPECIFIED: _OrderExecutionReportStatus.ValueType # 0 + EXECUTION_REPORT_STATUS_FILL: _OrderExecutionReportStatus.ValueType # 1 + """Исполнена""" + EXECUTION_REPORT_STATUS_REJECTED: _OrderExecutionReportStatus.ValueType # 2 + """Отклонена""" + EXECUTION_REPORT_STATUS_CANCELLED: _OrderExecutionReportStatus.ValueType # 3 + """Отменена пользователем""" + EXECUTION_REPORT_STATUS_NEW: _OrderExecutionReportStatus.ValueType # 4 + """Новая""" + EXECUTION_REPORT_STATUS_PARTIALLYFILL: _OrderExecutionReportStatus.ValueType # 5 + """Частично исполнена""" + +class OrderExecutionReportStatus(_OrderExecutionReportStatus, metaclass=_OrderExecutionReportStatusEnumTypeWrapper): + """Текущий статус заявки (поручения)""" + +EXECUTION_REPORT_STATUS_UNSPECIFIED: OrderExecutionReportStatus.ValueType # 0 +EXECUTION_REPORT_STATUS_FILL: OrderExecutionReportStatus.ValueType # 1 +"""Исполнена""" +EXECUTION_REPORT_STATUS_REJECTED: OrderExecutionReportStatus.ValueType # 2 +"""Отклонена""" +EXECUTION_REPORT_STATUS_CANCELLED: OrderExecutionReportStatus.ValueType # 3 +"""Отменена пользователем""" +EXECUTION_REPORT_STATUS_NEW: OrderExecutionReportStatus.ValueType # 4 +"""Новая""" +EXECUTION_REPORT_STATUS_PARTIALLYFILL: OrderExecutionReportStatus.ValueType # 5 +"""Частично исполнена""" +global___OrderExecutionReportStatus = OrderExecutionReportStatus + +class _TimeInForceType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _TimeInForceTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_TimeInForceType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + TIME_IN_FORCE_UNSPECIFIED: _TimeInForceType.ValueType # 0 + """Значение не определено см. TIME_IN_FORCE_DAY""" + TIME_IN_FORCE_DAY: _TimeInForceType.ValueType # 1 + """Заявка действует до конца торгового дня. Значение по умолчанию""" + TIME_IN_FORCE_FILL_AND_KILL: _TimeInForceType.ValueType # 2 + """Если в момент выставления возможно исполнение заявки(в т.ч. частичное), заявка будет исполнена или отменена сразу после выставления""" + TIME_IN_FORCE_FILL_OR_KILL: _TimeInForceType.ValueType # 3 + """Если в момент выставления возможно полное исполнение заявки, заявка будет исполнена или отменена сразу после выставления, недоступно для срочного рынка и торговли по выходным""" + +class TimeInForceType(_TimeInForceType, metaclass=_TimeInForceTypeEnumTypeWrapper): + """Алгоритм исполнения заявки""" + +TIME_IN_FORCE_UNSPECIFIED: TimeInForceType.ValueType # 0 +"""Значение не определено см. TIME_IN_FORCE_DAY""" +TIME_IN_FORCE_DAY: TimeInForceType.ValueType # 1 +"""Заявка действует до конца торгового дня. Значение по умолчанию""" +TIME_IN_FORCE_FILL_AND_KILL: TimeInForceType.ValueType # 2 +"""Если в момент выставления возможно исполнение заявки(в т.ч. частичное), заявка будет исполнена или отменена сразу после выставления""" +TIME_IN_FORCE_FILL_OR_KILL: TimeInForceType.ValueType # 3 +"""Если в момент выставления возможно полное исполнение заявки, заявка будет исполнена или отменена сразу после выставления, недоступно для срочного рынка и торговли по выходным""" +global___TimeInForceType = TimeInForceType + +class _OrderIdType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _OrderIdTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_OrderIdType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + ORDER_ID_TYPE_UNSPECIFIED: _OrderIdType.ValueType # 0 + """Тип идентификатора не указан.""" + ORDER_ID_TYPE_EXCHANGE: _OrderIdType.ValueType # 1 + """Биржевой идентификатор""" + ORDER_ID_TYPE_REQUEST: _OrderIdType.ValueType # 2 + """Ключ идемпотентности, переданный клиентом""" + +class OrderIdType(_OrderIdType, metaclass=_OrderIdTypeEnumTypeWrapper): + """Тип идентификатора заявки""" + +ORDER_ID_TYPE_UNSPECIFIED: OrderIdType.ValueType # 0 +"""Тип идентификатора не указан.""" +ORDER_ID_TYPE_EXCHANGE: OrderIdType.ValueType # 1 +"""Биржевой идентификатор""" +ORDER_ID_TYPE_REQUEST: OrderIdType.ValueType # 2 +"""Ключ идемпотентности, переданный клиентом""" +global___OrderIdType = OrderIdType + +@typing.final +class TradesStreamRequest(google.protobuf.message.Message): + """Запрос установки соединения.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNTS_FIELD_NUMBER: builtins.int + PING_DELAY_MS_FIELD_NUMBER: builtins.int + ping_delay_ms: builtins.int + """Задержка (пинг) сообщений: 5000–180 000 миллисекунд. Значение по умолчанию — 120 000.""" + @property + def accounts(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Идентификаторы счетов.""" + + def __init__( + self, + *, + accounts: collections.abc.Iterable[builtins.str] | None = ..., + ping_delay_ms: builtins.int | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_ping_delay_ms", b"_ping_delay_ms", "ping_delay_ms", b"ping_delay_ms"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_ping_delay_ms", b"_ping_delay_ms", "accounts", b"accounts", "ping_delay_ms", b"ping_delay_ms"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_ping_delay_ms", b"_ping_delay_ms"]) -> typing.Literal["ping_delay_ms"] | None: ... + +global___TradesStreamRequest = TradesStreamRequest + +@typing.final +class TradesStreamResponse(google.protobuf.message.Message): + """Информация о торговых поручениях.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ORDER_TRADES_FIELD_NUMBER: builtins.int + PING_FIELD_NUMBER: builtins.int + SUBSCRIPTION_FIELD_NUMBER: builtins.int + @property + def order_trades(self) -> global___OrderTrades: + """Информация об исполнении торгового поручения.""" + + @property + def ping(self) -> t_tech.invest.grpc.common_pb2.Ping: + """Проверка активности стрима.""" + + @property + def subscription(self) -> global___SubscriptionResponse: + """Ответ на запрос на подписку.""" + + def __init__( + self, + *, + order_trades: global___OrderTrades | None = ..., + ping: t_tech.invest.grpc.common_pb2.Ping | None = ..., + subscription: global___SubscriptionResponse | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["order_trades", b"order_trades", "payload", b"payload", "ping", b"ping", "subscription", b"subscription"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["order_trades", b"order_trades", "payload", b"payload", "ping", b"ping", "subscription", b"subscription"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["payload", b"payload"]) -> typing.Literal["order_trades", "ping", "subscription"] | None: ... + +global___TradesStreamResponse = TradesStreamResponse + +@typing.final +class OrderTrades(google.protobuf.message.Message): + """Информация об исполнении торгового поручения.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ORDER_ID_FIELD_NUMBER: builtins.int + CREATED_AT_FIELD_NUMBER: builtins.int + DIRECTION_FIELD_NUMBER: builtins.int + FIGI_FIELD_NUMBER: builtins.int + TRADES_FIELD_NUMBER: builtins.int + ACCOUNT_ID_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + order_id: builtins.str + """Идентификатор торгового поручения.""" + direction: global___OrderDirection.ValueType + """Направление сделки.""" + figi: builtins.str + """Figi-идентификатор инструмента.""" + account_id: builtins.str + """Идентификатор счета.""" + instrument_uid: builtins.str + """UID идентификатор инструмента.""" + @property + def created_at(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата и время создания сообщения в часовом поясе UTC.""" + + @property + def trades(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___OrderTrade]: + """Массив сделок.""" + + def __init__( + self, + *, + order_id: builtins.str = ..., + created_at: google.protobuf.timestamp_pb2.Timestamp | None = ..., + direction: global___OrderDirection.ValueType = ..., + figi: builtins.str = ..., + trades: collections.abc.Iterable[global___OrderTrade] | None = ..., + account_id: builtins.str = ..., + instrument_uid: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["created_at", b"created_at"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["account_id", b"account_id", "created_at", b"created_at", "direction", b"direction", "figi", b"figi", "instrument_uid", b"instrument_uid", "order_id", b"order_id", "trades", b"trades"]) -> None: ... + +global___OrderTrades = OrderTrades + +@typing.final +class OrderTrade(google.protobuf.message.Message): + """Информация о сделке.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + DATE_TIME_FIELD_NUMBER: builtins.int + PRICE_FIELD_NUMBER: builtins.int + QUANTITY_FIELD_NUMBER: builtins.int + TRADE_ID_FIELD_NUMBER: builtins.int + quantity: builtins.int + """Количество штук в сделке.""" + trade_id: builtins.str + """Идентификатор сделки.""" + @property + def date_time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата и время совершения сделки в часовом поясе UTC.""" + + @property + def price(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Цена за 1 инструмент, по которой совершена сделка.""" + + def __init__( + self, + *, + date_time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + price: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + quantity: builtins.int = ..., + trade_id: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["date_time", b"date_time", "price", b"price"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["date_time", b"date_time", "price", b"price", "quantity", b"quantity", "trade_id", b"trade_id"]) -> None: ... + +global___OrderTrade = OrderTrade + +@typing.final +class PostOrderRequest(google.protobuf.message.Message): + """Запрос выставления торгового поручения.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FIGI_FIELD_NUMBER: builtins.int + QUANTITY_FIELD_NUMBER: builtins.int + PRICE_FIELD_NUMBER: builtins.int + DIRECTION_FIELD_NUMBER: builtins.int + ACCOUNT_ID_FIELD_NUMBER: builtins.int + ORDER_TYPE_FIELD_NUMBER: builtins.int + ORDER_ID_FIELD_NUMBER: builtins.int + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + TIME_IN_FORCE_FIELD_NUMBER: builtins.int + PRICE_TYPE_FIELD_NUMBER: builtins.int + CONFIRM_MARGIN_TRADE_FIELD_NUMBER: builtins.int + figi: builtins.str + """Deprecated Figi-идентификатор инструмента. Необходимо использовать instrument_id.""" + quantity: builtins.int + """Количество лотов.""" + direction: global___OrderDirection.ValueType + """Направление операции.""" + account_id: builtins.str + """Номер счета.""" + order_type: global___OrderType.ValueType + """Тип заявки.""" + order_id: builtins.str + """Идентификатор запроса выставления поручения для целей идемпотентности в формате UID. Максимальная длина 36 символов.""" + instrument_id: builtins.str + """Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`.""" + time_in_force: global___TimeInForceType.ValueType + """Алгоритм исполнения поручения, применяется только к лимитной заявке.""" + price_type: t_tech.invest.grpc.common_pb2.PriceType.ValueType + """Тип цены.""" + confirm_margin_trade: builtins.bool + """Согласие на выставление заявки, которая может привести к непокрытой позиции, по умолчанию false.""" + @property + def price(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Цена за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента. Игнорируется для рыночных поручений.""" + + def __init__( + self, + *, + figi: builtins.str | None = ..., + quantity: builtins.int = ..., + price: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + direction: global___OrderDirection.ValueType = ..., + account_id: builtins.str = ..., + order_type: global___OrderType.ValueType = ..., + order_id: builtins.str = ..., + instrument_id: builtins.str = ..., + time_in_force: global___TimeInForceType.ValueType = ..., + price_type: t_tech.invest.grpc.common_pb2.PriceType.ValueType = ..., + confirm_margin_trade: builtins.bool = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_figi", b"_figi", "_price", b"_price", "figi", b"figi", "price", b"price"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_figi", b"_figi", "_price", b"_price", "account_id", b"account_id", "confirm_margin_trade", b"confirm_margin_trade", "direction", b"direction", "figi", b"figi", "instrument_id", b"instrument_id", "order_id", b"order_id", "order_type", b"order_type", "price", b"price", "price_type", b"price_type", "quantity", b"quantity", "time_in_force", b"time_in_force"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_figi", b"_figi"]) -> typing.Literal["figi"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_price", b"_price"]) -> typing.Literal["price"] | None: ... + +global___PostOrderRequest = PostOrderRequest + +@typing.final +class PostOrderResponse(google.protobuf.message.Message): + """Прочитайте про ключ идемпотентности [здесь](./head-orders/) + + Информация о выставлении поручения. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ORDER_ID_FIELD_NUMBER: builtins.int + EXECUTION_REPORT_STATUS_FIELD_NUMBER: builtins.int + LOTS_REQUESTED_FIELD_NUMBER: builtins.int + LOTS_EXECUTED_FIELD_NUMBER: builtins.int + INITIAL_ORDER_PRICE_FIELD_NUMBER: builtins.int + EXECUTED_ORDER_PRICE_FIELD_NUMBER: builtins.int + TOTAL_ORDER_AMOUNT_FIELD_NUMBER: builtins.int + INITIAL_COMMISSION_FIELD_NUMBER: builtins.int + EXECUTED_COMMISSION_FIELD_NUMBER: builtins.int + ACI_VALUE_FIELD_NUMBER: builtins.int + FIGI_FIELD_NUMBER: builtins.int + DIRECTION_FIELD_NUMBER: builtins.int + INITIAL_SECURITY_PRICE_FIELD_NUMBER: builtins.int + ORDER_TYPE_FIELD_NUMBER: builtins.int + MESSAGE_FIELD_NUMBER: builtins.int + INITIAL_ORDER_PRICE_PT_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + ORDER_REQUEST_ID_FIELD_NUMBER: builtins.int + RESPONSE_METADATA_FIELD_NUMBER: builtins.int + order_id: builtins.str + """Биржевой идентификатор заявки.""" + execution_report_status: global___OrderExecutionReportStatus.ValueType + """Текущий статус заявки.""" + lots_requested: builtins.int + """Запрошено лотов.""" + lots_executed: builtins.int + """Исполнено лотов.""" + figi: builtins.str + """Figi-идентификатор инструмента.""" + direction: global___OrderDirection.ValueType + """Направление сделки.""" + order_type: global___OrderType.ValueType + """Тип заявки.""" + message: builtins.str + """Дополнительные данные об исполнении заявки.""" + instrument_uid: builtins.str + """UID идентификатор инструмента.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + order_request_id: builtins.str + """Идентификатор ключа идемпотентности, переданный клиентом, в формате UID. Максимальная длина 36 символов.""" + @property + def initial_order_price(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Начальная цена заявки. Произведение количества запрошенных лотов на цену.""" + + @property + def executed_order_price(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Исполненная средняя цена одного инструмента в заявке.""" + + @property + def total_order_amount(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Итоговая стоимость заявки, включающая все комиссии.""" + + @property + def initial_commission(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Начальная комиссия. Комиссия рассчитанная при выставлении заявки.""" + + @property + def executed_commission(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Фактическая комиссия по итогам исполнения заявки.""" + + @property + def aci_value(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Значение НКД (накопленного купонного дохода) на дату. Подробнее: [НКД при выставлении торговых поручений](./head-orders#coupon)""" + + @property + def initial_security_price(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Начальная цена за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.""" + + @property + def initial_order_price_pt(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Начальная цена заявки в пунктах (для фьючерсов).""" + + @property + def response_metadata(self) -> t_tech.invest.grpc.common_pb2.ResponseMetadata: + """Метадата""" + + def __init__( + self, + *, + order_id: builtins.str = ..., + execution_report_status: global___OrderExecutionReportStatus.ValueType = ..., + lots_requested: builtins.int = ..., + lots_executed: builtins.int = ..., + initial_order_price: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + executed_order_price: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + total_order_amount: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + initial_commission: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + executed_commission: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + aci_value: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + figi: builtins.str = ..., + direction: global___OrderDirection.ValueType = ..., + initial_security_price: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + order_type: global___OrderType.ValueType = ..., + message: builtins.str = ..., + initial_order_price_pt: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + instrument_uid: builtins.str = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + order_request_id: builtins.str = ..., + response_metadata: t_tech.invest.grpc.common_pb2.ResponseMetadata | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["aci_value", b"aci_value", "executed_commission", b"executed_commission", "executed_order_price", b"executed_order_price", "initial_commission", b"initial_commission", "initial_order_price", b"initial_order_price", "initial_order_price_pt", b"initial_order_price_pt", "initial_security_price", b"initial_security_price", "response_metadata", b"response_metadata", "total_order_amount", b"total_order_amount"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["aci_value", b"aci_value", "class_code", b"class_code", "direction", b"direction", "executed_commission", b"executed_commission", "executed_order_price", b"executed_order_price", "execution_report_status", b"execution_report_status", "figi", b"figi", "initial_commission", b"initial_commission", "initial_order_price", b"initial_order_price", "initial_order_price_pt", b"initial_order_price_pt", "initial_security_price", b"initial_security_price", "instrument_uid", b"instrument_uid", "lots_executed", b"lots_executed", "lots_requested", b"lots_requested", "message", b"message", "order_id", b"order_id", "order_request_id", b"order_request_id", "order_type", b"order_type", "response_metadata", b"response_metadata", "ticker", b"ticker", "total_order_amount", b"total_order_amount"]) -> None: ... + +global___PostOrderResponse = PostOrderResponse + +@typing.final +class PostOrderAsyncRequest(google.protobuf.message.Message): + """Запрос выставления асинхронного торгового поручения.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + QUANTITY_FIELD_NUMBER: builtins.int + PRICE_FIELD_NUMBER: builtins.int + DIRECTION_FIELD_NUMBER: builtins.int + ACCOUNT_ID_FIELD_NUMBER: builtins.int + ORDER_TYPE_FIELD_NUMBER: builtins.int + ORDER_ID_FIELD_NUMBER: builtins.int + TIME_IN_FORCE_FIELD_NUMBER: builtins.int + PRICE_TYPE_FIELD_NUMBER: builtins.int + CONFIRM_MARGIN_TRADE_FIELD_NUMBER: builtins.int + instrument_id: builtins.str + """Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`.""" + quantity: builtins.int + """Количество лотов.""" + direction: global___OrderDirection.ValueType + """Направление операции.""" + account_id: builtins.str + """Номер счета.""" + order_type: global___OrderType.ValueType + """Тип заявки.""" + order_id: builtins.str + """Идентификатор запроса выставления поручения для целей идемпотентности в формате UID. Максимальная длина 36 символов.""" + time_in_force: global___TimeInForceType.ValueType + """Алгоритм исполнения поручения, применяется только к лимитной заявке.""" + price_type: t_tech.invest.grpc.common_pb2.PriceType.ValueType + """Тип цены.""" + confirm_margin_trade: builtins.bool + """Согласие на выставление заявки, которая может привести к непокрытой позиции, по умолчанию false.""" + @property + def price(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Цена за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента. Игнорируется для рыночных поручений.""" + + def __init__( + self, + *, + instrument_id: builtins.str = ..., + quantity: builtins.int = ..., + price: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + direction: global___OrderDirection.ValueType = ..., + account_id: builtins.str = ..., + order_type: global___OrderType.ValueType = ..., + order_id: builtins.str = ..., + time_in_force: global___TimeInForceType.ValueType | None = ..., + price_type: t_tech.invest.grpc.common_pb2.PriceType.ValueType | None = ..., + confirm_margin_trade: builtins.bool = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_price", b"_price", "_price_type", b"_price_type", "_time_in_force", b"_time_in_force", "price", b"price", "price_type", b"price_type", "time_in_force", b"time_in_force"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_price", b"_price", "_price_type", b"_price_type", "_time_in_force", b"_time_in_force", "account_id", b"account_id", "confirm_margin_trade", b"confirm_margin_trade", "direction", b"direction", "instrument_id", b"instrument_id", "order_id", b"order_id", "order_type", b"order_type", "price", b"price", "price_type", b"price_type", "quantity", b"quantity", "time_in_force", b"time_in_force"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_price", b"_price"]) -> typing.Literal["price"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_price_type", b"_price_type"]) -> typing.Literal["price_type"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_time_in_force", b"_time_in_force"]) -> typing.Literal["time_in_force"] | None: ... + +global___PostOrderAsyncRequest = PostOrderAsyncRequest + +@typing.final +class PostOrderAsyncResponse(google.protobuf.message.Message): + """Результат выставления асинхронного торгового поручения.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ORDER_REQUEST_ID_FIELD_NUMBER: builtins.int + EXECUTION_REPORT_STATUS_FIELD_NUMBER: builtins.int + TRADE_INTENT_ID_FIELD_NUMBER: builtins.int + order_request_id: builtins.str + """Идентификатор ключа идемпотентности, переданный клиентом, в формате UID. Максимальная длина 36 символов.""" + execution_report_status: global___OrderExecutionReportStatus.ValueType + """Текущий статус заявки.""" + trade_intent_id: builtins.str + """Идентификатор торгового поручения.""" + def __init__( + self, + *, + order_request_id: builtins.str = ..., + execution_report_status: global___OrderExecutionReportStatus.ValueType = ..., + trade_intent_id: builtins.str | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_trade_intent_id", b"_trade_intent_id", "trade_intent_id", b"trade_intent_id"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_trade_intent_id", b"_trade_intent_id", "execution_report_status", b"execution_report_status", "order_request_id", b"order_request_id", "trade_intent_id", b"trade_intent_id"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_trade_intent_id", b"_trade_intent_id"]) -> typing.Literal["trade_intent_id"] | None: ... + +global___PostOrderAsyncResponse = PostOrderAsyncResponse + +@typing.final +class CancelOrderRequest(google.protobuf.message.Message): + """Запрос отмены торгового поручения.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNT_ID_FIELD_NUMBER: builtins.int + ORDER_ID_FIELD_NUMBER: builtins.int + ORDER_ID_TYPE_FIELD_NUMBER: builtins.int + account_id: builtins.str + """Номер счета.""" + order_id: builtins.str + """Идентификатор заявки.""" + order_id_type: global___OrderIdType.ValueType + """Тип идентификатора заявки.""" + def __init__( + self, + *, + account_id: builtins.str = ..., + order_id: builtins.str = ..., + order_id_type: global___OrderIdType.ValueType | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_order_id_type", b"_order_id_type", "order_id_type", b"order_id_type"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_order_id_type", b"_order_id_type", "account_id", b"account_id", "order_id", b"order_id", "order_id_type", b"order_id_type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_order_id_type", b"_order_id_type"]) -> typing.Literal["order_id_type"] | None: ... + +global___CancelOrderRequest = CancelOrderRequest + +@typing.final +class CancelOrderResponse(google.protobuf.message.Message): + """Результат отмены торгового поручения.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TIME_FIELD_NUMBER: builtins.int + RESPONSE_METADATA_FIELD_NUMBER: builtins.int + @property + def time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата и время отмены заявки в часовом поясе UTC.""" + + @property + def response_metadata(self) -> t_tech.invest.grpc.common_pb2.ResponseMetadata: + """Метадата""" + + def __init__( + self, + *, + time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + response_metadata: t_tech.invest.grpc.common_pb2.ResponseMetadata | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["response_metadata", b"response_metadata", "time", b"time"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["response_metadata", b"response_metadata", "time", b"time"]) -> None: ... + +global___CancelOrderResponse = CancelOrderResponse + +@typing.final +class GetOrderStateRequest(google.protobuf.message.Message): + """Запрос получения статуса торгового поручения.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNT_ID_FIELD_NUMBER: builtins.int + ORDER_ID_FIELD_NUMBER: builtins.int + PRICE_TYPE_FIELD_NUMBER: builtins.int + ORDER_ID_TYPE_FIELD_NUMBER: builtins.int + account_id: builtins.str + """Номер счета.""" + order_id: builtins.str + """Идентификатор заявки.""" + price_type: t_tech.invest.grpc.common_pb2.PriceType.ValueType + """Тип цены.""" + order_id_type: global___OrderIdType.ValueType + """Тип идентификатора заявки.""" + def __init__( + self, + *, + account_id: builtins.str = ..., + order_id: builtins.str = ..., + price_type: t_tech.invest.grpc.common_pb2.PriceType.ValueType = ..., + order_id_type: global___OrderIdType.ValueType | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_order_id_type", b"_order_id_type", "order_id_type", b"order_id_type"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_order_id_type", b"_order_id_type", "account_id", b"account_id", "order_id", b"order_id", "order_id_type", b"order_id_type", "price_type", b"price_type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_order_id_type", b"_order_id_type"]) -> typing.Literal["order_id_type"] | None: ... + +global___GetOrderStateRequest = GetOrderStateRequest + +@typing.final +class GetOrdersRequest(google.protobuf.message.Message): + """Запрос получения списка активных торговых поручений.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing.final + class GetOrdersRequestFilters(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FROM_FIELD_NUMBER: builtins.int + TO_FIELD_NUMBER: builtins.int + EXECUTION_STATUS_FIELD_NUMBER: builtins.int + @property + def to(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата и время, до которой нужно получить информацию в часовом поясе UTC. Параметр применим только к ордерам, созданным сегодня.""" + + @property + def execution_status(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[global___OrderExecutionReportStatus.ValueType]: + """Статусы заявок.""" + + def __init__( + self, + *, + to: google.protobuf.timestamp_pb2.Timestamp | None = ..., + execution_status: collections.abc.Iterable[global___OrderExecutionReportStatus.ValueType] | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_from", b"_from", "_to", b"_to", "from", b"from", "to", b"to"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_from", b"_from", "_to", b"_to", "execution_status", b"execution_status", "from", b"from", "to", b"to"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_from", b"_from"]) -> typing.Literal["from"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_to", b"_to"]) -> typing.Literal["to"] | None: ... + + ACCOUNT_ID_FIELD_NUMBER: builtins.int + ADVANCED_FILTERS_FIELD_NUMBER: builtins.int + account_id: builtins.str + """Номер счета.""" + @property + def advanced_filters(self) -> global___GetOrdersRequest.GetOrdersRequestFilters: + """Дополнительные фильтры.""" + + def __init__( + self, + *, + account_id: builtins.str = ..., + advanced_filters: global___GetOrdersRequest.GetOrdersRequestFilters | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_advanced_filters", b"_advanced_filters", "advanced_filters", b"advanced_filters"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_advanced_filters", b"_advanced_filters", "account_id", b"account_id", "advanced_filters", b"advanced_filters"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_advanced_filters", b"_advanced_filters"]) -> typing.Literal["advanced_filters"] | None: ... + +global___GetOrdersRequest = GetOrdersRequest + +@typing.final +class GetOrdersResponse(google.protobuf.message.Message): + """Список активных торговых поручений.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ORDERS_FIELD_NUMBER: builtins.int + @property + def orders(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___OrderState]: + """Массив активных заявок.""" + + def __init__( + self, + *, + orders: collections.abc.Iterable[global___OrderState] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["orders", b"orders"]) -> None: ... + +global___GetOrdersResponse = GetOrdersResponse + +@typing.final +class OrderState(google.protobuf.message.Message): + """Информация о торговом поручении.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ORDER_ID_FIELD_NUMBER: builtins.int + EXECUTION_REPORT_STATUS_FIELD_NUMBER: builtins.int + LOTS_REQUESTED_FIELD_NUMBER: builtins.int + LOTS_EXECUTED_FIELD_NUMBER: builtins.int + INITIAL_ORDER_PRICE_FIELD_NUMBER: builtins.int + EXECUTED_ORDER_PRICE_FIELD_NUMBER: builtins.int + TOTAL_ORDER_AMOUNT_FIELD_NUMBER: builtins.int + AVERAGE_POSITION_PRICE_FIELD_NUMBER: builtins.int + INITIAL_COMMISSION_FIELD_NUMBER: builtins.int + EXECUTED_COMMISSION_FIELD_NUMBER: builtins.int + FIGI_FIELD_NUMBER: builtins.int + DIRECTION_FIELD_NUMBER: builtins.int + INITIAL_SECURITY_PRICE_FIELD_NUMBER: builtins.int + STAGES_FIELD_NUMBER: builtins.int + SERVICE_COMMISSION_FIELD_NUMBER: builtins.int + CURRENCY_FIELD_NUMBER: builtins.int + ORDER_TYPE_FIELD_NUMBER: builtins.int + ORDER_DATE_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + ORDER_REQUEST_ID_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + order_id: builtins.str + """Биржевой идентификатор заявки.""" + execution_report_status: global___OrderExecutionReportStatus.ValueType + """Текущий статус заявки.""" + lots_requested: builtins.int + """Запрошено лотов.""" + lots_executed: builtins.int + """Исполнено лотов.""" + figi: builtins.str + """Figi-идентификатор инструмента.""" + direction: global___OrderDirection.ValueType + """Направление заявки.""" + currency: builtins.str + """Валюта заявки.""" + order_type: global___OrderType.ValueType + """Тип заявки.""" + instrument_uid: builtins.str + """UID идентификатор инструмента.""" + order_request_id: builtins.str + """Идентификатор ключа идемпотентности, переданный клиентом, в формате UID. Максимальная длина 36 символов.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + @property + def initial_order_price(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Начальная цена заявки. Произведение количества запрошенных лотов на цену.""" + + @property + def executed_order_price(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Исполненная цена заявки. Произведение средней цены покупки на количество лотов.""" + + @property + def total_order_amount(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Итоговая стоимость заявки, включающая все комиссии.""" + + @property + def average_position_price(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Средняя цена позиции по сделке.""" + + @property + def initial_commission(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Начальная комиссия. Комиссия, рассчитанная на момент подачи заявки.""" + + @property + def executed_commission(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Фактическая комиссия по итогам исполнения заявки.""" + + @property + def initial_security_price(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Начальная цена за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.""" + + @property + def stages(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___OrderStage]: + """Стадии выполнения заявки.""" + + @property + def service_commission(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Сервисная комиссия.""" + + @property + def order_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата и время выставления заявки в часовом поясе UTC.""" + + def __init__( + self, + *, + order_id: builtins.str = ..., + execution_report_status: global___OrderExecutionReportStatus.ValueType = ..., + lots_requested: builtins.int = ..., + lots_executed: builtins.int = ..., + initial_order_price: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + executed_order_price: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + total_order_amount: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + average_position_price: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + initial_commission: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + executed_commission: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + figi: builtins.str = ..., + direction: global___OrderDirection.ValueType = ..., + initial_security_price: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + stages: collections.abc.Iterable[global___OrderStage] | None = ..., + service_commission: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + currency: builtins.str = ..., + order_type: global___OrderType.ValueType = ..., + order_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + instrument_uid: builtins.str = ..., + order_request_id: builtins.str = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["average_position_price", b"average_position_price", "executed_commission", b"executed_commission", "executed_order_price", b"executed_order_price", "initial_commission", b"initial_commission", "initial_order_price", b"initial_order_price", "initial_security_price", b"initial_security_price", "order_date", b"order_date", "service_commission", b"service_commission", "total_order_amount", b"total_order_amount"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["average_position_price", b"average_position_price", "class_code", b"class_code", "currency", b"currency", "direction", b"direction", "executed_commission", b"executed_commission", "executed_order_price", b"executed_order_price", "execution_report_status", b"execution_report_status", "figi", b"figi", "initial_commission", b"initial_commission", "initial_order_price", b"initial_order_price", "initial_security_price", b"initial_security_price", "instrument_uid", b"instrument_uid", "lots_executed", b"lots_executed", "lots_requested", b"lots_requested", "order_date", b"order_date", "order_id", b"order_id", "order_request_id", b"order_request_id", "order_type", b"order_type", "service_commission", b"service_commission", "stages", b"stages", "ticker", b"ticker", "total_order_amount", b"total_order_amount"]) -> None: ... + +global___OrderState = OrderState + +@typing.final +class OrderStage(google.protobuf.message.Message): + """Сделки в рамках торгового поручения.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PRICE_FIELD_NUMBER: builtins.int + QUANTITY_FIELD_NUMBER: builtins.int + TRADE_ID_FIELD_NUMBER: builtins.int + EXECUTION_TIME_FIELD_NUMBER: builtins.int + quantity: builtins.int + """Количество лотов.""" + trade_id: builtins.str + """Идентификатор сделки.""" + @property + def price(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Цена за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.""" + + @property + def execution_time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время исполнения сделки""" + + def __init__( + self, + *, + price: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + quantity: builtins.int = ..., + trade_id: builtins.str = ..., + execution_time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["execution_time", b"execution_time", "price", b"price"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["execution_time", b"execution_time", "price", b"price", "quantity", b"quantity", "trade_id", b"trade_id"]) -> None: ... + +global___OrderStage = OrderStage + +@typing.final +class ReplaceOrderRequest(google.protobuf.message.Message): + """Запрос изменения выставленной заявки.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNT_ID_FIELD_NUMBER: builtins.int + ORDER_ID_TYPE_FIELD_NUMBER: builtins.int + ORDER_ID_FIELD_NUMBER: builtins.int + IDEMPOTENCY_KEY_FIELD_NUMBER: builtins.int + QUANTITY_FIELD_NUMBER: builtins.int + PRICE_FIELD_NUMBER: builtins.int + PRICE_TYPE_FIELD_NUMBER: builtins.int + CONFIRM_MARGIN_TRADE_FIELD_NUMBER: builtins.int + account_id: builtins.str + """Номер счета.""" + order_id_type: global___OrderIdType.ValueType + """Тип идентификатора заявки.""" + order_id: builtins.str + """Идентификатор заявки на бирже.""" + idempotency_key: builtins.str + """Новый идентификатор запроса выставления поручения для целей идемпотентности. Максимальная длина 36 символов. Перезатирает старый ключ.""" + quantity: builtins.int + """Количество лотов.""" + price_type: t_tech.invest.grpc.common_pb2.PriceType.ValueType + """Тип цены.""" + confirm_margin_trade: builtins.bool + """Согласие на выставление заявки, которая может привести к непокрытой позиции, по умолчанию false.""" + @property + def price(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Цена за 1 инструмент.""" + + def __init__( + self, + *, + account_id: builtins.str = ..., + order_id_type: global___OrderIdType.ValueType | None = ..., + order_id: builtins.str = ..., + idempotency_key: builtins.str = ..., + quantity: builtins.int = ..., + price: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + price_type: t_tech.invest.grpc.common_pb2.PriceType.ValueType | None = ..., + confirm_margin_trade: builtins.bool = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_order_id_type", b"_order_id_type", "_price", b"_price", "_price_type", b"_price_type", "order_id_type", b"order_id_type", "price", b"price", "price_type", b"price_type"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_order_id_type", b"_order_id_type", "_price", b"_price", "_price_type", b"_price_type", "account_id", b"account_id", "confirm_margin_trade", b"confirm_margin_trade", "idempotency_key", b"idempotency_key", "order_id", b"order_id", "order_id_type", b"order_id_type", "price", b"price", "price_type", b"price_type", "quantity", b"quantity"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_order_id_type", b"_order_id_type"]) -> typing.Literal["order_id_type"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_price", b"_price"]) -> typing.Literal["price"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_price_type", b"_price_type"]) -> typing.Literal["price_type"] | None: ... + +global___ReplaceOrderRequest = ReplaceOrderRequest + +@typing.final +class GetMaxLotsRequest(google.protobuf.message.Message): + """Запрос на расчет количества доступных для покупки/продажи лотов. Если не указывать цену инструмента, то расчет произведется по текущум ценам в стакане: по лучшему предложению для покупки и по лучшему спросу для продажи.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNT_ID_FIELD_NUMBER: builtins.int + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + PRICE_FIELD_NUMBER: builtins.int + account_id: builtins.str + """Номер счета""" + instrument_id: builtins.str + """Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`.""" + @property + def price(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Цена инструмента""" + + def __init__( + self, + *, + account_id: builtins.str = ..., + instrument_id: builtins.str = ..., + price: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_price", b"_price", "price", b"price"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_price", b"_price", "account_id", b"account_id", "instrument_id", b"instrument_id", "price", b"price"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_price", b"_price"]) -> typing.Literal["price"] | None: ... + +global___GetMaxLotsRequest = GetMaxLotsRequest + +@typing.final +class GetMaxLotsResponse(google.protobuf.message.Message): + """Результат количество доступных для покупки/продажи лотов""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing.final + class BuyLimitsView(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + BUY_MONEY_AMOUNT_FIELD_NUMBER: builtins.int + BUY_MAX_LOTS_FIELD_NUMBER: builtins.int + BUY_MAX_MARKET_LOTS_FIELD_NUMBER: builtins.int + buy_max_lots: builtins.int + """Максимальное доступное количество лотов для покупки""" + buy_max_market_lots: builtins.int + """Максимальное доступное количество лотов для покупки для заявки по рыночной цене на текущий момент""" + @property + def buy_money_amount(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Количество доступной валюты для покупки""" + + def __init__( + self, + *, + buy_money_amount: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + buy_max_lots: builtins.int = ..., + buy_max_market_lots: builtins.int = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["buy_money_amount", b"buy_money_amount"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["buy_max_lots", b"buy_max_lots", "buy_max_market_lots", b"buy_max_market_lots", "buy_money_amount", b"buy_money_amount"]) -> None: ... + + @typing.final + class SellLimitsView(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SELL_MAX_LOTS_FIELD_NUMBER: builtins.int + sell_max_lots: builtins.int + """Максимальное доступное количество лотов для продажи""" + def __init__( + self, + *, + sell_max_lots: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["sell_max_lots", b"sell_max_lots"]) -> None: ... + + CURRENCY_FIELD_NUMBER: builtins.int + BUY_LIMITS_FIELD_NUMBER: builtins.int + BUY_MARGIN_LIMITS_FIELD_NUMBER: builtins.int + SELL_LIMITS_FIELD_NUMBER: builtins.int + SELL_MARGIN_LIMITS_FIELD_NUMBER: builtins.int + currency: builtins.str + """Валюта инструмента""" + @property + def buy_limits(self) -> global___GetMaxLotsResponse.BuyLimitsView: + """Лимиты для покупок на собственные деньги""" + + @property + def buy_margin_limits(self) -> global___GetMaxLotsResponse.BuyLimitsView: + """Лимиты для покупок с учетом маржинального кредитования""" + + @property + def sell_limits(self) -> global___GetMaxLotsResponse.SellLimitsView: + """Лимиты для продаж по собственной позиции""" + + @property + def sell_margin_limits(self) -> global___GetMaxLotsResponse.SellLimitsView: + """Лимиты для продаж с учетом маржинального кредитования""" + + def __init__( + self, + *, + currency: builtins.str = ..., + buy_limits: global___GetMaxLotsResponse.BuyLimitsView | None = ..., + buy_margin_limits: global___GetMaxLotsResponse.BuyLimitsView | None = ..., + sell_limits: global___GetMaxLotsResponse.SellLimitsView | None = ..., + sell_margin_limits: global___GetMaxLotsResponse.SellLimitsView | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["buy_limits", b"buy_limits", "buy_margin_limits", b"buy_margin_limits", "sell_limits", b"sell_limits", "sell_margin_limits", b"sell_margin_limits"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["buy_limits", b"buy_limits", "buy_margin_limits", b"buy_margin_limits", "currency", b"currency", "sell_limits", b"sell_limits", "sell_margin_limits", b"sell_margin_limits"]) -> None: ... + +global___GetMaxLotsResponse = GetMaxLotsResponse + +@typing.final +class GetOrderPriceRequest(google.protobuf.message.Message): + """Запрос получения предварительной стоимости заявки""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNT_ID_FIELD_NUMBER: builtins.int + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + PRICE_FIELD_NUMBER: builtins.int + DIRECTION_FIELD_NUMBER: builtins.int + QUANTITY_FIELD_NUMBER: builtins.int + account_id: builtins.str + """Номер счета""" + instrument_id: builtins.str + """Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`.""" + direction: global___OrderDirection.ValueType + """Направление заявки""" + quantity: builtins.int + """Количество лотов""" + @property + def price(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Цена инструмента""" + + def __init__( + self, + *, + account_id: builtins.str = ..., + instrument_id: builtins.str = ..., + price: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + direction: global___OrderDirection.ValueType = ..., + quantity: builtins.int = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["price", b"price"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["account_id", b"account_id", "direction", b"direction", "instrument_id", b"instrument_id", "price", b"price", "quantity", b"quantity"]) -> None: ... + +global___GetOrderPriceRequest = GetOrderPriceRequest + +@typing.final +class GetOrderPriceResponse(google.protobuf.message.Message): + """Предварительная стоимость заявки""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing.final + class ExtraBond(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACI_VALUE_FIELD_NUMBER: builtins.int + NOMINAL_CONVERSION_RATE_FIELD_NUMBER: builtins.int + @property + def aci_value(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Значение НКД (накопленного купонного дохода) на дату""" + + @property + def nominal_conversion_rate(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Курс конвертации для замещающих облигаций""" + + def __init__( + self, + *, + aci_value: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + nominal_conversion_rate: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["aci_value", b"aci_value", "nominal_conversion_rate", b"nominal_conversion_rate"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["aci_value", b"aci_value", "nominal_conversion_rate", b"nominal_conversion_rate"]) -> None: ... + + @typing.final + class ExtraFuture(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INITIAL_MARGIN_FIELD_NUMBER: builtins.int + @property + def initial_margin(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Гарантийное обеспечение для фьючерса""" + + def __init__( + self, + *, + initial_margin: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["initial_margin", b"initial_margin"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["initial_margin", b"initial_margin"]) -> None: ... + + TOTAL_ORDER_AMOUNT_FIELD_NUMBER: builtins.int + INITIAL_ORDER_AMOUNT_FIELD_NUMBER: builtins.int + LOTS_REQUESTED_FIELD_NUMBER: builtins.int + EXECUTED_COMMISSION_FIELD_NUMBER: builtins.int + EXECUTED_COMMISSION_RUB_FIELD_NUMBER: builtins.int + SERVICE_COMMISSION_FIELD_NUMBER: builtins.int + DEAL_COMMISSION_FIELD_NUMBER: builtins.int + EXTRA_BOND_FIELD_NUMBER: builtins.int + EXTRA_FUTURE_FIELD_NUMBER: builtins.int + lots_requested: builtins.int + """Запрошено лотов""" + @property + def total_order_amount(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Итоговая стоимость заявки""" + + @property + def initial_order_amount(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Стоимость заявки без комиссий, НКД, ГО (для фьючерсов — стоимость контрактов)""" + + @property + def executed_commission(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Общая комиссия""" + + @property + def executed_commission_rub(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Общая комиссия в рублях""" + + @property + def service_commission(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Сервисная комиссия""" + + @property + def deal_commission(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Комиссия за проведение сделки""" + + @property + def extra_bond(self) -> global___GetOrderPriceResponse.ExtraBond: + """Дополнительная информация по облигациям""" + + @property + def extra_future(self) -> global___GetOrderPriceResponse.ExtraFuture: + """Дополнительная информация по фьючерсам""" + + def __init__( + self, + *, + total_order_amount: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + initial_order_amount: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + lots_requested: builtins.int = ..., + executed_commission: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + executed_commission_rub: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + service_commission: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + deal_commission: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + extra_bond: global___GetOrderPriceResponse.ExtraBond | None = ..., + extra_future: global___GetOrderPriceResponse.ExtraFuture | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["deal_commission", b"deal_commission", "executed_commission", b"executed_commission", "executed_commission_rub", b"executed_commission_rub", "extra_bond", b"extra_bond", "extra_future", b"extra_future", "initial_order_amount", b"initial_order_amount", "instrument_extra", b"instrument_extra", "service_commission", b"service_commission", "total_order_amount", b"total_order_amount"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["deal_commission", b"deal_commission", "executed_commission", b"executed_commission", "executed_commission_rub", b"executed_commission_rub", "extra_bond", b"extra_bond", "extra_future", b"extra_future", "initial_order_amount", b"initial_order_amount", "instrument_extra", b"instrument_extra", "lots_requested", b"lots_requested", "service_commission", b"service_commission", "total_order_amount", b"total_order_amount"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["instrument_extra", b"instrument_extra"]) -> typing.Literal["extra_bond", "extra_future"] | None: ... + +global___GetOrderPriceResponse = GetOrderPriceResponse + +@typing.final +class OrderStateStreamRequest(google.protobuf.message.Message): + """Запрос установки стрим-соединения торговых поручений""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNTS_FIELD_NUMBER: builtins.int + PING_DELAY_MILLIS_FIELD_NUMBER: builtins.int + ping_delay_millis: builtins.int + """Задержка (пинг) сообщений: 1000-120 000 миллисекунд. Значение по умолчанию — 120 000.""" + @property + def accounts(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Идентификаторы счетов.""" + + def __init__( + self, + *, + accounts: collections.abc.Iterable[builtins.str] | None = ..., + ping_delay_millis: builtins.int | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_ping_delay_millis", b"_ping_delay_millis", "ping_delay_millis", b"ping_delay_millis"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_ping_delay_millis", b"_ping_delay_millis", "accounts", b"accounts", "ping_delay_millis", b"ping_delay_millis"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_ping_delay_millis", b"_ping_delay_millis"]) -> typing.Literal["ping_delay_millis"] | None: ... + +global___OrderStateStreamRequest = OrderStateStreamRequest + +@typing.final +class SubscriptionResponse(google.protobuf.message.Message): + """Информация по подпискам""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TRACKING_ID_FIELD_NUMBER: builtins.int + STATUS_FIELD_NUMBER: builtins.int + STREAM_ID_FIELD_NUMBER: builtins.int + ACCOUNTS_FIELD_NUMBER: builtins.int + ERROR_FIELD_NUMBER: builtins.int + tracking_id: builtins.str + """Уникальный идентификатор запроса, подробнее: [tracking_id](./grpc#tracking-id).""" + status: t_tech.invest.grpc.common_pb2.ResultSubscriptionStatus.ValueType + """Статус подписки.""" + stream_id: builtins.str + """Идентификатор открытого соединения""" + @property + def accounts(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Идентификаторы счетов.""" + + @property + def error(self) -> t_tech.invest.grpc.common_pb2.ErrorDetail: ... + def __init__( + self, + *, + tracking_id: builtins.str = ..., + status: t_tech.invest.grpc.common_pb2.ResultSubscriptionStatus.ValueType = ..., + stream_id: builtins.str = ..., + accounts: collections.abc.Iterable[builtins.str] | None = ..., + error: t_tech.invest.grpc.common_pb2.ErrorDetail | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_error", b"_error", "error", b"error"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_error", b"_error", "accounts", b"accounts", "error", b"error", "status", b"status", "stream_id", b"stream_id", "tracking_id", b"tracking_id"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_error", b"_error"]) -> typing.Literal["error"] | None: ... + +global___SubscriptionResponse = SubscriptionResponse + +@typing.final +class OrderStateStreamResponse(google.protobuf.message.Message): + """Информация по заявкам""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _MarkerType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _MarkerTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[OrderStateStreamResponse._MarkerType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + MARKER_UNKNOWN: OrderStateStreamResponse._MarkerType.ValueType # 0 + """не определено""" + MARKER_BROKER: OrderStateStreamResponse._MarkerType.ValueType # 1 + """сделки брокера""" + MARKER_CHAT: OrderStateStreamResponse._MarkerType.ValueType # 2 + """исполнение поручение, полученного от клиента через каналы связи""" + MARKER_PAPER: OrderStateStreamResponse._MarkerType.ValueType # 3 + """исполнение поручение, полученного от клиента в бумажной форме""" + MARKER_MARGIN: OrderStateStreamResponse._MarkerType.ValueType # 4 + """принудительное закрытие позиций""" + MARKER_TKBNM: OrderStateStreamResponse._MarkerType.ValueType # 5 + """сделки по управлению ликвидностью""" + MARKER_SHORT: OrderStateStreamResponse._MarkerType.ValueType # 6 + """сделки РЕПО по привлечению у клиентов бумаг""" + MARKER_SPECMM: OrderStateStreamResponse._MarkerType.ValueType # 7 + """перенос временно непокрытых позиций""" + MARKER_PO: OrderStateStreamResponse._MarkerType.ValueType # 8 + + class MarkerType(_MarkerType, metaclass=_MarkerTypeEnumTypeWrapper): + """Маркер""" + + MARKER_UNKNOWN: OrderStateStreamResponse.MarkerType.ValueType # 0 + """не определено""" + MARKER_BROKER: OrderStateStreamResponse.MarkerType.ValueType # 1 + """сделки брокера""" + MARKER_CHAT: OrderStateStreamResponse.MarkerType.ValueType # 2 + """исполнение поручение, полученного от клиента через каналы связи""" + MARKER_PAPER: OrderStateStreamResponse.MarkerType.ValueType # 3 + """исполнение поручение, полученного от клиента в бумажной форме""" + MARKER_MARGIN: OrderStateStreamResponse.MarkerType.ValueType # 4 + """принудительное закрытие позиций""" + MARKER_TKBNM: OrderStateStreamResponse.MarkerType.ValueType # 5 + """сделки по управлению ликвидностью""" + MARKER_SHORT: OrderStateStreamResponse.MarkerType.ValueType # 6 + """сделки РЕПО по привлечению у клиентов бумаг""" + MARKER_SPECMM: OrderStateStreamResponse.MarkerType.ValueType # 7 + """перенос временно непокрытых позиций""" + MARKER_PO: OrderStateStreamResponse.MarkerType.ValueType # 8 + + class _StatusCauseInfo: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _StatusCauseInfoEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[OrderStateStreamResponse._StatusCauseInfo.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + CAUSE_UNSPECIFIED: OrderStateStreamResponse._StatusCauseInfo.ValueType # 0 + """Не определено""" + CAUSE_CANCELLED_BY_CLIENT: OrderStateStreamResponse._StatusCauseInfo.ValueType # 15 + """Отменено клиентом""" + CAUSE_CANCELLED_BY_EXCHANGE: OrderStateStreamResponse._StatusCauseInfo.ValueType # 1 + """Отменено биржей""" + CAUSE_CANCELLED_NOT_ENOUGH_POSITION: OrderStateStreamResponse._StatusCauseInfo.ValueType # 2 + """Заявка не выставлена из-за нехватки средств""" + CAUSE_CANCELLED_BY_CLIENT_BLOCK: OrderStateStreamResponse._StatusCauseInfo.ValueType # 3 + """Отменено из-за блокировки клиента""" + CAUSE_REJECTED_BY_BROKER: OrderStateStreamResponse._StatusCauseInfo.ValueType # 4 + """Отклонено брокером""" + CAUSE_REJECTED_BY_EXCHANGE: OrderStateStreamResponse._StatusCauseInfo.ValueType # 5 + """Отклонено биржей""" + CAUSE_CANCELLED_BY_BROKER: OrderStateStreamResponse._StatusCauseInfo.ValueType # 6 + """Отменено брокером""" + + class StatusCauseInfo(_StatusCauseInfo, metaclass=_StatusCauseInfoEnumTypeWrapper): + """Дополнительная информация по статусу заявки""" + + CAUSE_UNSPECIFIED: OrderStateStreamResponse.StatusCauseInfo.ValueType # 0 + """Не определено""" + CAUSE_CANCELLED_BY_CLIENT: OrderStateStreamResponse.StatusCauseInfo.ValueType # 15 + """Отменено клиентом""" + CAUSE_CANCELLED_BY_EXCHANGE: OrderStateStreamResponse.StatusCauseInfo.ValueType # 1 + """Отменено биржей""" + CAUSE_CANCELLED_NOT_ENOUGH_POSITION: OrderStateStreamResponse.StatusCauseInfo.ValueType # 2 + """Заявка не выставлена из-за нехватки средств""" + CAUSE_CANCELLED_BY_CLIENT_BLOCK: OrderStateStreamResponse.StatusCauseInfo.ValueType # 3 + """Отменено из-за блокировки клиента""" + CAUSE_REJECTED_BY_BROKER: OrderStateStreamResponse.StatusCauseInfo.ValueType # 4 + """Отклонено брокером""" + CAUSE_REJECTED_BY_EXCHANGE: OrderStateStreamResponse.StatusCauseInfo.ValueType # 5 + """Отклонено биржей""" + CAUSE_CANCELLED_BY_BROKER: OrderStateStreamResponse.StatusCauseInfo.ValueType # 6 + """Отменено брокером""" + + @typing.final + class OrderState(google.protobuf.message.Message): + """Заявка""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ORDER_ID_FIELD_NUMBER: builtins.int + ORDER_REQUEST_ID_FIELD_NUMBER: builtins.int + CLIENT_CODE_FIELD_NUMBER: builtins.int + CREATED_AT_FIELD_NUMBER: builtins.int + EXECUTION_REPORT_STATUS_FIELD_NUMBER: builtins.int + STATUS_INFO_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + LOT_SIZE_FIELD_NUMBER: builtins.int + DIRECTION_FIELD_NUMBER: builtins.int + TIME_IN_FORCE_FIELD_NUMBER: builtins.int + ORDER_TYPE_FIELD_NUMBER: builtins.int + ACCOUNT_ID_FIELD_NUMBER: builtins.int + TRADE_ORDER_ID_FIELD_NUMBER: builtins.int + INITIAL_ORDER_PRICE_FIELD_NUMBER: builtins.int + ORDER_PRICE_FIELD_NUMBER: builtins.int + AMOUNT_FIELD_NUMBER: builtins.int + EXECUTED_ORDER_PRICE_FIELD_NUMBER: builtins.int + CURRENCY_FIELD_NUMBER: builtins.int + LOTS_REQUESTED_FIELD_NUMBER: builtins.int + LOTS_EXECUTED_FIELD_NUMBER: builtins.int + LOTS_LEFT_FIELD_NUMBER: builtins.int + LOTS_CANCELLED_FIELD_NUMBER: builtins.int + MARKER_FIELD_NUMBER: builtins.int + TRADES_FIELD_NUMBER: builtins.int + COMPLETION_TIME_FIELD_NUMBER: builtins.int + EXCHANGE_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + order_id: builtins.str + """Биржевой идентификатор заявки.""" + order_request_id: builtins.str + """Идентификатор ключа идемпотентности, переданный клиентом, в формате UID. Максимальная длина 36 символов.""" + client_code: builtins.str + """Код клиента на бирже.""" + execution_report_status: global___OrderExecutionReportStatus.ValueType + """Статус заявки.""" + status_info: global___OrderStateStreamResponse.StatusCauseInfo.ValueType + """Дополнительная информация по статусу.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + lot_size: builtins.int + """Лотность инструмента заявки.""" + direction: global___OrderDirection.ValueType + """Направление заявки.""" + time_in_force: global___TimeInForceType.ValueType + """Алгоритм исполнения поручения.""" + order_type: global___OrderType.ValueType + """Тип заявки.""" + account_id: builtins.str + """Номер счета.""" + trade_order_id: builtins.str + """Идентификатор торгового поручения.""" + currency: builtins.str + """Валюта исполнения.""" + lots_requested: builtins.int + """Запрошено лотов.""" + lots_executed: builtins.int + """Исполнено лотов.""" + lots_left: builtins.int + """Число неисполненных лотов по заявке.""" + lots_cancelled: builtins.int + """Отмененные лоты.""" + marker: global___OrderStateStreamResponse.MarkerType.ValueType + """Спецсимвол.""" + exchange: builtins.str + """Код биржи.""" + instrument_uid: builtins.str + """UID идентификатор инструмента.""" + @property + def created_at(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата создания заявки.""" + + @property + def initial_order_price(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Начальная цена заявки.""" + + @property + def order_price(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Цена выставления заявки.""" + + @property + def amount(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Предрассчитанная стоимость полной заявки.""" + + @property + def executed_order_price(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Исполненная цена заявки.""" + + @property + def trades(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___OrderTrade]: + """ Список сделок.""" + + @property + def completion_time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время исполнения заявки.""" + + def __init__( + self, + *, + order_id: builtins.str = ..., + order_request_id: builtins.str | None = ..., + client_code: builtins.str = ..., + created_at: google.protobuf.timestamp_pb2.Timestamp | None = ..., + execution_report_status: global___OrderExecutionReportStatus.ValueType = ..., + status_info: global___OrderStateStreamResponse.StatusCauseInfo.ValueType | None = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + lot_size: builtins.int = ..., + direction: global___OrderDirection.ValueType = ..., + time_in_force: global___TimeInForceType.ValueType = ..., + order_type: global___OrderType.ValueType = ..., + account_id: builtins.str = ..., + trade_order_id: builtins.str = ..., + initial_order_price: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + order_price: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + amount: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + executed_order_price: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + currency: builtins.str = ..., + lots_requested: builtins.int = ..., + lots_executed: builtins.int = ..., + lots_left: builtins.int = ..., + lots_cancelled: builtins.int = ..., + marker: global___OrderStateStreamResponse.MarkerType.ValueType | None = ..., + trades: collections.abc.Iterable[global___OrderTrade] | None = ..., + completion_time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + exchange: builtins.str = ..., + instrument_uid: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_amount", b"_amount", "_marker", b"_marker", "_order_request_id", b"_order_request_id", "_status_info", b"_status_info", "amount", b"amount", "completion_time", b"completion_time", "created_at", b"created_at", "executed_order_price", b"executed_order_price", "initial_order_price", b"initial_order_price", "marker", b"marker", "order_price", b"order_price", "order_request_id", b"order_request_id", "status_info", b"status_info"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_amount", b"_amount", "_marker", b"_marker", "_order_request_id", b"_order_request_id", "_status_info", b"_status_info", "account_id", b"account_id", "amount", b"amount", "class_code", b"class_code", "client_code", b"client_code", "completion_time", b"completion_time", "created_at", b"created_at", "currency", b"currency", "direction", b"direction", "exchange", b"exchange", "executed_order_price", b"executed_order_price", "execution_report_status", b"execution_report_status", "initial_order_price", b"initial_order_price", "instrument_uid", b"instrument_uid", "lot_size", b"lot_size", "lots_cancelled", b"lots_cancelled", "lots_executed", b"lots_executed", "lots_left", b"lots_left", "lots_requested", b"lots_requested", "marker", b"marker", "order_id", b"order_id", "order_price", b"order_price", "order_request_id", b"order_request_id", "order_type", b"order_type", "status_info", b"status_info", "ticker", b"ticker", "time_in_force", b"time_in_force", "trade_order_id", b"trade_order_id", "trades", b"trades"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_amount", b"_amount"]) -> typing.Literal["amount"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_marker", b"_marker"]) -> typing.Literal["marker"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_order_request_id", b"_order_request_id"]) -> typing.Literal["order_request_id"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_status_info", b"_status_info"]) -> typing.Literal["status_info"] | None: ... + + ORDER_STATE_FIELD_NUMBER: builtins.int + PING_FIELD_NUMBER: builtins.int + SUBSCRIPTION_FIELD_NUMBER: builtins.int + @property + def order_state(self) -> global___OrderStateStreamResponse.OrderState: + """Информация об исполнении торгового поручения.""" + + @property + def ping(self) -> t_tech.invest.grpc.common_pb2.Ping: + """Проверка активности стрима.""" + + @property + def subscription(self) -> global___SubscriptionResponse: + """Ответ на запрос на подписку.""" + + def __init__( + self, + *, + order_state: global___OrderStateStreamResponse.OrderState | None = ..., + ping: t_tech.invest.grpc.common_pb2.Ping | None = ..., + subscription: global___SubscriptionResponse | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["order_state", b"order_state", "payload", b"payload", "ping", b"ping", "subscription", b"subscription"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["order_state", b"order_state", "payload", b"payload", "ping", b"ping", "subscription", b"subscription"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["payload", b"payload"]) -> typing.Literal["order_state", "ping", "subscription"] | None: ... + +global___OrderStateStreamResponse = OrderStateStreamResponse diff --git a/invest-python-master/t_tech/invest/grpc/orders_pb2_grpc.py b/invest-python-master/t_tech/invest/grpc/orders_pb2_grpc.py new file mode 100644 index 0000000..1e32c41 --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/orders_pb2_grpc.py @@ -0,0 +1,412 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +from t_tech.invest.grpc import orders_pb2 as t__tech_dot_invest_dot_grpc_dot_orders__pb2 + + +class OrdersStreamServiceStub(object): + """Missing associated documentation comment in .proto file.""" + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.TradesStream = channel.unary_stream( + '/tinkoff.public.invest.api.contract.v1.OrdersStreamService/TradesStream', + request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.TradesStreamRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.TradesStreamResponse.FromString, + ) + self.OrderStateStream = channel.unary_stream( + '/tinkoff.public.invest.api.contract.v1.OrdersStreamService/OrderStateStream', + request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.OrderStateStreamRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.OrderStateStreamResponse.FromString, + ) + + +class OrdersStreamServiceServicer(object): + """Missing associated documentation comment in .proto file.""" + + def TradesStream(self, request, context): + """TradesStream — стрим сделок пользователя + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def OrderStateStream(self, request, context): + """OrderStateStream — стрим поручений пользователя + Перед работой прочитайте [статью](/invest/services/orders/orders_state_stream). + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_OrdersStreamServiceServicer_to_server(servicer, server): + rpc_method_handlers = { + 'TradesStream': grpc.unary_stream_rpc_method_handler( + servicer.TradesStream, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.TradesStreamRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.TradesStreamResponse.SerializeToString, + ), + 'OrderStateStream': grpc.unary_stream_rpc_method_handler( + servicer.OrderStateStream, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.OrderStateStreamRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.OrderStateStreamResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'tinkoff.public.invest.api.contract.v1.OrdersStreamService', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class OrdersStreamService(object): + """Missing associated documentation comment in .proto file.""" + + @staticmethod + def TradesStream(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_stream(request, target, '/tinkoff.public.invest.api.contract.v1.OrdersStreamService/TradesStream', + t__tech_dot_invest_dot_grpc_dot_orders__pb2.TradesStreamRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_orders__pb2.TradesStreamResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def OrderStateStream(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_stream(request, target, '/tinkoff.public.invest.api.contract.v1.OrdersStreamService/OrderStateStream', + t__tech_dot_invest_dot_grpc_dot_orders__pb2.OrderStateStreamRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_orders__pb2.OrderStateStreamResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + +class OrdersServiceStub(object): + """Сервис предназначен для работы с торговыми поручениями:
**1**. + выставление;
**2**. отмена;
**3**. получение статуса;
**4**. + расчет полной стоимости;
**5**. получение списка заявок. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.PostOrder = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.OrdersService/PostOrder', + request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderResponse.FromString, + ) + self.PostOrderAsync = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.OrdersService/PostOrderAsync', + request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderAsyncRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderAsyncResponse.FromString, + ) + self.CancelOrder = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.OrdersService/CancelOrder', + request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.CancelOrderRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.CancelOrderResponse.FromString, + ) + self.GetOrderState = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.OrdersService/GetOrderState', + request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderStateRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.OrderState.FromString, + ) + self.GetOrders = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.OrdersService/GetOrders', + request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrdersRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrdersResponse.FromString, + ) + self.ReplaceOrder = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.OrdersService/ReplaceOrder', + request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.ReplaceOrderRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderResponse.FromString, + ) + self.GetMaxLots = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.OrdersService/GetMaxLots', + request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetMaxLotsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetMaxLotsResponse.FromString, + ) + self.GetOrderPrice = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.OrdersService/GetOrderPrice', + request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderPriceRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderPriceResponse.FromString, + ) + + +class OrdersServiceServicer(object): + """Сервис предназначен для работы с торговыми поручениями:
**1**. + выставление;
**2**. отмена;
**3**. получение статуса;
**4**. + расчет полной стоимости;
**5**. получение списка заявок. + """ + + def PostOrder(self, request, context): + """PostOrder — выставить заявку + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def PostOrderAsync(self, request, context): + """PostOrderAsync — выставить заявку асинхронным методом + Особенности работы приведены в [статье](/invest/services/orders/async). + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def CancelOrder(self, request, context): + """CancelOrder — отменить заявку + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetOrderState(self, request, context): + """GetOrderState — получить статус торгового поручения + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetOrders(self, request, context): + """GetOrders — получить список активных заявок по счету + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def ReplaceOrder(self, request, context): + """ReplaceOrder — изменить выставленную заявку + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetMaxLots(self, request, context): + """GetMaxLots — расчет количества доступных для покупки/продажи лотов + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetOrderPrice(self, request, context): + """GetOrderPrice — получить предварительную стоимость для лимитной заявки + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_OrdersServiceServicer_to_server(servicer, server): + rpc_method_handlers = { + 'PostOrder': grpc.unary_unary_rpc_method_handler( + servicer.PostOrder, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderResponse.SerializeToString, + ), + 'PostOrderAsync': grpc.unary_unary_rpc_method_handler( + servicer.PostOrderAsync, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderAsyncRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderAsyncResponse.SerializeToString, + ), + 'CancelOrder': grpc.unary_unary_rpc_method_handler( + servicer.CancelOrder, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.CancelOrderRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.CancelOrderResponse.SerializeToString, + ), + 'GetOrderState': grpc.unary_unary_rpc_method_handler( + servicer.GetOrderState, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderStateRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.OrderState.SerializeToString, + ), + 'GetOrders': grpc.unary_unary_rpc_method_handler( + servicer.GetOrders, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrdersRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrdersResponse.SerializeToString, + ), + 'ReplaceOrder': grpc.unary_unary_rpc_method_handler( + servicer.ReplaceOrder, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.ReplaceOrderRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderResponse.SerializeToString, + ), + 'GetMaxLots': grpc.unary_unary_rpc_method_handler( + servicer.GetMaxLots, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetMaxLotsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetMaxLotsResponse.SerializeToString, + ), + 'GetOrderPrice': grpc.unary_unary_rpc_method_handler( + servicer.GetOrderPrice, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderPriceRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderPriceResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'tinkoff.public.invest.api.contract.v1.OrdersService', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class OrdersService(object): + """Сервис предназначен для работы с торговыми поручениями:
**1**. + выставление;
**2**. отмена;
**3**. получение статуса;
**4**. + расчет полной стоимости;
**5**. получение списка заявок. + """ + + @staticmethod + def PostOrder(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OrdersService/PostOrder', + t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def PostOrderAsync(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OrdersService/PostOrderAsync', + t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderAsyncRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderAsyncResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def CancelOrder(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OrdersService/CancelOrder', + t__tech_dot_invest_dot_grpc_dot_orders__pb2.CancelOrderRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_orders__pb2.CancelOrderResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetOrderState(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OrdersService/GetOrderState', + t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderStateRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_orders__pb2.OrderState.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetOrders(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OrdersService/GetOrders', + t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrdersRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrdersResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def ReplaceOrder(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OrdersService/ReplaceOrder', + t__tech_dot_invest_dot_grpc_dot_orders__pb2.ReplaceOrderRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetMaxLots(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OrdersService/GetMaxLots', + t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetMaxLotsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetMaxLotsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetOrderPrice(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OrdersService/GetOrderPrice', + t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderPriceRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderPriceResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/invest-python-master/t_tech/invest/grpc/sandbox_pb2.py b/invest-python-master/t_tech/invest/grpc/sandbox_pb2.py new file mode 100644 index 0000000..168b860 --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/sandbox_pb2.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: t_tech/invest/grpc/sandbox.proto +# Protobuf Python Version: 4.25.1 +"""Generated protocol buffer code.""" +from google.protobuf import ( + descriptor as _descriptor, + descriptor_pool as _descriptor_pool, + symbol_database as _symbol_database, +) +from google.protobuf.internal import builder as _builder + +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from t_tech.invest.grpc import ( + common_pb2 as t__tech_dot_invest_dot_grpc_dot_common__pb2, + operations_pb2 as t__tech_dot_invest_dot_grpc_dot_operations__pb2, + orders_pb2 as t__tech_dot_invest_dot_grpc_dot_orders__pb2, + stoporders_pb2 as t__tech_dot_invest_dot_grpc_dot_stoporders__pb2, + users_pb2 as t__tech_dot_invest_dot_grpc_dot_users__pb2, +) +from t_tech.invest.grpc.google.api import ( + field_behavior_pb2 as t__tech_dot_invest_dot_grpc_dot_google_dot_api_dot_field__behavior__pb2, +) + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n t_tech/invest/grpc/sandbox.proto\x12%tinkoff.public.invest.api.contract.v1\x1a\x1ft_tech/invest/grpc/common.proto\x1a\x1ft_tech/invest/grpc/orders.proto\x1a#t_tech/invest/grpc/operations.proto\x1a#t_tech/invest/grpc/stoporders.proto\x1a\x1et_tech/invest/grpc/users.proto\x1a\x32t_tech/invest/grpc/google/api/field_behavior.proto\"7\n\x19OpenSandboxAccountRequest\x12\x11\n\x04name\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\x07\n\x05_name\"0\n\x1aOpenSandboxAccountResponse\x12\x12\n\naccount_id\x18\x01 \x01(\t\"6\n\x1a\x43loseSandboxAccountRequest\x12\x18\n\naccount_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\"\x1d\n\x1b\x43loseSandboxAccountResponse\"x\n\x13SandboxPayInRequest\x12\x18\n\naccount_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\x12G\n\x06\x61mount\x18\x02 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValueB\x04\xe2\x41\x01\x02\"Z\n\x14SandboxPayInResponse\x12\x42\n\x07\x62\x61lance\x18\x01 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue2\xfa\x16\n\x0eSandboxService\x12\x99\x01\n\x12OpenSandboxAccount\x12@.tinkoff.public.invest.api.contract.v1.OpenSandboxAccountRequest\x1a\x41.tinkoff.public.invest.api.contract.v1.OpenSandboxAccountResponse\x12\x8b\x01\n\x12GetSandboxAccounts\x12\x39.tinkoff.public.invest.api.contract.v1.GetAccountsRequest\x1a:.tinkoff.public.invest.api.contract.v1.GetAccountsResponse\x12\x9c\x01\n\x13\x43loseSandboxAccount\x12\x41.tinkoff.public.invest.api.contract.v1.CloseSandboxAccountRequest\x1a\x42.tinkoff.public.invest.api.contract.v1.CloseSandboxAccountResponse\x12\x85\x01\n\x10PostSandboxOrder\x12\x37.tinkoff.public.invest.api.contract.v1.PostOrderRequest\x1a\x38.tinkoff.public.invest.api.contract.v1.PostOrderResponse\x12\x94\x01\n\x15PostSandboxOrderAsync\x12<.tinkoff.public.invest.api.contract.v1.PostOrderAsyncRequest\x1a=.tinkoff.public.invest.api.contract.v1.PostOrderAsyncResponse\x12\x8b\x01\n\x13ReplaceSandboxOrder\x12:.tinkoff.public.invest.api.contract.v1.ReplaceOrderRequest\x1a\x38.tinkoff.public.invest.api.contract.v1.PostOrderResponse\x12\x85\x01\n\x10GetSandboxOrders\x12\x37.tinkoff.public.invest.api.contract.v1.GetOrdersRequest\x1a\x38.tinkoff.public.invest.api.contract.v1.GetOrdersResponse\x12\x8b\x01\n\x12\x43\x61ncelSandboxOrder\x12\x39.tinkoff.public.invest.api.contract.v1.CancelOrderRequest\x1a:.tinkoff.public.invest.api.contract.v1.CancelOrderResponse\x12\x86\x01\n\x14GetSandboxOrderState\x12;.tinkoff.public.invest.api.contract.v1.GetOrderStateRequest\x1a\x31.tinkoff.public.invest.api.contract.v1.OrderState\x12\x91\x01\n\x14GetSandboxOrderPrice\x12;.tinkoff.public.invest.api.contract.v1.GetOrderPriceRequest\x1a<.tinkoff.public.invest.api.contract.v1.GetOrderPriceResponse\x12\x88\x01\n\x13GetSandboxPositions\x12\x37.tinkoff.public.invest.api.contract.v1.PositionsRequest\x1a\x38.tinkoff.public.invest.api.contract.v1.PositionsResponse\x12\x8b\x01\n\x14GetSandboxOperations\x12\x38.tinkoff.public.invest.api.contract.v1.OperationsRequest\x1a\x39.tinkoff.public.invest.api.contract.v1.OperationsResponse\x12\xa9\x01\n\x1cGetSandboxOperationsByCursor\x12\x43.tinkoff.public.invest.api.contract.v1.GetOperationsByCursorRequest\x1a\x44.tinkoff.public.invest.api.contract.v1.GetOperationsByCursorResponse\x12\x88\x01\n\x13GetSandboxPortfolio\x12\x37.tinkoff.public.invest.api.contract.v1.PortfolioRequest\x1a\x38.tinkoff.public.invest.api.contract.v1.PortfolioResponse\x12\x87\x01\n\x0cSandboxPayIn\x12:.tinkoff.public.invest.api.contract.v1.SandboxPayInRequest\x1a;.tinkoff.public.invest.api.contract.v1.SandboxPayInResponse\x12\x97\x01\n\x18GetSandboxWithdrawLimits\x12<.tinkoff.public.invest.api.contract.v1.WithdrawLimitsRequest\x1a=.tinkoff.public.invest.api.contract.v1.WithdrawLimitsResponse\x12\x88\x01\n\x11GetSandboxMaxLots\x12\x38.tinkoff.public.invest.api.contract.v1.GetMaxLotsRequest\x1a\x39.tinkoff.public.invest.api.contract.v1.GetMaxLotsResponse\x12\x91\x01\n\x14PostSandboxStopOrder\x12;.tinkoff.public.invest.api.contract.v1.PostStopOrderRequest\x1a<.tinkoff.public.invest.api.contract.v1.PostStopOrderResponse\x12\x91\x01\n\x14GetSandboxStopOrders\x12;.tinkoff.public.invest.api.contract.v1.GetStopOrdersRequest\x1a<.tinkoff.public.invest.api.contract.v1.GetStopOrdersResponse\x12\x97\x01\n\x16\x43\x61ncelSandboxStopOrder\x12=.tinkoff.public.invest.api.contract.v1.CancelStopOrderRequest\x1a>.tinkoff.public.invest.api.contract.v1.CancelStopOrderResponseBa\n\x1cru.tinkoff.piapi.contract.v1P\x01Z\x0c./;investapi\xa2\x02\x05TIAPI\xaa\x02\x14Tinkoff.InvestApi.V1\xca\x02\x11Tinkoff\\Invest\\V1b\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 't_tech.invest.grpc.sandbox_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\034ru.tinkoff.piapi.contract.v1P\001Z\014./;investapi\242\002\005TIAPI\252\002\024Tinkoff.InvestApi.V1\312\002\021Tinkoff\\Invest\\V1' + _globals['_CLOSESANDBOXACCOUNTREQUEST'].fields_by_name['account_id']._options = None + _globals['_CLOSESANDBOXACCOUNTREQUEST'].fields_by_name['account_id']._serialized_options = b'\342A\001\002' + _globals['_SANDBOXPAYINREQUEST'].fields_by_name['account_id']._options = None + _globals['_SANDBOXPAYINREQUEST'].fields_by_name['account_id']._serialized_options = b'\342A\001\002' + _globals['_SANDBOXPAYINREQUEST'].fields_by_name['amount']._options = None + _globals['_SANDBOXPAYINREQUEST'].fields_by_name['amount']._serialized_options = b'\342A\001\002' + _globals['_OPENSANDBOXACCOUNTREQUEST']._serialized_start=299 + _globals['_OPENSANDBOXACCOUNTREQUEST']._serialized_end=354 + _globals['_OPENSANDBOXACCOUNTRESPONSE']._serialized_start=356 + _globals['_OPENSANDBOXACCOUNTRESPONSE']._serialized_end=404 + _globals['_CLOSESANDBOXACCOUNTREQUEST']._serialized_start=406 + _globals['_CLOSESANDBOXACCOUNTREQUEST']._serialized_end=460 + _globals['_CLOSESANDBOXACCOUNTRESPONSE']._serialized_start=462 + _globals['_CLOSESANDBOXACCOUNTRESPONSE']._serialized_end=491 + _globals['_SANDBOXPAYINREQUEST']._serialized_start=493 + _globals['_SANDBOXPAYINREQUEST']._serialized_end=613 + _globals['_SANDBOXPAYINRESPONSE']._serialized_start=615 + _globals['_SANDBOXPAYINRESPONSE']._serialized_end=705 + _globals['_SANDBOXSERVICE']._serialized_start=708 + _globals['_SANDBOXSERVICE']._serialized_end=3646 +# @@protoc_insertion_point(module_scope) diff --git a/invest-python-master/t_tech/invest/grpc/sandbox_pb2.pyi b/invest-python-master/t_tech/invest/grpc/sandbox_pb2.pyi new file mode 100644 index 0000000..2422e56 --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/sandbox_pb2.pyi @@ -0,0 +1,128 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" + +import builtins +import google.protobuf.descriptor +import google.protobuf.message +import t_tech.invest.grpc.common_pb2 +import typing + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing.final +class OpenSandboxAccountRequest(google.protobuf.message.Message): + """Запрос открытия счета в песочнице.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + NAME_FIELD_NUMBER: builtins.int + name: builtins.str + """Название счета""" + def __init__( + self, + *, + name: builtins.str | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_name", b"_name", "name", b"name"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_name", b"_name", "name", b"name"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_name", b"_name"]) -> typing.Literal["name"] | None: ... + +global___OpenSandboxAccountRequest = OpenSandboxAccountRequest + +@typing.final +class OpenSandboxAccountResponse(google.protobuf.message.Message): + """Номер открытого счета в песочнице.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNT_ID_FIELD_NUMBER: builtins.int + account_id: builtins.str + """Номер счета""" + def __init__( + self, + *, + account_id: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["account_id", b"account_id"]) -> None: ... + +global___OpenSandboxAccountResponse = OpenSandboxAccountResponse + +@typing.final +class CloseSandboxAccountRequest(google.protobuf.message.Message): + """Запрос закрытия счета в песочнице.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNT_ID_FIELD_NUMBER: builtins.int + account_id: builtins.str + """Номер счета""" + def __init__( + self, + *, + account_id: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["account_id", b"account_id"]) -> None: ... + +global___CloseSandboxAccountRequest = CloseSandboxAccountRequest + +@typing.final +class CloseSandboxAccountResponse(google.protobuf.message.Message): + """Результат закрытия счета в песочнице. + пустой ответ + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + def __init__( + self, + ) -> None: ... + +global___CloseSandboxAccountResponse = CloseSandboxAccountResponse + +@typing.final +class SandboxPayInRequest(google.protobuf.message.Message): + """Запрос пополнения счета в песочнице.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNT_ID_FIELD_NUMBER: builtins.int + AMOUNT_FIELD_NUMBER: builtins.int + account_id: builtins.str + """Номер счета""" + @property + def amount(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Сумма пополнения счета в рублях""" + + def __init__( + self, + *, + account_id: builtins.str = ..., + amount: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["amount", b"amount"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["account_id", b"account_id", "amount", b"amount"]) -> None: ... + +global___SandboxPayInRequest = SandboxPayInRequest + +@typing.final +class SandboxPayInResponse(google.protobuf.message.Message): + """Результат пополнения счета, текущий баланс.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + BALANCE_FIELD_NUMBER: builtins.int + @property + def balance(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Текущий баланс счета""" + + def __init__( + self, + *, + balance: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["balance", b"balance"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["balance", b"balance"]) -> None: ... + +global___SandboxPayInResponse = SandboxPayInResponse diff --git a/invest-python-master/t_tech/invest/grpc/sandbox_pb2_grpc.py b/invest-python-master/t_tech/invest/grpc/sandbox_pb2_grpc.py new file mode 100644 index 0000000..44a56d8 --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/sandbox_pb2_grpc.py @@ -0,0 +1,725 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +from t_tech.invest.grpc import ( + operations_pb2 as t__tech_dot_invest_dot_grpc_dot_operations__pb2, + orders_pb2 as t__tech_dot_invest_dot_grpc_dot_orders__pb2, + sandbox_pb2 as t__tech_dot_invest_dot_grpc_dot_sandbox__pb2, + stoporders_pb2 as t__tech_dot_invest_dot_grpc_dot_stoporders__pb2, + users_pb2 as t__tech_dot_invest_dot_grpc_dot_users__pb2, +) + + +class SandboxServiceStub(object): + """Методы для работы с песочницей T-Invest API + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.OpenSandboxAccount = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.SandboxService/OpenSandboxAccount', + request_serializer=t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.OpenSandboxAccountRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.OpenSandboxAccountResponse.FromString, + ) + self.GetSandboxAccounts = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxAccounts', + request_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountsResponse.FromString, + ) + self.CloseSandboxAccount = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.SandboxService/CloseSandboxAccount', + request_serializer=t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.CloseSandboxAccountRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.CloseSandboxAccountResponse.FromString, + ) + self.PostSandboxOrder = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.SandboxService/PostSandboxOrder', + request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderResponse.FromString, + ) + self.PostSandboxOrderAsync = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.SandboxService/PostSandboxOrderAsync', + request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderAsyncRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderAsyncResponse.FromString, + ) + self.ReplaceSandboxOrder = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.SandboxService/ReplaceSandboxOrder', + request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.ReplaceOrderRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderResponse.FromString, + ) + self.GetSandboxOrders = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxOrders', + request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrdersRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrdersResponse.FromString, + ) + self.CancelSandboxOrder = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.SandboxService/CancelSandboxOrder', + request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.CancelOrderRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.CancelOrderResponse.FromString, + ) + self.GetSandboxOrderState = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxOrderState', + request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderStateRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.OrderState.FromString, + ) + self.GetSandboxOrderPrice = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxOrderPrice', + request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderPriceRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderPriceResponse.FromString, + ) + self.GetSandboxPositions = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxPositions', + request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsResponse.FromString, + ) + self.GetSandboxOperations = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxOperations', + request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsResponse.FromString, + ) + self.GetSandboxOperationsByCursor = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxOperationsByCursor', + request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetOperationsByCursorRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetOperationsByCursorResponse.FromString, + ) + self.GetSandboxPortfolio = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxPortfolio', + request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioResponse.FromString, + ) + self.SandboxPayIn = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.SandboxService/SandboxPayIn', + request_serializer=t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.SandboxPayInRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.SandboxPayInResponse.FromString, + ) + self.GetSandboxWithdrawLimits = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxWithdrawLimits', + request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.WithdrawLimitsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.WithdrawLimitsResponse.FromString, + ) + self.GetSandboxMaxLots = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxMaxLots', + request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetMaxLotsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetMaxLotsResponse.FromString, + ) + self.PostSandboxStopOrder = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.SandboxService/PostSandboxStopOrder', + request_serializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.PostStopOrderRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.PostStopOrderResponse.FromString, + ) + self.GetSandboxStopOrders = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxStopOrders', + request_serializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.GetStopOrdersRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.GetStopOrdersResponse.FromString, + ) + self.CancelSandboxStopOrder = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.SandboxService/CancelSandboxStopOrder', + request_serializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.CancelStopOrderRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.CancelStopOrderResponse.FromString, + ) + + +class SandboxServiceServicer(object): + """Методы для работы с песочницей T-Invest API + """ + + def OpenSandboxAccount(self, request, context): + """OpenSandboxAccount — зарегистрировать счет + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetSandboxAccounts(self, request, context): + """GetSandboxAccounts — счета пользователя + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def CloseSandboxAccount(self, request, context): + """CloseSandboxAccount — закрыть счет + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def PostSandboxOrder(self, request, context): + """PostSandboxOrder — выставить заявку + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def PostSandboxOrderAsync(self, request, context): + """PostSandboxOrderAsync — выставить заявку асинхронным методом + Особенности работы приведены в [статье](/invest/services/orders/async). + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def ReplaceSandboxOrder(self, request, context): + """ReplaceSandboxOrder — изменить выставленную заявку + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetSandboxOrders(self, request, context): + """GetSandboxOrders — получить список активных заявок по счету + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def CancelSandboxOrder(self, request, context): + """CancelSandboxOrder — отменить заявку + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetSandboxOrderState(self, request, context): + """GetSandboxOrderState — получить статус торгового поручения + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetSandboxOrderPrice(self, request, context): + """GetSandboxOrderPrice — получить предварительную стоимость для лимитной заявки + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetSandboxPositions(self, request, context): + """GetSandboxPositions — список позиций по счету + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetSandboxOperations(self, request, context): + """GetSandboxOperations — список операций по счету + При работе с методом учитывайте [особенности взаимодействия](/invest/services/operations/operations_problems). + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetSandboxOperationsByCursor(self, request, context): + """GetSandboxOperationsByCursor — список операций по счету с пагинацией + При работе с методом учитывайте [особенности взаимодействия](/invest/services/operations/operations_problems). + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetSandboxPortfolio(self, request, context): + """GetSandboxPortfolio — портфель по счету + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def SandboxPayIn(self, request, context): + """SandboxPayIn — пополнить счет. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetSandboxWithdrawLimits(self, request, context): + """GetSandboxWithdrawLimits — доступный остаток для вывода средств + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetSandboxMaxLots(self, request, context): + """GetSandboxMaxLots — расчет количества доступных для покупки/продажи лотов + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def PostSandboxStopOrder(self, request, context): + """PostSandboxStopOrder — выставить стоп-заявку + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetSandboxStopOrders(self, request, context): + """GetSandboxStopOrders — получить список активных стоп-заявок по счету + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def CancelSandboxStopOrder(self, request, context): + """CancelSandboxStopOrder — отменить стоп-заявку + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_SandboxServiceServicer_to_server(servicer, server): + rpc_method_handlers = { + 'OpenSandboxAccount': grpc.unary_unary_rpc_method_handler( + servicer.OpenSandboxAccount, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.OpenSandboxAccountRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.OpenSandboxAccountResponse.SerializeToString, + ), + 'GetSandboxAccounts': grpc.unary_unary_rpc_method_handler( + servicer.GetSandboxAccounts, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountsResponse.SerializeToString, + ), + 'CloseSandboxAccount': grpc.unary_unary_rpc_method_handler( + servicer.CloseSandboxAccount, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.CloseSandboxAccountRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.CloseSandboxAccountResponse.SerializeToString, + ), + 'PostSandboxOrder': grpc.unary_unary_rpc_method_handler( + servicer.PostSandboxOrder, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderResponse.SerializeToString, + ), + 'PostSandboxOrderAsync': grpc.unary_unary_rpc_method_handler( + servicer.PostSandboxOrderAsync, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderAsyncRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderAsyncResponse.SerializeToString, + ), + 'ReplaceSandboxOrder': grpc.unary_unary_rpc_method_handler( + servicer.ReplaceSandboxOrder, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.ReplaceOrderRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderResponse.SerializeToString, + ), + 'GetSandboxOrders': grpc.unary_unary_rpc_method_handler( + servicer.GetSandboxOrders, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrdersRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrdersResponse.SerializeToString, + ), + 'CancelSandboxOrder': grpc.unary_unary_rpc_method_handler( + servicer.CancelSandboxOrder, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.CancelOrderRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.CancelOrderResponse.SerializeToString, + ), + 'GetSandboxOrderState': grpc.unary_unary_rpc_method_handler( + servicer.GetSandboxOrderState, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderStateRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.OrderState.SerializeToString, + ), + 'GetSandboxOrderPrice': grpc.unary_unary_rpc_method_handler( + servicer.GetSandboxOrderPrice, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderPriceRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderPriceResponse.SerializeToString, + ), + 'GetSandboxPositions': grpc.unary_unary_rpc_method_handler( + servicer.GetSandboxPositions, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsResponse.SerializeToString, + ), + 'GetSandboxOperations': grpc.unary_unary_rpc_method_handler( + servicer.GetSandboxOperations, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsResponse.SerializeToString, + ), + 'GetSandboxOperationsByCursor': grpc.unary_unary_rpc_method_handler( + servicer.GetSandboxOperationsByCursor, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetOperationsByCursorRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetOperationsByCursorResponse.SerializeToString, + ), + 'GetSandboxPortfolio': grpc.unary_unary_rpc_method_handler( + servicer.GetSandboxPortfolio, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioResponse.SerializeToString, + ), + 'SandboxPayIn': grpc.unary_unary_rpc_method_handler( + servicer.SandboxPayIn, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.SandboxPayInRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.SandboxPayInResponse.SerializeToString, + ), + 'GetSandboxWithdrawLimits': grpc.unary_unary_rpc_method_handler( + servicer.GetSandboxWithdrawLimits, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.WithdrawLimitsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.WithdrawLimitsResponse.SerializeToString, + ), + 'GetSandboxMaxLots': grpc.unary_unary_rpc_method_handler( + servicer.GetSandboxMaxLots, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetMaxLotsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetMaxLotsResponse.SerializeToString, + ), + 'PostSandboxStopOrder': grpc.unary_unary_rpc_method_handler( + servicer.PostSandboxStopOrder, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.PostStopOrderRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.PostStopOrderResponse.SerializeToString, + ), + 'GetSandboxStopOrders': grpc.unary_unary_rpc_method_handler( + servicer.GetSandboxStopOrders, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.GetStopOrdersRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.GetStopOrdersResponse.SerializeToString, + ), + 'CancelSandboxStopOrder': grpc.unary_unary_rpc_method_handler( + servicer.CancelSandboxStopOrder, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.CancelStopOrderRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.CancelStopOrderResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'tinkoff.public.invest.api.contract.v1.SandboxService', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class SandboxService(object): + """Методы для работы с песочницей T-Invest API + """ + + @staticmethod + def OpenSandboxAccount(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/OpenSandboxAccount', + t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.OpenSandboxAccountRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.OpenSandboxAccountResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetSandboxAccounts(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxAccounts', + t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def CloseSandboxAccount(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/CloseSandboxAccount', + t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.CloseSandboxAccountRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.CloseSandboxAccountResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def PostSandboxOrder(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/PostSandboxOrder', + t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def PostSandboxOrderAsync(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/PostSandboxOrderAsync', + t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderAsyncRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderAsyncResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def ReplaceSandboxOrder(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/ReplaceSandboxOrder', + t__tech_dot_invest_dot_grpc_dot_orders__pb2.ReplaceOrderRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetSandboxOrders(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxOrders', + t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrdersRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrdersResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def CancelSandboxOrder(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/CancelSandboxOrder', + t__tech_dot_invest_dot_grpc_dot_orders__pb2.CancelOrderRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_orders__pb2.CancelOrderResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetSandboxOrderState(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxOrderState', + t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderStateRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_orders__pb2.OrderState.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetSandboxOrderPrice(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxOrderPrice', + t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderPriceRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderPriceResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetSandboxPositions(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxPositions', + t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetSandboxOperations(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxOperations', + t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetSandboxOperationsByCursor(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxOperationsByCursor', + t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetOperationsByCursorRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetOperationsByCursorResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetSandboxPortfolio(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxPortfolio', + t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def SandboxPayIn(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/SandboxPayIn', + t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.SandboxPayInRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.SandboxPayInResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetSandboxWithdrawLimits(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxWithdrawLimits', + t__tech_dot_invest_dot_grpc_dot_operations__pb2.WithdrawLimitsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_operations__pb2.WithdrawLimitsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetSandboxMaxLots(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxMaxLots', + t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetMaxLotsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetMaxLotsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def PostSandboxStopOrder(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/PostSandboxStopOrder', + t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.PostStopOrderRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.PostStopOrderResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetSandboxStopOrders(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxStopOrders', + t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.GetStopOrdersRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.GetStopOrdersResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def CancelSandboxStopOrder(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/CancelSandboxStopOrder', + t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.CancelStopOrderRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.CancelStopOrderResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/invest-python-master/t_tech/invest/grpc/signals_pb2.py b/invest-python-master/t_tech/invest/grpc/signals_pb2.py new file mode 100644 index 0000000..4d2c9e4 --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/signals_pb2.py @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: t_tech/invest/grpc/signals.proto +# Protobuf Python Version: 4.25.1 +"""Generated protocol buffer code.""" +from google.protobuf import ( + descriptor as _descriptor, + descriptor_pool as _descriptor_pool, + symbol_database as _symbol_database, +) +from google.protobuf.internal import builder as _builder + +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 + +from t_tech.invest.grpc import common_pb2 as t__tech_dot_invest_dot_grpc_dot_common__pb2 +from t_tech.invest.grpc.google.api import ( + field_behavior_pb2 as t__tech_dot_invest_dot_grpc_dot_google_dot_api_dot_field__behavior__pb2, +) + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n t_tech/invest/grpc/signals.proto\x12%tinkoff.public.invest.api.contract.v1\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x32t_tech/invest/grpc/google/api/field_behavior.proto\x1a\x1ft_tech/invest/grpc/common.proto\"@\n\x14GetStrategiesRequest\x12\x18\n\x0bstrategy_id\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_strategy_id\"\\\n\x15GetStrategiesResponse\x12\x43\n\nstrategies\x18\x01 \x03(\x0b\x32/.tinkoff.public.invest.api.contract.v1.Strategy\"\x9b\x05\n\x08Strategy\x12\x19\n\x0bstrategy_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\x12\x1b\n\rstrategy_name\x18\x02 \x01(\tB\x04\xe2\x41\x01\x02\x12!\n\x14strategy_description\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x19\n\x0cstrategy_url\x18\x04 \x01(\tH\x01\x88\x01\x01\x12P\n\rstrategy_type\x18\x05 \x01(\x0e\x32\x33.tinkoff.public.invest.api.contract.v1.StrategyTypeB\x04\xe2\x41\x01\x02\x12\x1c\n\x0e\x61\x63tive_signals\x18\x06 \x01(\x05\x42\x04\xe2\x41\x01\x02\x12\x1b\n\rtotal_signals\x18\x07 \x01(\x05\x42\x04\xe2\x41\x01\x02\x12\x1e\n\x10time_in_position\x18\x08 \x01(\x03\x42\x04\xe2\x41\x01\x02\x12T\n\x14\x61verage_signal_yield\x18\t \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationB\x04\xe2\x41\x01\x02\x12Y\n\x19\x61verage_signal_yield_year\x18\n \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationB\x04\xe2\x41\x01\x02\x12\x45\n\x05yield\x18\x0b \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationB\x04\xe2\x41\x01\x02\x12J\n\nyield_year\x18\x0c \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationB\x04\xe2\x41\x01\x02\x42\x17\n\x15_strategy_descriptionB\x0f\n\r_strategy_url\"\xe1\x04\n\x11GetSignalsRequest\x12\x16\n\tsignal_id\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x18\n\x0bstrategy_id\x18\x02 \x01(\tH\x01\x88\x01\x01\x12O\n\rstrategy_type\x18\x03 \x01(\x0e\x32\x33.tinkoff.public.invest.api.contract.v1.StrategyTypeH\x02\x88\x01\x01\x12\x1b\n\x0einstrument_uid\x18\x04 \x01(\tH\x03\x88\x01\x01\x12-\n\x04\x66rom\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x04\x88\x01\x01\x12+\n\x02to\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x05\x88\x01\x01\x12N\n\tdirection\x18\x07 \x01(\x0e\x32\x36.tinkoff.public.invest.api.contract.v1.SignalDirectionH\x06\x88\x01\x01\x12G\n\x06\x61\x63tive\x18\x08 \x01(\x0e\x32\x32.tinkoff.public.invest.api.contract.v1.SignalStateH\x07\x88\x01\x01\x12@\n\x06paging\x18\t \x01(\x0b\x32+.tinkoff.public.invest.api.contract.v1.PageH\x08\x88\x01\x01\x42\x0c\n\n_signal_idB\x0e\n\x0c_strategy_idB\x10\n\x0e_strategy_typeB\x11\n\x0f_instrument_uidB\x07\n\x05_fromB\x05\n\x03_toB\x0c\n\n_directionB\t\n\x07_activeB\t\n\x07_paging\"\x99\x01\n\x12GetSignalsResponse\x12>\n\x07signals\x18\x01 \x03(\x0b\x32-.tinkoff.public.invest.api.contract.v1.Signal\x12\x43\n\x06paging\x18\x02 \x01(\x0b\x32\x33.tinkoff.public.invest.api.contract.v1.PageResponse\"\x98\x06\n\x06Signal\x12\x17\n\tsignal_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\x12\x19\n\x0bstrategy_id\x18\x02 \x01(\tB\x04\xe2\x41\x01\x02\x12\x1b\n\rstrategy_name\x18\x03 \x01(\tB\x04\xe2\x41\x01\x02\x12\x1c\n\x0einstrument_uid\x18\x04 \x01(\tB\x04\xe2\x41\x01\x02\x12\x33\n\tcreate_dt\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x04\xe2\x41\x01\x02\x12O\n\tdirection\x18\x06 \x01(\x0e\x32\x36.tinkoff.public.invest.api.contract.v1.SignalDirectionB\x04\xe2\x41\x01\x02\x12M\n\rinitial_price\x18\x07 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationB\x04\xe2\x41\x01\x02\x12\x11\n\x04info\x18\x08 \x01(\tH\x00\x88\x01\x01\x12\x12\n\x04name\x18\t \x01(\tB\x04\xe2\x41\x01\x02\x12L\n\x0ctarget_price\x18\n \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationB\x04\xe2\x41\x01\x02\x12\x30\n\x06\x65nd_dt\x18\x0b \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x04\xe2\x41\x01\x02\x12\x18\n\x0bprobability\x18\x0c \x01(\x05H\x01\x88\x01\x01\x12G\n\x08stoploss\x18\r \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationH\x02\x88\x01\x01\x12J\n\x0b\x63lose_price\x18\x0e \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationH\x03\x88\x01\x01\x12\x31\n\x08\x63lose_dt\x18\x0f \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x04\x88\x01\x01\x42\x07\n\x05_infoB\x0e\n\x0c_probabilityB\x0b\n\t_stoplossB\x0e\n\x0c_close_priceB\x0b\n\t_close_dt*i\n\x0cStrategyType\x12\x1d\n\x19STRATEGY_TYPE_UNSPECIFIED\x10\x00\x12\x1b\n\x17STRATEGY_TYPE_TECHNICAL\x10\x01\x12\x1d\n\x19STRATEGY_TYPE_FUNDAMENTAL\x10\x02*h\n\x0fSignalDirection\x12 \n\x1cSIGNAL_DIRECTION_UNSPECIFIED\x10\x00\x12\x18\n\x14SIGNAL_DIRECTION_BUY\x10\x01\x12\x19\n\x15SIGNAL_DIRECTION_SELL\x10\x02*s\n\x0bSignalState\x12\x1c\n\x18SIGNAL_STATE_UNSPECIFIED\x10\x00\x12\x17\n\x13SIGNAL_STATE_ACTIVE\x10\x01\x12\x17\n\x13SIGNAL_STATE_CLOSED\x10\x02\x12\x14\n\x10SIGNAL_STATE_ALL\x10\x03\x32\xa0\x02\n\rSignalService\x12\x8a\x01\n\rGetStrategies\x12;.tinkoff.public.invest.api.contract.v1.GetStrategiesRequest\x1a<.tinkoff.public.invest.api.contract.v1.GetStrategiesResponse\x12\x81\x01\n\nGetSignals\x12\x38.tinkoff.public.invest.api.contract.v1.GetSignalsRequest\x1a\x39.tinkoff.public.invest.api.contract.v1.GetSignalsResponseBa\n\x1cru.tinkoff.piapi.contract.v1P\x01Z\x0c./;investapi\xa2\x02\x05TIAPI\xaa\x02\x14Tinkoff.InvestApi.V1\xca\x02\x11Tinkoff\\Invest\\V1b\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 't_tech.invest.grpc.signals_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\034ru.tinkoff.piapi.contract.v1P\001Z\014./;investapi\242\002\005TIAPI\252\002\024Tinkoff.InvestApi.V1\312\002\021Tinkoff\\Invest\\V1' + _globals['_STRATEGY'].fields_by_name['strategy_id']._options = None + _globals['_STRATEGY'].fields_by_name['strategy_id']._serialized_options = b'\342A\001\002' + _globals['_STRATEGY'].fields_by_name['strategy_name']._options = None + _globals['_STRATEGY'].fields_by_name['strategy_name']._serialized_options = b'\342A\001\002' + _globals['_STRATEGY'].fields_by_name['strategy_type']._options = None + _globals['_STRATEGY'].fields_by_name['strategy_type']._serialized_options = b'\342A\001\002' + _globals['_STRATEGY'].fields_by_name['active_signals']._options = None + _globals['_STRATEGY'].fields_by_name['active_signals']._serialized_options = b'\342A\001\002' + _globals['_STRATEGY'].fields_by_name['total_signals']._options = None + _globals['_STRATEGY'].fields_by_name['total_signals']._serialized_options = b'\342A\001\002' + _globals['_STRATEGY'].fields_by_name['time_in_position']._options = None + _globals['_STRATEGY'].fields_by_name['time_in_position']._serialized_options = b'\342A\001\002' + _globals['_STRATEGY'].fields_by_name['average_signal_yield']._options = None + _globals['_STRATEGY'].fields_by_name['average_signal_yield']._serialized_options = b'\342A\001\002' + _globals['_STRATEGY'].fields_by_name['average_signal_yield_year']._options = None + _globals['_STRATEGY'].fields_by_name['average_signal_yield_year']._serialized_options = b'\342A\001\002' + _globals['_STRATEGY'].fields_by_name['yield']._options = None + _globals['_STRATEGY'].fields_by_name['yield']._serialized_options = b'\342A\001\002' + _globals['_STRATEGY'].fields_by_name['yield_year']._options = None + _globals['_STRATEGY'].fields_by_name['yield_year']._serialized_options = b'\342A\001\002' + _globals['_SIGNAL'].fields_by_name['signal_id']._options = None + _globals['_SIGNAL'].fields_by_name['signal_id']._serialized_options = b'\342A\001\002' + _globals['_SIGNAL'].fields_by_name['strategy_id']._options = None + _globals['_SIGNAL'].fields_by_name['strategy_id']._serialized_options = b'\342A\001\002' + _globals['_SIGNAL'].fields_by_name['strategy_name']._options = None + _globals['_SIGNAL'].fields_by_name['strategy_name']._serialized_options = b'\342A\001\002' + _globals['_SIGNAL'].fields_by_name['instrument_uid']._options = None + _globals['_SIGNAL'].fields_by_name['instrument_uid']._serialized_options = b'\342A\001\002' + _globals['_SIGNAL'].fields_by_name['create_dt']._options = None + _globals['_SIGNAL'].fields_by_name['create_dt']._serialized_options = b'\342A\001\002' + _globals['_SIGNAL'].fields_by_name['direction']._options = None + _globals['_SIGNAL'].fields_by_name['direction']._serialized_options = b'\342A\001\002' + _globals['_SIGNAL'].fields_by_name['initial_price']._options = None + _globals['_SIGNAL'].fields_by_name['initial_price']._serialized_options = b'\342A\001\002' + _globals['_SIGNAL'].fields_by_name['name']._options = None + _globals['_SIGNAL'].fields_by_name['name']._serialized_options = b'\342A\001\002' + _globals['_SIGNAL'].fields_by_name['target_price']._options = None + _globals['_SIGNAL'].fields_by_name['target_price']._serialized_options = b'\342A\001\002' + _globals['_SIGNAL'].fields_by_name['end_dt']._options = None + _globals['_SIGNAL'].fields_by_name['end_dt']._serialized_options = b'\342A\001\002' + _globals['_STRATEGYTYPE']._serialized_start=2586 + _globals['_STRATEGYTYPE']._serialized_end=2691 + _globals['_SIGNALDIRECTION']._serialized_start=2693 + _globals['_SIGNALDIRECTION']._serialized_end=2797 + _globals['_SIGNALSTATE']._serialized_start=2799 + _globals['_SIGNALSTATE']._serialized_end=2914 + _globals['_GETSTRATEGIESREQUEST']._serialized_start=193 + _globals['_GETSTRATEGIESREQUEST']._serialized_end=257 + _globals['_GETSTRATEGIESRESPONSE']._serialized_start=259 + _globals['_GETSTRATEGIESRESPONSE']._serialized_end=351 + _globals['_STRATEGY']._serialized_start=354 + _globals['_STRATEGY']._serialized_end=1021 + _globals['_GETSIGNALSREQUEST']._serialized_start=1024 + _globals['_GETSIGNALSREQUEST']._serialized_end=1633 + _globals['_GETSIGNALSRESPONSE']._serialized_start=1636 + _globals['_GETSIGNALSRESPONSE']._serialized_end=1789 + _globals['_SIGNAL']._serialized_start=1792 + _globals['_SIGNAL']._serialized_end=2584 + _globals['_SIGNALSERVICE']._serialized_start=2917 + _globals['_SIGNALSERVICE']._serialized_end=3205 +# @@protoc_insertion_point(module_scope) diff --git a/invest-python-master/t_tech/invest/grpc/signals_pb2.pyi b/invest-python-master/t_tech/invest/grpc/signals_pb2.pyi new file mode 100644 index 0000000..169c93e --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/signals_pb2.pyi @@ -0,0 +1,402 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" + +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.internal.enum_type_wrapper +import google.protobuf.message +import google.protobuf.timestamp_pb2 +import sys +import t_tech.invest.grpc.common_pb2 +import typing + +if sys.version_info >= (3, 10): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +class _StrategyType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _StrategyTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_StrategyType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + STRATEGY_TYPE_UNSPECIFIED: _StrategyType.ValueType # 0 + """Не определен.""" + STRATEGY_TYPE_TECHNICAL: _StrategyType.ValueType # 1 + """Техническая стратегия.""" + STRATEGY_TYPE_FUNDAMENTAL: _StrategyType.ValueType # 2 + """Фундаментальная стратегия.""" + +class StrategyType(_StrategyType, metaclass=_StrategyTypeEnumTypeWrapper): + """Тип стратегии.""" + +STRATEGY_TYPE_UNSPECIFIED: StrategyType.ValueType # 0 +"""Не определен.""" +STRATEGY_TYPE_TECHNICAL: StrategyType.ValueType # 1 +"""Техническая стратегия.""" +STRATEGY_TYPE_FUNDAMENTAL: StrategyType.ValueType # 2 +"""Фундаментальная стратегия.""" +global___StrategyType = StrategyType + +class _SignalDirection: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _SignalDirectionEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_SignalDirection.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + SIGNAL_DIRECTION_UNSPECIFIED: _SignalDirection.ValueType # 0 + """Не определен.""" + SIGNAL_DIRECTION_BUY: _SignalDirection.ValueType # 1 + """Покупка.""" + SIGNAL_DIRECTION_SELL: _SignalDirection.ValueType # 2 + """Продажа.""" + +class SignalDirection(_SignalDirection, metaclass=_SignalDirectionEnumTypeWrapper): + """Направление сигнала.""" + +SIGNAL_DIRECTION_UNSPECIFIED: SignalDirection.ValueType # 0 +"""Не определен.""" +SIGNAL_DIRECTION_BUY: SignalDirection.ValueType # 1 +"""Покупка.""" +SIGNAL_DIRECTION_SELL: SignalDirection.ValueType # 2 +"""Продажа.""" +global___SignalDirection = SignalDirection + +class _SignalState: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _SignalStateEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_SignalState.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + SIGNAL_STATE_UNSPECIFIED: _SignalState.ValueType # 0 + """Не определен.""" + SIGNAL_STATE_ACTIVE: _SignalState.ValueType # 1 + """Активный сигнал.""" + SIGNAL_STATE_CLOSED: _SignalState.ValueType # 2 + """Закрытый сигнал.""" + SIGNAL_STATE_ALL: _SignalState.ValueType # 3 + """Все состояния.""" + +class SignalState(_SignalState, metaclass=_SignalStateEnumTypeWrapper): + """Статус сигнала.""" + +SIGNAL_STATE_UNSPECIFIED: SignalState.ValueType # 0 +"""Не определен.""" +SIGNAL_STATE_ACTIVE: SignalState.ValueType # 1 +"""Активный сигнал.""" +SIGNAL_STATE_CLOSED: SignalState.ValueType # 2 +"""Закрытый сигнал.""" +SIGNAL_STATE_ALL: SignalState.ValueType # 3 +"""Все состояния.""" +global___SignalState = SignalState + +@typing.final +class GetStrategiesRequest(google.protobuf.message.Message): + """Запрос стратегий.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + STRATEGY_ID_FIELD_NUMBER: builtins.int + strategy_id: builtins.str + """Идентификатор стратегии.""" + def __init__( + self, + *, + strategy_id: builtins.str | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_strategy_id", b"_strategy_id", "strategy_id", b"strategy_id"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_strategy_id", b"_strategy_id", "strategy_id", b"strategy_id"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_strategy_id", b"_strategy_id"]) -> typing.Literal["strategy_id"] | None: ... + +global___GetStrategiesRequest = GetStrategiesRequest + +@typing.final +class GetStrategiesResponse(google.protobuf.message.Message): + """Стратегии""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + STRATEGIES_FIELD_NUMBER: builtins.int + @property + def strategies(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Strategy]: ... + def __init__( + self, + *, + strategies: collections.abc.Iterable[global___Strategy] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["strategies", b"strategies"]) -> None: ... + +global___GetStrategiesResponse = GetStrategiesResponse + +@typing.final +class Strategy(google.protobuf.message.Message): + """Стратегия""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + STRATEGY_ID_FIELD_NUMBER: builtins.int + STRATEGY_NAME_FIELD_NUMBER: builtins.int + STRATEGY_DESCRIPTION_FIELD_NUMBER: builtins.int + STRATEGY_URL_FIELD_NUMBER: builtins.int + STRATEGY_TYPE_FIELD_NUMBER: builtins.int + ACTIVE_SIGNALS_FIELD_NUMBER: builtins.int + TOTAL_SIGNALS_FIELD_NUMBER: builtins.int + TIME_IN_POSITION_FIELD_NUMBER: builtins.int + AVERAGE_SIGNAL_YIELD_FIELD_NUMBER: builtins.int + AVERAGE_SIGNAL_YIELD_YEAR_FIELD_NUMBER: builtins.int + YIELD_FIELD_NUMBER: builtins.int + YIELD_YEAR_FIELD_NUMBER: builtins.int + strategy_id: builtins.str + """Идентификатор стратегии.""" + strategy_name: builtins.str + """Название стратегии.""" + strategy_description: builtins.str + """Описание стратегии.""" + strategy_url: builtins.str + """Ссылка на страницу с описанием стратегии.""" + strategy_type: global___StrategyType.ValueType + """Тип стратегии.""" + active_signals: builtins.int + """Количество активных сигналов.""" + total_signals: builtins.int + """Общее количество сигналов.""" + time_in_position: builtins.int + """Среднее время нахождения сигнала в позиции.""" + @property + def average_signal_yield(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Средняя доходность сигнала в стратегии.""" + + @property + def average_signal_yield_year(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Средняя доходность сигналов в стратегии за последний год.""" + + @property + def yield_year(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Доходность стратегии за последний год.""" + + def __init__( + self, + *, + strategy_id: builtins.str = ..., + strategy_name: builtins.str = ..., + strategy_description: builtins.str | None = ..., + strategy_url: builtins.str | None = ..., + strategy_type: global___StrategyType.ValueType = ..., + active_signals: builtins.int = ..., + total_signals: builtins.int = ..., + time_in_position: builtins.int = ..., + average_signal_yield: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + average_signal_yield_year: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + yield_year: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_strategy_description", b"_strategy_description", "_strategy_url", b"_strategy_url", "average_signal_yield", b"average_signal_yield", "average_signal_yield_year", b"average_signal_yield_year", "strategy_description", b"strategy_description", "strategy_url", b"strategy_url", "yield", b"yield", "yield_year", b"yield_year"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_strategy_description", b"_strategy_description", "_strategy_url", b"_strategy_url", "active_signals", b"active_signals", "average_signal_yield", b"average_signal_yield", "average_signal_yield_year", b"average_signal_yield_year", "strategy_description", b"strategy_description", "strategy_id", b"strategy_id", "strategy_name", b"strategy_name", "strategy_type", b"strategy_type", "strategy_url", b"strategy_url", "time_in_position", b"time_in_position", "total_signals", b"total_signals", "yield", b"yield", "yield_year", b"yield_year"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_strategy_description", b"_strategy_description"]) -> typing.Literal["strategy_description"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_strategy_url", b"_strategy_url"]) -> typing.Literal["strategy_url"] | None: ... + +global___Strategy = Strategy + +@typing.final +class GetSignalsRequest(google.protobuf.message.Message): + """Запрос сигналов.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SIGNAL_ID_FIELD_NUMBER: builtins.int + STRATEGY_ID_FIELD_NUMBER: builtins.int + STRATEGY_TYPE_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + FROM_FIELD_NUMBER: builtins.int + TO_FIELD_NUMBER: builtins.int + DIRECTION_FIELD_NUMBER: builtins.int + ACTIVE_FIELD_NUMBER: builtins.int + PAGING_FIELD_NUMBER: builtins.int + signal_id: builtins.str + """Идентификатор сигнала.""" + strategy_id: builtins.str + """Идентификатор стратегии.""" + strategy_type: global___StrategyType.ValueType + """Тип стратегии.""" + instrument_uid: builtins.str + """ Идентификатор бумаги.""" + direction: global___SignalDirection.ValueType + """ Направление сигнала.""" + active: global___SignalState.ValueType + """Состояние сигнала.""" + @property + def to(self) -> google.protobuf.timestamp_pb2.Timestamp: + """ Дата конца запрашиваемого интервала по UTC.""" + + @property + def paging(self) -> t_tech.invest.grpc.common_pb2.Page: + """Настройки пагинации.""" + + def __init__( + self, + *, + signal_id: builtins.str | None = ..., + strategy_id: builtins.str | None = ..., + strategy_type: global___StrategyType.ValueType | None = ..., + instrument_uid: builtins.str | None = ..., + to: google.protobuf.timestamp_pb2.Timestamp | None = ..., + direction: global___SignalDirection.ValueType | None = ..., + active: global___SignalState.ValueType | None = ..., + paging: t_tech.invest.grpc.common_pb2.Page | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_active", b"_active", "_direction", b"_direction", "_from", b"_from", "_instrument_uid", b"_instrument_uid", "_paging", b"_paging", "_signal_id", b"_signal_id", "_strategy_id", b"_strategy_id", "_strategy_type", b"_strategy_type", "_to", b"_to", "active", b"active", "direction", b"direction", "from", b"from", "instrument_uid", b"instrument_uid", "paging", b"paging", "signal_id", b"signal_id", "strategy_id", b"strategy_id", "strategy_type", b"strategy_type", "to", b"to"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_active", b"_active", "_direction", b"_direction", "_from", b"_from", "_instrument_uid", b"_instrument_uid", "_paging", b"_paging", "_signal_id", b"_signal_id", "_strategy_id", b"_strategy_id", "_strategy_type", b"_strategy_type", "_to", b"_to", "active", b"active", "direction", b"direction", "from", b"from", "instrument_uid", b"instrument_uid", "paging", b"paging", "signal_id", b"signal_id", "strategy_id", b"strategy_id", "strategy_type", b"strategy_type", "to", b"to"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_active", b"_active"]) -> typing.Literal["active"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_direction", b"_direction"]) -> typing.Literal["direction"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_from", b"_from"]) -> typing.Literal["from"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_instrument_uid", b"_instrument_uid"]) -> typing.Literal["instrument_uid"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_paging", b"_paging"]) -> typing.Literal["paging"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_signal_id", b"_signal_id"]) -> typing.Literal["signal_id"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_strategy_id", b"_strategy_id"]) -> typing.Literal["strategy_id"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_strategy_type", b"_strategy_type"]) -> typing.Literal["strategy_type"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_to", b"_to"]) -> typing.Literal["to"] | None: ... + +global___GetSignalsRequest = GetSignalsRequest + +@typing.final +class GetSignalsResponse(google.protobuf.message.Message): + """Сигналы.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SIGNALS_FIELD_NUMBER: builtins.int + PAGING_FIELD_NUMBER: builtins.int + @property + def signals(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Signal]: + """Массив сигналов.""" + + @property + def paging(self) -> t_tech.invest.grpc.common_pb2.PageResponse: + """Данные по пагинации.""" + + def __init__( + self, + *, + signals: collections.abc.Iterable[global___Signal] | None = ..., + paging: t_tech.invest.grpc.common_pb2.PageResponse | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["paging", b"paging"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["paging", b"paging", "signals", b"signals"]) -> None: ... + +global___GetSignalsResponse = GetSignalsResponse + +@typing.final +class Signal(google.protobuf.message.Message): + """Сигнал.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SIGNAL_ID_FIELD_NUMBER: builtins.int + STRATEGY_ID_FIELD_NUMBER: builtins.int + STRATEGY_NAME_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + CREATE_DT_FIELD_NUMBER: builtins.int + DIRECTION_FIELD_NUMBER: builtins.int + INITIAL_PRICE_FIELD_NUMBER: builtins.int + INFO_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + TARGET_PRICE_FIELD_NUMBER: builtins.int + END_DT_FIELD_NUMBER: builtins.int + PROBABILITY_FIELD_NUMBER: builtins.int + STOPLOSS_FIELD_NUMBER: builtins.int + CLOSE_PRICE_FIELD_NUMBER: builtins.int + CLOSE_DT_FIELD_NUMBER: builtins.int + signal_id: builtins.str + """Идентификатор сигнала.""" + strategy_id: builtins.str + """Идентификатор стратегии.""" + strategy_name: builtins.str + """Название стратегии.""" + instrument_uid: builtins.str + """Идентификатор бумаги.""" + direction: global___SignalDirection.ValueType + """Направление сигнала.""" + info: builtins.str + """Дополнительная информация о сигнале.""" + name: builtins.str + """Название сигнала.""" + probability: builtins.int + """Вероятность сигнала.""" + @property + def create_dt(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата и время создания сигнала по UTC.""" + + @property + def initial_price(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Цена бумаги на момент формирования сигнала.""" + + @property + def target_price(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Целевая цена.""" + + @property + def end_dt(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата и время дедлайна сигнала по UTC.""" + + @property + def stoploss(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Порог закрытия сигнала по стоплосс.""" + + @property + def close_price(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Цена закрытия сигнала.""" + + @property + def close_dt(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата и время закрытия сигнала по UTC.""" + + def __init__( + self, + *, + signal_id: builtins.str = ..., + strategy_id: builtins.str = ..., + strategy_name: builtins.str = ..., + instrument_uid: builtins.str = ..., + create_dt: google.protobuf.timestamp_pb2.Timestamp | None = ..., + direction: global___SignalDirection.ValueType = ..., + initial_price: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + info: builtins.str | None = ..., + name: builtins.str = ..., + target_price: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + end_dt: google.protobuf.timestamp_pb2.Timestamp | None = ..., + probability: builtins.int | None = ..., + stoploss: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + close_price: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + close_dt: google.protobuf.timestamp_pb2.Timestamp | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_close_dt", b"_close_dt", "_close_price", b"_close_price", "_info", b"_info", "_probability", b"_probability", "_stoploss", b"_stoploss", "close_dt", b"close_dt", "close_price", b"close_price", "create_dt", b"create_dt", "end_dt", b"end_dt", "info", b"info", "initial_price", b"initial_price", "probability", b"probability", "stoploss", b"stoploss", "target_price", b"target_price"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_close_dt", b"_close_dt", "_close_price", b"_close_price", "_info", b"_info", "_probability", b"_probability", "_stoploss", b"_stoploss", "close_dt", b"close_dt", "close_price", b"close_price", "create_dt", b"create_dt", "direction", b"direction", "end_dt", b"end_dt", "info", b"info", "initial_price", b"initial_price", "instrument_uid", b"instrument_uid", "name", b"name", "probability", b"probability", "signal_id", b"signal_id", "stoploss", b"stoploss", "strategy_id", b"strategy_id", "strategy_name", b"strategy_name", "target_price", b"target_price"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_close_dt", b"_close_dt"]) -> typing.Literal["close_dt"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_close_price", b"_close_price"]) -> typing.Literal["close_price"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_info", b"_info"]) -> typing.Literal["info"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_probability", b"_probability"]) -> typing.Literal["probability"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_stoploss", b"_stoploss"]) -> typing.Literal["stoploss"] | None: ... + +global___Signal = Signal diff --git a/invest-python-master/t_tech/invest/grpc/signals_pb2_grpc.py b/invest-python-master/t_tech/invest/grpc/signals_pb2_grpc.py new file mode 100644 index 0000000..fef07ea --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/signals_pb2_grpc.py @@ -0,0 +1,106 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +from t_tech.invest.grpc import ( + signals_pb2 as t__tech_dot_invest_dot_grpc_dot_signals__pb2, +) + + +class SignalServiceStub(object): + """Сервис для получения технических сигналов и мнений аналитиков по инструментам. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.GetStrategies = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.SignalService/GetStrategies', + request_serializer=t__tech_dot_invest_dot_grpc_dot_signals__pb2.GetStrategiesRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_signals__pb2.GetStrategiesResponse.FromString, + ) + self.GetSignals = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.SignalService/GetSignals', + request_serializer=t__tech_dot_invest_dot_grpc_dot_signals__pb2.GetSignalsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_signals__pb2.GetSignalsResponse.FromString, + ) + + +class SignalServiceServicer(object): + """Сервис для получения технических сигналов и мнений аналитиков по инструментам. + """ + + def GetStrategies(self, request, context): + """GetStrategies — стратегии + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetSignals(self, request, context): + """GetSignals — сигналы + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_SignalServiceServicer_to_server(servicer, server): + rpc_method_handlers = { + 'GetStrategies': grpc.unary_unary_rpc_method_handler( + servicer.GetStrategies, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_signals__pb2.GetStrategiesRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_signals__pb2.GetStrategiesResponse.SerializeToString, + ), + 'GetSignals': grpc.unary_unary_rpc_method_handler( + servicer.GetSignals, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_signals__pb2.GetSignalsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_signals__pb2.GetSignalsResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'tinkoff.public.invest.api.contract.v1.SignalService', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class SignalService(object): + """Сервис для получения технических сигналов и мнений аналитиков по инструментам. + """ + + @staticmethod + def GetStrategies(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SignalService/GetStrategies', + t__tech_dot_invest_dot_grpc_dot_signals__pb2.GetStrategiesRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_signals__pb2.GetStrategiesResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetSignals(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SignalService/GetSignals', + t__tech_dot_invest_dot_grpc_dot_signals__pb2.GetSignalsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_signals__pb2.GetSignalsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/invest-python-master/t_tech/invest/grpc/stoporders_pb2.py b/invest-python-master/t_tech/invest/grpc/stoporders_pb2.py new file mode 100644 index 0000000..edc8708 --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/stoporders_pb2.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: t_tech/invest/grpc/stoporders.proto +# Protobuf Python Version: 4.25.1 +"""Generated protocol buffer code.""" +from google.protobuf import ( + descriptor as _descriptor, + descriptor_pool as _descriptor_pool, + symbol_database as _symbol_database, +) +from google.protobuf.internal import builder as _builder + +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 + +from t_tech.invest.grpc import common_pb2 as t__tech_dot_invest_dot_grpc_dot_common__pb2 +from t_tech.invest.grpc.google.api import ( + field_behavior_pb2 as t__tech_dot_invest_dot_grpc_dot_google_dot_api_dot_field__behavior__pb2, +) + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#t_tech/invest/grpc/stoporders.proto\x12%tinkoff.public.invest.api.contract.v1\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x32t_tech/invest/grpc/google/api/field_behavior.proto\x1a\x1ft_tech/invest/grpc/common.proto\"\xeb\n\n\x14PostStopOrderRequest\x12\x15\n\x04\x66igi\x18\x01 \x01(\tB\x02\x18\x01H\x00\x88\x01\x01\x12\x16\n\x08quantity\x18\x02 \x01(\x03\x42\x04\xe2\x41\x01\x02\x12\x44\n\x05price\x18\x03 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationH\x01\x88\x01\x01\x12I\n\nstop_price\x18\x04 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationH\x02\x88\x01\x01\x12R\n\tdirection\x18\x05 \x01(\x0e\x32\x39.tinkoff.public.invest.api.contract.v1.StopOrderDirectionB\x04\xe2\x41\x01\x02\x12\x18\n\naccount_id\x18\x06 \x01(\tB\x04\xe2\x41\x01\x02\x12]\n\x0f\x65xpiration_type\x18\x07 \x01(\x0e\x32>.tinkoff.public.invest.api.contract.v1.StopOrderExpirationTypeB\x04\xe2\x41\x01\x02\x12S\n\x0fstop_order_type\x18\x08 \x01(\x0e\x32\x34.tinkoff.public.invest.api.contract.v1.StopOrderTypeB\x04\xe2\x41\x01\x02\x12\x34\n\x0b\x65xpire_date\x18\t \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x03\x88\x01\x01\x12\x1b\n\rinstrument_id\x18\n \x01(\tB\x04\xe2\x41\x01\x02\x12U\n\x13\x65xchange_order_type\x18\x0b \x01(\x0e\x32\x38.tinkoff.public.invest.api.contract.v1.ExchangeOrderType\x12O\n\x10take_profit_type\x18\x0c \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.TakeProfitType\x12_\n\rtrailing_data\x18\r \x01(\x0b\x32H.tinkoff.public.invest.api.contract.v1.PostStopOrderRequest.TrailingData\x12\x44\n\nprice_type\x18\x0e \x01(\x0e\x32\x30.tinkoff.public.invest.api.contract.v1.PriceType\x12\x16\n\x08order_id\x18\x0f \x01(\tB\x04\xe2\x41\x01\x02\x12\x1c\n\x14\x63onfirm_margin_trade\x18\x10 \x01(\x08\x12\x1e\n\x11instant_execution\x18\x11 \x01(\x08H\x04\x88\x01\x01\x1a\xb0\x02\n\x0cTrailingData\x12@\n\x06indent\x18\x01 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12M\n\x0bindent_type\x18\x02 \x01(\x0e\x32\x38.tinkoff.public.invest.api.contract.v1.TrailingValueType\x12@\n\x06spread\x18\x03 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12M\n\x0bspread_type\x18\x04 \x01(\x0e\x32\x38.tinkoff.public.invest.api.contract.v1.TrailingValueTypeB\x07\n\x05_figiB\x08\n\x06_priceB\r\n\x0b_stop_priceB\x0e\n\x0c_expire_dateB\x14\n\x12_instant_execution\"\x9d\x01\n\x15PostStopOrderResponse\x12\x15\n\rstop_order_id\x18\x01 \x01(\t\x12\x18\n\x10order_request_id\x18\x02 \x01(\t\x12S\n\x11response_metadata\x18\xfe\x01 \x01(\x0b\x32\x37.tinkoff.public.invest.api.contract.v1.ResponseMetadata\"\xd0\x01\n\x14GetStopOrdersRequest\x12\x18\n\naccount_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\x12L\n\x06status\x18\x02 \x01(\x0e\x32<.tinkoff.public.invest.api.contract.v1.StopOrderStatusOption\x12(\n\x04\x66rom\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12&\n\x02to\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"^\n\x15GetStopOrdersResponse\x12\x45\n\x0bstop_orders\x18\x01 \x03(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.StopOrder\"O\n\x16\x43\x61ncelStopOrderRequest\x12\x18\n\naccount_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\x12\x1b\n\rstop_order_id\x18\x02 \x01(\tB\x04\xe2\x41\x01\x02\"C\n\x17\x43\x61ncelStopOrderResponse\x12(\n\x04time\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\xf3\x0b\n\tStopOrder\x12\x15\n\rstop_order_id\x18\x01 \x01(\t\x12\x16\n\x0elots_requested\x18\x02 \x01(\x03\x12\x0c\n\x04\x66igi\x18\x03 \x01(\t\x12L\n\tdirection\x18\x04 \x01(\x0e\x32\x39.tinkoff.public.invest.api.contract.v1.StopOrderDirection\x12\x10\n\x08\x63urrency\x18\x05 \x01(\t\x12H\n\norder_type\x18\x06 \x01(\x0e\x32\x34.tinkoff.public.invest.api.contract.v1.StopOrderType\x12/\n\x0b\x63reate_date\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x38\n\x14\x61\x63tivation_date_time\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x33\n\x0f\x65xpiration_time\x18\t \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12@\n\x05price\x18\n \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x45\n\nstop_price\x18\x0b \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12\x16\n\x0einstrument_uid\x18\x0c \x01(\t\x12O\n\x10take_profit_type\x18\r \x01(\x0e\x32\x35.tinkoff.public.invest.api.contract.v1.TakeProfitType\x12T\n\rtrailing_data\x18\x0e \x01(\x0b\x32=.tinkoff.public.invest.api.contract.v1.StopOrder.TrailingData\x12L\n\x06status\x18\x0f \x01(\x0e\x32<.tinkoff.public.invest.api.contract.v1.StopOrderStatusOption\x12U\n\x13\x65xchange_order_type\x18\x10 \x01(\x0e\x32\x38.tinkoff.public.invest.api.contract.v1.ExchangeOrderType\x12\x1e\n\x11\x65xchange_order_id\x18\x11 \x01(\tH\x00\x88\x01\x01\x12\x0e\n\x06ticker\x18\x12 \x01(\t\x12\x12\n\nclass_code\x18\x13 \x01(\t\x12\x19\n\x11instant_execution\x18\x14 \x01(\x08\x1a\xfc\x03\n\x0cTrailingData\x12@\n\x06indent\x18\x01 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12M\n\x0bindent_type\x18\x02 \x01(\x0e\x32\x38.tinkoff.public.invest.api.contract.v1.TrailingValueType\x12@\n\x06spread\x18\x03 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12M\n\x0bspread_type\x18\x04 \x01(\x0e\x32\x38.tinkoff.public.invest.api.contract.v1.TrailingValueType\x12I\n\x06status\x18\x05 \x01(\x0e\x32\x39.tinkoff.public.invest.api.contract.v1.TrailingStopStatus\x12?\n\x05price\x18\x07 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12>\n\x04\x65xtr\x18\x08 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.QuotationB\x14\n\x12_exchange_order_id*w\n\x12StopOrderDirection\x12$\n STOP_ORDER_DIRECTION_UNSPECIFIED\x10\x00\x12\x1c\n\x18STOP_ORDER_DIRECTION_BUY\x10\x01\x12\x1d\n\x19STOP_ORDER_DIRECTION_SELL\x10\x02*\xa5\x01\n\x17StopOrderExpirationType\x12*\n&STOP_ORDER_EXPIRATION_TYPE_UNSPECIFIED\x10\x00\x12/\n+STOP_ORDER_EXPIRATION_TYPE_GOOD_TILL_CANCEL\x10\x01\x12-\n)STOP_ORDER_EXPIRATION_TYPE_GOOD_TILL_DATE\x10\x02*\x90\x01\n\rStopOrderType\x12\x1f\n\x1bSTOP_ORDER_TYPE_UNSPECIFIED\x10\x00\x12\x1f\n\x1bSTOP_ORDER_TYPE_TAKE_PROFIT\x10\x01\x12\x1d\n\x19STOP_ORDER_TYPE_STOP_LOSS\x10\x02\x12\x1e\n\x1aSTOP_ORDER_TYPE_STOP_LIMIT\x10\x03*\xd2\x01\n\x15StopOrderStatusOption\x12!\n\x1dSTOP_ORDER_STATUS_UNSPECIFIED\x10\x00\x12\x19\n\x15STOP_ORDER_STATUS_ALL\x10\x01\x12\x1c\n\x18STOP_ORDER_STATUS_ACTIVE\x10\x02\x12\x1e\n\x1aSTOP_ORDER_STATUS_EXECUTED\x10\x03\x12\x1e\n\x1aSTOP_ORDER_STATUS_CANCELED\x10\x04\x12\x1d\n\x19STOP_ORDER_STATUS_EXPIRED\x10\x05*w\n\x11\x45xchangeOrderType\x12#\n\x1f\x45XCHANGE_ORDER_TYPE_UNSPECIFIED\x10\x00\x12\x1e\n\x1a\x45XCHANGE_ORDER_TYPE_MARKET\x10\x01\x12\x1d\n\x19\x45XCHANGE_ORDER_TYPE_LIMIT\x10\x02*o\n\x0eTakeProfitType\x12 \n\x1cTAKE_PROFIT_TYPE_UNSPECIFIED\x10\x00\x12\x1c\n\x18TAKE_PROFIT_TYPE_REGULAR\x10\x01\x12\x1d\n\x19TAKE_PROFIT_TYPE_TRAILING\x10\x02*m\n\x11TrailingValueType\x12\x1e\n\x1aTRAILING_VALUE_UNSPECIFIED\x10\x00\x12\x1b\n\x17TRAILING_VALUE_ABSOLUTE\x10\x01\x12\x1b\n\x17TRAILING_VALUE_RELATIVE\x10\x02*j\n\x12TrailingStopStatus\x12\x1d\n\x19TRAILING_STOP_UNSPECIFIED\x10\x00\x12\x18\n\x14TRAILING_STOP_ACTIVE\x10\x01\x12\x1b\n\x17TRAILING_STOP_ACTIVATED\x10\x02\x32\xc0\x03\n\x11StopOrdersService\x12\x8a\x01\n\rPostStopOrder\x12;.tinkoff.public.invest.api.contract.v1.PostStopOrderRequest\x1a<.tinkoff.public.invest.api.contract.v1.PostStopOrderResponse\x12\x8a\x01\n\rGetStopOrders\x12;.tinkoff.public.invest.api.contract.v1.GetStopOrdersRequest\x1a<.tinkoff.public.invest.api.contract.v1.GetStopOrdersResponse\x12\x90\x01\n\x0f\x43\x61ncelStopOrder\x12=.tinkoff.public.invest.api.contract.v1.CancelStopOrderRequest\x1a>.tinkoff.public.invest.api.contract.v1.CancelStopOrderResponseBa\n\x1cru.tinkoff.piapi.contract.v1P\x01Z\x0c./;investapi\xa2\x02\x05TIAPI\xaa\x02\x14Tinkoff.InvestApi.V1\xca\x02\x11Tinkoff\\Invest\\V1b\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 't_tech.invest.grpc.stoporders_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\034ru.tinkoff.piapi.contract.v1P\001Z\014./;investapi\242\002\005TIAPI\252\002\024Tinkoff.InvestApi.V1\312\002\021Tinkoff\\Invest\\V1' + _globals['_POSTSTOPORDERREQUEST'].fields_by_name['figi']._options = None + _globals['_POSTSTOPORDERREQUEST'].fields_by_name['figi']._serialized_options = b'\030\001' + _globals['_POSTSTOPORDERREQUEST'].fields_by_name['quantity']._options = None + _globals['_POSTSTOPORDERREQUEST'].fields_by_name['quantity']._serialized_options = b'\342A\001\002' + _globals['_POSTSTOPORDERREQUEST'].fields_by_name['direction']._options = None + _globals['_POSTSTOPORDERREQUEST'].fields_by_name['direction']._serialized_options = b'\342A\001\002' + _globals['_POSTSTOPORDERREQUEST'].fields_by_name['account_id']._options = None + _globals['_POSTSTOPORDERREQUEST'].fields_by_name['account_id']._serialized_options = b'\342A\001\002' + _globals['_POSTSTOPORDERREQUEST'].fields_by_name['expiration_type']._options = None + _globals['_POSTSTOPORDERREQUEST'].fields_by_name['expiration_type']._serialized_options = b'\342A\001\002' + _globals['_POSTSTOPORDERREQUEST'].fields_by_name['stop_order_type']._options = None + _globals['_POSTSTOPORDERREQUEST'].fields_by_name['stop_order_type']._serialized_options = b'\342A\001\002' + _globals['_POSTSTOPORDERREQUEST'].fields_by_name['instrument_id']._options = None + _globals['_POSTSTOPORDERREQUEST'].fields_by_name['instrument_id']._serialized_options = b'\342A\001\002' + _globals['_POSTSTOPORDERREQUEST'].fields_by_name['order_id']._options = None + _globals['_POSTSTOPORDERREQUEST'].fields_by_name['order_id']._serialized_options = b'\342A\001\002' + _globals['_GETSTOPORDERSREQUEST'].fields_by_name['account_id']._options = None + _globals['_GETSTOPORDERSREQUEST'].fields_by_name['account_id']._serialized_options = b'\342A\001\002' + _globals['_CANCELSTOPORDERREQUEST'].fields_by_name['account_id']._options = None + _globals['_CANCELSTOPORDERREQUEST'].fields_by_name['account_id']._serialized_options = b'\342A\001\002' + _globals['_CANCELSTOPORDERREQUEST'].fields_by_name['stop_order_id']._options = None + _globals['_CANCELSTOPORDERREQUEST'].fields_by_name['stop_order_id']._serialized_options = b'\342A\001\002' + _globals['_STOPORDERDIRECTION']._serialized_start=3729 + _globals['_STOPORDERDIRECTION']._serialized_end=3848 + _globals['_STOPORDEREXPIRATIONTYPE']._serialized_start=3851 + _globals['_STOPORDEREXPIRATIONTYPE']._serialized_end=4016 + _globals['_STOPORDERTYPE']._serialized_start=4019 + _globals['_STOPORDERTYPE']._serialized_end=4163 + _globals['_STOPORDERSTATUSOPTION']._serialized_start=4166 + _globals['_STOPORDERSTATUSOPTION']._serialized_end=4376 + _globals['_EXCHANGEORDERTYPE']._serialized_start=4378 + _globals['_EXCHANGEORDERTYPE']._serialized_end=4497 + _globals['_TAKEPROFITTYPE']._serialized_start=4499 + _globals['_TAKEPROFITTYPE']._serialized_end=4610 + _globals['_TRAILINGVALUETYPE']._serialized_start=4612 + _globals['_TRAILINGVALUETYPE']._serialized_end=4721 + _globals['_TRAILINGSTOPSTATUS']._serialized_start=4723 + _globals['_TRAILINGSTOPSTATUS']._serialized_end=4829 + _globals['_POSTSTOPORDERREQUEST']._serialized_start=197 + _globals['_POSTSTOPORDERREQUEST']._serialized_end=1584 + _globals['_POSTSTOPORDERREQUEST_TRAILINGDATA']._serialized_start=1208 + _globals['_POSTSTOPORDERREQUEST_TRAILINGDATA']._serialized_end=1512 + _globals['_POSTSTOPORDERRESPONSE']._serialized_start=1587 + _globals['_POSTSTOPORDERRESPONSE']._serialized_end=1744 + _globals['_GETSTOPORDERSREQUEST']._serialized_start=1747 + _globals['_GETSTOPORDERSREQUEST']._serialized_end=1955 + _globals['_GETSTOPORDERSRESPONSE']._serialized_start=1957 + _globals['_GETSTOPORDERSRESPONSE']._serialized_end=2051 + _globals['_CANCELSTOPORDERREQUEST']._serialized_start=2053 + _globals['_CANCELSTOPORDERREQUEST']._serialized_end=2132 + _globals['_CANCELSTOPORDERRESPONSE']._serialized_start=2134 + _globals['_CANCELSTOPORDERRESPONSE']._serialized_end=2201 + _globals['_STOPORDER']._serialized_start=2204 + _globals['_STOPORDER']._serialized_end=3727 + _globals['_STOPORDER_TRAILINGDATA']._serialized_start=3197 + _globals['_STOPORDER_TRAILINGDATA']._serialized_end=3705 + _globals['_STOPORDERSSERVICE']._serialized_start=4832 + _globals['_STOPORDERSSERVICE']._serialized_end=5280 +# @@protoc_insertion_point(module_scope) diff --git a/invest-python-master/t_tech/invest/grpc/stoporders_pb2.pyi b/invest-python-master/t_tech/invest/grpc/stoporders_pb2.pyi new file mode 100644 index 0000000..6ea9d21 --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/stoporders_pb2.pyi @@ -0,0 +1,639 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" + +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.internal.enum_type_wrapper +import google.protobuf.message +import google.protobuf.timestamp_pb2 +import sys +import t_tech.invest.grpc.common_pb2 +import typing + +if sys.version_info >= (3, 10): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +class _StopOrderDirection: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _StopOrderDirectionEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_StopOrderDirection.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + STOP_ORDER_DIRECTION_UNSPECIFIED: _StopOrderDirection.ValueType # 0 + """Значение не указано.""" + STOP_ORDER_DIRECTION_BUY: _StopOrderDirection.ValueType # 1 + """Покупка.""" + STOP_ORDER_DIRECTION_SELL: _StopOrderDirection.ValueType # 2 + """Продажа.""" + +class StopOrderDirection(_StopOrderDirection, metaclass=_StopOrderDirectionEnumTypeWrapper): + """Направление сделки стоп-заявки.""" + +STOP_ORDER_DIRECTION_UNSPECIFIED: StopOrderDirection.ValueType # 0 +"""Значение не указано.""" +STOP_ORDER_DIRECTION_BUY: StopOrderDirection.ValueType # 1 +"""Покупка.""" +STOP_ORDER_DIRECTION_SELL: StopOrderDirection.ValueType # 2 +"""Продажа.""" +global___StopOrderDirection = StopOrderDirection + +class _StopOrderExpirationType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _StopOrderExpirationTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_StopOrderExpirationType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + STOP_ORDER_EXPIRATION_TYPE_UNSPECIFIED: _StopOrderExpirationType.ValueType # 0 + """Значение не указано.""" + STOP_ORDER_EXPIRATION_TYPE_GOOD_TILL_CANCEL: _StopOrderExpirationType.ValueType # 1 + """Действительно до отмены.""" + STOP_ORDER_EXPIRATION_TYPE_GOOD_TILL_DATE: _StopOrderExpirationType.ValueType # 2 + """Действительно до даты снятия.""" + +class StopOrderExpirationType(_StopOrderExpirationType, metaclass=_StopOrderExpirationTypeEnumTypeWrapper): + """Тип экспирации стоп-заявке.""" + +STOP_ORDER_EXPIRATION_TYPE_UNSPECIFIED: StopOrderExpirationType.ValueType # 0 +"""Значение не указано.""" +STOP_ORDER_EXPIRATION_TYPE_GOOD_TILL_CANCEL: StopOrderExpirationType.ValueType # 1 +"""Действительно до отмены.""" +STOP_ORDER_EXPIRATION_TYPE_GOOD_TILL_DATE: StopOrderExpirationType.ValueType # 2 +"""Действительно до даты снятия.""" +global___StopOrderExpirationType = StopOrderExpirationType + +class _StopOrderType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _StopOrderTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_StopOrderType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + STOP_ORDER_TYPE_UNSPECIFIED: _StopOrderType.ValueType # 0 + """Значение не указано.""" + STOP_ORDER_TYPE_TAKE_PROFIT: _StopOrderType.ValueType # 1 + """`Take-profit`-заявка.""" + STOP_ORDER_TYPE_STOP_LOSS: _StopOrderType.ValueType # 2 + """`Stop-loss`-заявка.""" + STOP_ORDER_TYPE_STOP_LIMIT: _StopOrderType.ValueType # 3 + """`Stop-limit`-заявка.""" + +class StopOrderType(_StopOrderType, metaclass=_StopOrderTypeEnumTypeWrapper): + """Тип стоп-заявки.""" + +STOP_ORDER_TYPE_UNSPECIFIED: StopOrderType.ValueType # 0 +"""Значение не указано.""" +STOP_ORDER_TYPE_TAKE_PROFIT: StopOrderType.ValueType # 1 +"""`Take-profit`-заявка.""" +STOP_ORDER_TYPE_STOP_LOSS: StopOrderType.ValueType # 2 +"""`Stop-loss`-заявка.""" +STOP_ORDER_TYPE_STOP_LIMIT: StopOrderType.ValueType # 3 +"""`Stop-limit`-заявка.""" +global___StopOrderType = StopOrderType + +class _StopOrderStatusOption: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _StopOrderStatusOptionEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_StopOrderStatusOption.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + STOP_ORDER_STATUS_UNSPECIFIED: _StopOrderStatusOption.ValueType # 0 + """Значение не указано.""" + STOP_ORDER_STATUS_ALL: _StopOrderStatusOption.ValueType # 1 + """Все заявки.""" + STOP_ORDER_STATUS_ACTIVE: _StopOrderStatusOption.ValueType # 2 + """Активные заявки.""" + STOP_ORDER_STATUS_EXECUTED: _StopOrderStatusOption.ValueType # 3 + """Исполненные заявки.""" + STOP_ORDER_STATUS_CANCELED: _StopOrderStatusOption.ValueType # 4 + """Отмененные заявки.""" + STOP_ORDER_STATUS_EXPIRED: _StopOrderStatusOption.ValueType # 5 + """Истекшие заявки.""" + +class StopOrderStatusOption(_StopOrderStatusOption, metaclass=_StopOrderStatusOptionEnumTypeWrapper): + """Статус стоп-заяки.""" + +STOP_ORDER_STATUS_UNSPECIFIED: StopOrderStatusOption.ValueType # 0 +"""Значение не указано.""" +STOP_ORDER_STATUS_ALL: StopOrderStatusOption.ValueType # 1 +"""Все заявки.""" +STOP_ORDER_STATUS_ACTIVE: StopOrderStatusOption.ValueType # 2 +"""Активные заявки.""" +STOP_ORDER_STATUS_EXECUTED: StopOrderStatusOption.ValueType # 3 +"""Исполненные заявки.""" +STOP_ORDER_STATUS_CANCELED: StopOrderStatusOption.ValueType # 4 +"""Отмененные заявки.""" +STOP_ORDER_STATUS_EXPIRED: StopOrderStatusOption.ValueType # 5 +"""Истекшие заявки.""" +global___StopOrderStatusOption = StopOrderStatusOption + +class _ExchangeOrderType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _ExchangeOrderTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_ExchangeOrderType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + EXCHANGE_ORDER_TYPE_UNSPECIFIED: _ExchangeOrderType.ValueType # 0 + """Значение не указано.""" + EXCHANGE_ORDER_TYPE_MARKET: _ExchangeOrderType.ValueType # 1 + """Заявка по рыночной цене.""" + EXCHANGE_ORDER_TYPE_LIMIT: _ExchangeOrderType.ValueType # 2 + """Лимитная заявка.""" + +class ExchangeOrderType(_ExchangeOrderType, metaclass=_ExchangeOrderTypeEnumTypeWrapper): + """Тип выставляемой заявки.""" + +EXCHANGE_ORDER_TYPE_UNSPECIFIED: ExchangeOrderType.ValueType # 0 +"""Значение не указано.""" +EXCHANGE_ORDER_TYPE_MARKET: ExchangeOrderType.ValueType # 1 +"""Заявка по рыночной цене.""" +EXCHANGE_ORDER_TYPE_LIMIT: ExchangeOrderType.ValueType # 2 +"""Лимитная заявка.""" +global___ExchangeOrderType = ExchangeOrderType + +class _TakeProfitType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _TakeProfitTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_TakeProfitType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + TAKE_PROFIT_TYPE_UNSPECIFIED: _TakeProfitType.ValueType # 0 + """Значение не указано.""" + TAKE_PROFIT_TYPE_REGULAR: _TakeProfitType.ValueType # 1 + """Обычная заявка, значение по умолчанию.""" + TAKE_PROFIT_TYPE_TRAILING: _TakeProfitType.ValueType # 2 + """Трейлинг-стоп.""" + +class TakeProfitType(_TakeProfitType, metaclass=_TakeProfitTypeEnumTypeWrapper): + """Тип TakeProfit-заявки.""" + +TAKE_PROFIT_TYPE_UNSPECIFIED: TakeProfitType.ValueType # 0 +"""Значение не указано.""" +TAKE_PROFIT_TYPE_REGULAR: TakeProfitType.ValueType # 1 +"""Обычная заявка, значение по умолчанию.""" +TAKE_PROFIT_TYPE_TRAILING: TakeProfitType.ValueType # 2 +"""Трейлинг-стоп.""" +global___TakeProfitType = TakeProfitType + +class _TrailingValueType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _TrailingValueTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_TrailingValueType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + TRAILING_VALUE_UNSPECIFIED: _TrailingValueType.ValueType # 0 + """Значение не указано.""" + TRAILING_VALUE_ABSOLUTE: _TrailingValueType.ValueType # 1 + """Абсолютное значение в единицах цены.""" + TRAILING_VALUE_RELATIVE: _TrailingValueType.ValueType # 2 + """Относительное значение в процентах.""" + +class TrailingValueType(_TrailingValueType, metaclass=_TrailingValueTypeEnumTypeWrapper): + """Тип параметров значений трейлинг-стопа.""" + +TRAILING_VALUE_UNSPECIFIED: TrailingValueType.ValueType # 0 +"""Значение не указано.""" +TRAILING_VALUE_ABSOLUTE: TrailingValueType.ValueType # 1 +"""Абсолютное значение в единицах цены.""" +TRAILING_VALUE_RELATIVE: TrailingValueType.ValueType # 2 +"""Относительное значение в процентах.""" +global___TrailingValueType = TrailingValueType + +class _TrailingStopStatus: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _TrailingStopStatusEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_TrailingStopStatus.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + TRAILING_STOP_UNSPECIFIED: _TrailingStopStatus.ValueType # 0 + """Значение не указано.""" + TRAILING_STOP_ACTIVE: _TrailingStopStatus.ValueType # 1 + """Активный.""" + TRAILING_STOP_ACTIVATED: _TrailingStopStatus.ValueType # 2 + """Активированный.""" + +class TrailingStopStatus(_TrailingStopStatus, metaclass=_TrailingStopStatusEnumTypeWrapper): + """Статус трейлинг-стопа.""" + +TRAILING_STOP_UNSPECIFIED: TrailingStopStatus.ValueType # 0 +"""Значение не указано.""" +TRAILING_STOP_ACTIVE: TrailingStopStatus.ValueType # 1 +"""Активный.""" +TRAILING_STOP_ACTIVATED: TrailingStopStatus.ValueType # 2 +"""Активированный.""" +global___TrailingStopStatus = TrailingStopStatus + +@typing.final +class PostStopOrderRequest(google.protobuf.message.Message): + """Запрос выставления стоп-заявки.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing.final + class TrailingData(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INDENT_FIELD_NUMBER: builtins.int + INDENT_TYPE_FIELD_NUMBER: builtins.int + SPREAD_FIELD_NUMBER: builtins.int + SPREAD_TYPE_FIELD_NUMBER: builtins.int + indent_type: global___TrailingValueType.ValueType + """Тип величины отступа.""" + spread_type: global___TrailingValueType.ValueType + """Тип величины защитного спреда.""" + @property + def indent(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Отступ.""" + + @property + def spread(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Размер защитного спреда.""" + + def __init__( + self, + *, + indent: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + indent_type: global___TrailingValueType.ValueType = ..., + spread: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + spread_type: global___TrailingValueType.ValueType = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["indent", b"indent", "spread", b"spread"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["indent", b"indent", "indent_type", b"indent_type", "spread", b"spread", "spread_type", b"spread_type"]) -> None: ... + + FIGI_FIELD_NUMBER: builtins.int + QUANTITY_FIELD_NUMBER: builtins.int + PRICE_FIELD_NUMBER: builtins.int + STOP_PRICE_FIELD_NUMBER: builtins.int + DIRECTION_FIELD_NUMBER: builtins.int + ACCOUNT_ID_FIELD_NUMBER: builtins.int + EXPIRATION_TYPE_FIELD_NUMBER: builtins.int + STOP_ORDER_TYPE_FIELD_NUMBER: builtins.int + EXPIRE_DATE_FIELD_NUMBER: builtins.int + INSTRUMENT_ID_FIELD_NUMBER: builtins.int + EXCHANGE_ORDER_TYPE_FIELD_NUMBER: builtins.int + TAKE_PROFIT_TYPE_FIELD_NUMBER: builtins.int + TRAILING_DATA_FIELD_NUMBER: builtins.int + PRICE_TYPE_FIELD_NUMBER: builtins.int + ORDER_ID_FIELD_NUMBER: builtins.int + CONFIRM_MARGIN_TRADE_FIELD_NUMBER: builtins.int + INSTANT_EXECUTION_FIELD_NUMBER: builtins.int + figi: builtins.str + """Deprecated FIGI-идентификатор инструмента. Используйте `instrument_id`.""" + quantity: builtins.int + """Количество лотов.""" + direction: global___StopOrderDirection.ValueType + """Направление операции.""" + account_id: builtins.str + """Номер счета.""" + expiration_type: global___StopOrderExpirationType.ValueType + """Тип экспирации заявки.""" + stop_order_type: global___StopOrderType.ValueType + """Тип заявки.""" + instrument_id: builtins.str + """Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`.""" + exchange_order_type: global___ExchangeOrderType.ValueType + """Тип дочерней биржевой заявки.""" + take_profit_type: global___TakeProfitType.ValueType + """Подтип стоп-заявки — `TakeProfit`.""" + price_type: t_tech.invest.grpc.common_pb2.PriceType.ValueType + """Тип цены.""" + order_id: builtins.str + """Идентификатор запроса выставления поручения для целей идемпотентности в формате `UID`. Максимальная длина — 36 символов.""" + confirm_margin_trade: builtins.bool + """Согласие на выставление заявки, которая может привести к непокрытой позиции, по умолчанию false.""" + instant_execution: builtins.bool + """Признак необходимости моментальной активации, используется только для трейлинг-стопа.""" + @property + def price(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Цена за 1 инструмент биржевой заявки, которая будет выставлена при срабатывании по достижению `stop_price`. Чтобы получить стоимость лота, нужно умножить на лотность инструмента.""" + + @property + def stop_price(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Стоп-цена заявки за 1 инструмент. При достижении стоп-цены происходит активация стоп-заявки, в результате чего выставляется биржевая заявка. Чтобы получить стоимость лота, нужно умножить на лотность инструмента.""" + + @property + def expire_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата и время окончания действия стоп-заявки по UTC. Для `ExpirationType = GoodTillDate` заполнение обязательно, для `GoodTillCancel` игнорируется.""" + + @property + def trailing_data(self) -> global___PostStopOrderRequest.TrailingData: + """Массив с параметрами трейлинг-стопа.""" + + def __init__( + self, + *, + figi: builtins.str | None = ..., + quantity: builtins.int = ..., + price: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + stop_price: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + direction: global___StopOrderDirection.ValueType = ..., + account_id: builtins.str = ..., + expiration_type: global___StopOrderExpirationType.ValueType = ..., + stop_order_type: global___StopOrderType.ValueType = ..., + expire_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + instrument_id: builtins.str = ..., + exchange_order_type: global___ExchangeOrderType.ValueType = ..., + take_profit_type: global___TakeProfitType.ValueType = ..., + trailing_data: global___PostStopOrderRequest.TrailingData | None = ..., + price_type: t_tech.invest.grpc.common_pb2.PriceType.ValueType = ..., + order_id: builtins.str = ..., + confirm_margin_trade: builtins.bool = ..., + instant_execution: builtins.bool | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_expire_date", b"_expire_date", "_figi", b"_figi", "_instant_execution", b"_instant_execution", "_price", b"_price", "_stop_price", b"_stop_price", "expire_date", b"expire_date", "figi", b"figi", "instant_execution", b"instant_execution", "price", b"price", "stop_price", b"stop_price", "trailing_data", b"trailing_data"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_expire_date", b"_expire_date", "_figi", b"_figi", "_instant_execution", b"_instant_execution", "_price", b"_price", "_stop_price", b"_stop_price", "account_id", b"account_id", "confirm_margin_trade", b"confirm_margin_trade", "direction", b"direction", "exchange_order_type", b"exchange_order_type", "expiration_type", b"expiration_type", "expire_date", b"expire_date", "figi", b"figi", "instant_execution", b"instant_execution", "instrument_id", b"instrument_id", "order_id", b"order_id", "price", b"price", "price_type", b"price_type", "quantity", b"quantity", "stop_order_type", b"stop_order_type", "stop_price", b"stop_price", "take_profit_type", b"take_profit_type", "trailing_data", b"trailing_data"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_expire_date", b"_expire_date"]) -> typing.Literal["expire_date"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_figi", b"_figi"]) -> typing.Literal["figi"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_instant_execution", b"_instant_execution"]) -> typing.Literal["instant_execution"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_price", b"_price"]) -> typing.Literal["price"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_stop_price", b"_stop_price"]) -> typing.Literal["stop_price"] | None: ... + +global___PostStopOrderRequest = PostStopOrderRequest + +@typing.final +class PostStopOrderResponse(google.protobuf.message.Message): + """Результат выставления стоп-заявки.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + STOP_ORDER_ID_FIELD_NUMBER: builtins.int + ORDER_REQUEST_ID_FIELD_NUMBER: builtins.int + RESPONSE_METADATA_FIELD_NUMBER: builtins.int + stop_order_id: builtins.str + """Уникальный идентификатор стоп-заявки.""" + order_request_id: builtins.str + """Идентификатор ключа идемпотентности, переданный клиентом, в формате `UID`. Максимальная длина 36 — символов.""" + @property + def response_metadata(self) -> t_tech.invest.grpc.common_pb2.ResponseMetadata: + """Метадата.""" + + def __init__( + self, + *, + stop_order_id: builtins.str = ..., + order_request_id: builtins.str = ..., + response_metadata: t_tech.invest.grpc.common_pb2.ResponseMetadata | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["response_metadata", b"response_metadata"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["order_request_id", b"order_request_id", "response_metadata", b"response_metadata", "stop_order_id", b"stop_order_id"]) -> None: ... + +global___PostStopOrderResponse = PostStopOrderResponse + +@typing.final +class GetStopOrdersRequest(google.protobuf.message.Message): + """Запрос получения списка активных стоп-заявок.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNT_ID_FIELD_NUMBER: builtins.int + STATUS_FIELD_NUMBER: builtins.int + FROM_FIELD_NUMBER: builtins.int + TO_FIELD_NUMBER: builtins.int + account_id: builtins.str + """Идентификатор счета клиента.""" + status: global___StopOrderStatusOption.ValueType + """Статус заявок.""" + @property + def to(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Правая граница.""" + + def __init__( + self, + *, + account_id: builtins.str = ..., + status: global___StopOrderStatusOption.ValueType = ..., + to: google.protobuf.timestamp_pb2.Timestamp | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["from", b"from", "to", b"to"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["account_id", b"account_id", "from", b"from", "status", b"status", "to", b"to"]) -> None: ... + +global___GetStopOrdersRequest = GetStopOrdersRequest + +@typing.final +class GetStopOrdersResponse(google.protobuf.message.Message): + """Список активных стоп-заявок.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + STOP_ORDERS_FIELD_NUMBER: builtins.int + @property + def stop_orders(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___StopOrder]: + """Массив стоп-заявок по счету.""" + + def __init__( + self, + *, + stop_orders: collections.abc.Iterable[global___StopOrder] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["stop_orders", b"stop_orders"]) -> None: ... + +global___GetStopOrdersResponse = GetStopOrdersResponse + +@typing.final +class CancelStopOrderRequest(google.protobuf.message.Message): + """Запрос отмены выставленной стоп-заявки.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNT_ID_FIELD_NUMBER: builtins.int + STOP_ORDER_ID_FIELD_NUMBER: builtins.int + account_id: builtins.str + """Идентификатор счета клиента.""" + stop_order_id: builtins.str + """Уникальный идентификатор стоп-заявки.""" + def __init__( + self, + *, + account_id: builtins.str = ..., + stop_order_id: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["account_id", b"account_id", "stop_order_id", b"stop_order_id"]) -> None: ... + +global___CancelStopOrderRequest = CancelStopOrderRequest + +@typing.final +class CancelStopOrderResponse(google.protobuf.message.Message): + """Результат отмены выставленной стоп-заявки.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TIME_FIELD_NUMBER: builtins.int + @property + def time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Время отмены заявки по UTC.""" + + def __init__( + self, + *, + time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["time", b"time"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["time", b"time"]) -> None: ... + +global___CancelStopOrderResponse = CancelStopOrderResponse + +@typing.final +class StopOrder(google.protobuf.message.Message): + """Информация о стоп-заявке.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing.final + class TrailingData(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INDENT_FIELD_NUMBER: builtins.int + INDENT_TYPE_FIELD_NUMBER: builtins.int + SPREAD_FIELD_NUMBER: builtins.int + SPREAD_TYPE_FIELD_NUMBER: builtins.int + STATUS_FIELD_NUMBER: builtins.int + PRICE_FIELD_NUMBER: builtins.int + EXTR_FIELD_NUMBER: builtins.int + indent_type: global___TrailingValueType.ValueType + """Тип величины отступа.""" + spread_type: global___TrailingValueType.ValueType + """Тип величины защитного спреда.""" + status: global___TrailingStopStatus.ValueType + """Статус трейлинг-стопа.""" + @property + def indent(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Отступ.""" + + @property + def spread(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Размер защитного спреда.""" + + @property + def price(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Цена исполнения.""" + + @property + def extr(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Локальный экстремум.""" + + def __init__( + self, + *, + indent: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + indent_type: global___TrailingValueType.ValueType = ..., + spread: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + spread_type: global___TrailingValueType.ValueType = ..., + status: global___TrailingStopStatus.ValueType = ..., + price: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + extr: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["extr", b"extr", "indent", b"indent", "price", b"price", "spread", b"spread"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["extr", b"extr", "indent", b"indent", "indent_type", b"indent_type", "price", b"price", "spread", b"spread", "spread_type", b"spread_type", "status", b"status"]) -> None: ... + + STOP_ORDER_ID_FIELD_NUMBER: builtins.int + LOTS_REQUESTED_FIELD_NUMBER: builtins.int + FIGI_FIELD_NUMBER: builtins.int + DIRECTION_FIELD_NUMBER: builtins.int + CURRENCY_FIELD_NUMBER: builtins.int + ORDER_TYPE_FIELD_NUMBER: builtins.int + CREATE_DATE_FIELD_NUMBER: builtins.int + ACTIVATION_DATE_TIME_FIELD_NUMBER: builtins.int + EXPIRATION_TIME_FIELD_NUMBER: builtins.int + PRICE_FIELD_NUMBER: builtins.int + STOP_PRICE_FIELD_NUMBER: builtins.int + INSTRUMENT_UID_FIELD_NUMBER: builtins.int + TAKE_PROFIT_TYPE_FIELD_NUMBER: builtins.int + TRAILING_DATA_FIELD_NUMBER: builtins.int + STATUS_FIELD_NUMBER: builtins.int + EXCHANGE_ORDER_TYPE_FIELD_NUMBER: builtins.int + EXCHANGE_ORDER_ID_FIELD_NUMBER: builtins.int + TICKER_FIELD_NUMBER: builtins.int + CLASS_CODE_FIELD_NUMBER: builtins.int + INSTANT_EXECUTION_FIELD_NUMBER: builtins.int + stop_order_id: builtins.str + """Уникальный идентификатор стоп-заявки.""" + lots_requested: builtins.int + """Запрошено лотов.""" + figi: builtins.str + """FIGI-идентификатор инструмента.""" + direction: global___StopOrderDirection.ValueType + """Направление операции.""" + currency: builtins.str + """Валюта стоп-заявки.""" + order_type: global___StopOrderType.ValueType + """Тип стоп-заявки.""" + instrument_uid: builtins.str + """`instrument_uid`-идентификатор инструмента.""" + take_profit_type: global___TakeProfitType.ValueType + """Подтип стоп-заявки — `TakeProfit`.""" + status: global___StopOrderStatusOption.ValueType + """Статус заявки.""" + exchange_order_type: global___ExchangeOrderType.ValueType + """Тип дочерней биржевой заявки для тейкпрофита.""" + exchange_order_id: builtins.str + """Идентификатор биржевой заявки.""" + ticker: builtins.str + """Тикер инструмента.""" + class_code: builtins.str + """Класс-код (секция торгов).""" + instant_execution: builtins.bool + """Признак необходимости моментальной активации, используется только для трейлинг-стопа.""" + @property + def create_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата и время выставления заявки по UTC.""" + + @property + def activation_date_time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата и время конвертации стоп-заявки в биржевую по UTC.""" + + @property + def expiration_time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата и время снятия заявки по UTC.""" + + @property + def price(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Цена заявки за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента.""" + + @property + def stop_price(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Цена активации стоп-заявки за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента.""" + + @property + def trailing_data(self) -> global___StopOrder.TrailingData: + """Параметры трейлинг-стопа.""" + + def __init__( + self, + *, + stop_order_id: builtins.str = ..., + lots_requested: builtins.int = ..., + figi: builtins.str = ..., + direction: global___StopOrderDirection.ValueType = ..., + currency: builtins.str = ..., + order_type: global___StopOrderType.ValueType = ..., + create_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + activation_date_time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + expiration_time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + price: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + stop_price: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + instrument_uid: builtins.str = ..., + take_profit_type: global___TakeProfitType.ValueType = ..., + trailing_data: global___StopOrder.TrailingData | None = ..., + status: global___StopOrderStatusOption.ValueType = ..., + exchange_order_type: global___ExchangeOrderType.ValueType = ..., + exchange_order_id: builtins.str | None = ..., + ticker: builtins.str = ..., + class_code: builtins.str = ..., + instant_execution: builtins.bool = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_exchange_order_id", b"_exchange_order_id", "activation_date_time", b"activation_date_time", "create_date", b"create_date", "exchange_order_id", b"exchange_order_id", "expiration_time", b"expiration_time", "price", b"price", "stop_price", b"stop_price", "trailing_data", b"trailing_data"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_exchange_order_id", b"_exchange_order_id", "activation_date_time", b"activation_date_time", "class_code", b"class_code", "create_date", b"create_date", "currency", b"currency", "direction", b"direction", "exchange_order_id", b"exchange_order_id", "exchange_order_type", b"exchange_order_type", "expiration_time", b"expiration_time", "figi", b"figi", "instant_execution", b"instant_execution", "instrument_uid", b"instrument_uid", "lots_requested", b"lots_requested", "order_type", b"order_type", "price", b"price", "status", b"status", "stop_order_id", b"stop_order_id", "stop_price", b"stop_price", "take_profit_type", b"take_profit_type", "ticker", b"ticker", "trailing_data", b"trailing_data"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_exchange_order_id", b"_exchange_order_id"]) -> typing.Literal["exchange_order_id"] | None: ... + +global___StopOrder = StopOrder diff --git a/invest-python-master/t_tech/invest/grpc/stoporders_pb2_grpc.py b/invest-python-master/t_tech/invest/grpc/stoporders_pb2_grpc.py new file mode 100644 index 0000000..667d9b5 --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/stoporders_pb2_grpc.py @@ -0,0 +1,140 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +from t_tech.invest.grpc import ( + stoporders_pb2 as t__tech_dot_invest_dot_grpc_dot_stoporders__pb2, +) + + +class StopOrdersServiceStub(object): + """Сервис для работы со стоп-заявками: выставление, отмена, получение списка стоп-заявок. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.PostStopOrder = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.StopOrdersService/PostStopOrder', + request_serializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.PostStopOrderRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.PostStopOrderResponse.FromString, + ) + self.GetStopOrders = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.StopOrdersService/GetStopOrders', + request_serializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.GetStopOrdersRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.GetStopOrdersResponse.FromString, + ) + self.CancelStopOrder = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.StopOrdersService/CancelStopOrder', + request_serializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.CancelStopOrderRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.CancelStopOrderResponse.FromString, + ) + + +class StopOrdersServiceServicer(object): + """Сервис для работы со стоп-заявками: выставление, отмена, получение списка стоп-заявок. + """ + + def PostStopOrder(self, request, context): + """PostStopOrder — выставить стоп-заявку + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetStopOrders(self, request, context): + """GetStopOrders — получить список активных стоп-заявок по счету + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def CancelStopOrder(self, request, context): + """CancelStopOrder — отменить стоп-заявку + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_StopOrdersServiceServicer_to_server(servicer, server): + rpc_method_handlers = { + 'PostStopOrder': grpc.unary_unary_rpc_method_handler( + servicer.PostStopOrder, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.PostStopOrderRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.PostStopOrderResponse.SerializeToString, + ), + 'GetStopOrders': grpc.unary_unary_rpc_method_handler( + servicer.GetStopOrders, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.GetStopOrdersRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.GetStopOrdersResponse.SerializeToString, + ), + 'CancelStopOrder': grpc.unary_unary_rpc_method_handler( + servicer.CancelStopOrder, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.CancelStopOrderRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.CancelStopOrderResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'tinkoff.public.invest.api.contract.v1.StopOrdersService', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class StopOrdersService(object): + """Сервис для работы со стоп-заявками: выставление, отмена, получение списка стоп-заявок. + """ + + @staticmethod + def PostStopOrder(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.StopOrdersService/PostStopOrder', + t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.PostStopOrderRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.PostStopOrderResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetStopOrders(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.StopOrdersService/GetStopOrders', + t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.GetStopOrdersRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.GetStopOrdersResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def CancelStopOrder(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.StopOrdersService/CancelStopOrder', + t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.CancelStopOrderRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.CancelStopOrderResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/invest-python-master/t_tech/invest/grpc/users_pb2.py b/invest-python-master/t_tech/invest/grpc/users_pb2.py new file mode 100644 index 0000000..1f2f018 --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/users_pb2.py @@ -0,0 +1,101 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: t_tech/invest/grpc/users.proto +# Protobuf Python Version: 4.25.1 +"""Generated protocol buffer code.""" +from google.protobuf import ( + descriptor as _descriptor, + descriptor_pool as _descriptor_pool, + symbol_database as _symbol_database, +) +from google.protobuf.internal import builder as _builder + +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 + +from t_tech.invest.grpc import common_pb2 as t__tech_dot_invest_dot_grpc_dot_common__pb2 +from t_tech.invest.grpc.google.api import ( + field_behavior_pb2 as t__tech_dot_invest_dot_grpc_dot_google_dot_api_dot_field__behavior__pb2, +) + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1et_tech/invest/grpc/users.proto\x12%tinkoff.public.invest.api.contract.v1\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x32t_tech/invest/grpc/google/api/field_behavior.proto\x1a\x1ft_tech/invest/grpc/common.proto\"j\n\x12GetAccountsRequest\x12I\n\x06status\x18\x01 \x01(\x0e\x32\x34.tinkoff.public.invest.api.contract.v1.AccountStatusH\x00\x88\x01\x01\x42\t\n\x07_status\"W\n\x13GetAccountsResponse\x12@\n\x08\x61\x63\x63ounts\x18\x01 \x03(\x0b\x32..tinkoff.public.invest.api.contract.v1.Account\"\xd7\x02\n\x07\x41\x63\x63ount\x12\n\n\x02id\x18\x01 \x01(\t\x12@\n\x04type\x18\x02 \x01(\x0e\x32\x32.tinkoff.public.invest.api.contract.v1.AccountType\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x44\n\x06status\x18\x04 \x01(\x0e\x32\x34.tinkoff.public.invest.api.contract.v1.AccountStatus\x12/\n\x0bopened_date\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12/\n\x0b\x63losed_date\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12H\n\x0c\x61\x63\x63\x65ss_level\x18\x07 \x01(\x0e\x32\x32.tinkoff.public.invest.api.contract.v1.AccessLevel\"6\n\x1aGetMarginAttributesRequest\x12\x18\n\naccount_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\"\xc7\x04\n\x1bGetMarginAttributesResponse\x12K\n\x10liquid_portfolio\x18\x01 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12J\n\x0fstarting_margin\x18\x02 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12I\n\x0eminimal_margin\x18\x03 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12Q\n\x17\x66unds_sufficiency_level\x18\x04 \x01(\x0b\x32\x30.tinkoff.public.invest.api.contract.v1.Quotation\x12R\n\x17\x61mount_of_missing_funds\x18\x05 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12K\n\x10\x63orrected_margin\x18\x06 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12P\n\x15guarantee_for_futures\x18\x07 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\"\x16\n\x14GetUserTariffRequest\"\xab\x01\n\x15GetUserTariffResponse\x12G\n\x0cunary_limits\x18\x01 \x03(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.UnaryLimit\x12I\n\rstream_limits\x18\x02 \x03(\x0b\x32\x32.tinkoff.public.invest.api.contract.v1.StreamLimit\"k\n\nUnaryLimit\x12\x18\n\x10limit_per_minute\x18\x01 \x01(\x05\x12\x0f\n\x07methods\x18\x02 \x03(\t\x12\x1d\n\x10limit_per_second\x18\x03 \x01(\x05H\x00\x88\x01\x01\x42\x13\n\x11_limit_per_second\";\n\x0bStreamLimit\x12\r\n\x05limit\x18\x01 \x01(\x05\x12\x0f\n\x07streams\x18\x02 \x03(\t\x12\x0c\n\x04open\x18\x03 \x01(\x05\"\x10\n\x0eGetInfoRequest\"\x96\x01\n\x0fGetInfoResponse\x12\x13\n\x0bprem_status\x18\x01 \x01(\x08\x12\x13\n\x0bqual_status\x18\x02 \x01(\x08\x12\x1f\n\x17qualified_for_work_with\x18\x03 \x03(\t\x12\x0e\n\x06tariff\x18\x04 \x01(\t\x12\x0f\n\x07user_id\x18\t \x01(\t\x12\x17\n\x0frisk_level_code\x18\x0c \x01(\t\"\x18\n\x16GetBankAccountsRequest\"d\n\x17GetBankAccountsResponse\x12I\n\rbank_accounts\x18\x01 \x03(\x0b\x32\x32.tinkoff.public.invest.api.contract.v1.BankAccount\"\xdc\x01\n\x0b\x42\x61nkAccount\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12@\n\x05money\x18\x03 \x03(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue\x12/\n\x0bopened_date\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12@\n\x04type\x18\x05 \x01(\x0e\x32\x32.tinkoff.public.invest.api.contract.v1.AccountType\"\xb6\x01\n\x17\x43urrencyTransferRequest\x12\x1d\n\x0f\x66rom_account_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\x12\x1b\n\rto_account_id\x18\x02 \x01(\tB\x04\xe2\x41\x01\x02\x12G\n\x06\x61mount\x18\x03 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValueB\x04\xe2\x41\x01\x02\x12\x16\n\x0etransaction_id\x18\x04 \x01(\t\"\x1a\n\x18\x43urrencyTransferResponse\"\x93\x01\n\x0cPayInRequest\x12\x1d\n\x0f\x66rom_account_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\x12\x1b\n\rto_account_id\x18\x02 \x01(\tB\x04\xe2\x41\x01\x02\x12G\n\x06\x61mount\x18\x03 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValueB\x04\xe2\x41\x01\x02\"\x0f\n\rPayInResponse\"p\n\x17GetAccountValuesRequest\x12\x10\n\x08\x61\x63\x63ounts\x18\x01 \x03(\t\x12\x43\n\x06values\x18\x02 \x03(\x0e\x32\x33.tinkoff.public.invest.api.contract.v1.AccountValue\"p\n\x18GetAccountValuesResponse\x12T\n\x08\x61\x63\x63ounts\x18\x01 \x03(\x0b\x32\x42.tinkoff.public.invest.api.contract.v1.AccountValuesWithParameters\"}\n\x1b\x41\x63\x63ountValuesWithParameters\x12\x12\n\naccount_id\x18\x01 \x01(\t\x12J\n\x06values\x18\x02 \x03(\x0b\x32:.tinkoff.public.invest.api.contract.v1.InstrumentParameter\"\x9a\x01\n\x13InstrumentParameter\x12\x41\n\x04name\x18\x01 \x01(\x0e\x32\x33.tinkoff.public.invest.api.contract.v1.AccountValue\x12@\n\x05value\x18\x02 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue*\xe5\x01\n\x0b\x41\x63\x63ountType\x12\x1c\n\x18\x41\x43\x43OUNT_TYPE_UNSPECIFIED\x10\x00\x12\x18\n\x14\x41\x43\x43OUNT_TYPE_TINKOFF\x10\x01\x12\x1c\n\x18\x41\x43\x43OUNT_TYPE_TINKOFF_IIS\x10\x02\x12\x1b\n\x17\x41\x43\x43OUNT_TYPE_INVEST_BOX\x10\x03\x12\x1c\n\x18\x41\x43\x43OUNT_TYPE_INVEST_FUND\x10\x04\x12\x16\n\x12\x41\x43\x43OUNT_TYPE_DEBIT\x10\x05\x12\x17\n\x13\x41\x43\x43OUNT_TYPE_SAVING\x10\x06\x12\x14\n\x10\x41\x43\x43OUNT_TYPE_DFA\x10\x07*\x93\x01\n\rAccountStatus\x12\x1e\n\x1a\x41\x43\x43OUNT_STATUS_UNSPECIFIED\x10\x00\x12\x16\n\x12\x41\x43\x43OUNT_STATUS_NEW\x10\x01\x12\x17\n\x13\x41\x43\x43OUNT_STATUS_OPEN\x10\x02\x12\x19\n\x15\x41\x43\x43OUNT_STATUS_CLOSED\x10\x03\x12\x16\n\x12\x41\x43\x43OUNT_STATUS_ALL\x10\x04*\xa1\x01\n\x0b\x41\x63\x63\x65ssLevel\x12$\n ACCOUNT_ACCESS_LEVEL_UNSPECIFIED\x10\x00\x12$\n ACCOUNT_ACCESS_LEVEL_FULL_ACCESS\x10\x01\x12\"\n\x1e\x41\x43\x43OUNT_ACCESS_LEVEL_READ_ONLY\x10\x02\x12\"\n\x1e\x41\x43\x43OUNT_ACCESS_LEVEL_NO_ACCESS\x10\x03*w\n\x0c\x41\x63\x63ountValue\x12\x1d\n\x19\x41\x43\x43OUNT_VALUE_UNSPECIFIED\x10\x00\x12\x1c\n\x18\x41\x43\x43OUNT_VALUE_MARGIN_FEE\x10\x01\x12*\n&ACCOUNT_VALUE_AMOUNT_WITHOUT_EXTRA_FEE\x10\x02\x32\xee\x08\n\x0cUsersService\x12\x84\x01\n\x0bGetAccounts\x12\x39.tinkoff.public.invest.api.contract.v1.GetAccountsRequest\x1a:.tinkoff.public.invest.api.contract.v1.GetAccountsResponse\x12\x9c\x01\n\x13GetMarginAttributes\x12\x41.tinkoff.public.invest.api.contract.v1.GetMarginAttributesRequest\x1a\x42.tinkoff.public.invest.api.contract.v1.GetMarginAttributesResponse\x12\x8a\x01\n\rGetUserTariff\x12;.tinkoff.public.invest.api.contract.v1.GetUserTariffRequest\x1a<.tinkoff.public.invest.api.contract.v1.GetUserTariffResponse\x12x\n\x07GetInfo\x12\x35.tinkoff.public.invest.api.contract.v1.GetInfoRequest\x1a\x36.tinkoff.public.invest.api.contract.v1.GetInfoResponse\x12\x90\x01\n\x0fGetBankAccounts\x12=.tinkoff.public.invest.api.contract.v1.GetBankAccountsRequest\x1a>.tinkoff.public.invest.api.contract.v1.GetBankAccountsResponse\x12\x93\x01\n\x10\x43urrencyTransfer\x12>.tinkoff.public.invest.api.contract.v1.CurrencyTransferRequest\x1a?.tinkoff.public.invest.api.contract.v1.CurrencyTransferResponse\x12r\n\x05PayIn\x12\x33.tinkoff.public.invest.api.contract.v1.PayInRequest\x1a\x34.tinkoff.public.invest.api.contract.v1.PayInResponse\x12\x93\x01\n\x10GetAccountValues\x12>.tinkoff.public.invest.api.contract.v1.GetAccountValuesRequest\x1a?.tinkoff.public.invest.api.contract.v1.GetAccountValuesResponseBa\n\x1cru.tinkoff.piapi.contract.v1P\x01Z\x0c./;investapi\xa2\x02\x05TIAPI\xaa\x02\x14Tinkoff.InvestApi.V1\xca\x02\x11Tinkoff\\Invest\\V1b\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 't_tech.invest.grpc.users_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\034ru.tinkoff.piapi.contract.v1P\001Z\014./;investapi\242\002\005TIAPI\252\002\024Tinkoff.InvestApi.V1\312\002\021Tinkoff\\Invest\\V1' + _globals['_GETMARGINATTRIBUTESREQUEST'].fields_by_name['account_id']._options = None + _globals['_GETMARGINATTRIBUTESREQUEST'].fields_by_name['account_id']._serialized_options = b'\342A\001\002' + _globals['_CURRENCYTRANSFERREQUEST'].fields_by_name['from_account_id']._options = None + _globals['_CURRENCYTRANSFERREQUEST'].fields_by_name['from_account_id']._serialized_options = b'\342A\001\002' + _globals['_CURRENCYTRANSFERREQUEST'].fields_by_name['to_account_id']._options = None + _globals['_CURRENCYTRANSFERREQUEST'].fields_by_name['to_account_id']._serialized_options = b'\342A\001\002' + _globals['_CURRENCYTRANSFERREQUEST'].fields_by_name['amount']._options = None + _globals['_CURRENCYTRANSFERREQUEST'].fields_by_name['amount']._serialized_options = b'\342A\001\002' + _globals['_PAYINREQUEST'].fields_by_name['from_account_id']._options = None + _globals['_PAYINREQUEST'].fields_by_name['from_account_id']._serialized_options = b'\342A\001\002' + _globals['_PAYINREQUEST'].fields_by_name['to_account_id']._options = None + _globals['_PAYINREQUEST'].fields_by_name['to_account_id']._serialized_options = b'\342A\001\002' + _globals['_PAYINREQUEST'].fields_by_name['amount']._options = None + _globals['_PAYINREQUEST'].fields_by_name['amount']._serialized_options = b'\342A\001\002' + _globals['_ACCOUNTTYPE']._serialized_start=3159 + _globals['_ACCOUNTTYPE']._serialized_end=3388 + _globals['_ACCOUNTSTATUS']._serialized_start=3391 + _globals['_ACCOUNTSTATUS']._serialized_end=3538 + _globals['_ACCESSLEVEL']._serialized_start=3541 + _globals['_ACCESSLEVEL']._serialized_end=3702 + _globals['_ACCOUNTVALUE']._serialized_start=3704 + _globals['_ACCOUNTVALUE']._serialized_end=3823 + _globals['_GETACCOUNTSREQUEST']._serialized_start=191 + _globals['_GETACCOUNTSREQUEST']._serialized_end=297 + _globals['_GETACCOUNTSRESPONSE']._serialized_start=299 + _globals['_GETACCOUNTSRESPONSE']._serialized_end=386 + _globals['_ACCOUNT']._serialized_start=389 + _globals['_ACCOUNT']._serialized_end=732 + _globals['_GETMARGINATTRIBUTESREQUEST']._serialized_start=734 + _globals['_GETMARGINATTRIBUTESREQUEST']._serialized_end=788 + _globals['_GETMARGINATTRIBUTESRESPONSE']._serialized_start=791 + _globals['_GETMARGINATTRIBUTESRESPONSE']._serialized_end=1374 + _globals['_GETUSERTARIFFREQUEST']._serialized_start=1376 + _globals['_GETUSERTARIFFREQUEST']._serialized_end=1398 + _globals['_GETUSERTARIFFRESPONSE']._serialized_start=1401 + _globals['_GETUSERTARIFFRESPONSE']._serialized_end=1572 + _globals['_UNARYLIMIT']._serialized_start=1574 + _globals['_UNARYLIMIT']._serialized_end=1681 + _globals['_STREAMLIMIT']._serialized_start=1683 + _globals['_STREAMLIMIT']._serialized_end=1742 + _globals['_GETINFOREQUEST']._serialized_start=1744 + _globals['_GETINFOREQUEST']._serialized_end=1760 + _globals['_GETINFORESPONSE']._serialized_start=1763 + _globals['_GETINFORESPONSE']._serialized_end=1913 + _globals['_GETBANKACCOUNTSREQUEST']._serialized_start=1915 + _globals['_GETBANKACCOUNTSREQUEST']._serialized_end=1939 + _globals['_GETBANKACCOUNTSRESPONSE']._serialized_start=1941 + _globals['_GETBANKACCOUNTSRESPONSE']._serialized_end=2041 + _globals['_BANKACCOUNT']._serialized_start=2044 + _globals['_BANKACCOUNT']._serialized_end=2264 + _globals['_CURRENCYTRANSFERREQUEST']._serialized_start=2267 + _globals['_CURRENCYTRANSFERREQUEST']._serialized_end=2449 + _globals['_CURRENCYTRANSFERRESPONSE']._serialized_start=2451 + _globals['_CURRENCYTRANSFERRESPONSE']._serialized_end=2477 + _globals['_PAYINREQUEST']._serialized_start=2480 + _globals['_PAYINREQUEST']._serialized_end=2627 + _globals['_PAYINRESPONSE']._serialized_start=2629 + _globals['_PAYINRESPONSE']._serialized_end=2644 + _globals['_GETACCOUNTVALUESREQUEST']._serialized_start=2646 + _globals['_GETACCOUNTVALUESREQUEST']._serialized_end=2758 + _globals['_GETACCOUNTVALUESRESPONSE']._serialized_start=2760 + _globals['_GETACCOUNTVALUESRESPONSE']._serialized_end=2872 + _globals['_ACCOUNTVALUESWITHPARAMETERS']._serialized_start=2874 + _globals['_ACCOUNTVALUESWITHPARAMETERS']._serialized_end=2999 + _globals['_INSTRUMENTPARAMETER']._serialized_start=3002 + _globals['_INSTRUMENTPARAMETER']._serialized_end=3156 + _globals['_USERSSERVICE']._serialized_start=3826 + _globals['_USERSSERVICE']._serialized_end=4960 +# @@protoc_insertion_point(module_scope) diff --git a/invest-python-master/t_tech/invest/grpc/users_pb2.pyi b/invest-python-master/t_tech/invest/grpc/users_pb2.pyi new file mode 100644 index 0000000..98f55f7 --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/users_pb2.pyi @@ -0,0 +1,695 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" + +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.internal.enum_type_wrapper +import google.protobuf.message +import google.protobuf.timestamp_pb2 +import sys +import t_tech.invest.grpc.common_pb2 +import typing + +if sys.version_info >= (3, 10): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +class _AccountType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _AccountTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_AccountType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + ACCOUNT_TYPE_UNSPECIFIED: _AccountType.ValueType # 0 + """Тип аккаунта не определeн.""" + ACCOUNT_TYPE_TINKOFF: _AccountType.ValueType # 1 + """Брокерский счeт Т-Инвестиций.""" + ACCOUNT_TYPE_TINKOFF_IIS: _AccountType.ValueType # 2 + """ИИС.""" + ACCOUNT_TYPE_INVEST_BOX: _AccountType.ValueType # 3 + """Инвесткопилка.""" + ACCOUNT_TYPE_INVEST_FUND: _AccountType.ValueType # 4 + """Фонд денежного рынка.""" + ACCOUNT_TYPE_DEBIT: _AccountType.ValueType # 5 + """Дебетовый карточный счeт.""" + ACCOUNT_TYPE_SAVING: _AccountType.ValueType # 6 + """Накопительный счeт.""" + ACCOUNT_TYPE_DFA: _AccountType.ValueType # 7 + """Смарт-счет.""" + +class AccountType(_AccountType, metaclass=_AccountTypeEnumTypeWrapper): + """Тип счeта.""" + +ACCOUNT_TYPE_UNSPECIFIED: AccountType.ValueType # 0 +"""Тип аккаунта не определeн.""" +ACCOUNT_TYPE_TINKOFF: AccountType.ValueType # 1 +"""Брокерский счeт Т-Инвестиций.""" +ACCOUNT_TYPE_TINKOFF_IIS: AccountType.ValueType # 2 +"""ИИС.""" +ACCOUNT_TYPE_INVEST_BOX: AccountType.ValueType # 3 +"""Инвесткопилка.""" +ACCOUNT_TYPE_INVEST_FUND: AccountType.ValueType # 4 +"""Фонд денежного рынка.""" +ACCOUNT_TYPE_DEBIT: AccountType.ValueType # 5 +"""Дебетовый карточный счeт.""" +ACCOUNT_TYPE_SAVING: AccountType.ValueType # 6 +"""Накопительный счeт.""" +ACCOUNT_TYPE_DFA: AccountType.ValueType # 7 +"""Смарт-счет.""" +global___AccountType = AccountType + +class _AccountStatus: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _AccountStatusEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_AccountStatus.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + ACCOUNT_STATUS_UNSPECIFIED: _AccountStatus.ValueType # 0 + """Статус счeта не определeн.""" + ACCOUNT_STATUS_NEW: _AccountStatus.ValueType # 1 + """Новый, в процессе открытия.""" + ACCOUNT_STATUS_OPEN: _AccountStatus.ValueType # 2 + """Открытый и активный счeт.""" + ACCOUNT_STATUS_CLOSED: _AccountStatus.ValueType # 3 + """Закрытый счeт.""" + ACCOUNT_STATUS_ALL: _AccountStatus.ValueType # 4 + """Все счета.""" + +class AccountStatus(_AccountStatus, metaclass=_AccountStatusEnumTypeWrapper): + """Статус счeта.""" + +ACCOUNT_STATUS_UNSPECIFIED: AccountStatus.ValueType # 0 +"""Статус счeта не определeн.""" +ACCOUNT_STATUS_NEW: AccountStatus.ValueType # 1 +"""Новый, в процессе открытия.""" +ACCOUNT_STATUS_OPEN: AccountStatus.ValueType # 2 +"""Открытый и активный счeт.""" +ACCOUNT_STATUS_CLOSED: AccountStatus.ValueType # 3 +"""Закрытый счeт.""" +ACCOUNT_STATUS_ALL: AccountStatus.ValueType # 4 +"""Все счета.""" +global___AccountStatus = AccountStatus + +class _AccessLevel: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _AccessLevelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_AccessLevel.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + ACCOUNT_ACCESS_LEVEL_UNSPECIFIED: _AccessLevel.ValueType # 0 + """Уровень доступа не определeн.""" + ACCOUNT_ACCESS_LEVEL_FULL_ACCESS: _AccessLevel.ValueType # 1 + """Полный доступ к счeту.""" + ACCOUNT_ACCESS_LEVEL_READ_ONLY: _AccessLevel.ValueType # 2 + """Доступ с уровнем прав «только чтение».""" + ACCOUNT_ACCESS_LEVEL_NO_ACCESS: _AccessLevel.ValueType # 3 + """Доступа нет.""" + +class AccessLevel(_AccessLevel, metaclass=_AccessLevelEnumTypeWrapper): + """Уровень доступа к счeту.""" + +ACCOUNT_ACCESS_LEVEL_UNSPECIFIED: AccessLevel.ValueType # 0 +"""Уровень доступа не определeн.""" +ACCOUNT_ACCESS_LEVEL_FULL_ACCESS: AccessLevel.ValueType # 1 +"""Полный доступ к счeту.""" +ACCOUNT_ACCESS_LEVEL_READ_ONLY: AccessLevel.ValueType # 2 +"""Доступ с уровнем прав «только чтение».""" +ACCOUNT_ACCESS_LEVEL_NO_ACCESS: AccessLevel.ValueType # 3 +"""Доступа нет.""" +global___AccessLevel = AccessLevel + +class _AccountValue: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _AccountValueEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_AccountValue.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + ACCOUNT_VALUE_UNSPECIFIED: _AccountValue.ValueType # 0 + """Не определён.""" + ACCOUNT_VALUE_MARGIN_FEE: _AccountValue.ValueType # 1 + """Размер комиссии за маржинальное кредитование.""" + ACCOUNT_VALUE_AMOUNT_WITHOUT_EXTRA_FEE: _AccountValue.ValueType # 2 + """Остаток доступного лимита с текущей комиссией.""" + +class AccountValue(_AccountValue, metaclass=_AccountValueEnumTypeWrapper): ... + +ACCOUNT_VALUE_UNSPECIFIED: AccountValue.ValueType # 0 +"""Не определён.""" +ACCOUNT_VALUE_MARGIN_FEE: AccountValue.ValueType # 1 +"""Размер комиссии за маржинальное кредитование.""" +ACCOUNT_VALUE_AMOUNT_WITHOUT_EXTRA_FEE: AccountValue.ValueType # 2 +"""Остаток доступного лимита с текущей комиссией.""" +global___AccountValue = AccountValue + +@typing.final +class GetAccountsRequest(google.protobuf.message.Message): + """Запрос получения счетов пользователя.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + STATUS_FIELD_NUMBER: builtins.int + status: global___AccountStatus.ValueType + """Статус счета.""" + def __init__( + self, + *, + status: global___AccountStatus.ValueType | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_status", b"_status", "status", b"status"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_status", b"_status", "status", b"status"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_status", b"_status"]) -> typing.Literal["status"] | None: ... + +global___GetAccountsRequest = GetAccountsRequest + +@typing.final +class GetAccountsResponse(google.protobuf.message.Message): + """Список счетов пользователя.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNTS_FIELD_NUMBER: builtins.int + @property + def accounts(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Account]: + """Массив счетов клиента.""" + + def __init__( + self, + *, + accounts: collections.abc.Iterable[global___Account] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["accounts", b"accounts"]) -> None: ... + +global___GetAccountsResponse = GetAccountsResponse + +@typing.final +class Account(google.protobuf.message.Message): + """Информация о счeте.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ID_FIELD_NUMBER: builtins.int + TYPE_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + STATUS_FIELD_NUMBER: builtins.int + OPENED_DATE_FIELD_NUMBER: builtins.int + CLOSED_DATE_FIELD_NUMBER: builtins.int + ACCESS_LEVEL_FIELD_NUMBER: builtins.int + id: builtins.str + """Идентификатор счeта.""" + type: global___AccountType.ValueType + """Тип счeта.""" + name: builtins.str + """Название счeта.""" + status: global___AccountStatus.ValueType + """Статус счeта.""" + access_level: global___AccessLevel.ValueType + """Уровень доступа к текущему счeту (определяется токеном).""" + @property + def opened_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата открытия счeта в часовом поясе UTC.""" + + @property + def closed_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата закрытия счeта в часовом поясе UTC.""" + + def __init__( + self, + *, + id: builtins.str = ..., + type: global___AccountType.ValueType = ..., + name: builtins.str = ..., + status: global___AccountStatus.ValueType = ..., + opened_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + closed_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + access_level: global___AccessLevel.ValueType = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["closed_date", b"closed_date", "opened_date", b"opened_date"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["access_level", b"access_level", "closed_date", b"closed_date", "id", b"id", "name", b"name", "opened_date", b"opened_date", "status", b"status", "type", b"type"]) -> None: ... + +global___Account = Account + +@typing.final +class GetMarginAttributesRequest(google.protobuf.message.Message): + """Запрос маржинальных показателей по счeту.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNT_ID_FIELD_NUMBER: builtins.int + account_id: builtins.str + """Идентификатор счeта пользователя.""" + def __init__( + self, + *, + account_id: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["account_id", b"account_id"]) -> None: ... + +global___GetMarginAttributesRequest = GetMarginAttributesRequest + +@typing.final +class GetMarginAttributesResponse(google.protobuf.message.Message): + """Маржинальные показатели по счeту.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + LIQUID_PORTFOLIO_FIELD_NUMBER: builtins.int + STARTING_MARGIN_FIELD_NUMBER: builtins.int + MINIMAL_MARGIN_FIELD_NUMBER: builtins.int + FUNDS_SUFFICIENCY_LEVEL_FIELD_NUMBER: builtins.int + AMOUNT_OF_MISSING_FUNDS_FIELD_NUMBER: builtins.int + CORRECTED_MARGIN_FIELD_NUMBER: builtins.int + GUARANTEE_FOR_FUTURES_FIELD_NUMBER: builtins.int + @property + def liquid_portfolio(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Ликвидная стоимость портфеля. [Подробнее про ликвидный портфель](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q4).""" + + @property + def starting_margin(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Начальная маржа — начальное обеспечение для совершения новой сделки. [Подробнее про начальную и минимальную маржу](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q6).""" + + @property + def minimal_margin(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Минимальная маржа — это минимальное обеспечение для поддержания позиции, которую вы уже открыли. [Подробнее про начальную и минимальную маржу](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q6).""" + + @property + def funds_sufficiency_level(self) -> t_tech.invest.grpc.common_pb2.Quotation: + """Уровень достаточности средств. Соотношение стоимости ликвидного портфеля к начальной марже.""" + + @property + def amount_of_missing_funds(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Объем недостающих средств. Разница между стартовой маржой и ликвидной стоимости портфеля.""" + + @property + def corrected_margin(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Скорректированная маржа. Начальная маржа, в которой плановые позиции рассчитываются с учeтом активных заявок на покупку позиций лонг или продажу позиций шорт.""" + + @property + def guarantee_for_futures(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Размер гарантийного обеспечения, заблокированного под фьючерсы.""" + + def __init__( + self, + *, + liquid_portfolio: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + starting_margin: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + minimal_margin: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + funds_sufficiency_level: t_tech.invest.grpc.common_pb2.Quotation | None = ..., + amount_of_missing_funds: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + corrected_margin: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + guarantee_for_futures: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["amount_of_missing_funds", b"amount_of_missing_funds", "corrected_margin", b"corrected_margin", "funds_sufficiency_level", b"funds_sufficiency_level", "guarantee_for_futures", b"guarantee_for_futures", "liquid_portfolio", b"liquid_portfolio", "minimal_margin", b"minimal_margin", "starting_margin", b"starting_margin"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["amount_of_missing_funds", b"amount_of_missing_funds", "corrected_margin", b"corrected_margin", "funds_sufficiency_level", b"funds_sufficiency_level", "guarantee_for_futures", b"guarantee_for_futures", "liquid_portfolio", b"liquid_portfolio", "minimal_margin", b"minimal_margin", "starting_margin", b"starting_margin"]) -> None: ... + +global___GetMarginAttributesResponse = GetMarginAttributesResponse + +@typing.final +class GetUserTariffRequest(google.protobuf.message.Message): + """Запрос текущих лимитов пользователя.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + def __init__( + self, + ) -> None: ... + +global___GetUserTariffRequest = GetUserTariffRequest + +@typing.final +class GetUserTariffResponse(google.protobuf.message.Message): + """Текущие лимиты пользователя.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + UNARY_LIMITS_FIELD_NUMBER: builtins.int + STREAM_LIMITS_FIELD_NUMBER: builtins.int + @property + def unary_limits(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___UnaryLimit]: + """Массив лимитов пользователя по unary-запросам.""" + + @property + def stream_limits(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___StreamLimit]: + """Массив лимитов пользователей для stream-соединений.""" + + def __init__( + self, + *, + unary_limits: collections.abc.Iterable[global___UnaryLimit] | None = ..., + stream_limits: collections.abc.Iterable[global___StreamLimit] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["stream_limits", b"stream_limits", "unary_limits", b"unary_limits"]) -> None: ... + +global___GetUserTariffResponse = GetUserTariffResponse + +@typing.final +class UnaryLimit(google.protobuf.message.Message): + """Лимит unary-методов.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + LIMIT_PER_MINUTE_FIELD_NUMBER: builtins.int + METHODS_FIELD_NUMBER: builtins.int + LIMIT_PER_SECOND_FIELD_NUMBER: builtins.int + limit_per_minute: builtins.int + """Количество unary-запросов в минуту.""" + limit_per_second: builtins.int + """Количество unary-запросов в секунду.""" + @property + def methods(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Названия методов.""" + + def __init__( + self, + *, + limit_per_minute: builtins.int = ..., + methods: collections.abc.Iterable[builtins.str] | None = ..., + limit_per_second: builtins.int | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_limit_per_second", b"_limit_per_second", "limit_per_second", b"limit_per_second"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_limit_per_second", b"_limit_per_second", "limit_per_minute", b"limit_per_minute", "limit_per_second", b"limit_per_second", "methods", b"methods"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_limit_per_second", b"_limit_per_second"]) -> typing.Literal["limit_per_second"] | None: ... + +global___UnaryLimit = UnaryLimit + +@typing.final +class StreamLimit(google.protobuf.message.Message): + """Лимит stream-соединений.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + LIMIT_FIELD_NUMBER: builtins.int + STREAMS_FIELD_NUMBER: builtins.int + OPEN_FIELD_NUMBER: builtins.int + limit: builtins.int + """Максимальное количество stream-соединений.""" + open: builtins.int + """Текущее количество открытых stream-соединений.""" + @property + def streams(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Названия stream-методов.""" + + def __init__( + self, + *, + limit: builtins.int = ..., + streams: collections.abc.Iterable[builtins.str] | None = ..., + open: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["limit", b"limit", "open", b"open", "streams", b"streams"]) -> None: ... + +global___StreamLimit = StreamLimit + +@typing.final +class GetInfoRequest(google.protobuf.message.Message): + """Запрос информации о пользователе.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + def __init__( + self, + ) -> None: ... + +global___GetInfoRequest = GetInfoRequest + +@typing.final +class GetInfoResponse(google.protobuf.message.Message): + """Информация о пользователе.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PREM_STATUS_FIELD_NUMBER: builtins.int + QUAL_STATUS_FIELD_NUMBER: builtins.int + QUALIFIED_FOR_WORK_WITH_FIELD_NUMBER: builtins.int + TARIFF_FIELD_NUMBER: builtins.int + USER_ID_FIELD_NUMBER: builtins.int + RISK_LEVEL_CODE_FIELD_NUMBER: builtins.int + prem_status: builtins.bool + """Признак премиум клиента.""" + qual_status: builtins.bool + """Признак квалифицированного инвестора.""" + tariff: builtins.str + """Наименование тарифа пользователя.""" + user_id: builtins.str + """Идентификатор пользователя.""" + risk_level_code: builtins.str + """Категория риска.""" + @property + def qualified_for_work_with(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Набор требующих тестирования инструментов и возможностей, с которыми может работать пользователь. [Подробнее](/invest/services/accounts/faq_users).""" + + def __init__( + self, + *, + prem_status: builtins.bool = ..., + qual_status: builtins.bool = ..., + qualified_for_work_with: collections.abc.Iterable[builtins.str] | None = ..., + tariff: builtins.str = ..., + user_id: builtins.str = ..., + risk_level_code: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["prem_status", b"prem_status", "qual_status", b"qual_status", "qualified_for_work_with", b"qualified_for_work_with", "risk_level_code", b"risk_level_code", "tariff", b"tariff", "user_id", b"user_id"]) -> None: ... + +global___GetInfoResponse = GetInfoResponse + +@typing.final +class GetBankAccountsRequest(google.protobuf.message.Message): + """Запрос списка банковских счетов пользователя.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + def __init__( + self, + ) -> None: ... + +global___GetBankAccountsRequest = GetBankAccountsRequest + +@typing.final +class GetBankAccountsResponse(google.protobuf.message.Message): + """Список банковских счетов пользователя.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + BANK_ACCOUNTS_FIELD_NUMBER: builtins.int + @property + def bank_accounts(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___BankAccount]: + """Массив банковских счетов.""" + + def __init__( + self, + *, + bank_accounts: collections.abc.Iterable[global___BankAccount] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["bank_accounts", b"bank_accounts"]) -> None: ... + +global___GetBankAccountsResponse = GetBankAccountsResponse + +@typing.final +class BankAccount(google.protobuf.message.Message): + """Банковский счeт.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ID_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + MONEY_FIELD_NUMBER: builtins.int + OPENED_DATE_FIELD_NUMBER: builtins.int + TYPE_FIELD_NUMBER: builtins.int + id: builtins.str + """Идентификатор счeта.""" + name: builtins.str + """Название счeта.""" + type: global___AccountType.ValueType + """Тип счeта.""" + @property + def money(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[t_tech.invest.grpc.common_pb2.MoneyValue]: + """Список валютных позиций на счeте.""" + + @property + def opened_date(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Дата открытия счeта в часовом поясе UTC.""" + + def __init__( + self, + *, + id: builtins.str = ..., + name: builtins.str = ..., + money: collections.abc.Iterable[t_tech.invest.grpc.common_pb2.MoneyValue] | None = ..., + opened_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., + type: global___AccountType.ValueType = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["opened_date", b"opened_date"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["id", b"id", "money", b"money", "name", b"name", "opened_date", b"opened_date", "type", b"type"]) -> None: ... + +global___BankAccount = BankAccount + +@typing.final +class CurrencyTransferRequest(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FROM_ACCOUNT_ID_FIELD_NUMBER: builtins.int + TO_ACCOUNT_ID_FIELD_NUMBER: builtins.int + AMOUNT_FIELD_NUMBER: builtins.int + TRANSACTION_ID_FIELD_NUMBER: builtins.int + from_account_id: builtins.str + """Номер счета списания.""" + to_account_id: builtins.str + """Номер счета зачисления.""" + transaction_id: builtins.str + """Идентификатор запроса выставления поручения для целей идемпотентности в формате UUID.""" + @property + def amount(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Сумма перевода с указанием валюты.""" + + def __init__( + self, + *, + from_account_id: builtins.str = ..., + to_account_id: builtins.str = ..., + amount: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + transaction_id: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["amount", b"amount"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["amount", b"amount", "from_account_id", b"from_account_id", "to_account_id", b"to_account_id", "transaction_id", b"transaction_id"]) -> None: ... + +global___CurrencyTransferRequest = CurrencyTransferRequest + +@typing.final +class CurrencyTransferResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + def __init__( + self, + ) -> None: ... + +global___CurrencyTransferResponse = CurrencyTransferResponse + +@typing.final +class PayInRequest(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FROM_ACCOUNT_ID_FIELD_NUMBER: builtins.int + TO_ACCOUNT_ID_FIELD_NUMBER: builtins.int + AMOUNT_FIELD_NUMBER: builtins.int + from_account_id: builtins.str + """Номер счета списания.""" + to_account_id: builtins.str + """Номер брокерского счета зачисления.""" + @property + def amount(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Сумма перевода с указанием валюты.""" + + def __init__( + self, + *, + from_account_id: builtins.str = ..., + to_account_id: builtins.str = ..., + amount: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["amount", b"amount"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["amount", b"amount", "from_account_id", b"from_account_id", "to_account_id", b"to_account_id"]) -> None: ... + +global___PayInRequest = PayInRequest + +@typing.final +class PayInResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + def __init__( + self, + ) -> None: ... + +global___PayInResponse = PayInResponse + +@typing.final +class GetAccountValuesRequest(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNTS_FIELD_NUMBER: builtins.int + VALUES_FIELD_NUMBER: builtins.int + @property + def accounts(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Массив счетов пользователя.""" + + @property + def values(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[global___AccountValue.ValueType]: + """Массив запрашиваемых параметров.""" + + def __init__( + self, + *, + accounts: collections.abc.Iterable[builtins.str] | None = ..., + values: collections.abc.Iterable[global___AccountValue.ValueType] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["accounts", b"accounts", "values", b"values"]) -> None: ... + +global___GetAccountValuesRequest = GetAccountValuesRequest + +@typing.final +class GetAccountValuesResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNTS_FIELD_NUMBER: builtins.int + @property + def accounts(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___AccountValuesWithParameters]: + """Массив счетов с параметрами.""" + + def __init__( + self, + *, + accounts: collections.abc.Iterable[global___AccountValuesWithParameters] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["accounts", b"accounts"]) -> None: ... + +global___GetAccountValuesResponse = GetAccountValuesResponse + +@typing.final +class AccountValuesWithParameters(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNT_ID_FIELD_NUMBER: builtins.int + VALUES_FIELD_NUMBER: builtins.int + account_id: builtins.str + """Номер счета.""" + @property + def values(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___InstrumentParameter]: + """Массив параметров инструмента.""" + + def __init__( + self, + *, + account_id: builtins.str = ..., + values: collections.abc.Iterable[global___InstrumentParameter] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["account_id", b"account_id", "values", b"values"]) -> None: ... + +global___AccountValuesWithParameters = AccountValuesWithParameters + +@typing.final +class InstrumentParameter(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + NAME_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + name: global___AccountValue.ValueType + """Тип запрашиваемого параметра.""" + @property + def value(self) -> t_tech.invest.grpc.common_pb2.MoneyValue: + """Значение запрашиваемого параметра.""" + + def __init__( + self, + *, + name: global___AccountValue.ValueType = ..., + value: t_tech.invest.grpc.common_pb2.MoneyValue | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["name", b"name", "value", b"value"]) -> None: ... + +global___InstrumentParameter = InstrumentParameter diff --git a/invest-python-master/t_tech/invest/grpc/users_pb2_grpc.py b/invest-python-master/t_tech/invest/grpc/users_pb2_grpc.py new file mode 100644 index 0000000..d2330d5 --- /dev/null +++ b/invest-python-master/t_tech/invest/grpc/users_pb2_grpc.py @@ -0,0 +1,319 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +from t_tech.invest.grpc import users_pb2 as t__tech_dot_invest_dot_grpc_dot_users__pb2 + + +class UsersServiceStub(object): + """С помощью сервиса можно получить:
1. + список счетов пользователя;
2. маржинальные показатели по счeту. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.GetAccounts = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.UsersService/GetAccounts', + request_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountsResponse.FromString, + ) + self.GetMarginAttributes = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.UsersService/GetMarginAttributes', + request_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetMarginAttributesRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetMarginAttributesResponse.FromString, + ) + self.GetUserTariff = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.UsersService/GetUserTariff', + request_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetUserTariffRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetUserTariffResponse.FromString, + ) + self.GetInfo = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.UsersService/GetInfo', + request_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetInfoRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetInfoResponse.FromString, + ) + self.GetBankAccounts = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.UsersService/GetBankAccounts', + request_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetBankAccountsRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetBankAccountsResponse.FromString, + ) + self.CurrencyTransfer = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.UsersService/CurrencyTransfer', + request_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.CurrencyTransferRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.CurrencyTransferResponse.FromString, + ) + self.PayIn = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.UsersService/PayIn', + request_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.PayInRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.PayInResponse.FromString, + ) + self.GetAccountValues = channel.unary_unary( + '/tinkoff.public.invest.api.contract.v1.UsersService/GetAccountValues', + request_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountValuesRequest.SerializeToString, + response_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountValuesResponse.FromString, + ) + + +class UsersServiceServicer(object): + """С помощью сервиса можно получить:
1. + список счетов пользователя;
2. маржинальные показатели по счeту. + """ + + def GetAccounts(self, request, context): + """GetAccounts — счета пользователя + Получить список счетов. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetMarginAttributes(self, request, context): + """GetMarginAttributes — маржинальные показатели по счeту + Метод позволяет получить маржинальные показатели и ликвидность по заданному счeту. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetUserTariff(self, request, context): + """GetUserTariff — тариф пользователя + Получить информацию о текущих лимитах на подклчение, согласно текущему тарифу пользователя. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetInfo(self, request, context): + """GetInfo — информация о пользователе + Получить информацию о пользователе: тариф, признак квалификации, пройденные тесты и др. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetBankAccounts(self, request, context): + """GetBankAccounts — банковские счета пользователя + Получить список счетов пользователя, в том числе и банковских. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def CurrencyTransfer(self, request, context): + """CurrencyTransfer — перевод денежных средств между счетами + Перевести денежные средства между брокерскими счетами + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def PayIn(self, request, context): + """PayIn — пополнение брокерского счета + Пополнить брокерский счёт с банковского + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetAccountValues(self, request, context): + """GetAccountValues — дополнительные показатели счетов + Метод предназначен для получения дополнительных показателей счетов + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_UsersServiceServicer_to_server(servicer, server): + rpc_method_handlers = { + 'GetAccounts': grpc.unary_unary_rpc_method_handler( + servicer.GetAccounts, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountsResponse.SerializeToString, + ), + 'GetMarginAttributes': grpc.unary_unary_rpc_method_handler( + servicer.GetMarginAttributes, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetMarginAttributesRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetMarginAttributesResponse.SerializeToString, + ), + 'GetUserTariff': grpc.unary_unary_rpc_method_handler( + servicer.GetUserTariff, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetUserTariffRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetUserTariffResponse.SerializeToString, + ), + 'GetInfo': grpc.unary_unary_rpc_method_handler( + servicer.GetInfo, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetInfoRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetInfoResponse.SerializeToString, + ), + 'GetBankAccounts': grpc.unary_unary_rpc_method_handler( + servicer.GetBankAccounts, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetBankAccountsRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetBankAccountsResponse.SerializeToString, + ), + 'CurrencyTransfer': grpc.unary_unary_rpc_method_handler( + servicer.CurrencyTransfer, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.CurrencyTransferRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.CurrencyTransferResponse.SerializeToString, + ), + 'PayIn': grpc.unary_unary_rpc_method_handler( + servicer.PayIn, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.PayInRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.PayInResponse.SerializeToString, + ), + 'GetAccountValues': grpc.unary_unary_rpc_method_handler( + servicer.GetAccountValues, + request_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountValuesRequest.FromString, + response_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountValuesResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'tinkoff.public.invest.api.contract.v1.UsersService', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class UsersService(object): + """С помощью сервиса можно получить:
1. + список счетов пользователя;
2. маржинальные показатели по счeту. + """ + + @staticmethod + def GetAccounts(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.UsersService/GetAccounts', + t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetMarginAttributes(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.UsersService/GetMarginAttributes', + t__tech_dot_invest_dot_grpc_dot_users__pb2.GetMarginAttributesRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_users__pb2.GetMarginAttributesResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetUserTariff(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.UsersService/GetUserTariff', + t__tech_dot_invest_dot_grpc_dot_users__pb2.GetUserTariffRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_users__pb2.GetUserTariffResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetInfo(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.UsersService/GetInfo', + t__tech_dot_invest_dot_grpc_dot_users__pb2.GetInfoRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_users__pb2.GetInfoResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetBankAccounts(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.UsersService/GetBankAccounts', + t__tech_dot_invest_dot_grpc_dot_users__pb2.GetBankAccountsRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_users__pb2.GetBankAccountsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def CurrencyTransfer(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.UsersService/CurrencyTransfer', + t__tech_dot_invest_dot_grpc_dot_users__pb2.CurrencyTransferRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_users__pb2.CurrencyTransferResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def PayIn(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.UsersService/PayIn', + t__tech_dot_invest_dot_grpc_dot_users__pb2.PayInRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_users__pb2.PayInResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetAccountValues(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.UsersService/GetAccountValues', + t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountValuesRequest.SerializeToString, + t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountValuesResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/invest-python-master/t_tech/invest/logging.py b/invest-python-master/t_tech/invest/logging.py new file mode 100644 index 0000000..afdb47d --- /dev/null +++ b/invest-python-master/t_tech/invest/logging.py @@ -0,0 +1,120 @@ +import logging +from collections import namedtuple +from contextvars import ContextVar +from typing import Any, Optional + +from .constants import ( + MESSAGE, + X_RATELIMIT_LIMIT, + X_RATELIMIT_REMAINING, + X_RATELIMIT_RESET, + X_TRACKING_ID, +) + +__all__ = ( + "get_current_tracking_id", + "get_tracking_id_from_call", + "get_tracking_id_from_coro", + "get_metadata_from_call", + "get_metadata_from_aio_error", + "log_request", + "log_error", +) + +logger = logging.getLogger(__name__) + +_TRACKING_ID: ContextVar[Optional[str]] = ContextVar("tracking_id", default=None) +Metadata = namedtuple( + "Metadata", + ( + "tracking_id", + "ratelimit_limit", + "ratelimit_remaining", + "ratelimit_reset", + "message", + ), +) + + +def get_current_tracking_id() -> Optional[str]: + return _TRACKING_ID.get() or None + + +def log_request(tracking_id: Optional[str], name: str) -> None: + _TRACKING_ID.set(tracking_id) + logger.info("%s %s", tracking_id, name) + + +def log_error(tracking_id: Optional[str], name: str, text: str) -> None: + _TRACKING_ID.set(tracking_id) + logger.error("%s %s %s", tracking_id, name, text) + + +def get_tracking_id_from_call(call: Any) -> Optional[str]: + metadata = call.initial_metadata() or call.trailing_metadata() + for item in metadata: + if item.key == X_TRACKING_ID: + return item.value + return None + + +async def get_tracking_id_from_coro(coro: Any) -> Optional[str]: + metadata = await coro.initial_metadata() or await coro.trailing_metadata() + for key, value in metadata: + if key == X_TRACKING_ID: + return value + return None + + +def get_metadata_from_call(call: Any) -> Optional[Metadata]: + metadata = call.initial_metadata() or call.trailing_metadata() + tracking_id = None + ratelimit_limit = None + ratelimit_remaining = None + ratelimit_reset = None + message = None + for item in metadata: + if item.key == X_TRACKING_ID: + tracking_id = item.value + elif item.key == X_RATELIMIT_LIMIT: + ratelimit_limit = item.value + elif item.key == X_RATELIMIT_REMAINING: + ratelimit_remaining = int(item.value) + elif item.key == X_RATELIMIT_RESET: + ratelimit_reset = int(item.value) + elif item.key == MESSAGE: + message = item.value + if not any( + (tracking_id, ratelimit_limit, ratelimit_remaining, ratelimit_reset, message) + ): + return None + return Metadata( + tracking_id, ratelimit_limit, ratelimit_remaining, ratelimit_reset, message + ) + + +def get_metadata_from_aio_error(err: Any) -> Optional[Metadata]: + metadata = err.initial_metadata() or err.trailing_metadata() + tracking_id = None + ratelimit_limit = None + ratelimit_remaining = None + ratelimit_reset = None + message = None + for key, value in metadata: + if key == X_TRACKING_ID: + tracking_id = value + elif key == X_RATELIMIT_LIMIT: + ratelimit_limit = value + elif key == X_RATELIMIT_REMAINING: + ratelimit_remaining = int(value) + elif key == X_RATELIMIT_RESET: + ratelimit_reset = int(value) + elif key == MESSAGE: + message = value + if not any( + (tracking_id, ratelimit_limit, ratelimit_remaining, ratelimit_reset, message) + ): + return None + return Metadata( + tracking_id, ratelimit_limit, ratelimit_remaining, ratelimit_reset, message + ) diff --git a/invest-python-master/t_tech/invest/market_data_stream/__init__.py b/invest-python-master/t_tech/invest/market_data_stream/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/invest-python-master/t_tech/invest/market_data_stream/async_market_data_stream_manager.py b/invest-python-master/t_tech/invest/market_data_stream/async_market_data_stream_manager.py new file mode 100644 index 0000000..c1a1439 --- /dev/null +++ b/invest-python-master/t_tech/invest/market_data_stream/async_market_data_stream_manager.py @@ -0,0 +1,77 @@ +import asyncio +import threading +from asyncio import Queue +from typing import AsyncIterable, AsyncIterator, Awaitable + +from t_tech.invest.market_data_stream.market_data_stream_interface import ( + IMarketDataStreamManager, +) +from t_tech.invest.market_data_stream.stream_managers import ( + CandlesStreamManager, + InfoStreamManager, + LastPriceStreamManager, + OrderBookStreamManager, + TradesStreamManager, +) +from t_tech.invest.schemas import MarketDataRequest, MarketDataResponse + + +class AsyncMarketDataStreamManager(IMarketDataStreamManager): + def __init__( + self, + market_data_stream: "MarketDataStreamService", # type: ignore # noqa: F821 + ): + self._market_data_stream_service = market_data_stream + self._market_data_stream: AsyncIterator[MarketDataResponse] + self._requests: Queue[MarketDataRequest] = Queue() + self._unsubscribe_event = threading.Event() + + async def _get_request_generator(self) -> AsyncIterable[MarketDataRequest]: + while not self._unsubscribe_event.is_set() or not self._requests.empty(): + try: + request = await asyncio.wait_for(self._requests.get(), timeout=1.0) + except asyncio.exceptions.TimeoutError: + pass + else: + yield request + self._requests.task_done() + + @property + def candles(self) -> "CandlesStreamManager[AsyncMarketDataStreamManager]": + return CandlesStreamManager[AsyncMarketDataStreamManager](parent_manager=self) + + @property + def order_book(self) -> "OrderBookStreamManager[AsyncMarketDataStreamManager]": + return OrderBookStreamManager[AsyncMarketDataStreamManager](parent_manager=self) + + @property + def trades(self) -> "TradesStreamManager[AsyncMarketDataStreamManager]": + return TradesStreamManager[AsyncMarketDataStreamManager](parent_manager=self) + + @property + def info(self) -> "InfoStreamManager[AsyncMarketDataStreamManager]": + return InfoStreamManager[AsyncMarketDataStreamManager](parent_manager=self) + + @property + def last_price(self) -> "LastPriceStreamManager[AsyncMarketDataStreamManager]": + return LastPriceStreamManager[AsyncMarketDataStreamManager](parent_manager=self) + + def subscribe(self, market_data_request: MarketDataRequest) -> None: + self._requests.put_nowait(market_data_request) + + def unsubscribe(self, market_data_request: MarketDataRequest) -> None: + self._requests.put_nowait(market_data_request) + + def stop(self) -> None: + self._unsubscribe_event.set() + + def __aiter__(self) -> "AsyncMarketDataStreamManager": + self._unsubscribe_event.clear() + self._market_data_stream = self._market_data_stream_service.market_data_stream( + self._get_request_generator() + ).__aiter__() + + return self + + def __anext__(self) -> Awaitable[MarketDataResponse]: + return self._market_data_stream.__anext__() diff --git a/invest-python-master/t_tech/invest/market_data_stream/market_data_stream_interface.py b/invest-python-master/t_tech/invest/market_data_stream/market_data_stream_interface.py new file mode 100644 index 0000000..7148577 --- /dev/null +++ b/invest-python-master/t_tech/invest/market_data_stream/market_data_stream_interface.py @@ -0,0 +1,51 @@ +import abc +from typing import Generic + +from t_tech.invest.market_data_stream.stream_managers import ( + CandlesStreamManager, + InfoStreamManager, + LastPriceStreamManager, + OrderBookStreamManager, + TradesStreamManager, +) +from t_tech.invest.market_data_stream.typevars import TMarketDataStreamManager +from t_tech.invest.schemas import MarketDataRequest + + +class IMarketDataStreamManager(abc.ABC, Generic[TMarketDataStreamManager]): + @property + @abc.abstractmethod + def candles(self) -> CandlesStreamManager[TMarketDataStreamManager]: + pass + + @property + @abc.abstractmethod + def order_book(self) -> OrderBookStreamManager[TMarketDataStreamManager]: + pass + + @property + @abc.abstractmethod + def trades(self) -> TradesStreamManager[TMarketDataStreamManager]: + pass + + @property + @abc.abstractmethod + def info(self) -> InfoStreamManager[TMarketDataStreamManager]: + pass + + @property + @abc.abstractmethod + def last_price(self) -> LastPriceStreamManager[TMarketDataStreamManager]: + pass + + @abc.abstractmethod + def subscribe(self, market_data_request: MarketDataRequest) -> None: + pass + + @abc.abstractmethod + def unsubscribe(self, market_data_request: MarketDataRequest) -> None: + pass + + @abc.abstractmethod + def stop(self) -> None: + pass diff --git a/invest-python-master/t_tech/invest/market_data_stream/market_data_stream_manager.py b/invest-python-master/t_tech/invest/market_data_stream/market_data_stream_manager.py new file mode 100644 index 0000000..67a0530 --- /dev/null +++ b/invest-python-master/t_tech/invest/market_data_stream/market_data_stream_manager.py @@ -0,0 +1,78 @@ +import queue +import threading +from typing import Iterable, Iterator + +from t_tech.invest.market_data_stream.market_data_stream_interface import ( + IMarketDataStreamManager, +) +from t_tech.invest.market_data_stream.stream_managers import ( + CandlesStreamManager, + InfoStreamManager, + LastPriceStreamManager, + OrderBookStreamManager, + TradesStreamManager, +) +from t_tech.invest.schemas import MarketDataRequest, MarketDataResponse + + +class MarketDataStreamManager(IMarketDataStreamManager): + def __init__( + self, + market_data_stream_service: ( # type: ignore + "MarketDataStreamService" # noqa: F821 + ), + ): + self._market_data_stream_service = market_data_stream_service + self._market_data_stream: Iterator[MarketDataResponse] + self._requests: queue.Queue[MarketDataRequest] = queue.Queue() + self._unsubscribe_event = threading.Event() + + def _get_request_generator(self) -> Iterable[MarketDataRequest]: + while not self._unsubscribe_event.is_set() or not self._requests.empty(): + try: + request = self._requests.get(timeout=1.0) + except queue.Empty: + pass + else: + yield request + + @property + def candles(self) -> "CandlesStreamManager[MarketDataStreamManager]": + return CandlesStreamManager[MarketDataStreamManager](parent_manager=self) + + @property + def order_book(self) -> "OrderBookStreamManager[MarketDataStreamManager]": + return OrderBookStreamManager[MarketDataStreamManager](parent_manager=self) + + @property + def trades(self) -> "TradesStreamManager[MarketDataStreamManager]": + return TradesStreamManager[MarketDataStreamManager](parent_manager=self) + + @property + def info(self) -> "InfoStreamManager[MarketDataStreamManager]": + return InfoStreamManager[MarketDataStreamManager](parent_manager=self) + + @property + def last_price(self) -> "LastPriceStreamManager[MarketDataStreamManager]": + return LastPriceStreamManager[MarketDataStreamManager](parent_manager=self) + + def subscribe(self, market_data_request: MarketDataRequest) -> None: + self._requests.put(market_data_request) + + def unsubscribe(self, market_data_request: MarketDataRequest) -> None: + self._requests.put(market_data_request) + + def stop(self) -> None: + self._unsubscribe_event.set() + + def __iter__(self) -> "MarketDataStreamManager": + self._unsubscribe_event.clear() + self._market_data_stream = iter( + self._market_data_stream_service.market_data_stream( + self._get_request_generator() + ) + ) + return self + + def __next__(self) -> MarketDataResponse: + return next(self._market_data_stream) diff --git a/invest-python-master/t_tech/invest/market_data_stream/stream_managers.py b/invest-python-master/t_tech/invest/market_data_stream/stream_managers.py new file mode 100644 index 0000000..296829d --- /dev/null +++ b/invest-python-master/t_tech/invest/market_data_stream/stream_managers.py @@ -0,0 +1,157 @@ +import abc +from typing import Generic, List, TypeVar + +from t_tech.invest.schemas import ( + CandleInstrument, + InfoInstrument, + LastPriceInstrument, + MarketDataRequest, + OrderBookInstrument, + SubscribeCandlesRequest, + SubscribeInfoRequest, + SubscribeLastPriceRequest, + SubscribeOrderBookRequest, + SubscribeTradesRequest, + SubscriptionAction, + TradeInstrument, +) + +TMarketDataStreamManager = TypeVar("TMarketDataStreamManager") +TInstrument = TypeVar("TInstrument") + + +class BaseStreamManager(abc.ABC, Generic[TInstrument, TMarketDataStreamManager]): + def __init__(self, parent_manager: TMarketDataStreamManager): + self._parent_manager = parent_manager + + @abc.abstractmethod + def _get_request( + self, + subscription_action: SubscriptionAction, + instruments: List[TInstrument], + ): + pass + + def subscribe(self, instruments: List[TInstrument]) -> TMarketDataStreamManager: + self._parent_manager.subscribe( # type: ignore + self._get_request( + SubscriptionAction.SUBSCRIPTION_ACTION_SUBSCRIBE, instruments + ) + ) + + return self._parent_manager + + def unsubscribe(self, instruments: List[TInstrument]) -> TMarketDataStreamManager: + self._parent_manager.unsubscribe( # type: ignore + self._get_request( + SubscriptionAction.SUBSCRIPTION_ACTION_UNSUBSCRIBE, instruments + ) + ) + + return self._parent_manager + + +class CandlesStreamManager( + BaseStreamManager[CandleInstrument, TMarketDataStreamManager] +): + def __init__( + self, parent_manager: TMarketDataStreamManager, waiting_close: bool = False + ): + super().__init__(parent_manager) + self._parent_manager = parent_manager + self._waiting_close = waiting_close + + def _get_request( + self, + subscription_action: SubscriptionAction, + instruments: List[CandleInstrument], + ) -> MarketDataRequest: + return MarketDataRequest( + subscribe_candles_request=SubscribeCandlesRequest( + subscription_action=subscription_action, + instruments=instruments, + waiting_close=self._waiting_close, + ) + ) + + def waiting_close(self, enabled: bool = True) -> "CandlesStreamManager": + """Добавить флаг ожидания завершения интервала минутной свечи.""" + return CandlesStreamManager( + parent_manager=self._parent_manager, waiting_close=enabled + ) + + +class OrderBookStreamManager( + BaseStreamManager[OrderBookInstrument, TMarketDataStreamManager] +): + def __init__(self, parent_manager: TMarketDataStreamManager): + super().__init__(parent_manager) + self._parent_manager = parent_manager + + def _get_request( + self, + subscription_action: SubscriptionAction, + instruments: List[OrderBookInstrument], + ) -> MarketDataRequest: + return MarketDataRequest( + subscribe_order_book_request=SubscribeOrderBookRequest( + subscription_action=subscription_action, + instruments=instruments, + ) + ) + + +class TradesStreamManager(BaseStreamManager[TradeInstrument, TMarketDataStreamManager]): + def __init__(self, parent_manager: TMarketDataStreamManager): + super().__init__(parent_manager) + self._parent_manager = parent_manager + + def _get_request( + self, + subscription_action: SubscriptionAction, + instruments: List[TradeInstrument], + ) -> MarketDataRequest: + return MarketDataRequest( + subscribe_trades_request=SubscribeTradesRequest( + subscription_action=subscription_action, + instruments=instruments, + ) + ) + + +class InfoStreamManager(BaseStreamManager[InfoInstrument, TMarketDataStreamManager]): + def __init__(self, parent_manager: TMarketDataStreamManager): + super().__init__(parent_manager) + self._parent_manager = parent_manager + + def _get_request( + self, + subscription_action: SubscriptionAction, + instruments: List[InfoInstrument], + ) -> MarketDataRequest: + return MarketDataRequest( + subscribe_info_request=SubscribeInfoRequest( + subscription_action=subscription_action, + instruments=instruments, + ) + ) + + +class LastPriceStreamManager( + BaseStreamManager[LastPriceInstrument, TMarketDataStreamManager] +): + def __init__(self, parent_manager: TMarketDataStreamManager): + super().__init__(parent_manager) + self._parent_manager = parent_manager + + def _get_request( + self, + subscription_action: SubscriptionAction, + instruments: List[LastPriceInstrument], + ) -> MarketDataRequest: + return MarketDataRequest( + subscribe_last_price_request=SubscribeLastPriceRequest( + subscription_action=subscription_action, + instruments=instruments, + ) + ) diff --git a/invest-python-master/t_tech/invest/market_data_stream/typevars.py b/invest-python-master/t_tech/invest/market_data_stream/typevars.py new file mode 100644 index 0000000..8189e3a --- /dev/null +++ b/invest-python-master/t_tech/invest/market_data_stream/typevars.py @@ -0,0 +1,4 @@ +from typing import TypeVar + +TMarketDataStreamManager = TypeVar("TMarketDataStreamManager") +TInstrument = TypeVar("TInstrument") diff --git a/invest-python-master/t_tech/invest/metadata.py b/invest-python-master/t_tech/invest/metadata.py new file mode 100644 index 0000000..f90e185 --- /dev/null +++ b/invest-python-master/t_tech/invest/metadata.py @@ -0,0 +1,10 @@ +from typing import List, Optional, Tuple + +from .constants import APP_NAME + + +def get_metadata(token: str, app_name: Optional[str] = None) -> List[Tuple[str, str]]: + if not app_name: + app_name = APP_NAME + + return [("authorization", f"Bearer {token}"), ("x-app-name", app_name)] diff --git a/invest-python-master/t_tech/invest/mock_services.py b/invest-python-master/t_tech/invest/mock_services.py new file mode 100644 index 0000000..afc2ab5 --- /dev/null +++ b/invest-python-master/t_tech/invest/mock_services.py @@ -0,0 +1,332 @@ +import logging +from contextlib import contextmanager +from datetime import datetime, timedelta +from decimal import Decimal +from functools import cached_property +from typing import Any, Callable, Dict, Generator, List, Optional + +from grpc import Channel +from pytest_freezegun import freeze_time + +from t_tech.invest import ( + Candle, + GetCandlesResponse, + GetMarginAttributesResponse, + HistoricCandle, + MarketDataResponse, + MoneyValue, + OrderDirection, + OrderType, + PortfolioPosition, + PortfolioResponse, + PostOrderResponse, + Quotation, +) +from t_tech.invest.channels import create_channel +from t_tech.invest.services import Services +from t_tech.invest.strategies.base.strategy_settings_base import StrategySettings +from t_tech.invest.typedefs import AccountId, ChannelArgumentType +from t_tech.invest.utils import ( + candle_interval_to_subscription_interval, + decimal_to_quotation, + now, + quotation_to_decimal, +) + +logger = logging.getLogger(__name__) + + +@contextmanager +def MockedClient( + token: str, + *, + settings: StrategySettings, + real_market_data_test_from: datetime, + real_market_data_test_start: datetime, + real_market_data_test_end: datetime, + balance: MoneyValue, + options: Optional[ChannelArgumentType] = None, +) -> Generator[Services, None, None]: + with create_channel(options=options) as channel: + with freeze_time(real_market_data_test_start) as frozen_datetime: + yield MockedServices( + channel=channel, + token=token, + settings=settings, + frozen_datetime=frozen_datetime, + real_market_data_test_from=real_market_data_test_from, + real_market_data_test_start=real_market_data_test_start, + real_market_data_test_end=real_market_data_test_end, + balance=balance, + ) + + +@contextmanager +def MockedSandboxClient( + token: str, + *, + balance: MoneyValue, + options: Optional[ChannelArgumentType] = None, +) -> Generator[Services, None, None]: + with create_channel(options=options) as channel: + services = MockedSandboxServices( + channel=channel, + token=token, + balance=balance, + ) + try: + yield services + except Exception: + del services + raise + + +class MockedServices(Services): + def __init__( + self, + channel: Channel, + token: str, + settings: StrategySettings, + frozen_datetime, + real_market_data_test_from: datetime, + real_market_data_test_start: datetime, + real_market_data_test_end: datetime, + balance: MoneyValue, + ): + super().__init__(channel, token) + self._settings = settings + self._figi = settings.share_id + self._current_market_data: List[Candle] = [] + self._portfolio_positions: Dict[str, PortfolioPosition] = {} + self._real_market_data_test_from = real_market_data_test_from + self._real_market_data_test_start = real_market_data_test_start + self._real_market_data_test_end = real_market_data_test_end + self._balance = balance + self._frozen_datetime = frozen_datetime + + _ = self._real_market_data + + self.market_data.get_candles = self._mocked_market_data_get_candles() + self.orders.post_order = self._mocked_orders_post_order() + self.operations.get_portfolio = self._mocked_operations_get_portfolio() + self.market_data_stream.market_data_stream = self._mocked_market_data_stream() + self.users.get_margin_attributes = self._mocked_users_get_margin_attributes() + + def _mocked_orders_post_order(self) -> Callable[[Any], Any]: + def _post_order( # pylint: disable=too-many-locals + *, + figi: str = "", + quantity: int = 0, + price: Optional[Quotation] = None, # pylint: disable=unused-argument + direction: OrderDirection = OrderDirection(0), + account_id: str = "", # pylint: disable=unused-argument + order_type: OrderType = OrderType(0), # pylint: disable=unused-argument + order_id: str = "", # pylint: disable=unused-argument + ): + last_candle = self._current_market_data[-1] + last_market_price = quotation_to_decimal(last_candle.close) + + position = self._portfolio_positions.get(figi) + if position is None: + position = PortfolioPosition( + figi=figi, + quantity=decimal_to_quotation(Decimal(0)), + ) + + if direction == OrderDirection.ORDER_DIRECTION_SELL: + quantity_delta = -quantity + balance_delta = last_market_price * quantity + elif direction == OrderDirection.ORDER_DIRECTION_BUY: + quantity_delta = +quantity + balance_delta = -(last_market_price * quantity) + + else: + raise AssertionError("Incorrect direction") + + logger.warning("Operation: %s, %s", direction, balance_delta) + + old_quantity = quotation_to_decimal(position.quantity) + new_quantity = decimal_to_quotation(old_quantity + quantity_delta) + + position.quantity.units = new_quantity.units + position.quantity.nano = new_quantity.nano + + old_balance = quotation_to_decimal( + Quotation(units=self._balance.units, nano=self._balance.nano) + ) + new_balance = decimal_to_quotation(old_balance + balance_delta) + + self._balance.units = new_balance.units + self._balance.nano = new_balance.nano + + self._portfolio_positions[figi] = position + + return _post_order # type: ignore + + @cached_property + def _portfolio_response(self) -> PortfolioResponse: + return PortfolioResponse( + total_amount_shares=MoneyValue(currency="rub", units=28691, nano=300000000), + total_amount_bonds=MoneyValue(currency="rub", units=0, nano=0), + total_amount_etf=MoneyValue(currency="rub", units=0, nano=0), + total_amount_currencies=self._balance, + total_amount_futures=MoneyValue(currency="rub", units=0, nano=0), + expected_yield=Quotation(units=0, nano=-350000000), + positions=list(self._portfolio_positions.values()), + ) + + def _mocked_operations_get_portfolio(self) -> Callable[[Any], Any]: + def _get_portfolio(*args, **kwars): # pylint: disable=unused-argument + return self._portfolio_response + + return _get_portfolio + + def _mocked_market_data_stream(self) -> Callable[[Any], Any]: + self._frozen_datetime.move_to(self._real_market_data_test_start) + + def _market_data_stream(*args, **kwargs): # pylint: disable=unused-argument + yield MarketDataResponse(candle=None) # type: ignore + + interval = candle_interval_to_subscription_interval( + self._settings.candle_interval + ) + for historic_candle in self._after_start_candles: + candle = Candle( + figi=self._figi, + interval=interval, + open=historic_candle.open, + high=historic_candle.high, + low=historic_candle.low, + close=historic_candle.close, + volume=historic_candle.volume, + time=historic_candle.time, + ) + self._current_market_data.append(candle) + yield MarketDataResponse(candle=candle) + self._frozen_datetime.move_to(now() + timedelta(minutes=1)) + + return _market_data_stream + + @cached_property + def _real_market_data(self) -> List[HistoricCandle]: + real_market_data = [] + for candle in self.get_all_candles( + figi=self._figi, + from_=self._real_market_data_test_from, + to=self._real_market_data_test_end, + interval=self._settings.candle_interval, + ): + real_market_data.append(candle) + return real_market_data + + @cached_property + def _initial_candles(self) -> List[HistoricCandle]: + return [ + candle + for candle in self._real_market_data + if candle.time < self._real_market_data_test_start + ] + + @cached_property + def _after_start_candles(self) -> List[HistoricCandle]: + return [ + candle + for candle in self._real_market_data + if candle.time >= self._real_market_data_test_start + ] + + def _mocked_market_data_get_candles(self): + def _get_candles(*args, **kwargs): # pylint: disable=unused-argument + return GetCandlesResponse(candles=self._initial_candles) + + return _get_candles + + def _mocked_users_get_margin_attributes(self): + def _get_margin_attributes(*agrs, **kwargs): # pylint: disable=unused-argument + return GetMarginAttributesResponse( + liquid_portfolio=MoneyValue(currency="", units=0, nano=0), + starting_margin=MoneyValue(currency="", units=0, nano=0), + minimal_margin=MoneyValue(currency="", units=0, nano=0), + funds_sufficiency_level=Quotation(units=322, nano=0), + amount_of_missing_funds=MoneyValue(currency="", units=0, nano=0), + ) + + return _get_margin_attributes + + +class MockedSandboxServices(Services): + def __init__( + self, + channel: Channel, + token: str, + balance: MoneyValue, + ): + super().__init__(channel, token) + self.orders.post_order = self._mocked_orders_post_order() + self.operations.get_portfolio = self._mocked_operations_get_portfolio() + self.users.get_margin_attributes = self._mocked_users_get_margin_attributes() + + self._account_id = self._open_account() + self._pay_in(balance) + + def _pay_in(self, amount: MoneyValue): + logger.info("Pay in %s for %s", amount, self._account_id) + self.sandbox.sandbox_pay_in(account_id=self._account_id, amount=amount) + + def _open_account(self) -> AccountId: + response = self.sandbox.open_sandbox_account() + self._account_id = response.account_id + logger.info("Opened sandbox account %s", self._account_id) + return self._account_id + + def __del__(self): + self._close_account() + + def _close_account(self) -> None: + logger.info("Closing sandbox account %s", self._account_id) + self.sandbox.close_sandbox_account(account_id=self._account_id) + + def _mocked_orders_post_order( + self, + ) -> Callable[[Any], PostOrderResponse]: + def _post_order( + *, + figi: str = "", + quantity: int = 0, + price: Optional[Quotation] = None, + direction: OrderDirection = OrderDirection(0), + _: str = "", + order_type: OrderType = OrderType(0), + order_id: str = "", + ) -> PostOrderResponse: + return self.sandbox.post_sandbox_order( + figi=figi, + quantity=quantity, + price=price, + direction=direction, + account_id=self._account_id, + order_type=order_type, + order_id=order_id, + ) + + return _post_order # type: ignore + + def _mocked_operations_get_portfolio(self) -> Callable[[Any], Any]: + def _get_sandbox_portfolio( + *, account_id: str = "" # pylint: disable=unused-argument + ) -> PortfolioResponse: + return self.sandbox.get_sandbox_portfolio(account_id=self._account_id) + + return _get_sandbox_portfolio # type: ignore + + def _mocked_users_get_margin_attributes(self) -> Callable[[Any], PortfolioResponse]: + def _get_margin_attributes(*agrs, **kwargs): # pylint: disable=unused-argument + return GetMarginAttributesResponse( + liquid_portfolio=MoneyValue(currency="", units=0, nano=0), + starting_margin=MoneyValue(currency="", units=0, nano=0), + minimal_margin=MoneyValue(currency="", units=0, nano=0), + funds_sufficiency_level=Quotation(units=322, nano=0), + amount_of_missing_funds=MoneyValue(currency="", units=0, nano=0), + ) + + return _get_margin_attributes diff --git a/invest-python-master/t_tech/invest/py.typed b/invest-python-master/t_tech/invest/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/invest-python-master/t_tech/invest/retrying/__init__.py b/invest-python-master/t_tech/invest/retrying/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/invest-python-master/t_tech/invest/retrying/aio/__init__.py b/invest-python-master/t_tech/invest/retrying/aio/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/invest-python-master/t_tech/invest/retrying/aio/client.py b/invest-python-master/t_tech/invest/retrying/aio/client.py new file mode 100644 index 0000000..9a4209c --- /dev/null +++ b/invest-python-master/t_tech/invest/retrying/aio/client.py @@ -0,0 +1,21 @@ +from t_tech.invest import AsyncClient +from t_tech.invest.retrying.aio.grpc_interceptor import AsyncRetryClientInterceptor +from t_tech.invest.retrying.aio.retry_manager import AsyncRetryManager +from t_tech.invest.retrying.settings_protocol import RetryClientSettingsProtocol + + +class AsyncRetryingClient(AsyncClient): + def __init__( + self, + token: str, + settings: RetryClientSettingsProtocol, + **kwargs, + ): + self._retry_manager = AsyncRetryManager(settings=settings) + self._retry_interceptor = AsyncRetryClientInterceptor( + retry_manager=self._retry_manager + ) + interceptors = kwargs.get("interceptors", []) + interceptors.append(self._retry_interceptor) + kwargs["interceptors"] = interceptors + super().__init__(token, **kwargs) diff --git a/invest-python-master/t_tech/invest/retrying/aio/grpc_interceptor.py b/invest-python-master/t_tech/invest/retrying/aio/grpc_interceptor.py new file mode 100644 index 0000000..e13df7a --- /dev/null +++ b/invest-python-master/t_tech/invest/retrying/aio/grpc_interceptor.py @@ -0,0 +1,21 @@ +import grpc + +from t_tech.invest.retrying.aio.retry_manager import AsyncRetryManager + + +class AsyncRetryClientInterceptor(grpc.aio.UnaryUnaryClientInterceptor): + def __init__( + self, retry_manager: AsyncRetryManager + ): # pylint: disable=super-init-not-called + self._retry_manager = retry_manager + + async def _intercept_with_retry(self, continuation, client_call_details, request): + async def call(): + return await continuation(client_call_details, request) + + return await self._retry_manager.call_with_retries(call=call) + + async def intercept_unary_unary(self, continuation, client_call_details, request): + return await self._intercept_with_retry( + continuation, client_call_details, request + ) diff --git a/invest-python-master/t_tech/invest/retrying/aio/retry_manager.py b/invest-python-master/t_tech/invest/retrying/aio/retry_manager.py new file mode 100644 index 0000000..c1084d6 --- /dev/null +++ b/invest-python-master/t_tech/invest/retrying/aio/retry_manager.py @@ -0,0 +1,35 @@ +import asyncio +import logging +from typing import Any + +from grpc.aio import AioRpcError + +from t_tech.invest.logging import get_metadata_from_aio_error +from t_tech.invest.retrying.base_retry_manager import BaseRetryManager + +logger = logging.getLogger(__name__) + + +class AsyncRetryManager(BaseRetryManager): + async def call_with_retries(self, call: Any): + retries_left = self.get_initial_retries() + while retries_left > 0: + logger.debug("Trying to call") + response = await call() + try: + await response + logger.debug("Call succeeded") + return response + except AioRpcError as exception: + retries_left -= 1 + logger.debug("Retries left = %s", retries_left) + + metadata = get_metadata_from_aio_error(exception) + seconds_to_sleep = self.extract_seconds_to_sleep(metadata) + await self._sleep(seconds_to_sleep) + + logger.debug("RetryManager exhausted, no retries left") + return response + + async def _sleep(self, seconds_to_sleep): + await asyncio.sleep(seconds_to_sleep) diff --git a/invest-python-master/t_tech/invest/retrying/base_retry_manager.py b/invest-python-master/t_tech/invest/retrying/base_retry_manager.py new file mode 100644 index 0000000..8c787c4 --- /dev/null +++ b/invest-python-master/t_tech/invest/retrying/base_retry_manager.py @@ -0,0 +1,25 @@ +import logging + +from t_tech.invest.retrying.settings_protocol import RetryClientSettingsProtocol + +logger = logging.getLogger(__name__) + + +class BaseRetryManager: + def __init__(self, settings: RetryClientSettingsProtocol): + self._settings = settings + + def get_initial_retries(self): + retries_left = self._settings.max_retry_attempt + if not self._settings.use_retry: + retries_left = 0 + logger.debug("Retrying disabled") + retries_left += 1 + return retries_left + + @staticmethod + def extract_seconds_to_sleep(metadata) -> int: + logger.debug("Received metadata %s", metadata) + seconds_to_sleep = metadata.ratelimit_reset + logger.debug("Sleeping for %s seconds", seconds_to_sleep) + return seconds_to_sleep diff --git a/invest-python-master/t_tech/invest/retrying/settings.py b/invest-python-master/t_tech/invest/retrying/settings.py new file mode 100644 index 0000000..895e69a --- /dev/null +++ b/invest-python-master/t_tech/invest/retrying/settings.py @@ -0,0 +1,9 @@ +import dataclasses + +from t_tech.invest.retrying.settings_protocol import RetryClientSettingsProtocol + + +@dataclasses.dataclass() +class RetryClientSettings(RetryClientSettingsProtocol): + use_retry: bool = True + max_retry_attempt: int = 3 diff --git a/invest-python-master/t_tech/invest/retrying/settings_protocol.py b/invest-python-master/t_tech/invest/retrying/settings_protocol.py new file mode 100644 index 0000000..7bad587 --- /dev/null +++ b/invest-python-master/t_tech/invest/retrying/settings_protocol.py @@ -0,0 +1,6 @@ +from typing import Protocol + + +class RetryClientSettingsProtocol(Protocol): + use_retry: bool + max_retry_attempt: int diff --git a/invest-python-master/t_tech/invest/retrying/sync/__init__.py b/invest-python-master/t_tech/invest/retrying/sync/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/invest-python-master/t_tech/invest/retrying/sync/client.py b/invest-python-master/t_tech/invest/retrying/sync/client.py new file mode 100644 index 0000000..781aa8f --- /dev/null +++ b/invest-python-master/t_tech/invest/retrying/sync/client.py @@ -0,0 +1,21 @@ +from t_tech.invest import Client +from t_tech.invest.retrying.settings_protocol import RetryClientSettingsProtocol +from t_tech.invest.retrying.sync.grpc_interceptor import RetryClientInterceptor +from t_tech.invest.retrying.sync.retry_manager import RetryManager + + +class RetryingClient(Client): + def __init__( + self, + token: str, + settings: RetryClientSettingsProtocol, + **kwargs, + ): + self._retry_manager = RetryManager(settings=settings) + self._retry_interceptor = RetryClientInterceptor( + retry_manager=self._retry_manager + ) + interceptors = kwargs.get("interceptors", []) + interceptors.append(self._retry_interceptor) + kwargs["interceptors"] = interceptors + super().__init__(token, **kwargs) diff --git a/invest-python-master/t_tech/invest/retrying/sync/grpc_interceptor.py b/invest-python-master/t_tech/invest/retrying/sync/grpc_interceptor.py new file mode 100644 index 0000000..0d03bb1 --- /dev/null +++ b/invest-python-master/t_tech/invest/retrying/sync/grpc_interceptor.py @@ -0,0 +1,19 @@ +import grpc + +from t_tech.invest.retrying.sync.retry_manager import RetryManager + + +class RetryClientInterceptor(grpc.UnaryUnaryClientInterceptor): + def __init__( + self, retry_manager: RetryManager + ): # pylint: disable=super-init-not-called + self._retry_manager = retry_manager + + def _intercept_with_retry(self, continuation, client_call_details, request): + def call(): + return continuation(client_call_details, request) + + return self._retry_manager.call_with_retries(call=call) + + def intercept_unary_unary(self, continuation, client_call_details, request): + return self._intercept_with_retry(continuation, client_call_details, request) diff --git a/invest-python-master/t_tech/invest/retrying/sync/retry_manager.py b/invest-python-master/t_tech/invest/retrying/sync/retry_manager.py new file mode 100644 index 0000000..3d04d61 --- /dev/null +++ b/invest-python-master/t_tech/invest/retrying/sync/retry_manager.py @@ -0,0 +1,31 @@ +import logging +import time +from typing import Any + +from t_tech.invest.logging import get_metadata_from_call +from t_tech.invest.retrying.base_retry_manager import BaseRetryManager + +logger = logging.getLogger(__name__) + + +class RetryManager(BaseRetryManager): + def call_with_retries(self, call: Any): + retries_left = self.get_initial_retries() + while retries_left > 0: + logger.debug("Trying to call") + result = call() + logger.debug("Call succeeded") + exception = result.exception() + if not exception: + return result + retries_left -= 1 + logger.debug("Retries left = %s", retries_left) + metadata = get_metadata_from_call(exception) + seconds_to_sleep = self.extract_seconds_to_sleep(metadata) + self._sleep(seconds_to_sleep) + + logger.debug("RetryManager exhausted, no retries left") + return result + + def _sleep(self, seconds_to_sleep): + time.sleep(seconds_to_sleep) diff --git a/invest-python-master/t_tech/invest/sandbox/__init__.py b/invest-python-master/t_tech/invest/sandbox/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/invest-python-master/t_tech/invest/sandbox/async_client.py b/invest-python-master/t_tech/invest/sandbox/async_client.py new file mode 100644 index 0000000..fa136e0 --- /dev/null +++ b/invest-python-master/t_tech/invest/sandbox/async_client.py @@ -0,0 +1,12 @@ +from t_tech.invest import AsyncClient +from t_tech.invest.constants import INVEST_GRPC_API_SANDBOX + + +class AsyncSandboxClient(AsyncClient): + def __init__( + self, + token: str, + **kwargs, + ): + kwargs["target"] = INVEST_GRPC_API_SANDBOX + super().__init__(token, **kwargs) diff --git a/invest-python-master/t_tech/invest/sandbox/client.py b/invest-python-master/t_tech/invest/sandbox/client.py new file mode 100644 index 0000000..cc41049 --- /dev/null +++ b/invest-python-master/t_tech/invest/sandbox/client.py @@ -0,0 +1,12 @@ +from t_tech.invest import Client +from t_tech.invest.constants import INVEST_GRPC_API_SANDBOX + + +class SandboxClient(Client): + def __init__( + self, + token: str, + **kwargs, + ): + kwargs["target"] = INVEST_GRPC_API_SANDBOX + super().__init__(token, **kwargs) diff --git a/invest-python-master/t_tech/invest/schemas.py b/invest-python-master/t_tech/invest/schemas.py new file mode 100644 index 0000000..fee06b1 --- /dev/null +++ b/invest-python-master/t_tech/invest/schemas.py @@ -0,0 +1,3732 @@ +# pylint:disable=too-many-lines +# pylint:disable=too-many-instance-attributes +from dataclasses import dataclass +from datetime import datetime +from typing import List, Optional, SupportsAbs + +from . import _grpc_helpers + + +class SecurityTradingStatus(_grpc_helpers.Enum): + SECURITY_TRADING_STATUS_UNSPECIFIED = 0 + SECURITY_TRADING_STATUS_NOT_AVAILABLE_FOR_TRADING = 1 + SECURITY_TRADING_STATUS_OPENING_PERIOD = 2 + SECURITY_TRADING_STATUS_CLOSING_PERIOD = 3 + SECURITY_TRADING_STATUS_BREAK_IN_TRADING = 4 + SECURITY_TRADING_STATUS_NORMAL_TRADING = 5 + SECURITY_TRADING_STATUS_CLOSING_AUCTION = 6 + SECURITY_TRADING_STATUS_DARK_POOL_AUCTION = 7 + SECURITY_TRADING_STATUS_DISCRETE_AUCTION = 8 + SECURITY_TRADING_STATUS_OPENING_AUCTION_PERIOD = 9 + SECURITY_TRADING_STATUS_TRADING_AT_CLOSING_AUCTION_PRICE = 10 + SECURITY_TRADING_STATUS_SESSION_ASSIGNED = 11 + SECURITY_TRADING_STATUS_SESSION_CLOSE = 12 + SECURITY_TRADING_STATUS_SESSION_OPEN = 13 + SECURITY_TRADING_STATUS_DEALER_NORMAL_TRADING = 14 + SECURITY_TRADING_STATUS_DEALER_BREAK_IN_TRADING = 15 + SECURITY_TRADING_STATUS_DEALER_NOT_AVAILABLE_FOR_TRADING = 16 + SECURITY_TRADING_STATUS_STABILIZATION_AUCTION = 17 + + +class InstrumentIdType(_grpc_helpers.Enum): + INSTRUMENT_ID_UNSPECIFIED = 0 + INSTRUMENT_ID_TYPE_FIGI = 1 + INSTRUMENT_ID_TYPE_TICKER = 2 + INSTRUMENT_ID_TYPE_UID = 3 + INSTRUMENT_ID_TYPE_POSITION_UID = 4 + INSTRUMENT_ID_TYPE_ID = 5 + + +class InstrumentStatus(_grpc_helpers.Enum): + INSTRUMENT_STATUS_UNSPECIFIED = 0 + INSTRUMENT_STATUS_BASE = 1 + INSTRUMENT_STATUS_ALL = 2 + + +class ShareType(_grpc_helpers.Enum): + SHARE_TYPE_UNSPECIFIED = 0 + SHARE_TYPE_COMMON = 1 + SHARE_TYPE_PREFERRED = 2 + SHARE_TYPE_ADR = 3 + SHARE_TYPE_GDR = 4 + SHARE_TYPE_MLP = 5 + SHARE_TYPE_NY_REG_SHRS = 6 + SHARE_TYPE_CLOSED_END_FUND = 7 + SHARE_TYPE_REIT = 8 + + +class SubscriptionAction(_grpc_helpers.Enum): + SUBSCRIPTION_ACTION_UNSPECIFIED = 0 + SUBSCRIPTION_ACTION_SUBSCRIBE = 1 + SUBSCRIPTION_ACTION_UNSUBSCRIBE = 2 + + +class SubscriptionInterval(_grpc_helpers.Enum): + SUBSCRIPTION_INTERVAL_UNSPECIFIED = 0 + SUBSCRIPTION_INTERVAL_ONE_MINUTE = 1 + SUBSCRIPTION_INTERVAL_FIVE_MINUTES = 2 + SUBSCRIPTION_INTERVAL_FIFTEEN_MINUTES = 3 + SUBSCRIPTION_INTERVAL_ONE_HOUR = 4 + SUBSCRIPTION_INTERVAL_ONE_DAY = 5 + SUBSCRIPTION_INTERVAL_2_MIN = 6 + SUBSCRIPTION_INTERVAL_3_MIN = 7 + SUBSCRIPTION_INTERVAL_10_MIN = 8 + SUBSCRIPTION_INTERVAL_30_MIN = 9 + SUBSCRIPTION_INTERVAL_2_HOUR = 10 + SUBSCRIPTION_INTERVAL_4_HOUR = 11 + SUBSCRIPTION_INTERVAL_WEEK = 12 + SUBSCRIPTION_INTERVAL_MONTH = 13 + + +class SubscriptionStatus(_grpc_helpers.Enum): + SUBSCRIPTION_STATUS_UNSPECIFIED = 0 + SUBSCRIPTION_STATUS_SUCCESS = 1 + SUBSCRIPTION_STATUS_INSTRUMENT_NOT_FOUND = 2 + SUBSCRIPTION_STATUS_SUBSCRIPTION_ACTION_IS_INVALID = 3 + SUBSCRIPTION_STATUS_DEPTH_IS_INVALID = 4 + SUBSCRIPTION_STATUS_INTERVAL_IS_INVALID = 5 + SUBSCRIPTION_STATUS_LIMIT_IS_EXCEEDED = 6 + SUBSCRIPTION_STATUS_INTERNAL_ERROR = 7 + SUBSCRIPTION_STATUS_TOO_MANY_REQUESTS = 8 + SUBSCRIPTION_STATUS_SUBSCRIPTION_NOT_FOUND = 9 + SUBSCRIPTION_STATUS_SOURCE_IS_INVALID = 10 + + +class TradeDirection(_grpc_helpers.Enum): + TRADE_DIRECTION_UNSPECIFIED = 0 + TRADE_DIRECTION_BUY = 1 + TRADE_DIRECTION_SELL = 2 + + +class CandleInterval(_grpc_helpers.Enum): + CANDLE_INTERVAL_UNSPECIFIED = 0 + CANDLE_INTERVAL_5_SEC = 14 + CANDLE_INTERVAL_10_SEC = 15 + CANDLE_INTERVAL_30_SEC = 16 + CANDLE_INTERVAL_1_MIN = 1 + CANDLE_INTERVAL_2_MIN = 6 + CANDLE_INTERVAL_3_MIN = 7 + CANDLE_INTERVAL_5_MIN = 2 + CANDLE_INTERVAL_10_MIN = 8 + CANDLE_INTERVAL_15_MIN = 3 + CANDLE_INTERVAL_30_MIN = 9 + CANDLE_INTERVAL_HOUR = 4 + CANDLE_INTERVAL_2_HOUR = 10 + CANDLE_INTERVAL_4_HOUR = 11 + CANDLE_INTERVAL_DAY = 5 + CANDLE_INTERVAL_WEEK = 12 + CANDLE_INTERVAL_MONTH = 13 + + +class CandleSource(_grpc_helpers.Enum): + CANDLE_SOURCE_UNSPECIFIED = 0 + CANDLE_SOURCE_EXCHANGE = 1 + CANDLE_SOURCE_DEALER_WEEKEND = 2 + CANDLE_SOURCE_INCLUDE_WEEKEND = 3 + + +class OperationState(_grpc_helpers.Enum): + OPERATION_STATE_UNSPECIFIED = 0 + OPERATION_STATE_EXECUTED = 1 + OPERATION_STATE_CANCELED = 2 + OPERATION_STATE_PROGRESS = 3 + + +class OrderDirection(_grpc_helpers.Enum): + ORDER_DIRECTION_UNSPECIFIED = 0 + ORDER_DIRECTION_BUY = 1 + ORDER_DIRECTION_SELL = 2 + + +class OrderType(_grpc_helpers.Enum): + ORDER_TYPE_UNSPECIFIED = 0 + ORDER_TYPE_LIMIT = 1 + ORDER_TYPE_MARKET = 2 + ORDER_TYPE_BESTPRICE = 3 + + +class OrderExecutionReportStatus(_grpc_helpers.Enum): + EXECUTION_REPORT_STATUS_UNSPECIFIED = 0 + EXECUTION_REPORT_STATUS_FILL = 1 + EXECUTION_REPORT_STATUS_REJECTED = 2 + EXECUTION_REPORT_STATUS_CANCELLED = 3 + EXECUTION_REPORT_STATUS_NEW = 4 + EXECUTION_REPORT_STATUS_PARTIALLYFILL = 5 + + +class AccountType(_grpc_helpers.Enum): + ACCOUNT_TYPE_UNSPECIFIED = 0 + ACCOUNT_TYPE_TINKOFF = 1 + ACCOUNT_TYPE_TINKOFF_IIS = 2 + ACCOUNT_TYPE_INVEST_BOX = 3 + ACCOUNT_TYPE_INVEST_FUND = 4 + ACCOUNT_TYPE_DEBIT = 5 + ACCOUNT_TYPE_SAVING = 6 + ACCOUNT_TYPE_DFA = 7 + + +class AccountStatus(_grpc_helpers.Enum): + ACCOUNT_STATUS_UNSPECIFIED = 0 + ACCOUNT_STATUS_NEW = 1 + ACCOUNT_STATUS_OPEN = 2 + ACCOUNT_STATUS_CLOSED = 3 + + +class StopOrderDirection(_grpc_helpers.Enum): + STOP_ORDER_DIRECTION_UNSPECIFIED = 0 + STOP_ORDER_DIRECTION_BUY = 1 + STOP_ORDER_DIRECTION_SELL = 2 + + +class StopOrderExpirationType(_grpc_helpers.Enum): + STOP_ORDER_EXPIRATION_TYPE_UNSPECIFIED = 0 + STOP_ORDER_EXPIRATION_TYPE_GOOD_TILL_CANCEL = 1 + STOP_ORDER_EXPIRATION_TYPE_GOOD_TILL_DATE = 2 + + +class StopOrderType(_grpc_helpers.Enum): + STOP_ORDER_TYPE_UNSPECIFIED = 0 + STOP_ORDER_TYPE_TAKE_PROFIT = 1 + STOP_ORDER_TYPE_STOP_LOSS = 2 + STOP_ORDER_TYPE_STOP_LIMIT = 3 + + +class OperationType(_grpc_helpers.Enum): + OPERATION_TYPE_UNSPECIFIED = 0 + OPERATION_TYPE_INPUT = 1 + OPERATION_TYPE_BOND_TAX = 2 + OPERATION_TYPE_OUTPUT_SECURITIES = 3 + OPERATION_TYPE_OVERNIGHT = 4 + OPERATION_TYPE_TAX = 5 + OPERATION_TYPE_BOND_REPAYMENT_FULL = 6 + OPERATION_TYPE_SELL_CARD = 7 + OPERATION_TYPE_DIVIDEND_TAX = 8 + OPERATION_TYPE_OUTPUT = 9 + OPERATION_TYPE_BOND_REPAYMENT = 10 + OPERATION_TYPE_TAX_CORRECTION = 11 + OPERATION_TYPE_SERVICE_FEE = 12 + OPERATION_TYPE_BENEFIT_TAX = 13 + OPERATION_TYPE_MARGIN_FEE = 14 + OPERATION_TYPE_BUY = 15 + OPERATION_TYPE_BUY_CARD = 16 + OPERATION_TYPE_INPUT_SECURITIES = 17 + OPERATION_TYPE_SELL_MARGIN = 18 + OPERATION_TYPE_BROKER_FEE = 19 + OPERATION_TYPE_BUY_MARGIN = 20 + OPERATION_TYPE_DIVIDEND = 21 + OPERATION_TYPE_SELL = 22 + OPERATION_TYPE_COUPON = 23 + OPERATION_TYPE_SUCCESS_FEE = 24 + OPERATION_TYPE_DIVIDEND_TRANSFER = 25 + OPERATION_TYPE_ACCRUING_VARMARGIN = 26 + OPERATION_TYPE_WRITING_OFF_VARMARGIN = 27 + OPERATION_TYPE_DELIVERY_BUY = 28 + OPERATION_TYPE_DELIVERY_SELL = 29 + OPERATION_TYPE_TRACK_MFEE = 30 + OPERATION_TYPE_TRACK_PFEE = 31 + OPERATION_TYPE_TAX_PROGRESSIVE = 32 + OPERATION_TYPE_BOND_TAX_PROGRESSIVE = 33 + OPERATION_TYPE_DIVIDEND_TAX_PROGRESSIVE = 34 + OPERATION_TYPE_BENEFIT_TAX_PROGRESSIVE = 35 + OPERATION_TYPE_TAX_CORRECTION_PROGRESSIVE = 36 + OPERATION_TYPE_TAX_REPO_PROGRESSIVE = 37 + OPERATION_TYPE_TAX_REPO = 38 + OPERATION_TYPE_TAX_REPO_HOLD = 39 + OPERATION_TYPE_TAX_REPO_REFUND = 40 + OPERATION_TYPE_TAX_REPO_HOLD_PROGRESSIVE = 41 + OPERATION_TYPE_TAX_REPO_REFUND_PROGRESSIVE = 42 + OPERATION_TYPE_DIV_EXT = 43 + OPERATION_TYPE_TAX_CORRECTION_COUPON = 44 + OPERATION_TYPE_CASH_FEE = 45 + OPERATION_TYPE_OUT_FEE = 46 + OPERATION_TYPE_OUT_STAMP_DUTY = 47 + OPERATION_TYPE_OUTPUT_SWIFT = 50 + OPERATION_TYPE_INPUT_SWIFT = 51 + OPERATION_TYPE_OUTPUT_ACQUIRING = 53 + OPERATION_TYPE_INPUT_ACQUIRING = 54 + OPERATION_TYPE_OUTPUT_PENALTY = 55 + OPERATION_TYPE_ADVICE_FEE = 56 + OPERATION_TYPE_TRANS_IIS_BS = 57 + OPERATION_TYPE_TRANS_BS_BS = 58 + OPERATION_TYPE_OUT_MULTI = 59 + OPERATION_TYPE_INP_MULTI = 60 + OPERATION_TYPE_OVER_PLACEMENT = 61 + OPERATION_TYPE_OVER_COM = 62 + OPERATION_TYPE_OVER_INCOME = 63 + OPERATION_TYPE_OPTION_EXPIRATION = 64 + OPERATION_TYPE_FUTURE_EXPIRATION = 65 + OPERATION_TYPE_OTHER_FEE = 66 + OPERATION_TYPE_OTHER = 67 + OPERATION_TYPE_DFA_REDEMPTION = 68 + OPERATION_TYPE_PRIMARY_ORDER = 69 + + +class AccessLevel(_grpc_helpers.Enum): + ACCOUNT_ACCESS_LEVEL_UNSPECIFIED = 0 + ACCOUNT_ACCESS_LEVEL_FULL_ACCESS = 1 + ACCOUNT_ACCESS_LEVEL_READ_ONLY = 2 + ACCOUNT_ACCESS_LEVEL_NO_ACCESS = 3 + + +class CouponType(_grpc_helpers.Enum): + COUPON_TYPE_UNSPECIFIED = 0 + COUPON_TYPE_CONSTANT = 1 + COUPON_TYPE_FLOATING = 2 + COUPON_TYPE_DISCOUNT = 3 + COUPON_TYPE_MORTGAGE = 4 + COUPON_TYPE_FIX = 5 + COUPON_TYPE_VARIABLE = 6 + COUPON_TYPE_OTHER = 7 + + +class AssetType(_grpc_helpers.Enum): + ASSET_TYPE_UNSPECIFIED = 0 + ASSET_TYPE_CURRENCY = 1 + ASSET_TYPE_COMMODITY = 2 + ASSET_TYPE_INDEX = 3 + ASSET_TYPE_SECURITY = 4 + + +class StructuredProductType(_grpc_helpers.Enum): + SP_TYPE_UNSPECIFIED = 0 + SP_TYPE_DELIVERABLE = 1 + SP_TYPE_NON_DELIVERABLE = 2 + + +class EditFavoritesActionType(_grpc_helpers.Enum): + EDIT_FAVORITES_ACTION_TYPE_UNSPECIFIED = 0 + EDIT_FAVORITES_ACTION_TYPE_ADD = 1 + EDIT_FAVORITES_ACTION_TYPE_DEL = 2 + + +class RealExchange(_grpc_helpers.Enum): + REAL_EXCHANGE_UNSPECIFIED = 0 + REAL_EXCHANGE_MOEX = 1 + REAL_EXCHANGE_RTS = 2 + REAL_EXCHANGE_OTC = 3 + REAL_EXCHANGE_DEALER = 4 + + +class PortfolioSubscriptionStatus(_grpc_helpers.Enum): + PORTFOLIO_SUBSCRIPTION_STATUS_UNSPECIFIED = 0 + PORTFOLIO_SUBSCRIPTION_STATUS_SUCCESS = 1 + PORTFOLIO_SUBSCRIPTION_STATUS_ACCOUNT_NOT_FOUND = 2 + PORTFOLIO_SUBSCRIPTION_STATUS_INTERNAL_ERROR = 3 + + +class InstrumentType(_grpc_helpers.Enum): + INSTRUMENT_TYPE_UNSPECIFIED = 0 + INSTRUMENT_TYPE_BOND = 1 + INSTRUMENT_TYPE_SHARE = 2 + INSTRUMENT_TYPE_CURRENCY = 3 + INSTRUMENT_TYPE_ETF = 4 + INSTRUMENT_TYPE_FUTURES = 5 + INSTRUMENT_TYPE_SP = 6 + INSTRUMENT_TYPE_OPTION = 7 + INSTRUMENT_TYPE_CLEARING_CERTIFICATE = 8 + INSTRUMENT_TYPE_INDEX = 9 + INSTRUMENT_TYPE_COMMODITY = 10 + INSTRUMENT_TYPE_DFA = 11 + + +class OptionDirection(_grpc_helpers.Enum): + OPTION_DIRECTION_UNSPECIFIED = 0 + OPTION_DIRECTION_PUT = 1 + OPTION_DIRECTION_CALL = 2 + + +class OptionPaymentType(_grpc_helpers.Enum): + OPTION_PAYMENT_TYPE_UNSPECIFIED = 0 + OPTION_PAYMENT_TYPE_PREMIUM = 1 + OPTION_PAYMENT_TYPE_MARGINAL = 2 + + +class OptionStyle(_grpc_helpers.Enum): + OPTION_STYLE_UNSPECIFIED = 0 + OPTION_STYLE_AMERICAN = 1 + OPTION_STYLE_EUROPEAN = 2 + + +class OptionSettlementType(_grpc_helpers.Enum): + OPTION_EXECUTION_TYPE_UNSPECIFIED = 0 + OPTION_EXECUTION_TYPE_PHYSICAL_DELIVERY = 1 + OPTION_EXECUTION_TYPE_CASH_SETTLEMENT = 2 + + +class PositionsAccountSubscriptionStatus(_grpc_helpers.Enum): + POSITIONS_SUBSCRIPTION_STATUS_UNSPECIFIED = 0 + POSITIONS_SUBSCRIPTION_STATUS_SUCCESS = 1 + POSITIONS_SUBSCRIPTION_STATUS_ACCOUNT_NOT_FOUND = 2 + POSITIONS_SUBSCRIPTION_STATUS_INTERNAL_ERROR = 3 + + +class RiskLevel(_grpc_helpers.Enum): + RISK_LEVEL_UNSPECIFIED = 0 + RISK_LEVEL_LOW = 1 + RISK_LEVEL_MODERATE = 2 + RISK_LEVEL_HIGH = 3 + + +class StopOrderStatusOption(_grpc_helpers.Enum): + STOP_ORDER_STATUS_UNSPECIFIED = 0 + STOP_ORDER_STATUS_ALL = 1 + STOP_ORDER_STATUS_ACTIVE = 2 + STOP_ORDER_STATUS_EXECUTED = 3 + STOP_ORDER_STATUS_CANCELED = 4 + STOP_ORDER_STATUS_EXPIRED = 5 + + +class ExchangeOrderType(_grpc_helpers.Enum): + EXCHANGE_ORDER_TYPE_UNSPECIFIED = 0 + EXCHANGE_ORDER_TYPE_MARKET = 1 + EXCHANGE_ORDER_TYPE_LIMIT = 2 + + +class TakeProfitType(_grpc_helpers.Enum): + TAKE_PROFIT_TYPE_UNSPECIFIED = 0 + TAKE_PROFIT_TYPE_REGULAR = 1 + TAKE_PROFIT_TYPE_TRAILING = 2 + + +class TrailingValueType(_grpc_helpers.Enum): + TRAILING_VALUE_UNSPECIFIED = 0 + TRAILING_VALUE_ABSOLUTE = 1 + TRAILING_VALUE_RELATIVE = 2 + + +class TrailingStopStatus(_grpc_helpers.Enum): + TRAILING_STOP_UNSPECIFIED = 0 + TRAILING_STOP_ACTIVE = 1 + TRAILING_STOP_ACTIVATED = 2 + + +class PriceType(_grpc_helpers.Enum): + PRICE_TYPE_UNSPECIFIED = 0 + PRICE_TYPE_POINT = 1 + PRICE_TYPE_CURRENCY = 2 + + +class TimeInForceType(_grpc_helpers.Enum): + TIME_IN_FORCE_UNSPECIFIED = 0 + TIME_IN_FORCE_DAY = 1 + TIME_IN_FORCE_FILL_AND_KILL = 2 + TIME_IN_FORCE_FILL_OR_KILL = 3 + + +class OrderIdType(_grpc_helpers.Enum): + ORDER_ID_TYPE_UNSPECIFIED = 0 + ORDER_ID_TYPE_EXCHANGE = 1 + ORDER_ID_TYPE_REQUEST = 2 + + +class EventType(_grpc_helpers.Enum): + EVENT_TYPE_UNSPECIFIED = 0 + EVENT_TYPE_CPN = 1 + EVENT_TYPE_CALL = 2 + EVENT_TYPE_MTY = 3 + EVENT_TYPE_CONV = 4 + + +class AssetReportPeriodType(_grpc_helpers.Enum): + PERIOD_TYPE_UNSPECIFIED = 0 + PERIOD_TYPE_QUARTER = 1 + PERIOD_TYPE_SEMIANNUAL = 2 + PERIOD_TYPE_ANNUAL = 3 + + +class Recommendation(_grpc_helpers.Enum): + RECOMMENDATION_UNSPECIFIED = 0 + RECOMMENDATION_BUY = 1 + RECOMMENDATION_HOLD = 2 + RECOMMENDATION_SELL = 3 + + +class OrderBookType(_grpc_helpers.Enum): + ORDERBOOK_TYPE_UNSPECIFIED = 0 + ORDERBOOK_TYPE_EXCHANGE = 1 + ORDERBOOK_TYPE_DEALER = 2 + ORDERBOOK_TYPE_ALL = 3 + + +class BondType(_grpc_helpers.Enum): + BOND_TYPE_UNSPECIFIED = 0 + BOND_TYPE_REPLACED = 1 + + +class InstrumentExchangeType(_grpc_helpers.Enum): + INSTRUMENT_EXCHANGE_UNSPECIFIED = 0 + INSTRUMENT_EXCHANGE_DEALER = 1 + + +class TradeSourceType(_grpc_helpers.Enum): + TRADE_SOURCE_UNSPECIFIED = 0 + TRADE_SOURCE_EXCHANGE = 1 + TRADE_SOURCE_DEALER = 2 + TRADE_SOURCE_ALL = 3 + + +class ResultSubscriptionStatus(_grpc_helpers.Enum): + RESULT_SUBSCRIPTION_STATUS_UNSPECIFIED = 0 + RESULT_SUBSCRIPTION_STATUS_OK = 1 + RESULT_SUBSCRIPTION_STATUS_ERROR = 13 + + +class MarkerType(_grpc_helpers.Enum): + MARKER_UNKNOWN = 0 + MARKER_BROKER = 1 + MARKER_CHAT = 2 + MARKER_PAPER = 3 + MARKER_MARGIN = 4 + MARKER_TKBNM = 5 + MARKER_SHORT = 6 + MARKER_SPECMM = 7 + MARKER_PO = 8 + + +class StatusCauseInfo(_grpc_helpers.Enum): + CAUSE_UNSPECIFIED = 0 + CAUSE_CANCELLED_BY_CLIENT = 15 + CAUSE_CANCELLED_BY_EXCHANGE = 1 + CAUSE_CANCELLED_NOT_ENOUGH_POSITION = 2 + CAUSE_CANCELLED_BY_CLIENT_BLOCK = 3 + CAUSE_REJECTED_BY_BROKER = 4 + CAUSE_REJECTED_BY_EXCHANGE = 5 + CAUSE_CANCELLED_BY_BROKER = 6 + + +class LastPriceType(_grpc_helpers.Enum): + LAST_PRICE_UNSPECIFIED = 0 + LAST_PRICE_EXCHANGE = 1 + LAST_PRICE_DEALER = 2 + + +class StrategyType(_grpc_helpers.Enum): + STRATEGY_TYPE_UNSPECIFIED = 0 + STRATEGY_TYPE_TECHNICAL = 1 + STRATEGY_TYPE_FUNDAMENTAL = 2 + + +class SignalDirection(_grpc_helpers.Enum): + SIGNAL_DIRECTION_UNSPECIFIED = 0 + SIGNAL_DIRECTION_BUY = 1 + SIGNAL_DIRECTION_SELL = 2 + + +class SignalState(_grpc_helpers.Enum): + SIGNAL_STATE_UNSPECIFIED = 0 + SIGNAL_STATE_ACTIVE = 1 + SIGNAL_STATE_CLOSED = 2 + SIGNAL_STATE_ALL = 3 + + +@dataclass(eq=False, repr=True) +class MoneyValue(_grpc_helpers.Message): + currency: str = _grpc_helpers.string_field(1) + units: int = _grpc_helpers.int64_field(2) + nano: int = _grpc_helpers.int32_field(3) + + +@dataclass(eq=False, repr=True) +class Quotation(_grpc_helpers.Message, SupportsAbs): + units: int = _grpc_helpers.int64_field(1) + nano: int = _grpc_helpers.int32_field(2) + + def __init__(self, units: int, nano: int): + max_quotation_nano = 1_000_000_000 + self.units = units + nano // max_quotation_nano + self.nano = nano % max_quotation_nano + + def __add__(self, other: "Quotation") -> "Quotation": + return Quotation( + units=self.units + other.units, + nano=self.nano + other.nano, + ) + + def __sub__(self, other: "Quotation") -> "Quotation": + return Quotation( + units=self.units - other.units, + nano=self.nano - other.nano, + ) + + def __hash__(self) -> int: + return hash((self.units, self.nano)) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, Quotation): + return NotImplemented + return self.units == other.units and self.nano == other.nano + + def __lt__(self, other: "Quotation") -> bool: + return self.units < other.units or ( + self.units == other.units and self.nano < other.nano + ) + + def __le__(self, other: "Quotation") -> bool: + return self.units < other.units or ( + self.units == other.units and self.nano <= other.nano + ) + + def __gt__(self, other: "Quotation") -> bool: + return self.units > other.units or ( + self.units == other.units and self.nano > other.nano + ) + + def __ge__(self, other: "Quotation") -> bool: + return self.units > other.units or ( + self.units == other.units and self.nano >= other.nano + ) + + def __abs__(self) -> "Quotation": + return Quotation(units=abs(self.units), nano=abs(self.nano)) + + +@dataclass(eq=False, repr=True) +class PingRequest(_grpc_helpers.Message): + time: Optional[datetime] = _grpc_helpers.message_field(1, optional=True) + + +@dataclass(eq=False, repr=True) +class PingDelaySettings(_grpc_helpers.Message): + ping_delay_ms: Optional[int] = _grpc_helpers.int32_field(1, optional=True) + + +@dataclass(eq=False, repr=True) +class Ping(_grpc_helpers.Message): + time: datetime = _grpc_helpers.int64_field(1) + stream_id: str = _grpc_helpers.string_field(2) + ping_request_time: Optional[datetime] = _grpc_helpers.message_field( + 4, optional=True + ) + + +@dataclass(eq=False, repr=True) +class TradingSchedulesRequest(_grpc_helpers.Message): + exchange: Optional[str] = _grpc_helpers.string_field(1) + from_: Optional[datetime] = _grpc_helpers.message_field(2) + to: Optional[datetime] = _grpc_helpers.message_field(3) + + +@dataclass(eq=False, repr=True) +class TradingSchedulesResponse(_grpc_helpers.Message): + exchanges: List["TradingSchedule"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class TradingSchedule(_grpc_helpers.Message): + exchange: str = _grpc_helpers.string_field(1) + days: List["TradingDay"] = _grpc_helpers.message_field(2) + + +@dataclass(eq=False, repr=True) +class TradingDay(_grpc_helpers.Message): # pylint:disable=too-many-instance-attributes + date: datetime = _grpc_helpers.message_field(1) + is_trading_day: bool = _grpc_helpers.bool_field(2) + start_time: datetime = _grpc_helpers.message_field(3) + end_time: datetime = _grpc_helpers.message_field(4) + # reserved 5,6 + opening_auction_start_time: datetime = _grpc_helpers.message_field(7) + closing_auction_end_time: datetime = _grpc_helpers.message_field(8) + evening_opening_auction_start_time: datetime = _grpc_helpers.message_field(9) + evening_start_time: datetime = _grpc_helpers.message_field(10) + evening_end_time: datetime = _grpc_helpers.message_field(11) + clearing_start_time: datetime = _grpc_helpers.message_field(12) + clearing_end_time: datetime = _grpc_helpers.message_field(13) + premarket_start_time: datetime = _grpc_helpers.message_field(14) + premarket_end_time: datetime = _grpc_helpers.message_field(15) + closing_auction_start_time: datetime = _grpc_helpers.message_field(16) + opening_auction_end_time: datetime = _grpc_helpers.message_field(17) + intervals: List["TradingInterval"] = _grpc_helpers.message_field(18) + + +@dataclass(eq=False, repr=True) +class InstrumentRequest(_grpc_helpers.Message): + id_type: "InstrumentIdType" = _grpc_helpers.enum_field(1) + class_code: Optional[str] = _grpc_helpers.string_field(2) + id: str = _grpc_helpers.string_field(3) + + +@dataclass(eq=False, repr=True) +class InstrumentsRequest(_grpc_helpers.Message): + instrument_status: Optional["InstrumentStatus"] = _grpc_helpers.enum_field(1) + instrument_exchange: Optional["InstrumentExchangeType"] = _grpc_helpers.enum_field( + 2 + ) + + +@dataclass(eq=False, repr=True) +class FilterOptionsRequest(_grpc_helpers.Message): + basic_asset_uid: Optional[str] = _grpc_helpers.string_field(1) + basic_asset_position_uid: Optional[str] = _grpc_helpers.string_field(2) + + +@dataclass(eq=False, repr=True) +class BondResponse(_grpc_helpers.Message): + instrument: "Bond" = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class BondsResponse(_grpc_helpers.Message): + instruments: List["Bond"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class GetBondCouponsRequest(_grpc_helpers.Message): + figi: str = _grpc_helpers.string_field(1) + from_: Optional[datetime] = _grpc_helpers.message_field(2) + to: Optional[datetime] = _grpc_helpers.message_field(3) + instrument_id: str = _grpc_helpers.string_field(4) + + +@dataclass(eq=False, repr=True) +class GetBondCouponsResponse(_grpc_helpers.Message): + events: List["Coupon"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class GetBondEventsRequest(_grpc_helpers.Message): + from_: Optional[datetime] = _grpc_helpers.message_field(2) + to: Optional[datetime] = _grpc_helpers.message_field(3) + instrument_id: str = _grpc_helpers.string_field(4) + type: "EventType" = _grpc_helpers.enum_field(5) + + +@dataclass(eq=False, repr=True) +class BondEvent(_grpc_helpers.Message): + instrument_id: str = _grpc_helpers.string_field(2) + event_number: int = _grpc_helpers.int32_field(3) + event_date: datetime = _grpc_helpers.message_field(4) + event_type: "EventType" = _grpc_helpers.enum_field(5) + event_total_vol: "Quotation" = _grpc_helpers.message_field(6) + fix_date: datetime = _grpc_helpers.message_field(7) + rate_date: datetime = _grpc_helpers.message_field(8) + default_date: datetime = _grpc_helpers.message_field(9) + real_pay_date: datetime = _grpc_helpers.message_field(10) + pay_date: datetime = _grpc_helpers.message_field(11) + pay_one_bond: "MoneyValue" = _grpc_helpers.message_field(12) + money_flow_val: "MoneyValue" = _grpc_helpers.message_field(13) + execution: str = _grpc_helpers.string_field(14) + operation_type: str = _grpc_helpers.string_field(15) + value: "Quotation" = _grpc_helpers.message_field(16) + note: str = _grpc_helpers.string_field(17) + convert_to_fin_tool_id: str = _grpc_helpers.string_field(18) + coupon_start_date: datetime = _grpc_helpers.message_field(19) + coupon_end_date: datetime = _grpc_helpers.message_field(20) + coupon_period: int = _grpc_helpers.int32_field(21) + coupon_interest_rate: "Quotation" = _grpc_helpers.message_field(22) + + +@dataclass(eq=False, repr=True) +class GetBondEventsResponse(_grpc_helpers.Message): + events: List["BondEvent"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class Coupon(_grpc_helpers.Message): + figi: str = _grpc_helpers.string_field(1) + coupon_date: datetime = _grpc_helpers.message_field(2) + coupon_number: int = _grpc_helpers.int64_field(3) + fix_date: datetime = _grpc_helpers.message_field(4) + pay_one_bond: "MoneyValue" = _grpc_helpers.message_field(5) + coupon_type: "CouponType" = _grpc_helpers.enum_field(6) + coupon_start_date: datetime = _grpc_helpers.message_field(7) + coupon_end_date: datetime = _grpc_helpers.message_field(8) + coupon_period: int = _grpc_helpers.int32_field(9) + + +@dataclass(eq=False, repr=True) +class CurrencyResponse(_grpc_helpers.Message): + instrument: "Currency" = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class CurrenciesResponse(_grpc_helpers.Message): + instruments: List["Currency"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class EtfResponse(_grpc_helpers.Message): + instrument: "Etf" = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class EtfsResponse(_grpc_helpers.Message): + instruments: List["Etf"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class FutureResponse(_grpc_helpers.Message): + instrument: "Future" = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class FuturesResponse(_grpc_helpers.Message): + instruments: List["Future"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class OptionResponse(_grpc_helpers.Message): + instrument: "Option" = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class OptionsResponse(_grpc_helpers.Message): + instruments: List["Option"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class Option(_grpc_helpers.Message): + uid: str = _grpc_helpers.string_field(1) + position_uid: str = _grpc_helpers.string_field(2) + ticker: str = _grpc_helpers.string_field(3) + class_code: str = _grpc_helpers.string_field(4) + basic_asset_position_uid: str = _grpc_helpers.string_field(5) + + trading_status: "SecurityTradingStatus" = _grpc_helpers.message_field(21) + real_exchange: "RealExchange" = _grpc_helpers.message_field(31) + direction: "OptionDirection" = _grpc_helpers.message_field(41) + payment_type: "OptionPaymentType" = _grpc_helpers.message_field(42) + style: "OptionStyle" = _grpc_helpers.message_field(43) + settlement_type: "OptionSettlementType" = _grpc_helpers.message_field(44) + + name: str = _grpc_helpers.string_field(101) + currency: str = _grpc_helpers.string_field(111) + settlement_currency: str = _grpc_helpers.string_field(112) + asset_type: str = _grpc_helpers.string_field(131) + basic_asset: str = _grpc_helpers.string_field(132) + exchange: str = _grpc_helpers.string_field(141) + country_of_risk: str = _grpc_helpers.string_field(151) + country_of_risk_name: str = _grpc_helpers.string_field(152) + sector: str = _grpc_helpers.string_field(161) + brand: "BrandData" = _grpc_helpers.message_field(162) + + lot: int = _grpc_helpers.int32_field(201) + basic_asset_size: "Quotation" = _grpc_helpers.message_field(211) + klong: "Quotation" = _grpc_helpers.message_field(221) + kshort: "Quotation" = _grpc_helpers.message_field(222) + dlong: "Quotation" = _grpc_helpers.message_field(223) + dshort: "Quotation" = _grpc_helpers.message_field(224) + dlong_min: "Quotation" = _grpc_helpers.message_field(225) + dshort_min: "Quotation" = _grpc_helpers.message_field(226) + min_price_increment: "Quotation" = _grpc_helpers.message_field(231) + strike_price: "MoneyValue" = _grpc_helpers.message_field(241) + + dlong_client: "Quotation" = _grpc_helpers.message_field(290) + dshort_client: "Quotation" = _grpc_helpers.message_field(291) + + expiration_date: datetime = _grpc_helpers.message_field(301) + first_trade_date: datetime = _grpc_helpers.message_field(311) + last_trade_date: datetime = _grpc_helpers.message_field(312) + first_1min_candle_date: datetime = _grpc_helpers.message_field(321) + first_1day_candle_date: datetime = _grpc_helpers.message_field(322) + + short_enabled_flag: bool = _grpc_helpers.bool_field(401) + for_iis_flag: bool = _grpc_helpers.bool_field(402) + otc_flag: bool = _grpc_helpers.bool_field(403) + buy_available_flag: bool = _grpc_helpers.bool_field(404) + sell_available_flag: bool = _grpc_helpers.bool_field(405) + for_qual_investor_flag: bool = _grpc_helpers.bool_field(406) + weekend_flag: bool = _grpc_helpers.bool_field(407) + blocked_tca_flag: bool = _grpc_helpers.bool_field(408) + api_trade_available_flag: bool = _grpc_helpers.bool_field(409) + required_tests: List[str] = _grpc_helpers.string_field(410) + + +@dataclass(eq=False, repr=True) +class ShareResponse(_grpc_helpers.Message): + instrument: "Share" = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class SharesResponse(_grpc_helpers.Message): + instruments: List["Share"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class Bond(_grpc_helpers.Message): # pylint:disable=too-many-instance-attributes + figi: str = _grpc_helpers.string_field(1) + ticker: str = _grpc_helpers.string_field(2) + class_code: str = _grpc_helpers.string_field(3) + isin: str = _grpc_helpers.string_field(4) + lot: int = _grpc_helpers.int32_field(5) + currency: str = _grpc_helpers.string_field(6) + klong: "Quotation" = _grpc_helpers.message_field(7) + kshort: "Quotation" = _grpc_helpers.message_field(8) + dlong: "Quotation" = _grpc_helpers.message_field(9) + dshort: "Quotation" = _grpc_helpers.message_field(10) + dlong_min: "Quotation" = _grpc_helpers.message_field(11) + dshort_min: "Quotation" = _grpc_helpers.message_field(12) + short_enabled_flag: bool = _grpc_helpers.bool_field(13) + name: str = _grpc_helpers.string_field(15) + exchange: str = _grpc_helpers.string_field(16) + coupon_quantity_per_year: int = _grpc_helpers.int32_field(17) + maturity_date: datetime = _grpc_helpers.message_field(18) + nominal: "MoneyValue" = _grpc_helpers.message_field(19) + initial_nominal: "MoneyValue" = _grpc_helpers.message_field(20) + state_reg_date: datetime = _grpc_helpers.message_field(21) + placement_date: datetime = _grpc_helpers.message_field(22) + placement_price: "MoneyValue" = _grpc_helpers.message_field(23) + aci_value: "MoneyValue" = _grpc_helpers.message_field(24) + country_of_risk: str = _grpc_helpers.string_field(25) + country_of_risk_name: str = _grpc_helpers.string_field(26) + sector: str = _grpc_helpers.string_field(27) + issue_kind: str = _grpc_helpers.string_field(28) + issue_size: int = _grpc_helpers.int64_field(29) + issue_size_plan: int = _grpc_helpers.int64_field(30) + trading_status: "SecurityTradingStatus" = _grpc_helpers.enum_field(31) + otc_flag: bool = _grpc_helpers.bool_field(32) + buy_available_flag: bool = _grpc_helpers.bool_field(33) + sell_available_flag: bool = _grpc_helpers.bool_field(34) + floating_coupon_flag: bool = _grpc_helpers.bool_field(35) + perpetual_flag: bool = _grpc_helpers.bool_field(36) + amortization_flag: bool = _grpc_helpers.bool_field(37) + min_price_increment: "Quotation" = _grpc_helpers.message_field(38) + api_trade_available_flag: bool = _grpc_helpers.bool_field(39) + uid: str = _grpc_helpers.string_field(40) + real_exchange: "RealExchange" = _grpc_helpers.message_field(41) + position_uid: str = _grpc_helpers.string_field(42) + asset_uid: str = _grpc_helpers.string_field(43) + for_iis_flag: bool = _grpc_helpers.bool_field(51) + for_qual_investor_flag: bool = _grpc_helpers.bool_field(52) + weekend_flag: bool = _grpc_helpers.bool_field(53) + blocked_tca_flag: bool = _grpc_helpers.bool_field(54) + subordinated_flag: bool = _grpc_helpers.bool_field(55) + liquidity_flag: bool = _grpc_helpers.bool_field(56) + first_1min_candle_date: datetime = _grpc_helpers.message_field(61) + first_1day_candle_date: datetime = _grpc_helpers.message_field(62) + risk_level: "RiskLevel" = _grpc_helpers.enum_field(63) + brand: "BrandData" = _grpc_helpers.message_field(64) + bond_type: "BondType" = _grpc_helpers.message_field(65) + call_date: datetime = _grpc_helpers.message_field(69) + dlong_client: "Quotation" = _grpc_helpers.message_field(90) + dshort_client: "Quotation" = _grpc_helpers.message_field(91) + required_tests: List[str] = _grpc_helpers.string_field(44) + + +@dataclass(eq=False, repr=True) +class Currency(_grpc_helpers.Message): # pylint:disable=too-many-instance-attributes + figi: str = _grpc_helpers.string_field(1) + ticker: str = _grpc_helpers.string_field(2) + class_code: str = _grpc_helpers.string_field(3) + isin: str = _grpc_helpers.string_field(4) + lot: int = _grpc_helpers.int32_field(5) + currency: str = _grpc_helpers.string_field(6) + klong: "Quotation" = _grpc_helpers.message_field(7) + kshort: "Quotation" = _grpc_helpers.message_field(8) + dlong: "Quotation" = _grpc_helpers.message_field(9) + dshort: "Quotation" = _grpc_helpers.message_field(10) + dlong_min: "Quotation" = _grpc_helpers.message_field(11) + dshort_min: "Quotation" = _grpc_helpers.message_field(12) + short_enabled_flag: bool = _grpc_helpers.bool_field(13) + name: str = _grpc_helpers.string_field(15) + exchange: str = _grpc_helpers.string_field(16) + nominal: "MoneyValue" = _grpc_helpers.message_field(17) + country_of_risk: str = _grpc_helpers.string_field(18) + country_of_risk_name: str = _grpc_helpers.string_field(19) + trading_status: "SecurityTradingStatus" = _grpc_helpers.enum_field(20) + otc_flag: bool = _grpc_helpers.bool_field(21) + buy_available_flag: bool = _grpc_helpers.bool_field(22) + sell_available_flag: bool = _grpc_helpers.bool_field(23) + iso_currency_name: str = _grpc_helpers.string_field(24) + min_price_increment: "Quotation" = _grpc_helpers.message_field(25) + api_trade_available_flag: bool = _grpc_helpers.bool_field(26) + uid: str = _grpc_helpers.string_field(27) + real_exchange: "RealExchange" = _grpc_helpers.message_field(28) + position_uid: str = _grpc_helpers.string_field(29) + required_tests: List[str] = _grpc_helpers.string_field(30) + asset_uid: str = _grpc_helpers.string_field(31) + for_iis_flag: bool = _grpc_helpers.bool_field(41) + for_qual_investor_flag: bool = _grpc_helpers.bool_field(52) + weekend_flag: bool = _grpc_helpers.bool_field(53) + blocked_tca_flag: bool = _grpc_helpers.bool_field(54) + first_1min_candle_date: datetime = _grpc_helpers.message_field(56) + first_1day_candle_date: datetime = _grpc_helpers.message_field(57) + brand: "BrandData" = _grpc_helpers.message_field(60) + dlong_client: "Quotation" = _grpc_helpers.message_field(90) + dshort_client: "Quotation" = _grpc_helpers.message_field(91) + + +@dataclass(eq=False, repr=True) +class Etf(_grpc_helpers.Message): # pylint:disable=too-many-instance-attributes + figi: str = _grpc_helpers.string_field(1) + ticker: str = _grpc_helpers.string_field(2) + class_code: str = _grpc_helpers.string_field(3) + isin: str = _grpc_helpers.string_field(4) + lot: int = _grpc_helpers.int32_field(5) + currency: str = _grpc_helpers.string_field(6) + klong: "Quotation" = _grpc_helpers.message_field(7) + kshort: "Quotation" = _grpc_helpers.message_field(8) + dlong: "Quotation" = _grpc_helpers.message_field(9) + dshort: "Quotation" = _grpc_helpers.message_field(10) + dlong_min: "Quotation" = _grpc_helpers.message_field(11) + dshort_min: "Quotation" = _grpc_helpers.message_field(12) + short_enabled_flag: bool = _grpc_helpers.bool_field(13) + name: str = _grpc_helpers.string_field(15) + exchange: str = _grpc_helpers.string_field(16) + fixed_commission: "Quotation" = _grpc_helpers.message_field(17) + focus_type: str = _grpc_helpers.string_field(18) + released_date: datetime = _grpc_helpers.message_field(19) + num_shares: "Quotation" = _grpc_helpers.message_field(20) + country_of_risk: str = _grpc_helpers.string_field(21) + country_of_risk_name: str = _grpc_helpers.string_field(22) + sector: str = _grpc_helpers.string_field(23) + rebalancing_freq: str = _grpc_helpers.string_field(24) + trading_status: "SecurityTradingStatus" = _grpc_helpers.enum_field(25) + otc_flag: bool = _grpc_helpers.bool_field(26) + buy_available_flag: bool = _grpc_helpers.bool_field(27) + sell_available_flag: bool = _grpc_helpers.bool_field(28) + min_price_increment: "Quotation" = _grpc_helpers.message_field(29) + api_trade_available_flag: bool = _grpc_helpers.bool_field(30) + uid: str = _grpc_helpers.string_field(31) + real_exchange: "RealExchange" = _grpc_helpers.message_field(32) + position_uid: str = _grpc_helpers.string_field(33) + asset_uid: str = _grpc_helpers.string_field(34) + instrument_exchange: "InstrumentExchangeType" = _grpc_helpers.message_field(35) + required_tests: List[str] = _grpc_helpers.string_field(36) + for_iis_flag: bool = _grpc_helpers.bool_field(41) + for_qual_investor_flag: bool = _grpc_helpers.bool_field(42) + weekend_flag: bool = _grpc_helpers.bool_field(43) + blocked_tca_flag: bool = _grpc_helpers.bool_field(44) + liquidity_flag: bool = _grpc_helpers.bool_field(45) + first_1min_candle_date: datetime = _grpc_helpers.message_field(56) + first_1day_candle_date: datetime = _grpc_helpers.message_field(57) + brand: "BrandData" = _grpc_helpers.message_field(60) + dlong_client: "Quotation" = _grpc_helpers.message_field(90) + dshort_client: "Quotation" = _grpc_helpers.message_field(91) + + +@dataclass(eq=False, repr=True) +class Future(_grpc_helpers.Message): # pylint:disable=too-many-instance-attributes + figi: str = _grpc_helpers.string_field(1) + ticker: str = _grpc_helpers.string_field(2) + class_code: str = _grpc_helpers.string_field(3) + lot: int = _grpc_helpers.int32_field(4) + currency: str = _grpc_helpers.string_field(5) + klong: "Quotation" = _grpc_helpers.message_field(6) + kshort: "Quotation" = _grpc_helpers.message_field(7) + dlong: "Quotation" = _grpc_helpers.message_field(8) + dshort: "Quotation" = _grpc_helpers.message_field(9) + dlong_min: "Quotation" = _grpc_helpers.message_field(10) + dshort_min: "Quotation" = _grpc_helpers.message_field(11) + short_enabled_flag: bool = _grpc_helpers.bool_field(12) + name: str = _grpc_helpers.string_field(13) + exchange: str = _grpc_helpers.string_field(14) + first_trade_date: datetime = _grpc_helpers.message_field(15) + last_trade_date: datetime = _grpc_helpers.message_field(16) + futures_type: str = _grpc_helpers.string_field(17) + asset_type: str = _grpc_helpers.string_field(18) + basic_asset: str = _grpc_helpers.string_field(19) + basic_asset_size: "Quotation" = _grpc_helpers.message_field(20) + country_of_risk: str = _grpc_helpers.string_field(21) + country_of_risk_name: str = _grpc_helpers.string_field(22) + sector: str = _grpc_helpers.string_field(23) + expiration_date: datetime = _grpc_helpers.message_field(24) + trading_status: "SecurityTradingStatus" = _grpc_helpers.enum_field(25) + otc_flag: bool = _grpc_helpers.bool_field(26) + buy_available_flag: bool = _grpc_helpers.bool_field(27) + sell_available_flag: bool = _grpc_helpers.bool_field(28) + min_price_increment: "Quotation" = _grpc_helpers.message_field(29) + api_trade_available_flag: bool = _grpc_helpers.bool_field(30) + uid: str = _grpc_helpers.string_field(31) + real_exchange: "RealExchange" = _grpc_helpers.message_field(32) + position_uid: str = _grpc_helpers.string_field(33) + basic_asset_position_uid: str = _grpc_helpers.string_field(34) + required_tests: List[str] = _grpc_helpers.string_field(35) + for_iis_flag: bool = _grpc_helpers.bool_field(41) + for_qual_investor_flag: bool = _grpc_helpers.bool_field(42) + weekend_flag: bool = _grpc_helpers.bool_field(43) + blocked_tca_flag: bool = _grpc_helpers.bool_field(44) + first_1min_candle_date: datetime = _grpc_helpers.message_field(56) + first_1day_candle_date: datetime = _grpc_helpers.message_field(57) + initial_margin_on_buy: "MoneyValue" = _grpc_helpers.message_field(61) + initial_margin_on_sell: "MoneyValue" = _grpc_helpers.message_field(62) + min_price_increment_amount: "Quotation" = _grpc_helpers.message_field(63) + brand: "BrandData" = _grpc_helpers.message_field(64) + dlong_client: "Quotation" = _grpc_helpers.message_field(90) + dshort_client: "Quotation" = _grpc_helpers.message_field(91) + + +@dataclass(eq=False, repr=True) +class Share(_grpc_helpers.Message): # pylint:disable=too-many-instance-attributes + figi: str = _grpc_helpers.string_field(1) + ticker: str = _grpc_helpers.string_field(2) + class_code: str = _grpc_helpers.string_field(3) + isin: str = _grpc_helpers.string_field(4) + lot: int = _grpc_helpers.int32_field(5) + currency: str = _grpc_helpers.string_field(6) + klong: "Quotation" = _grpc_helpers.message_field(7) + kshort: "Quotation" = _grpc_helpers.message_field(8) + dlong: "Quotation" = _grpc_helpers.message_field(9) + dshort: "Quotation" = _grpc_helpers.message_field(10) + dlong_min: "Quotation" = _grpc_helpers.message_field(11) + dshort_min: "Quotation" = _grpc_helpers.message_field(12) + short_enabled_flag: bool = _grpc_helpers.bool_field(13) + name: str = _grpc_helpers.string_field(15) + exchange: str = _grpc_helpers.string_field(16) + ipo_date: datetime = _grpc_helpers.message_field(17) + issue_size: int = _grpc_helpers.int64_field(18) + country_of_risk: str = _grpc_helpers.string_field(19) + country_of_risk_name: str = _grpc_helpers.string_field(20) + sector: str = _grpc_helpers.string_field(21) + issue_size_plan: int = _grpc_helpers.int64_field(22) + nominal: "MoneyValue" = _grpc_helpers.message_field(23) + trading_status: "SecurityTradingStatus" = _grpc_helpers.enum_field(25) + otc_flag: bool = _grpc_helpers.bool_field(26) + buy_available_flag: bool = _grpc_helpers.bool_field(27) + sell_available_flag: bool = _grpc_helpers.bool_field(28) + div_yield_flag: bool = _grpc_helpers.bool_field(29) + share_type: "ShareType" = _grpc_helpers.enum_field(30) + min_price_increment: "Quotation" = _grpc_helpers.message_field(31) + api_trade_available_flag: bool = _grpc_helpers.bool_field(32) + uid: str = _grpc_helpers.string_field(33) + real_exchange: "RealExchange" = _grpc_helpers.message_field(34) + position_uid: str = _grpc_helpers.string_field(35) + asset_uid: str = _grpc_helpers.string_field(36) + instrument_exchange: "InstrumentExchangeType" = _grpc_helpers.message_field(37) + required_tests: List[str] = _grpc_helpers.string_field(38) + for_iis_flag: bool = _grpc_helpers.bool_field(46) + for_qual_investor_flag: bool = _grpc_helpers.bool_field(47) + weekend_flag: bool = _grpc_helpers.bool_field(48) + blocked_tca_flag: bool = _grpc_helpers.bool_field(49) + liquidity_flag: bool = _grpc_helpers.bool_field(50) + first_1min_candle_date: datetime = _grpc_helpers.message_field(56) + first_1day_candle_date: datetime = _grpc_helpers.message_field(57) + brand: "BrandData" = _grpc_helpers.message_field(60) + dlong_client: "Quotation" = _grpc_helpers.message_field(90) + dshort_client: "Quotation" = _grpc_helpers.message_field(91) + + +@dataclass(eq=False, repr=True) +class GetAccruedInterestsRequest(_grpc_helpers.Message): + figi: str = _grpc_helpers.string_field(1) + from_: datetime = _grpc_helpers.message_field(2) + to: datetime = _grpc_helpers.message_field(3) + instrument_id: str = _grpc_helpers.string_field(4) + + +@dataclass(eq=False, repr=True) +class GetAccruedInterestsResponse(_grpc_helpers.Message): + accrued_interests: List["AccruedInterest"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class AccruedInterest(_grpc_helpers.Message): + date: datetime = _grpc_helpers.message_field(1) + value: "Quotation" = _grpc_helpers.message_field(2) + value_percent: "Quotation" = _grpc_helpers.message_field(3) + nominal: "Quotation" = _grpc_helpers.message_field(4) + + +@dataclass(eq=False, repr=True) +class GetFuturesMarginRequest(_grpc_helpers.Message): + figi: str = _grpc_helpers.string_field(1) + instrument_id: str = _grpc_helpers.string_field(4) + + +@dataclass(eq=False, repr=True) +class GetFuturesMarginResponse(_grpc_helpers.Message): + initial_margin_on_buy: "MoneyValue" = _grpc_helpers.message_field(1) + initial_margin_on_sell: "MoneyValue" = _grpc_helpers.message_field(2) + min_price_increment: "Quotation" = _grpc_helpers.message_field(3) + min_price_increment_amount: "Quotation" = _grpc_helpers.message_field(4) + + +@dataclass(eq=False, repr=True) +class InstrumentResponse(_grpc_helpers.Message): + instrument: "Instrument" = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class Instrument(_grpc_helpers.Message): # pylint:disable=too-many-instance-attributes + figi: str = _grpc_helpers.string_field(1) + ticker: str = _grpc_helpers.string_field(2) + class_code: str = _grpc_helpers.string_field(3) + isin: str = _grpc_helpers.string_field(4) + lot: int = _grpc_helpers.int32_field(5) + currency: str = _grpc_helpers.string_field(6) + klong: "Quotation" = _grpc_helpers.message_field(7) + kshort: "Quotation" = _grpc_helpers.message_field(8) + dlong: "Quotation" = _grpc_helpers.message_field(9) + dshort: "Quotation" = _grpc_helpers.message_field(10) + dlong_min: "Quotation" = _grpc_helpers.message_field(11) + dshort_min: "Quotation" = _grpc_helpers.message_field(12) + short_enabled_flag: bool = _grpc_helpers.bool_field(13) + name: str = _grpc_helpers.string_field(14) + exchange: str = _grpc_helpers.string_field(15) + country_of_risk: str = _grpc_helpers.string_field(16) + country_of_risk_name: str = _grpc_helpers.string_field(17) + instrument_type: str = _grpc_helpers.string_field(18) + trading_status: "SecurityTradingStatus" = _grpc_helpers.enum_field(19) + otc_flag: bool = _grpc_helpers.bool_field(20) + buy_available_flag: bool = _grpc_helpers.bool_field(21) + sell_available_flag: bool = _grpc_helpers.bool_field(22) + min_price_increment: "Quotation" = _grpc_helpers.message_field(23) + api_trade_available_flag: bool = _grpc_helpers.bool_field(24) + uid: str = _grpc_helpers.string_field(25) + real_exchange: "RealExchange" = _grpc_helpers.message_field(26) + position_uid: str = _grpc_helpers.string_field(27) + asset_uid: str = _grpc_helpers.string_field(28) + required_tests: List[str] = _grpc_helpers.string_field(29) + for_iis_flag: bool = _grpc_helpers.bool_field(36) + for_qual_investor_flag: bool = _grpc_helpers.bool_field(37) + weekend_flag: bool = _grpc_helpers.bool_field(38) + blocked_tca_flag: bool = _grpc_helpers.bool_field(39) + instrument_kind: "InstrumentType" = _grpc_helpers.enum_field(40) + first_1min_candle_date: datetime = _grpc_helpers.message_field(56) + first_1day_candle_date: datetime = _grpc_helpers.message_field(57) + brand: "BrandData" = _grpc_helpers.message_field(60) + dlong_client: "Quotation" = _grpc_helpers.message_field(490) + dshort_client: "Quotation" = _grpc_helpers.message_field(491) + + +@dataclass(eq=False, repr=True) +class GetDividendsRequest(_grpc_helpers.Message): + figi: str = _grpc_helpers.string_field(1) + from_: Optional[datetime] = _grpc_helpers.message_field(2) + to: Optional[datetime] = _grpc_helpers.message_field(3) + instrument_id: str = _grpc_helpers.string_field(4) + + +@dataclass(eq=False, repr=True) +class GetDividendsResponse(_grpc_helpers.Message): + dividends: List["Dividend"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class Dividend(_grpc_helpers.Message): + dividend_net: "MoneyValue" = _grpc_helpers.message_field(1) + payment_date: datetime = _grpc_helpers.message_field(2) + declared_date: datetime = _grpc_helpers.message_field(3) + last_buy_date: datetime = _grpc_helpers.message_field(4) + dividend_type: str = _grpc_helpers.string_field(5) + record_date: datetime = _grpc_helpers.message_field(6) + regularity: str = _grpc_helpers.string_field(7) + close_price: "MoneyValue" = _grpc_helpers.message_field(8) + yield_value: "Quotation" = _grpc_helpers.message_field(9) + created_at: datetime = _grpc_helpers.message_field(10) + + +@dataclass(eq=False, repr=True) +class AssetRequest(_grpc_helpers.Message): + id: str = _grpc_helpers.string_field(1) + + +@dataclass(eq=False, repr=True) +class AssetResponse(_grpc_helpers.Message): + asset: "AssetFull" = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class AssetsRequest(_grpc_helpers.Message): + instrument_type: Optional["InstrumentType"] = _grpc_helpers.enum_field(1) + instrument_status: Optional["InstrumentStatus"] = _grpc_helpers.enum_field(2) + + +@dataclass(eq=False, repr=True) +class AssetsResponse(_grpc_helpers.Message): + assets: List["Asset"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class AssetFull(_grpc_helpers.Message): + uid: str = _grpc_helpers.string_field(1) + type: "AssetType" = _grpc_helpers.enum_field(2) + name: str = _grpc_helpers.string_field(3) + name_brief: str = _grpc_helpers.string_field(4) + description: str = _grpc_helpers.string_field(5) + deleted_at: datetime = _grpc_helpers.message_field(6) + required_tests: List[str] = _grpc_helpers.message_field(7) + currency: "AssetCurrency" = _grpc_helpers.message_field(8, group="ext") + security: "AssetSecurity" = _grpc_helpers.message_field(9, group="ext") + gos_reg_code: str = _grpc_helpers.string_field(10) + cfi: str = _grpc_helpers.string_field(11) + code_nsd: str = _grpc_helpers.string_field(12) + status: str = _grpc_helpers.string_field(13) + brand: "Brand" = _grpc_helpers.message_field(14) + updated_at: datetime = _grpc_helpers.message_field(15) + br_code: str = _grpc_helpers.string_field(16) + br_code_name: str = _grpc_helpers.string_field(17) + instruments: List["AssetInstrument"] = _grpc_helpers.message_field(18) + + +@dataclass(eq=False, repr=True) +class Asset(_grpc_helpers.Message): + uid: str = _grpc_helpers.string_field(1) + type: "AssetType" = _grpc_helpers.enum_field(2) + name: str = _grpc_helpers.string_field(3) + instruments: List["AssetInstrument"] = _grpc_helpers.message_field(4) + + +@dataclass(eq=False, repr=True) +class AssetCurrency(_grpc_helpers.Message): + base_currency: str = _grpc_helpers.string_field(1) + + +@dataclass(eq=False, repr=True) +class AssetSecurity(_grpc_helpers.Message): + isin: str = _grpc_helpers.string_field(1) + type: str = _grpc_helpers.string_field(2) + instrument_kind: "InstrumentType" = _grpc_helpers.enum_field(10) + share: "AssetShare" = _grpc_helpers.message_field(3, group="ext") + bond: "AssetBond" = _grpc_helpers.message_field(4, group="ext") + sp: "AssetStructuredProduct" = _grpc_helpers.message_field(5, group="ext") + etf: "AssetEtf" = _grpc_helpers.message_field(6, group="ext") + clearing_certificate: "AssetClearingCertificate" = _grpc_helpers.message_field( + 7, group="ext" + ) + + +@dataclass(eq=False, repr=True) +class AssetShare(_grpc_helpers.Message): + type: "ShareType" = _grpc_helpers.enum_field(1) + issue_size: "Quotation" = _grpc_helpers.message_field(2) + nominal: "Quotation" = _grpc_helpers.message_field(3) + nominal_currency: str = _grpc_helpers.string_field(4) + primary_index: str = _grpc_helpers.string_field(5) + dividend_rate: "Quotation" = _grpc_helpers.message_field(6) + preferred_share_type: str = _grpc_helpers.string_field(7) + ipo_date: datetime = _grpc_helpers.message_field(8) + registry_date: datetime = _grpc_helpers.message_field(9) + div_yield_flag: bool = _grpc_helpers.bool_field(10) + issue_kind: str = _grpc_helpers.string_field(11) + placement_date: datetime = _grpc_helpers.message_field(12) + repres_isin: str = _grpc_helpers.string_field(13) + issue_size_plan: "Quotation" = _grpc_helpers.message_field(14) + total_float: "Quotation" = _grpc_helpers.message_field(15) + + +@dataclass(eq=False, repr=True) +class AssetBond(_grpc_helpers.Message): + current_nominal: "Quotation" = _grpc_helpers.message_field(1) + borrow_name: str = _grpc_helpers.string_field(2) + issue_size: "Quotation" = _grpc_helpers.message_field(3) + nominal: "Quotation" = _grpc_helpers.message_field(4) + nominal_currency: str = _grpc_helpers.string_field(5) + issue_kind: str = _grpc_helpers.string_field(6) + interest_kind: str = _grpc_helpers.string_field(7) + coupon_quantity_per_year: int = _grpc_helpers.int32_field(8) + indexed_nominal_flag: bool = _grpc_helpers.bool_field(9) + subordinated_flag: bool = _grpc_helpers.bool_field(10) + collateral_flag: bool = _grpc_helpers.bool_field(11) + tax_free_flag: bool = _grpc_helpers.bool_field(12) + amortization_flag: bool = _grpc_helpers.bool_field(13) + floating_coupon_flag: bool = _grpc_helpers.bool_field(14) + perpetual_flag: bool = _grpc_helpers.bool_field(15) + maturity_date: datetime = _grpc_helpers.message_field(16) + return_condition: str = _grpc_helpers.string_field(17) + state_reg_date: datetime = _grpc_helpers.message_field(18) + placement_date: datetime = _grpc_helpers.message_field(19) + placement_price: "Quotation" = _grpc_helpers.message_field(20) + issue_size_plan: "Quotation" = _grpc_helpers.message_field(21) + + +@dataclass(eq=False, repr=True) +class AssetStructuredProduct(_grpc_helpers.Message): + borrow_name: str = _grpc_helpers.string_field(1) + nominal: "Quotation" = _grpc_helpers.message_field(2) + nominal_currency: str = _grpc_helpers.string_field(3) + type: "StructuredProductType" = _grpc_helpers.enum_field(4) + logic_portfolio: str = _grpc_helpers.string_field(5) + asset_type: "AssetType" = _grpc_helpers.enum_field(6) + basic_asset: str = _grpc_helpers.string_field(7) + safety_barrier: "Quotation" = _grpc_helpers.message_field(8) + maturity_date: datetime = _grpc_helpers.message_field(9) + issue_size_plan: "Quotation" = _grpc_helpers.message_field(10) + issue_size: "Quotation" = _grpc_helpers.message_field(11) + placement_date: datetime = _grpc_helpers.message_field(12) + issue_kind: str = _grpc_helpers.string_field(13) + + +@dataclass(eq=False, repr=True) +class AssetEtf(_grpc_helpers.Message): + total_expense: "Quotation" = _grpc_helpers.message_field(1) + hurdle_rate: "Quotation" = _grpc_helpers.message_field(2) + performance_fee: "Quotation" = _grpc_helpers.message_field(3) + fixed_commission: "Quotation" = _grpc_helpers.message_field(4) + payment_type: str = _grpc_helpers.string_field(5) + watermark_flag: bool = _grpc_helpers.bool_field(6) + buy_premium: "Quotation" = _grpc_helpers.message_field(7) + sell_discount: "Quotation" = _grpc_helpers.message_field(8) + rebalancing_flag: bool = _grpc_helpers.bool_field(9) + rebalancing_freq: str = _grpc_helpers.string_field(10) + management_type: str = _grpc_helpers.string_field(11) + primary_index: str = _grpc_helpers.string_field(12) + focus_type: str = _grpc_helpers.string_field(13) + leveraged_flag: bool = _grpc_helpers.bool_field(14) + num_share: "Quotation" = _grpc_helpers.message_field(15) + ucits_flag: bool = _grpc_helpers.bool_field(16) + released_date: datetime = _grpc_helpers.message_field(17) + description: str = _grpc_helpers.string_field(18) + primary_index_description: str = _grpc_helpers.string_field(19) + primary_index_company: str = _grpc_helpers.string_field(20) + index_recovery_period: "Quotation" = _grpc_helpers.message_field(21) + inav_code: str = _grpc_helpers.string_field(22) + div_yield_flag: bool = _grpc_helpers.bool_field(23) + expense_commission: "Quotation" = _grpc_helpers.message_field(24) + primary_index_tracking_error: "Quotation" = _grpc_helpers.message_field(25) + rebalancing_plan: str = _grpc_helpers.string_field(26) + tax_rate: str = _grpc_helpers.string_field(27) + rebalancing_dates: List[datetime] = _grpc_helpers.message_field(28) + issue_kind: str = _grpc_helpers.string_field(29) + nominal: "Quotation" = _grpc_helpers.message_field(30) + nominal_currency: str = _grpc_helpers.string_field(31) + + +@dataclass(eq=False, repr=True) +class AssetClearingCertificate(_grpc_helpers.Message): + nominal: "Quotation" = _grpc_helpers.message_field(1) + nominal_currency: str = _grpc_helpers.string_field(2) + + +@dataclass(eq=False, repr=True) +class Brand(_grpc_helpers.Message): + uid: str = _grpc_helpers.string_field(1) + name: str = _grpc_helpers.string_field(2) + description: str = _grpc_helpers.string_field(3) + info: str = _grpc_helpers.string_field(4) + company: str = _grpc_helpers.string_field(5) + sector: str = _grpc_helpers.string_field(6) + country_of_risk: str = _grpc_helpers.string_field(7) + country_of_risk_name: str = _grpc_helpers.string_field(8) + + +@dataclass(eq=False, repr=True) +class AssetInstrument(_grpc_helpers.Message): + uid: str = _grpc_helpers.string_field(1) + figi: str = _grpc_helpers.string_field(2) + instrument_type: str = _grpc_helpers.string_field(3) + ticker: str = _grpc_helpers.string_field(4) + class_code: str = _grpc_helpers.string_field(5) + links: List["InstrumentLink"] = _grpc_helpers.message_field(6) + instrument_kind: "InstrumentType" = _grpc_helpers.enum_field(10) + position_uid: str = _grpc_helpers.string_field(11) + + +@dataclass(eq=False, repr=True) +class InstrumentLink(_grpc_helpers.Message): + type: str = _grpc_helpers.string_field(1) + instrument_uid: str = _grpc_helpers.string_field(2) + + +@dataclass(eq=False, repr=True) +class GetFavoritesRequest(_grpc_helpers.Message): + group_id: Optional[str] = _grpc_helpers.string_field(1) + + +@dataclass(eq=False, repr=True) +class GetFavoritesResponse(_grpc_helpers.Message): + favorite_instruments: List["FavoriteInstrument"] = _grpc_helpers.message_field(1) + group_id: Optional[str] = _grpc_helpers.string_field(2) + + +@dataclass(eq=False, repr=True) +class FavoriteInstrument(_grpc_helpers.Message): + figi: str = _grpc_helpers.string_field(1) + ticker: str = _grpc_helpers.string_field(2) + class_code: str = _grpc_helpers.string_field(3) + isin: str = _grpc_helpers.string_field(4) + instrument_type: str = _grpc_helpers.string_field(11) + name: str = _grpc_helpers.string_field(12) + uid: str = _grpc_helpers.string_field(13) + otc_flag: bool = _grpc_helpers.bool_field(16) + api_trade_available_flag: bool = _grpc_helpers.bool_field(17) + instrument_kind: "InstrumentType" = _grpc_helpers.enum_field(18) + + +@dataclass(eq=False, repr=True) +class EditFavoritesRequest(_grpc_helpers.Message): + instruments: List["EditFavoritesRequestInstrument"] = _grpc_helpers.message_field(1) + action_type: "EditFavoritesActionType" = _grpc_helpers.enum_field(6) + group_id: Optional[str] = _grpc_helpers.string_field(7) + + +@dataclass(eq=False, repr=True) +class EditFavoritesRequestInstrument(_grpc_helpers.Message): + figi: Optional[str] = _grpc_helpers.string_field(1) + instrument_id: str = _grpc_helpers.string_field(2) + + +@dataclass(eq=False, repr=True) +class EditFavoritesResponse(_grpc_helpers.Message): + favorite_instruments: List["FavoriteInstrument"] = _grpc_helpers.message_field(1) + group_id: Optional[str] = _grpc_helpers.string_field(2) + + +@dataclass(eq=False, repr=True) +class CreateFavoriteGroupRequest(_grpc_helpers.Message): + group_name: str = _grpc_helpers.string_field(1) + group_color: str = _grpc_helpers.string_field(2) + note: Optional[str] = _grpc_helpers.string_field(3) + + +@dataclass(eq=False, repr=True) +class CreateFavoriteGroupResponse(_grpc_helpers.Message): + group_id: str = _grpc_helpers.string_field(1) + group_name: str = _grpc_helpers.string_field(2) + + +@dataclass(eq=False, repr=True) +class DeleteFavoriteGroupRequest(_grpc_helpers.Message): + group_id: str = _grpc_helpers.string_field(1) + + +@dataclass(eq=False, repr=True) +class DeleteFavoriteGroupResponse(_grpc_helpers.Message): + pass + + +@dataclass(eq=False, repr=True) +class GetFavoriteGroupsRequest(_grpc_helpers.Message): + instrument_id: List[str] = _grpc_helpers.string_field(1) + excluded_group_id: List[str] = _grpc_helpers.string_field(2) + + +@dataclass(eq=False, repr=True) +class GetFavoriteGroupsResponse(_grpc_helpers.Message): + groups: List["FavoriteGroup"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class FavoriteGroup(_grpc_helpers.Message): + group_id: str = _grpc_helpers.string_field(1) + group_name: str = _grpc_helpers.string_field(2) + color: str = _grpc_helpers.string_field(3) + size: int = _grpc_helpers.int32_field(4) + contains_instrument: Optional[bool] = _grpc_helpers.message_field(5) + + +@dataclass(eq=False, repr=True) +class GetCountriesRequest(_grpc_helpers.Message): + pass + + +@dataclass(eq=False, repr=True) +class GetCountriesResponse(_grpc_helpers.Message): + countries: List["CountryResponse"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class IndicativesRequest(_grpc_helpers.Message): + pass + + +@dataclass(eq=False, repr=True) +class IndicativeResponse(_grpc_helpers.Message): + figi: str = _grpc_helpers.string_field(1) + ticker: str = _grpc_helpers.string_field(2) + class_code: str = _grpc_helpers.string_field(3) + currency: str = _grpc_helpers.string_field(4) + instrument_kind: "InstrumentType" = _grpc_helpers.enum_field(10) + name: str = _grpc_helpers.string_field(12) + exchange: str = _grpc_helpers.string_field(13) + uid: str = _grpc_helpers.string_field(14) + buy_available_flag: bool = _grpc_helpers.bool_field(404) + sell_available_flag: bool = _grpc_helpers.bool_field(405) + + +@dataclass(eq=False, repr=True) +class IndicativesResponse(_grpc_helpers.Message): + instruments: List["IndicativeResponse"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class CountryResponse(_grpc_helpers.Message): + alfa_two: str = _grpc_helpers.string_field(1) + alfa_three: str = _grpc_helpers.string_field(2) + name: str = _grpc_helpers.string_field(3) + name_brief: str = _grpc_helpers.string_field(4) + + +@dataclass(eq=False, repr=True) +class FindInstrumentRequest(_grpc_helpers.Message): + query: str = _grpc_helpers.string_field(1) + instrument_kind: Optional["InstrumentType"] = _grpc_helpers.enum_field(2) + api_trade_available_flag: Optional[bool] = _grpc_helpers.bool_field(3) + + +@dataclass(eq=False, repr=True) +class FindInstrumentResponse(_grpc_helpers.Message): + instruments: List["InstrumentShort"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class InstrumentShort(_grpc_helpers.Message): + isin: str = _grpc_helpers.string_field(1) + figi: str = _grpc_helpers.string_field(2) + ticker: str = _grpc_helpers.string_field(3) + class_code: str = _grpc_helpers.string_field(4) + instrument_type: str = _grpc_helpers.string_field(5) + name: str = _grpc_helpers.string_field(6) + uid: str = _grpc_helpers.string_field(7) + position_uid: str = _grpc_helpers.string_field(8) + instrument_kind: "InstrumentType" = _grpc_helpers.enum_field(10) + api_trade_available_flag: str = _grpc_helpers.string_field(11) + for_iis_flag: bool = _grpc_helpers.bool_field(12) + first_1min_candle_date: datetime = _grpc_helpers.message_field(26) + first_1day_candle_date: datetime = _grpc_helpers.message_field(27) + for_qual_investor_flag: bool = _grpc_helpers.bool_field(28) + weekend_flag: bool = _grpc_helpers.bool_field(29) + blocked_tca_flag: bool = _grpc_helpers.bool_field(30) + lot: int = _grpc_helpers.int32_field(31) + + +@dataclass(eq=False, repr=True) +class GetBrandsRequest(_grpc_helpers.Message): + paging: "Page" = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class GetBrandRequest(_grpc_helpers.Message): + id: str = _grpc_helpers.string_field(1) + + +@dataclass(eq=False, repr=True) +class GetBrandsResponse(_grpc_helpers.Message): + brands: List["Brand"] = _grpc_helpers.message_field(1) + paging: "PageResponse" = _grpc_helpers.message_field(2) + + +@dataclass(eq=False, repr=True) +class MarketDataRequest(_grpc_helpers.Message): + subscribe_candles_request: "SubscribeCandlesRequest" = _grpc_helpers.message_field( + 1, group="payload" + ) + subscribe_order_book_request: "SubscribeOrderBookRequest" = ( + _grpc_helpers.message_field(2, group="payload") + ) + subscribe_trades_request: "SubscribeTradesRequest" = _grpc_helpers.message_field( + 3, group="payload" + ) + subscribe_info_request: "SubscribeInfoRequest" = _grpc_helpers.message_field( + 4, group="payload" + ) + subscribe_last_price_request: "SubscribeLastPriceRequest" = ( + _grpc_helpers.message_field(5, group="payload") + ) + get_my_subscriptions: "GetMySubscriptions" = _grpc_helpers.message_field( + 6, group="payload" + ) + ping: "PingRequest" = _grpc_helpers.message_field(7, group="payload") + ping_settings: "PingDelaySettings" = _grpc_helpers.message_field( + 15, group="payload" + ) + + +@dataclass(eq=False, repr=True) +class MarketDataServerSideStreamRequest(_grpc_helpers.Message): + subscribe_candles_request: "SubscribeCandlesRequest" = _grpc_helpers.message_field( + 1 + ) + subscribe_order_book_request: "SubscribeOrderBookRequest" = ( + _grpc_helpers.message_field(2) + ) + subscribe_trades_request: "SubscribeTradesRequest" = _grpc_helpers.message_field(3) + subscribe_info_request: "SubscribeInfoRequest" = _grpc_helpers.message_field(4) + subscribe_last_price_request: "SubscribeLastPriceRequest" = ( + _grpc_helpers.message_field(5) + ) + ping_settings: "PingDelaySettings" = _grpc_helpers.message_field(15) + + +@dataclass(eq=False, repr=True) +class MarketDataResponse( + _grpc_helpers.Message +): # pylint:disable=too-many-instance-attributes + subscribe_candles_response: "SubscribeCandlesResponse" = ( + _grpc_helpers.message_field(1, group="payload") + ) + subscribe_order_book_response: "SubscribeOrderBookResponse" = ( + _grpc_helpers.message_field(2, group="payload") + ) + subscribe_trades_response: "SubscribeTradesResponse" = _grpc_helpers.message_field( + 3, group="payload" + ) + subscribe_info_response: "SubscribeInfoResponse" = _grpc_helpers.message_field( + 4, group="payload" + ) + candle: "Candle" = _grpc_helpers.message_field(5, group="payload") + trade: "Trade" = _grpc_helpers.message_field(6, group="payload") + orderbook: "OrderBook" = _grpc_helpers.message_field(7, group="payload") + trading_status: "TradingStatus" = _grpc_helpers.message_field(8, group="payload") + ping: "Ping" = _grpc_helpers.message_field(9, group="payload") + subscribe_last_price_response: "SubscribeLastPriceResponse" = ( + _grpc_helpers.message_field(10, group="payload") + ) + last_price: "LastPrice" = _grpc_helpers.message_field(11, group="payload") + open_interest: "OpenInterest" = _grpc_helpers.message_field(12, group="payload") + + +@dataclass(eq=False, repr=True) +class SubscribeCandlesRequest(_grpc_helpers.Message): + subscription_action: "SubscriptionAction" = _grpc_helpers.enum_field(1) + instruments: List["CandleInstrument"] = _grpc_helpers.message_field(2) + waiting_close: bool = _grpc_helpers.bool_field(3) + candle_source_type: "CandleSource" = _grpc_helpers.enum_field(9) + + +@dataclass(eq=False, repr=True) +class CandleInstrument(_grpc_helpers.Message): + figi: str = _grpc_helpers.string_field(1) + interval: "SubscriptionInterval" = _grpc_helpers.enum_field(2) + instrument_id: str = _grpc_helpers.string_field(3) + + +@dataclass(eq=False, repr=True) +class SubscribeCandlesResponse(_grpc_helpers.Message): + tracking_id: str = _grpc_helpers.string_field(1) + candles_subscriptions: List["CandleSubscription"] = _grpc_helpers.message_field(2) + + +@dataclass(eq=False, repr=True) +class CandleSubscription(_grpc_helpers.Message): + figi: str = _grpc_helpers.string_field(1) + interval: "SubscriptionInterval" = _grpc_helpers.enum_field(2) + subscription_status: "SubscriptionStatus" = _grpc_helpers.enum_field(3) + instrument_uid: str = _grpc_helpers.string_field(4) + waiting_close: bool = _grpc_helpers.bool_field(5) + stream_id: str = _grpc_helpers.string_field(6) + subscription_id: str = _grpc_helpers.string_field(7) + subscription_action: "SubscriptionAction" = _grpc_helpers.enum_field(8) + candle_source_type: Optional["CandleSource"] = _grpc_helpers.enum_field( + 9, optional=True + ) + + +@dataclass(eq=False, repr=True) +class SubscribeOrderBookRequest(_grpc_helpers.Message): + subscription_action: "SubscriptionAction" = _grpc_helpers.enum_field(1) + instruments: List["OrderBookInstrument"] = _grpc_helpers.message_field(2) + + +@dataclass(eq=False, repr=True) +class OrderBookInstrument(_grpc_helpers.Message): + figi: str = _grpc_helpers.string_field(1) + depth: int = _grpc_helpers.int32_field(2) + instrument_id: str = _grpc_helpers.string_field(3) + order_book_type: "OrderBookType" = _grpc_helpers.message_field(4) + + +@dataclass(eq=False, repr=True) +class SubscribeOrderBookResponse(_grpc_helpers.Message): + tracking_id: str = _grpc_helpers.string_field(1) + order_book_subscriptions: List[ + "OrderBookSubscription" + ] = _grpc_helpers.message_field(2) + + +@dataclass(eq=False, repr=True) +class OrderBookSubscription(_grpc_helpers.Message): + figi: str = _grpc_helpers.string_field(1) + depth: int = _grpc_helpers.int32_field(2) + subscription_status: "SubscriptionStatus" = _grpc_helpers.enum_field(3) + instrument_uid: str = _grpc_helpers.string_field(4) + stream_id: str = _grpc_helpers.string_field(5) + subscription_id: str = _grpc_helpers.string_field(6) + order_book_type: "OrderBookType" = _grpc_helpers.message_field(7) + subscription_action: "SubscriptionAction" = _grpc_helpers.enum_field(8) + + +@dataclass(eq=False, repr=True) +class SubscribeTradesRequest(_grpc_helpers.Message): + subscription_action: "SubscriptionAction" = _grpc_helpers.enum_field(1) + instruments: List["TradeInstrument"] = _grpc_helpers.message_field(2) + trade_source: "TradeSourceType" = _grpc_helpers.message_field(3) + with_open_interest: bool = _grpc_helpers.bool_field(4) + + +@dataclass(eq=False, repr=True) +class SubscribeLastPriceRequest(_grpc_helpers.Message): + subscription_action: "SubscriptionAction" = _grpc_helpers.message_field(1) + instruments: List["LastPriceInstrument"] = _grpc_helpers.message_field(2) + + +@dataclass(eq=False, repr=True) +class LastPriceInstrument(_grpc_helpers.Message): + figi: str = _grpc_helpers.string_field(1) + instrument_id: str = _grpc_helpers.string_field(2) + + +@dataclass(eq=False, repr=True) +class SubscribeLastPriceResponse(_grpc_helpers.Message): + tracking_id: str = _grpc_helpers.string_field(1) + last_price_subscriptions: List[ + "LastPriceSubscription" + ] = _grpc_helpers.message_field(2) + + +@dataclass(eq=False, repr=True) +class LastPriceSubscription(_grpc_helpers.Message): + figi: str = _grpc_helpers.string_field(1) + subscription_status: "SubscriptionStatus" = _grpc_helpers.message_field(2) + instrument_uid: str = _grpc_helpers.string_field(3) + stream_id: str = _grpc_helpers.string_field(4) + subscription_id: str = _grpc_helpers.string_field(5) + subscription_action: "SubscriptionAction" = _grpc_helpers.message_field(6) + + +@dataclass(eq=False, repr=True) +class TradeInstrument(_grpc_helpers.Message): + figi: str = _grpc_helpers.string_field(1) + instrument_id: str = _grpc_helpers.string_field(2) + + +@dataclass(eq=False, repr=True) +class SubscribeTradesResponse(_grpc_helpers.Message): + tracking_id: str = _grpc_helpers.string_field(1) + trade_subscriptions: List["TradeSubscription"] = _grpc_helpers.message_field(2) + trade_source: "TradeSourceType" = _grpc_helpers.message_field(3) + + +@dataclass(eq=False, repr=True) +class TradeSubscription(_grpc_helpers.Message): + figi: str = _grpc_helpers.string_field(1) + subscription_status: "SubscriptionStatus" = _grpc_helpers.enum_field(2) + instrument_uid: str = _grpc_helpers.string_field(3) + stream_id: str = _grpc_helpers.string_field(4) + subscription_id: str = _grpc_helpers.string_field(5) + with_open_interest: bool = _grpc_helpers.bool_field(6) + subscription_action: "SubscriptionAction" = _grpc_helpers.enum_field(7) + + +@dataclass(eq=False, repr=True) +class SubscribeInfoRequest(_grpc_helpers.Message): + subscription_action: "SubscriptionAction" = _grpc_helpers.enum_field(1) + instruments: List["InfoInstrument"] = _grpc_helpers.message_field(2) + + +@dataclass(eq=False, repr=True) +class InfoInstrument(_grpc_helpers.Message): + figi: str = _grpc_helpers.string_field(1) + instrument_id: str = _grpc_helpers.string_field(2) + + +@dataclass(eq=False, repr=True) +class SubscribeInfoResponse(_grpc_helpers.Message): + tracking_id: str = _grpc_helpers.string_field(1) + info_subscriptions: List["InfoSubscription"] = _grpc_helpers.message_field(2) + + +@dataclass(eq=False, repr=True) +class InfoSubscription(_grpc_helpers.Message): + figi: str = _grpc_helpers.string_field(1) + subscription_status: "SubscriptionStatus" = _grpc_helpers.enum_field(2) + instrument_uid: str = _grpc_helpers.string_field(3) + stream_id: str = _grpc_helpers.string_field(4) + subscription_id: str = _grpc_helpers.string_field(5) + subscription_action: "SubscriptionAction" = _grpc_helpers.enum_field(6) + + +@dataclass(eq=False, repr=True) +class Candle(_grpc_helpers.Message): + figi: str = _grpc_helpers.string_field(1) + interval: "SubscriptionInterval" = _grpc_helpers.enum_field(2) + open: "Quotation" = _grpc_helpers.message_field(3) + high: "Quotation" = _grpc_helpers.message_field(4) + low: "Quotation" = _grpc_helpers.message_field(5) + close: "Quotation" = _grpc_helpers.message_field(6) + volume: int = _grpc_helpers.int64_field(7) + time: datetime = _grpc_helpers.message_field(8) + last_trade_ts: datetime = _grpc_helpers.message_field(9) + instrument_uid: str = _grpc_helpers.string_field(10) + ticker: str = _grpc_helpers.string_field(11) + class_code: str = _grpc_helpers.string_field(12) + volume_buy: int = _grpc_helpers.int64_field(13) + volume_sell: int = _grpc_helpers.int64_field(14) + candle_source_type: "CandleSource" = _grpc_helpers.enum_field(19) + + +@dataclass(eq=False, repr=True) +class OrderBook(_grpc_helpers.Message): + figi: str = _grpc_helpers.string_field(1) + depth: int = _grpc_helpers.int32_field(2) + is_consistent: bool = _grpc_helpers.bool_field(3) + bids: List["Order"] = _grpc_helpers.message_field(4) + asks: List["Order"] = _grpc_helpers.message_field(5) + time: datetime = _grpc_helpers.message_field(6) + limit_up: "Quotation" = _grpc_helpers.message_field(7) + limit_down: "Quotation" = _grpc_helpers.message_field(8) + instrument_uid: str = _grpc_helpers.string_field(9) + order_book_type: "OrderBookType" = _grpc_helpers.message_field(10) + + +@dataclass(eq=False, repr=True) +class Order(_grpc_helpers.Message): + price: "Quotation" = _grpc_helpers.message_field(1) + quantity: int = _grpc_helpers.int64_field(2) + + +@dataclass(eq=False, repr=True) +class Trade(_grpc_helpers.Message): + figi: str = _grpc_helpers.string_field(1) + direction: "TradeDirection" = _grpc_helpers.enum_field(2) + price: "Quotation" = _grpc_helpers.message_field(3) + quantity: int = _grpc_helpers.int64_field(4) + time: datetime = _grpc_helpers.message_field(5) + instrument_uid: str = _grpc_helpers.string_field(6) + trade_source: TradeSourceType = _grpc_helpers.message_field(7) + + +@dataclass(eq=False, repr=True) +class TradingStatus(_grpc_helpers.Message): + figi: str = _grpc_helpers.string_field(1) + trading_status: "SecurityTradingStatus" = _grpc_helpers.enum_field(2) + time: datetime = _grpc_helpers.enum_field(3) + limit_order_available_flag: bool = _grpc_helpers.bool_field(4) + market_order_available_flag: bool = _grpc_helpers.bool_field(5) + instrument_uid: str = _grpc_helpers.string_field(6) + + +@dataclass(eq=False, repr=True) +class GetCandlesRequest(_grpc_helpers.Message): + figi: Optional[str] = _grpc_helpers.string_field(1) + from_: datetime = _grpc_helpers.message_field(2) + to: datetime = _grpc_helpers.message_field(3) + interval: "CandleInterval" = _grpc_helpers.enum_field(4) + instrument_id: Optional[str] = _grpc_helpers.string_field(5) + candle_source_type: Optional[CandleSource] = _grpc_helpers.string_field(7) + limit: Optional[int] = _grpc_helpers.int32_field(10) + + +@dataclass(eq=False, repr=True) +class GetCandlesResponse(_grpc_helpers.Message): + candles: List["HistoricCandle"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=True, repr=True, frozen=True) +class HistoricCandle(_grpc_helpers.Message): + open: Quotation = _grpc_helpers.message_field(1) + high: Quotation = _grpc_helpers.message_field(2) + low: Quotation = _grpc_helpers.message_field(3) + close: Quotation = _grpc_helpers.message_field(4) + volume: int = _grpc_helpers.int64_field(5) + time: datetime = _grpc_helpers.message_field(6) + is_complete: bool = _grpc_helpers.bool_field(7) + candle_source: CandleSource = _grpc_helpers.message_field(9) + volume_buy: int = _grpc_helpers.int64_field(10) + volume_sell: int = _grpc_helpers.int64_field(11) + + +@dataclass(eq=False, repr=True) +class GetLastPricesRequest(_grpc_helpers.Message): + figi: List[str] = _grpc_helpers.string_field(1) + instrument_id: List[str] = _grpc_helpers.string_field(2) + last_price_type: LastPriceType = _grpc_helpers.message_field(3) + instrument_status: Optional["InstrumentStatus"] = _grpc_helpers.enum_field(9) + + +@dataclass(eq=False, repr=True) +class GetLastPricesResponse(_grpc_helpers.Message): + last_prices: List["LastPrice"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class LastPrice(_grpc_helpers.Message): + figi: str = _grpc_helpers.string_field(1) + price: "Quotation" = _grpc_helpers.message_field(2) + time: datetime = _grpc_helpers.message_field(3) + instrument_uid: str = _grpc_helpers.string_field(11) + last_price_type: LastPriceType = _grpc_helpers.message_field(12) + + +@dataclass(eq=False, repr=True) +class OpenInterest(_grpc_helpers.Message): + instrument_uid: str = _grpc_helpers.string_field(1) + time: datetime = _grpc_helpers.message_field(2) + open_interest: int = _grpc_helpers.int64_field(3) + + +@dataclass(eq=False, repr=True) +class GetOrderBookRequest(_grpc_helpers.Message): + figi: Optional[str] = _grpc_helpers.string_field(1) + depth: int = _grpc_helpers.int32_field(2) + instrument_id: Optional[str] = _grpc_helpers.string_field(3) + + +@dataclass(eq=False, repr=True) +class GetOrderBookResponse(_grpc_helpers.Message): + figi: str = _grpc_helpers.string_field(1) + depth: int = _grpc_helpers.int32_field(2) + bids: List["Order"] = _grpc_helpers.message_field(3) + asks: List["Order"] = _grpc_helpers.message_field(4) + last_price: "Quotation" = _grpc_helpers.message_field(5) + close_price: "Quotation" = _grpc_helpers.message_field(6) + limit_up: "Quotation" = _grpc_helpers.message_field(7) + limit_down: "Quotation" = _grpc_helpers.message_field(8) + last_price_ts: datetime = _grpc_helpers.message_field(21) + close_price_ts: datetime = _grpc_helpers.message_field(22) + orderbook_ts: datetime = _grpc_helpers.message_field(23) + instrument_uid: str = _grpc_helpers.string_field(9) + + +@dataclass(eq=False, repr=True) +class GetTradingStatusRequest(_grpc_helpers.Message): + figi: Optional[str] = _grpc_helpers.string_field(1) + instrument_id: Optional[str] = _grpc_helpers.string_field(2) + + +@dataclass(eq=False, repr=True) +class GetTradingStatusesRequest(_grpc_helpers.Message): + instrument_id: List[str] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class GetTradingStatusesResponse(_grpc_helpers.Message): + trading_statuses: List["GetTradingStatusResponse"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class GetTradingStatusResponse(_grpc_helpers.Message): + figi: str = _grpc_helpers.string_field(1) + trading_status: "SecurityTradingStatus" = _grpc_helpers.enum_field(2) + limit_order_available_flag: bool = _grpc_helpers.bool_field(3) + market_order_available_flag: bool = _grpc_helpers.bool_field(4) + api_trade_available_flag: bool = _grpc_helpers.bool_field(5) + instrument_uid: str = _grpc_helpers.string_field(6) + + bestprice_order_available_flag: bool = _grpc_helpers.bool_field(8) + only_best_price: bool = _grpc_helpers.bool_field(9) + + +@dataclass(eq=False, repr=True) +class GetLastTradesRequest(_grpc_helpers.Message): + figi: Optional[str] = _grpc_helpers.string_field(1) + from_: datetime = _grpc_helpers.message_field(2) + to: datetime = _grpc_helpers.message_field(3) + instrument_id: Optional[str] = _grpc_helpers.string_field(4) + trade_source: TradeSourceType = _grpc_helpers.enum_field(5) + + +@dataclass(eq=False, repr=True) +class GetLastTradesResponse(_grpc_helpers.Message): + trades: List["Trade"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class GetMySubscriptions(_grpc_helpers.Message): + pass + + +@dataclass(eq=False, repr=True) +class GetClosePricesRequest(_grpc_helpers.Message): + instruments: List["InstrumentClosePriceRequest"] = _grpc_helpers.message_field(1) + instrument_status: Optional["InstrumentStatus"] = _grpc_helpers.enum_field(9) + + +@dataclass(eq=False, repr=True) +class InstrumentClosePriceRequest(_grpc_helpers.Message): + instrument_id: str = _grpc_helpers.string_field(1) + + +@dataclass(eq=False, repr=True) +class GetClosePricesResponse(_grpc_helpers.Message): + close_prices: List["InstrumentClosePriceResponse"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class InstrumentClosePriceResponse(_grpc_helpers.Message): + figi: str = _grpc_helpers.string_field(1) + instrument_uid: str = _grpc_helpers.string_field(2) + price: "Quotation" = _grpc_helpers.message_field(11) + evening_session_price: "Quotation" = _grpc_helpers.message_field(12) + time: datetime = _grpc_helpers.message_field(21) + evening_session_price_time: datetime = _grpc_helpers.message_field(23) + + +@dataclass(eq=False, repr=True) +class GetMarketValuesRequest(_grpc_helpers.Message): + instrument_id: List[str] = _grpc_helpers.message_field(1) + values: List["MarketValueType"] = _grpc_helpers.message_field(2) + + +class MarketValueType(_grpc_helpers.Enum): + INSTRUMENT_VALUE_UNSPECIFIED = 0 + INSTRUMENT_VALUE_LAST_PRICE = 1 + INSTRUMENT_VALUE_LAST_PRICE_DEALER = 2 + INSTRUMENT_VALUE_CLOSE_PRICE = 3 + INSTRUMENT_VALUE_EVENING_SESSION_PRICE = 4 + INSTRUMENT_VALUE_OPEN_INTEREST = 5 + INSTRUMENT_VALUE_THEOR_PRICE = 6 + + +@dataclass(eq=False, repr=True) +class GetMarketValuesResponse(_grpc_helpers.Message): + instruments: List["MarketValueInstrument"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class MarketValueInstrument(_grpc_helpers.Message): + instrument_uid: str = _grpc_helpers.string_field(1) + values: List["MarketValue"] = _grpc_helpers.message_field(2) + + +@dataclass(eq=False, repr=True) +class MarketValue(_grpc_helpers.Message): + type: "MarketValueType" = _grpc_helpers.enum_field(1) + value: "Quotation" = _grpc_helpers.message_field(2) + time: datetime = _grpc_helpers.message_field(3) + + +@dataclass(eq=False, repr=True) +class Smoothing(_grpc_helpers.Message): + fast_length: int = _grpc_helpers.int32_field(1) + slow_length: int = _grpc_helpers.int32_field(2) + signal_smoothing: int = _grpc_helpers.int32_field(3) + + +@dataclass(eq=False, repr=True) +class Deviation(_grpc_helpers.Message): + deviation_multiplier: "Quotation" = _grpc_helpers.message_field(1) + + +class IndicatorInterval(_grpc_helpers.Enum): + INDICATOR_INTERVAL_UNSPECIFIED = 0 + INDICATOR_INTERVAL_ONE_MINUTE = 1 + INDICATOR_INTERVAL_FIVE_MINUTES = 2 + INDICATOR_INTERVAL_FIFTEEN_MINUTES = 3 + INDICATOR_INTERVAL_ONE_HOUR = 4 + INDICATOR_INTERVAL_ONE_DAY = 5 + INDICATOR_INTERVAL_2_MIN = 6 + INDICATOR_INTERVAL_3_MIN = 7 + INDICATOR_INTERVAL_10_MIN = 8 + INDICATOR_INTERVAL_30_MIN = 9 + INDICATOR_INTERVAL_2_HOUR = 10 + INDICATOR_INTERVAL_4_HOUR = 11 + INDICATOR_INTERVAL_WEEK = 12 + INDICATOR_INTERVAL_MONTH = 13 + + +class TypeOfPrice(_grpc_helpers.Enum): + TYPE_OF_PRICE_UNSPECIFIED = 0 + TYPE_OF_PRICE_CLOSE = 1 + TYPE_OF_PRICE_OPEN = 2 + TYPE_OF_PRICE_HIGH = 3 + TYPE_OF_PRICE_LOW = 4 + TYPE_OF_PRICE_AVG = 5 + + +class IndicatorType(_grpc_helpers.Enum): + INDICATOR_TYPE_UNSPECIFIED = 0 + INDICATOR_TYPE_BB = 1 + INDICATOR_TYPE_EMA = 2 + INDICATOR_TYPE_RSI = 3 + INDICATOR_TYPE_MACD = 4 + INDICATOR_TYPE_SMA = 5 + + +@dataclass(eq=False, repr=True) +class GetTechAnalysisRequest(_grpc_helpers.Message): + indicator_type: "IndicatorType" = _grpc_helpers.enum_field(1) + instrument_uid: str = _grpc_helpers.string_field(2) + from_: datetime = _grpc_helpers.message_field(3) + to: datetime = _grpc_helpers.message_field(4) + interval: "IndicatorInterval" = _grpc_helpers.enum_field(5) + type_of_price: "TypeOfPrice" = _grpc_helpers.enum_field(6) + length: int = _grpc_helpers.int32_field(7) + deviation: "Deviation" = _grpc_helpers.message_field(8) + smoothing: "Smoothing" = _grpc_helpers.message_field(9) + + +@dataclass(eq=False, repr=True) +class TechAnalysisItem(_grpc_helpers.Message): + timestamp: datetime = _grpc_helpers.message_field(1) + middle_band: Optional["Quotation"] = _grpc_helpers.message_field(2, optional=True) + upper_band: Optional["Quotation"] = _grpc_helpers.message_field(3, optional=True) + lower_band: Optional["Quotation"] = _grpc_helpers.message_field(4, optional=True) + signal: Optional["Quotation"] = _grpc_helpers.message_field(5, optional=True) + macd: Optional["Quotation"] = _grpc_helpers.message_field(6, optional=True) + + +@dataclass(eq=False, repr=True) +class GetTechAnalysisResponse(_grpc_helpers.Message): + technical_indicators: List["TechAnalysisItem"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class OperationsRequest(_grpc_helpers.Message): + account_id: str = _grpc_helpers.string_field(1) + from_: Optional[datetime] = _grpc_helpers.message_field(2) + to: Optional[datetime] = _grpc_helpers.message_field(3) + state: Optional["OperationState"] = _grpc_helpers.enum_field(4) + figi: Optional[str] = _grpc_helpers.string_field(5) + + +@dataclass(eq=False, repr=True) +class OperationsResponse(_grpc_helpers.Message): + operations: List["Operation"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class OperationTrade(_grpc_helpers.Message): + trade_id: str = _grpc_helpers.string_field(1) + date_time: datetime = _grpc_helpers.message_field(2) + quantity: int = _grpc_helpers.int64_field(3) + price: "MoneyValue" = _grpc_helpers.message_field(4) + + +@dataclass(eq=False, repr=True) +class ChildOperationItem(_grpc_helpers.Message): + instrument_uid: str = _grpc_helpers.string_field(1) + payment: "MoneyValue" = _grpc_helpers.message_field(2) + + +@dataclass(eq=False, repr=True) +class OperationsStreamRequest(_grpc_helpers.Message): + accounts: List[str] = _grpc_helpers.message_field(1) + ping_settings: "PingDelaySettings" = _grpc_helpers.message_field(15) + + +@dataclass(eq=False, repr=True) +class OperationsStreamResponse(_grpc_helpers.Message): + subscriptions: "OperationsSubscriptionResult" = _grpc_helpers.message_field( + 1, group="payload" + ) + operation: "OperationData" = _grpc_helpers.message_field(2, group="payload") + ping: "Ping" = _grpc_helpers.message_field(3, group="payload") + + +@dataclass(eq=False, repr=True) +class OperationsSubscriptionResult(_grpc_helpers.Message): + accounts: List[str] = _grpc_helpers.message_field(1) + subscription_status: "OperationsAccountSubscriptionStatus" = ( + _grpc_helpers.enum_field(2) + ) + tracking_id: str = _grpc_helpers.string_field(7) + stream_id: str = _grpc_helpers.string_field(8) + + +class OperationsAccountSubscriptionStatus(_grpc_helpers.Enum): + OPERATIONS_SUBSCRIPTION_STATUS_UNSPECIFIED = 0 + OPERATIONS_SUBSCRIPTION_STATUS_SUCCESS = 1 + OPERATIONS_SUBSCRIPTION_STATUS_ACCOUNT_NOT_FOUND = 2 + OPERATIONS_SUBSCRIPTION_STATUS_INTERNAL_ERROR = 3 + + +@dataclass(eq=False, repr=True) +class OperationData(_grpc_helpers.Message): + broker_account_id: str = _grpc_helpers.string_field(1) + id: str = _grpc_helpers.string_field(2) + parent_operation_id: str = _grpc_helpers.string_field(3) + name: str = _grpc_helpers.string_field(4) + date: datetime = _grpc_helpers.message_field(5) + type: "OperationType" = _grpc_helpers.enum_field(6) + state: "OperationState" = _grpc_helpers.enum_field(7) + instrument_uid: str = _grpc_helpers.string_field(8) + figi: str = _grpc_helpers.string_field(9) + instrument_type: str = _grpc_helpers.string_field(10) + instrument_kind: InstrumentType = _grpc_helpers.enum_field(11) + position_uid: str = _grpc_helpers.string_field(12) + ticker: str = _grpc_helpers.string_field(13) + class_code: str = _grpc_helpers.string_field(14) + payment: MoneyValue = _grpc_helpers.message_field(15) + + +@dataclass(eq=False, repr=True) +class Operation(_grpc_helpers.Message): # pylint:disable=too-many-instance-attributes + id: str = _grpc_helpers.string_field(1) + parent_operation_id: str = _grpc_helpers.string_field(2) + currency: str = _grpc_helpers.string_field(3) + payment: "MoneyValue" = _grpc_helpers.message_field(4) + price: "MoneyValue" = _grpc_helpers.message_field(5) + state: "OperationState" = _grpc_helpers.enum_field(6) + quantity: int = _grpc_helpers.int64_field(7) + quantity_rest: int = _grpc_helpers.int64_field(8) + figi: str = _grpc_helpers.string_field(9) + instrument_type: str = _grpc_helpers.string_field(10) + date: datetime = _grpc_helpers.message_field(11) + type: str = _grpc_helpers.string_field(12) + operation_type: "OperationType" = _grpc_helpers.enum_field(13) + trades: List["OperationTrade"] = _grpc_helpers.message_field(14) + asset_uid: str = _grpc_helpers.string_field(16) + position_uid: str = _grpc_helpers.string_field(17) + instrument_uid: str = _grpc_helpers.string_field(18) + child_operations: List["ChildOperationItem"] = _grpc_helpers.message_field(19) + + +class CurrencyRequest(_grpc_helpers.Enum): + RUB = 0 + USD = 1 + EUR = 2 + + +@dataclass(eq=False, repr=True) +class PortfolioRequest(_grpc_helpers.Message): + account_id: str = _grpc_helpers.string_field(1) + currency: Optional[CurrencyRequest] = _grpc_helpers.enum_field(2) + + +@dataclass(eq=False, repr=True) +class VirtualPortfolioPosition(_grpc_helpers.Message): + position_uid: str = _grpc_helpers.string_field(1) + instrument_uid: str = _grpc_helpers.string_field(2) + figi: str = _grpc_helpers.string_field(3) + instrument_type: str = _grpc_helpers.string_field(4) + quantity: "Quotation" = _grpc_helpers.message_field(5) + average_position_price: "MoneyValue" = _grpc_helpers.message_field(6) + expected_yield: "Quotation" = _grpc_helpers.message_field(7) + expected_yield_fifo: "Quotation" = _grpc_helpers.message_field(8) + expire_date: datetime = _grpc_helpers.message_field(9) + current_price: "MoneyValue" = _grpc_helpers.message_field(10) + average_position_price_fifo: "MoneyValue" = _grpc_helpers.message_field(11) + daily_yield: "MoneyValue" = _grpc_helpers.message_field(31) + ticker: str = _grpc_helpers.string_field(32) + + +@dataclass(eq=False, repr=True) +class PortfolioResponse(_grpc_helpers.Message): + total_amount_shares: "MoneyValue" = _grpc_helpers.message_field(1) + total_amount_bonds: "MoneyValue" = _grpc_helpers.message_field(2) + total_amount_etf: "MoneyValue" = _grpc_helpers.message_field(3) + total_amount_currencies: "MoneyValue" = _grpc_helpers.message_field(4) + total_amount_futures: "MoneyValue" = _grpc_helpers.message_field(5) + expected_yield: "Quotation" = _grpc_helpers.message_field(6) + positions: List["PortfolioPosition"] = _grpc_helpers.message_field(7) + account_id: str = _grpc_helpers.string_field(8) + + total_amount_options: MoneyValue = _grpc_helpers.message_field(9) + total_amount_sp: MoneyValue = _grpc_helpers.message_field(10) + total_amount_portfolio: MoneyValue = _grpc_helpers.message_field(11) + virtual_positions: List["VirtualPortfolioPosition"] = _grpc_helpers.message_field( + 12 + ) + daily_yield: MoneyValue = _grpc_helpers.message_field(15) + daily_yield_relative: Quotation = _grpc_helpers.message_field(16) + total_amount_dfa: MoneyValue = _grpc_helpers.message_field(17) + + +@dataclass(eq=False, repr=True) +class PositionsRequest(_grpc_helpers.Message): + account_id: str = _grpc_helpers.string_field(1) + + +@dataclass(eq=False, repr=True) +class PositionsResponse(_grpc_helpers.Message): + money: List["MoneyValue"] = _grpc_helpers.message_field(1) + blocked: List["MoneyValue"] = _grpc_helpers.message_field(2) + securities: List["PositionsSecurities"] = _grpc_helpers.message_field(3) + limits_loading_in_progress: bool = _grpc_helpers.bool_field(4) + futures: List["PositionsFutures"] = _grpc_helpers.bool_field(5) + options: List["PositionsOptions"] = _grpc_helpers.bool_field(6) + account_id: str = _grpc_helpers.string_field(15) + + +@dataclass(eq=False, repr=True) +class WithdrawLimitsRequest(_grpc_helpers.Message): + account_id: str = _grpc_helpers.string_field(1) + + +@dataclass(eq=False, repr=True) +class WithdrawLimitsResponse(_grpc_helpers.Message): + money: List["MoneyValue"] = _grpc_helpers.message_field(1) + blocked: List["MoneyValue"] = _grpc_helpers.message_field(2) + blocked_guarantee: List["MoneyValue"] = _grpc_helpers.message_field(3) + + +@dataclass(eq=False, repr=True) +class PortfolioPosition(_grpc_helpers.Message): + figi: str = _grpc_helpers.string_field(1) + instrument_type: str = _grpc_helpers.string_field(2) + quantity: "Quotation" = _grpc_helpers.message_field(3) + average_position_price: "MoneyValue" = _grpc_helpers.message_field(4) + expected_yield: "Quotation" = _grpc_helpers.message_field(5) + current_nkd: "MoneyValue" = _grpc_helpers.message_field(6) + average_position_price_pt: "Quotation" = _grpc_helpers.message_field(7) + current_price: "MoneyValue" = _grpc_helpers.message_field(8) + average_position_price_fifo: "MoneyValue" = _grpc_helpers.message_field(9) + quantity_lots: "Quotation" = _grpc_helpers.message_field(10) + blocked: bool = _grpc_helpers.bool_field(21) + blocked_lots: "Quotation" = _grpc_helpers.message_field(22) + position_uid: str = _grpc_helpers.string_field(24) + instrument_uid: str = _grpc_helpers.string_field(25) + var_margin: "MoneyValue" = _grpc_helpers.message_field(26) + expected_yield_fifo: "Quotation" = _grpc_helpers.message_field(27) + daily_yield: "MoneyValue" = _grpc_helpers.message_field(31) + ticker: str = _grpc_helpers.string_field(32) + + +@dataclass(eq=False, repr=True) +class PositionsSecurities(_grpc_helpers.Message): + figi: str = _grpc_helpers.string_field(1) + blocked: int = _grpc_helpers.int64_field(2) + balance: int = _grpc_helpers.int64_field(3) + position_uid: str = _grpc_helpers.string_field(4) + instrument_uid: str = _grpc_helpers.string_field(5) + exchange_blocked: bool = _grpc_helpers.bool_field(11) + instrument_type: str = _grpc_helpers.string_field(16) + ticker: str = _grpc_helpers.string_field(6) + + +@dataclass(eq=False, repr=True) +class TradesStreamRequest(_grpc_helpers.Message): + accounts: List[str] = _grpc_helpers.string_field(1) + ping_delay_ms: Optional[int] = _grpc_helpers.int32_field(15) + + +@dataclass(eq=False, repr=True) +class TradesStreamResponse(_grpc_helpers.Message): + order_trades: "OrderTrades" = _grpc_helpers.message_field(1, group="payload") + ping: "Ping" = _grpc_helpers.message_field(2, group="payload") + subscription: "SubscriptionResponse" = _grpc_helpers.message_field( + 3, group="payload" + ) + + +@dataclass(eq=False, repr=True) +class OrderTrades(_grpc_helpers.Message): + order_id: str = _grpc_helpers.string_field(1) + created_at: datetime = _grpc_helpers.message_field(2) + direction: "OrderDirection" = _grpc_helpers.enum_field(3) + figi: str = _grpc_helpers.string_field(4) + trades: List["OrderTrade"] = _grpc_helpers.message_field(5) + account_id: str = _grpc_helpers.string_field(6) + instrument_uid: str = _grpc_helpers.string_field(7) + + +@dataclass(eq=False, repr=True) +class OrderTrade(_grpc_helpers.Message): + date_time: datetime = _grpc_helpers.message_field(1) + price: "Quotation" = _grpc_helpers.message_field(2) + quantity: int = _grpc_helpers.int64_field(3) + trade_id: str = _grpc_helpers.string_field(4) + + +@dataclass(eq=False, repr=True) +class PostOrderRequest(_grpc_helpers.Message): + figi: Optional[str] = _grpc_helpers.string_field(1) + quantity: int = _grpc_helpers.int64_field(2) + price: Optional["Quotation"] = _grpc_helpers.message_field(3) + direction: "OrderDirection" = _grpc_helpers.enum_field(4) + account_id: str = _grpc_helpers.string_field(5) + order_type: "OrderType" = _grpc_helpers.enum_field(6) + order_id: str = _grpc_helpers.string_field(7) + instrument_id: str = _grpc_helpers.string_field(8) + time_in_force: "TimeInForceType" = _grpc_helpers.message_field(9) + price_type: "PriceType" = _grpc_helpers.message_field(10) + confirm_margin_trade: bool = _grpc_helpers.bool_field(11) + + +@dataclass(eq=False, repr=True) +class PostOrderResponse( # pylint:disable=too-many-instance-attributes + _grpc_helpers.Message +): + order_id: str = _grpc_helpers.string_field(1) + execution_report_status: "OrderExecutionReportStatus" = _grpc_helpers.enum_field(2) + lots_requested: int = _grpc_helpers.int64_field(3) + lots_executed: int = _grpc_helpers.int64_field(4) + initial_order_price: "MoneyValue" = _grpc_helpers.message_field(5) + executed_order_price: "MoneyValue" = _grpc_helpers.message_field(6) + total_order_amount: "MoneyValue" = _grpc_helpers.message_field(7) + initial_commission: "MoneyValue" = _grpc_helpers.message_field(8) + executed_commission: "MoneyValue" = _grpc_helpers.message_field(9) + aci_value: "MoneyValue" = _grpc_helpers.message_field(10) + figi: str = _grpc_helpers.string_field(11) + direction: "OrderDirection" = _grpc_helpers.enum_field(12) + initial_security_price: "MoneyValue" = _grpc_helpers.message_field(13) + order_type: "OrderType" = _grpc_helpers.enum_field(14) + message: str = _grpc_helpers.string_field(15) + initial_order_price_pt: "Quotation" = _grpc_helpers.message_field(16) + instrument_uid: str = _grpc_helpers.string_field(17) + order_request_id: str = _grpc_helpers.string_field(20) + response_metadata: "ResponseMetadata" = _grpc_helpers.message_field(254) + + +@dataclass(eq=False, repr=True) +class PostOrderAsyncRequest(_grpc_helpers.Message): + instrument_id: str = _grpc_helpers.string_field(1) + quantity: int = _grpc_helpers.int64_field(2) + price: "Quotation" = _grpc_helpers.message_field(3) + direction: "OrderDirection" = _grpc_helpers.message_field(4) + account_id: str = _grpc_helpers.string_field(5) + order_type: "OrderType" = _grpc_helpers.message_field(6) + order_id: str = _grpc_helpers.string_field(7) + time_in_force: TimeInForceType = _grpc_helpers.string_field(8) + price_type: PriceType = _grpc_helpers.string_field(9) + confirm_margin_trade: bool = _grpc_helpers.bool_field(10) + + +@dataclass(eq=False, repr=True) +class PostOrderAsyncResponse(_grpc_helpers.Message): + order_request_id: str = _grpc_helpers.string_field(1) + execution_report_status: "OrderExecutionReportStatus" = _grpc_helpers.message_field( + 2 + ) + trade_intent_id: str = _grpc_helpers.string_field(3) + + +@dataclass(eq=False, repr=True) +class CancelOrderRequest(_grpc_helpers.Message): + account_id: str = _grpc_helpers.string_field(1) + order_id: str = _grpc_helpers.string_field(2) + order_id_type: Optional["OrderIdType"] = _grpc_helpers.message_field(3) + + +@dataclass(eq=False, repr=True) +class CancelOrderResponse(_grpc_helpers.Message): + time: datetime = _grpc_helpers.message_field(1) + response_metadata: "ResponseMetadata" = _grpc_helpers.message_field(254) + + +@dataclass(eq=False, repr=True) +class GetOrderStateRequest(_grpc_helpers.Message): + account_id: str = _grpc_helpers.string_field(1) + order_id: str = _grpc_helpers.string_field(2) + price_type: "PriceType" = _grpc_helpers.message_field(3) + order_id_type: Optional["OrderIdType"] = _grpc_helpers.message_field(4) + + +@dataclass(eq=False, repr=True) +class GetOrdersRequest(_grpc_helpers.Message): + account_id: str = _grpc_helpers.string_field(1) + advanced_filters: Optional["GetOrdersRequestFilters"] = _grpc_helpers.message_field( + 2 + ) + + +@dataclass(eq=False, repr=True) +class GetOrdersRequestFilters(_grpc_helpers.Message): + from_: Optional[datetime] = _grpc_helpers.message_field(1) + to: Optional[datetime] = _grpc_helpers.message_field(2) + execution_status: List["OrderExecutionReportStatus"] = _grpc_helpers.message_field( + 3 + ) + + +@dataclass(eq=False, repr=True) +class GetOrdersResponse(_grpc_helpers.Message): + orders: List["OrderState"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class OrderState(_grpc_helpers.Message): # pylint:disable=too-many-instance-attributes + order_id: str = _grpc_helpers.string_field(1) + execution_report_status: "OrderExecutionReportStatus" = _grpc_helpers.enum_field(2) + lots_requested: int = _grpc_helpers.int64_field(3) + lots_executed: int = _grpc_helpers.int64_field(4) + initial_order_price: "MoneyValue" = _grpc_helpers.message_field(5) + executed_order_price: "MoneyValue" = _grpc_helpers.message_field(6) + total_order_amount: "MoneyValue" = _grpc_helpers.message_field(7) + average_position_price: "MoneyValue" = _grpc_helpers.message_field(8) + initial_commission: "MoneyValue" = _grpc_helpers.message_field(9) + executed_commission: "MoneyValue" = _grpc_helpers.message_field(10) + figi: str = _grpc_helpers.string_field(11) + direction: "OrderDirection" = _grpc_helpers.enum_field(12) + initial_security_price: "MoneyValue" = _grpc_helpers.message_field(13) + stages: List["OrderStage"] = _grpc_helpers.message_field(14) + service_commission: "MoneyValue" = _grpc_helpers.message_field(15) + currency: str = _grpc_helpers.string_field(16) + order_type: "OrderType" = _grpc_helpers.enum_field(17) + order_date: datetime = _grpc_helpers.message_field(18) + instrument_uid: str = _grpc_helpers.string_field(19) + order_request_id: str = _grpc_helpers.string_field(20) + + +@dataclass(eq=False, repr=True) +class OrderStage(_grpc_helpers.Message): + price: "MoneyValue" = _grpc_helpers.message_field(1) + quantity: int = _grpc_helpers.int64_field(2) + trade_id: str = _grpc_helpers.string_field(3) + execution_time: datetime = _grpc_helpers.message_field(5) + + +@dataclass(eq=False, repr=True) +class ReplaceOrderRequest(_grpc_helpers.Message): + account_id: str = _grpc_helpers.string_field(1) + order_id_type: "OrderIdType" = _grpc_helpers.message_field(5) + order_id: str = _grpc_helpers.string_field(6) + idempotency_key: str = _grpc_helpers.string_field(7) + quantity: int = _grpc_helpers.int64_field(11) + price: Optional["Quotation"] = _grpc_helpers.message_field(12) + price_type: Optional["PriceType"] = _grpc_helpers.enum_field(13) + confirm_margin_trade: bool = _grpc_helpers.bool_field(14) + + +@dataclass(eq=False, repr=True) +class GetAccountsRequest(_grpc_helpers.Message): + status: Optional["AccountStatus"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class GetAccountsResponse(_grpc_helpers.Message): + accounts: List["Account"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class Account(_grpc_helpers.Message): + id: str = _grpc_helpers.string_field(1) + type: "AccountType" = _grpc_helpers.enum_field(2) + name: str = _grpc_helpers.string_field(3) + status: "AccountStatus" = _grpc_helpers.enum_field(4) + opened_date: datetime = _grpc_helpers.message_field(5) + closed_date: datetime = _grpc_helpers.message_field(6) + access_level: "AccessLevel" = _grpc_helpers.message_field(7) + + @classmethod + def loads(cls, obj) -> "Account": + return cls( + id=obj.id, + type=AccountType(obj.type), + name=obj.name, + status=AccountStatus(obj.type), + opened_date=_grpc_helpers.ts_to_datetime(obj.opened_date), + closed_date=_grpc_helpers.ts_to_datetime(obj.closed_date), + ) + + +@dataclass(eq=False, repr=True) +class GetMarginAttributesRequest(_grpc_helpers.Message): + account_id: str = _grpc_helpers.string_field(1) + + +@dataclass(eq=False, repr=True) +class GetMarginAttributesResponse(_grpc_helpers.Message): + liquid_portfolio: "MoneyValue" = _grpc_helpers.message_field(1) + starting_margin: "MoneyValue" = _grpc_helpers.message_field(2) + minimal_margin: "MoneyValue" = _grpc_helpers.message_field(3) + funds_sufficiency_level: "Quotation" = _grpc_helpers.message_field(4) + amount_of_missing_funds: "MoneyValue" = _grpc_helpers.message_field(5) + corrected_margin: "MoneyValue" = _grpc_helpers.message_field(6) + guarantee_for_futures: "MoneyValue" = _grpc_helpers.message_field(7) + + +@dataclass(eq=False, repr=True) +class GetUserTariffRequest(_grpc_helpers.Message): + pass + + +@dataclass(eq=False, repr=True) +class GetUserTariffResponse(_grpc_helpers.Message): + unary_limits: List["UnaryLimit"] = _grpc_helpers.message_field(1) + stream_limits: List["StreamLimit"] = _grpc_helpers.message_field(2) + + +@dataclass(eq=False, repr=True) +class UnaryLimit(_grpc_helpers.Message): + limit_per_minute: int = _grpc_helpers.int32_field(1) + methods: List[str] = _grpc_helpers.string_field(2) + + +@dataclass(eq=False, repr=True) +class StreamLimit(_grpc_helpers.Message): + limit: int = _grpc_helpers.int32_field(1) + streams: List[str] = _grpc_helpers.string_field(2) + open: int = _grpc_helpers.int32_field(3) + + +@dataclass(eq=False, repr=True) +class GetInfoRequest(_grpc_helpers.Message): + pass + + +@dataclass(eq=False, repr=True) +class GetInfoResponse(_grpc_helpers.Message): + prem_status: bool = _grpc_helpers.bool_field(1) + qual_status: bool = _grpc_helpers.bool_field(2) + qualified_for_work_with: List[str] = _grpc_helpers.string_field(3) + tariff: str = _grpc_helpers.string_field(4) + user_id: str = _grpc_helpers.string_field(9) + risk_level_code: str = _grpc_helpers.string_field(12) + + +@dataclass(eq=False, repr=True) +class OpenSandboxAccountRequest(_grpc_helpers.Message): + name: Optional[str] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class OpenSandboxAccountResponse(_grpc_helpers.Message): + account_id: str = _grpc_helpers.string_field(1) + + +@dataclass(eq=False, repr=True) +class CloseSandboxAccountRequest(_grpc_helpers.Message): + account_id: str = _grpc_helpers.string_field(1) + + +@dataclass(eq=False, repr=True) +class CloseSandboxAccountResponse(_grpc_helpers.Message): + pass + + +@dataclass(eq=False, repr=True) +class SandboxPayInRequest(_grpc_helpers.Message): + account_id: str = _grpc_helpers.string_field(1) + amount: "MoneyValue" = _grpc_helpers.message_field(2) + + +@dataclass(eq=False, repr=True) +class SandboxPayInResponse(_grpc_helpers.Message): + balance: "MoneyValue" = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class PostStopOrderRequest(_grpc_helpers.Message): + figi: Optional[str] = _grpc_helpers.string_field(1) + quantity: int = _grpc_helpers.int64_field(2) + price: Optional["Quotation"] = _grpc_helpers.message_field(3) + stop_price: Optional["Quotation"] = _grpc_helpers.message_field(4) + direction: "StopOrderDirection" = _grpc_helpers.enum_field(5) + account_id: str = _grpc_helpers.string_field(6) + expiration_type: "StopOrderExpirationType" = _grpc_helpers.enum_field(7) + stop_order_type: "StopOrderType" = _grpc_helpers.enum_field(8) + expire_date: Optional[datetime] = _grpc_helpers.message_field(9) + instrument_id: str = _grpc_helpers.string_field(10) + exchange_order_type: "ExchangeOrderType" = _grpc_helpers.message_field(11) + take_profit_type: "TakeProfitType" = _grpc_helpers.message_field(12) + trailing_data: "PostStopOrderRequestTrailingData" = _grpc_helpers.message_field(13) + price_type: "PriceType" = _grpc_helpers.message_field(14) + order_id: str = _grpc_helpers.string_field(15) + confirm_margin_trade: bool = _grpc_helpers.bool_field(16) + instant_execution: Optional[bool] = _grpc_helpers.bool_field(17) + + +@dataclass(eq=False, repr=True) +class PostStopOrderRequestTrailingData(_grpc_helpers.Message): + indent: "Quotation" = _grpc_helpers.message_field(1) + indent_type: "TrailingValueType" = _grpc_helpers.message_field(2) + spread: "Quotation" = _grpc_helpers.message_field(3) + spread_type: "TrailingValueType" = _grpc_helpers.message_field(4) + + +@dataclass(eq=False, repr=True) +class PostStopOrderResponse(_grpc_helpers.Message): + stop_order_id: str = _grpc_helpers.string_field(1) + order_request_id: str = _grpc_helpers.string_field(2) + response_metadata: "ResponseMetadata" = _grpc_helpers.message_field(254) + + +@dataclass(eq=False, repr=True) +class GetStopOrdersRequest(_grpc_helpers.Message): + account_id: str = _grpc_helpers.string_field(1) + status: "StopOrderStatusOption" = _grpc_helpers.message_field(2) + from_: datetime = _grpc_helpers.message_field(3) + to: datetime = _grpc_helpers.message_field(4) + + +@dataclass(eq=False, repr=True) +class GetStopOrdersResponse(_grpc_helpers.Message): + stop_orders: List["StopOrder"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class CancelStopOrderRequest(_grpc_helpers.Message): + account_id: str = _grpc_helpers.string_field(1) + stop_order_id: str = _grpc_helpers.string_field(2) + + +@dataclass(eq=False, repr=True) +class CancelStopOrderResponse(_grpc_helpers.Message): + time: datetime = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class StopOrder(_grpc_helpers.Message): # pylint:disable=too-many-instance-attributes + stop_order_id: str = _grpc_helpers.string_field(1) + lots_requested: int = _grpc_helpers.int64_field(2) + figi: str = _grpc_helpers.string_field(3) + direction: "StopOrderDirection" = _grpc_helpers.enum_field(4) + currency: str = _grpc_helpers.string_field(5) + order_type: "StopOrderType" = _grpc_helpers.enum_field(6) + create_date: datetime = _grpc_helpers.message_field(7) + activation_date_time: datetime = _grpc_helpers.message_field(8) + expiration_time: datetime = _grpc_helpers.message_field(9) + price: "MoneyValue" = _grpc_helpers.message_field(10) + stop_price: "MoneyValue" = _grpc_helpers.message_field(11) + instrument_uid: str = _grpc_helpers.string_field(12) + take_profit_type: "TakeProfitType" = _grpc_helpers.message_field(13) + trailing_data: "StopOrderTrailingData" = _grpc_helpers.message_field(14) + status: "StopOrderStatusOption" = _grpc_helpers.message_field(15) + exchange_order_type: "ExchangeOrderType" = _grpc_helpers.message_field(16) + exchange_order_id: Optional[str] = _grpc_helpers.string_field(17) + ticker: str = _grpc_helpers.string_field(18) + class_code: str = _grpc_helpers.string_field(19) + instant_execution: bool = _grpc_helpers.bool_field(20) + + +@dataclass(eq=False, repr=True) +class StopOrderTrailingData(_grpc_helpers.Message): + indent: "Quotation" = _grpc_helpers.message_field(1) + indent_type: "TrailingValueType" = _grpc_helpers.message_field(2) + spread: "Quotation" = _grpc_helpers.message_field(3) + spread_type: "TrailingValueType" = _grpc_helpers.message_field(4) + status: "TrailingStopStatus" = _grpc_helpers.message_field(5) + price: "Quotation" = _grpc_helpers.message_field(7) + extr: "Quotation" = _grpc_helpers.message_field(8) + + +@dataclass(eq=False, repr=True) +class BrokerReportRequest(_grpc_helpers.Message): + generate_broker_report_request: "GenerateBrokerReportRequest" = ( + _grpc_helpers.message_field(1, group="payload") + ) + get_broker_report_request: "GetBrokerReportRequest" = _grpc_helpers.message_field( + 2, group="payload" + ) + + +@dataclass(eq=False, repr=True) +class BrokerReportResponse(_grpc_helpers.Message): + generate_broker_report_response: "GenerateBrokerReportResponse" = ( + _grpc_helpers.message_field(1, group="payload") + ) + get_broker_report_response: "GetBrokerReportResponse" = _grpc_helpers.message_field( + 2, group="payload" + ) + + +@dataclass(eq=False, repr=True) +class GenerateBrokerReportRequest(_grpc_helpers.Message): + account_id: str = _grpc_helpers.string_field(1) + from_: datetime = _grpc_helpers.message_field(2) + to: datetime = _grpc_helpers.message_field(3) + + +@dataclass(eq=False, repr=True) +class GenerateBrokerReportResponse(_grpc_helpers.Message): + task_id: str = _grpc_helpers.string_field(1) + + +@dataclass(eq=False, repr=True) +class GetBrokerReportRequest(_grpc_helpers.Message): + task_id: str = _grpc_helpers.string_field(1) + page: Optional[int] = _grpc_helpers.int32_field(2) + + +@dataclass(eq=False, repr=True) +class GetBrokerReportResponse(_grpc_helpers.Message): + broker_report: List["BrokerReport"] = _grpc_helpers.message_field(1) + itemsCount: int = _grpc_helpers.int32_field(2) + pagesCount: int = _grpc_helpers.int32_field(3) + page: int = _grpc_helpers.int32_field(4) + task_id: str = _grpc_helpers.string_field(5) + + +@dataclass(eq=False, repr=True) +class BrokerReport( # pylint:disable=too-many-instance-attributes + _grpc_helpers.Message +): + trade_id: str = _grpc_helpers.string_field(1) + order_id: str = _grpc_helpers.string_field(2) + figi: str = _grpc_helpers.string_field(3) + execute_sign: str = _grpc_helpers.string_field(4) + trade_datetime: datetime = _grpc_helpers.message_field(5) + exchange: str = _grpc_helpers.string_field(6) + class_code: str = _grpc_helpers.string_field(7) + direction: str = _grpc_helpers.string_field(8) + name: str = _grpc_helpers.string_field(9) + ticker: str = _grpc_helpers.string_field(10) + price: "MoneyValue" = _grpc_helpers.message_field(11) + quantity: int = _grpc_helpers.int64_field(12) + order_amount: "MoneyValue" = _grpc_helpers.message_field(13) + aci_value: float = _grpc_helpers.double_field(14) + total_order_amount: "MoneyValue" = _grpc_helpers.message_field(15) + broker_commission: "MoneyValue" = _grpc_helpers.message_field(16) + exchange_commission: "MoneyValue" = _grpc_helpers.message_field(17) + exchange_clearing_commission: "MoneyValue" = _grpc_helpers.message_field(18) + repo_rate: float = _grpc_helpers.double_field(19) + party: str = _grpc_helpers.string_field(20) + clear_value_date: datetime = _grpc_helpers.message_field(21) + sec_value_date: datetime = _grpc_helpers.message_field(22) + broker_status: str = _grpc_helpers.string_field(23) + separate_agreement_type: str = _grpc_helpers.string_field(24) + separate_agreement_number: str = _grpc_helpers.string_field(25) + separate_agreement_date: str = _grpc_helpers.string_field(26) + delivery_type: str = _grpc_helpers.string_field(27) + + +@dataclass(eq=False, repr=True) +class PositionsFutures(_grpc_helpers.Message): + figi: str = _grpc_helpers.string_field(1) + blocked: int = _grpc_helpers.int64_field(2) + balance: int = _grpc_helpers.int64_field(3) + position_uid: str = _grpc_helpers.string_field(4) + instrument_uid: str = _grpc_helpers.string_field(5) + ticker: str = _grpc_helpers.string_field(6) + + +@dataclass(eq=False, repr=True) +class PositionsOptions(_grpc_helpers.Message): + position_uid: str = _grpc_helpers.string_field(1) + instrument_uid: str = _grpc_helpers.string_field(2) + blocked: int = _grpc_helpers.int64_field(11) + balance: int = _grpc_helpers.int64_field(21) + ticker: str = _grpc_helpers.string_field(3) + + +@dataclass(eq=False, repr=True) +class GetDividendsForeignIssuerRequest(_grpc_helpers.Message): + generate_div_foreign_issuer_report: "GenerateDividendsForeignIssuerReportRequest" = _grpc_helpers.message_field( # noqa:E501 # pylint:disable=line-too-long + 1, group="payload" + ) + get_div_foreign_issuer_report: "GetDividendsForeignIssuerReportRequest" = ( + _grpc_helpers.message_field(2, group="payload") + ) + + +@dataclass(eq=False, repr=True) +class GetDividendsForeignIssuerResponse(_grpc_helpers.Message): + generate_div_foreign_issuer_report_response: "GenerateDividendsForeignIssuerReportResponse" = _grpc_helpers.message_field( # noqa:E501 # pylint:disable=line-too-long + 1, group="payload" + ) + div_foreign_issuer_report: "GetDividendsForeignIssuerReportResponse" = ( + _grpc_helpers.message_field(2, group="payload") + ) + + +@dataclass(eq=False, repr=True) +class GenerateDividendsForeignIssuerReportRequest(_grpc_helpers.Message): + account_id: str = _grpc_helpers.string_field(1) + from_: datetime = _grpc_helpers.message_field(2) + to: datetime = _grpc_helpers.message_field(3) + + +@dataclass(eq=False, repr=True) +class GetDividendsForeignIssuerReportRequest(_grpc_helpers.Message): + task_id: str = _grpc_helpers.string_field(1) + page: Optional[int] = _grpc_helpers.int32_field(2) + + +@dataclass(eq=False, repr=True) +class GenerateDividendsForeignIssuerReportResponse(_grpc_helpers.Message): + task_id: str = _grpc_helpers.string_field(1) + + +@dataclass(eq=False, repr=True) +class GetDividendsForeignIssuerReportResponse(_grpc_helpers.Message): + dividends_foreign_issuer_report: List[ + "DividendsForeignIssuerReport" + ] = _grpc_helpers.message_field(1) + itemsCount: int = _grpc_helpers.int32_field(2) + pagesCount: int = _grpc_helpers.int32_field(3) + page: int = _grpc_helpers.int32_field(4) + + +@dataclass(eq=False, repr=True) +class DividendsForeignIssuerReport( # pylint:disable=too-many-instance-attributes + _grpc_helpers.Message +): + record_date: datetime = _grpc_helpers.message_field(1) + payment_date: datetime = _grpc_helpers.message_field(2) + security_name: str = _grpc_helpers.string_field(3) + isin: str = _grpc_helpers.string_field(4) + issuer_country: str = _grpc_helpers.string_field(5) + quantity: int = _grpc_helpers.int64_field(6) + dividend: "Quotation" = _grpc_helpers.message_field(7) + external_commission: "Quotation" = _grpc_helpers.message_field(8) + dividend_gross: "Quotation" = _grpc_helpers.message_field(9) + tax: "Quotation" = _grpc_helpers.message_field(10) + dividend_amount: "Quotation" = _grpc_helpers.message_field(11) + currency: str = _grpc_helpers.string_field(12) + + +@dataclass(eq=False, repr=True) +class PortfolioStreamRequest(_grpc_helpers.Message): + accounts: List[str] = _grpc_helpers.message_field(1) + ping_settings: "PingDelaySettings" = _grpc_helpers.message_field(15) + + +@dataclass(eq=False, repr=True) +class PortfolioStreamResponse(_grpc_helpers.Message): + subscriptions: "PortfolioSubscriptionResult" = _grpc_helpers.message_field( + 1, group="payload" + ) + portfolio: "PortfolioResponse" = _grpc_helpers.message_field(2, group="payload") + ping: "Ping" = _grpc_helpers.message_field(3, group="payload") + + +@dataclass(eq=False, repr=True) +class PortfolioSubscriptionResult(_grpc_helpers.Message): + accounts: List["AccountSubscriptionStatus"] = _grpc_helpers.message_field(1) + tracking_id: str = _grpc_helpers.string_field(7) + stream_id: str = _grpc_helpers.string_field(8) + + +@dataclass(eq=False, repr=True) +class AccountSubscriptionStatus(_grpc_helpers.Message): + account_id: str = _grpc_helpers.string_field(1) + subscription_status: "PortfolioSubscriptionStatus" = _grpc_helpers.message_field(6) + + +@dataclass(eq=False, repr=True) +class GetOperationsByCursorRequest(_grpc_helpers.Message): + account_id: str = _grpc_helpers.string_field(1) + instrument_id: Optional[str] = _grpc_helpers.string_field(2) + from_: Optional[datetime] = _grpc_helpers.message_field(6) + to: Optional[datetime] = _grpc_helpers.message_field(7) + cursor: Optional[str] = _grpc_helpers.string_field(11) + limit: Optional[int] = _grpc_helpers.int32_field(12) + operation_types: List["OperationType"] = _grpc_helpers.message_field(13) + state: Optional["OperationState"] = _grpc_helpers.message_field(14) + without_commissions: Optional[bool] = _grpc_helpers.bool_field(15) + without_trades: Optional[bool] = _grpc_helpers.bool_field(16) + without_overnights: Optional[bool] = _grpc_helpers.bool_field(17) + + +@dataclass(eq=False, repr=True) +class GetOperationsByCursorResponse(_grpc_helpers.Message): + has_next: bool = _grpc_helpers.bool_field(1) + next_cursor: str = _grpc_helpers.string_field(2) + items: List["OperationItem"] = _grpc_helpers.message_field(6) + + +@dataclass(eq=False, repr=True) +class OperationItem(_grpc_helpers.Message): + cursor: str = _grpc_helpers.string_field(1) + broker_account_id: str = _grpc_helpers.string_field(6) + id: str = _grpc_helpers.string_field(16) + parent_operation_id: str = _grpc_helpers.string_field(17) + name: str = _grpc_helpers.string_field(18) + date: datetime = _grpc_helpers.message_field(21) + type: "OperationType" = _grpc_helpers.enum_field(22) + description: str = _grpc_helpers.string_field(23) + state: "OperationState" = _grpc_helpers.message_field(24) + instrument_uid: str = _grpc_helpers.string_field(31) + figi: str = _grpc_helpers.string_field(32) + instrument_type: str = _grpc_helpers.string_field(33) + instrument_kind: "InstrumentType" = _grpc_helpers.enum_field(34) + position_uid: str = _grpc_helpers.string_field(35) + payment: "MoneyValue" = _grpc_helpers.message_field(41) + price: "MoneyValue" = _grpc_helpers.message_field(42) + commission: "MoneyValue" = _grpc_helpers.message_field(43) + yield_: "MoneyValue" = _grpc_helpers.message_field(44) + yield_relative: "Quotation" = _grpc_helpers.message_field(45) + accrued_int: "MoneyValue" = _grpc_helpers.message_field(46) + quantity: int = _grpc_helpers.int64_field(51) + quantity_rest: int = _grpc_helpers.int64_field(52) + quantity_done: int = _grpc_helpers.int64_field(53) + cancel_date_time: datetime = _grpc_helpers.message_field(56) + cancel_reason: str = _grpc_helpers.string_field(57) + trades_info: "OperationItemTrades" = _grpc_helpers.message_field(61) + asset_uid: str = _grpc_helpers.string_field(64) + child_operations: List["ChildOperationItem"] = _grpc_helpers.message_field(65) + + +@dataclass(eq=False, repr=True) +class OperationItemTrades(_grpc_helpers.Message): + trades: List["OperationItemTrade"] = _grpc_helpers.message_field(6) + + +@dataclass(eq=False, repr=True) +class OperationItemTrade(_grpc_helpers.Message): + num: str = _grpc_helpers.string_field(1) + date: datetime = _grpc_helpers.message_field(6) + quantity: int = _grpc_helpers.int64_field(11) + price: "MoneyValue" = _grpc_helpers.message_field(16) + yield_: "MoneyValue" = _grpc_helpers.message_field(21) + yield_relative: "Quotation" = _grpc_helpers.message_field(22) + + +@dataclass(eq=False, repr=True) +class PositionsStreamRequest(_grpc_helpers.Message): + accounts: List[str] = _grpc_helpers.string_field(1) + ping_settings: "PingDelaySettings" = _grpc_helpers.message_field(15) + with_initial_positions: bool = _grpc_helpers.bool_field(3) + + +@dataclass(eq=False, repr=True) +class PositionsStreamResponse(_grpc_helpers.Message): + subscriptions: "PositionsSubscriptionResult" = _grpc_helpers.message_field( + 1, group="payload" + ) + position: "PositionData" = _grpc_helpers.message_field(2, group="payload") + ping: "Ping" = _grpc_helpers.message_field(3, group="payload") + initial_positions: "PositionsResponse" = _grpc_helpers.message_field( + 5, group="payload" + ) + + +@dataclass(eq=False, repr=True) +class PositionsSubscriptionResult(_grpc_helpers.Message): + accounts: List["PositionsSubscriptionStatus"] = _grpc_helpers.message_field(1) + tracking_id: str = _grpc_helpers.string_field(7) + stream_id: str = _grpc_helpers.string_field(8) + + +@dataclass(eq=False, repr=True) +class PositionsSubscriptionStatus(_grpc_helpers.Message): + account_id: str = _grpc_helpers.string_field(1) + subscription_status: "PositionsAccountSubscriptionStatus" = ( + _grpc_helpers.message_field(6) + ) + + +@dataclass(eq=False, repr=True) +class PositionData(_grpc_helpers.Message): + account_id: str = _grpc_helpers.string_field(1) + money: List["PositionsMoney"] = _grpc_helpers.message_field(2) + securities: List["PositionsSecurities"] = _grpc_helpers.message_field(3) + futures: List["PositionsFutures"] = _grpc_helpers.message_field(4) + options: List["PositionsOptions"] = _grpc_helpers.message_field(5) + date: datetime = _grpc_helpers.message_field(6) + + +@dataclass(eq=False, repr=True) +class PositionsMoney(_grpc_helpers.Message): + available_value: "MoneyValue" = _grpc_helpers.message_field(1) + blocked_value: "MoneyValue" = _grpc_helpers.message_field(2) + + +@dataclass(eq=False, repr=True) +class Page(_grpc_helpers.Message): + limit: int = _grpc_helpers.int32_field(1) + page_number: int = _grpc_helpers.int32_field(2) + + +@dataclass(eq=False, repr=True) +class PageResponse(_grpc_helpers.Message): + limit: int = _grpc_helpers.int32_field(1) + page_number: int = _grpc_helpers.int32_field(2) + total_count: int = _grpc_helpers.int32_field(3) + + +@dataclass(eq=False, repr=True) +class ResponseMetadata(_grpc_helpers.Message): + tracking_id: str = _grpc_helpers.string_field(42) + server_time: datetime = _grpc_helpers.message_field(43) + + +@dataclass(eq=False, repr=True) +class BrandData(_grpc_helpers.Message): + logo_name: str = _grpc_helpers.string_field(1) + logo_base_color: str = _grpc_helpers.string_field(2) + text_color: str = _grpc_helpers.string_field(3) + + +@dataclass(eq=False, repr=True) +class GetAssetFundamentalsRequest(_grpc_helpers.Message): + assets: List[str] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class GetAssetFundamentalsResponse(_grpc_helpers.Message): + fundamentals: List["StatisticResponse"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class StatisticResponse(_grpc_helpers.Message): + asset_uid: str = _grpc_helpers.string_field(1) + currency: str = _grpc_helpers.string_field(2) + market_capitalization: float = _grpc_helpers.double_field(3) + high_price_last_52_weeks: float = _grpc_helpers.double_field(4) + low_price_last_52_weeks: float = _grpc_helpers.double_field(5) + average_daily_volume_last_10_days: float = _grpc_helpers.double_field(6) + average_daily_volume_last_4_weeks: float = _grpc_helpers.double_field(7) + beta: float = _grpc_helpers.double_field(8) + free_float: float = _grpc_helpers.double_field(9) + forward_annual_dividend_yield: float = _grpc_helpers.double_field(10) + shares_outstanding: float = _grpc_helpers.double_field(11) + revenue_ttm: float = _grpc_helpers.double_field(12) + ebitda_ttm: float = _grpc_helpers.double_field(13) + net_income_ttm: float = _grpc_helpers.double_field(14) + eps_ttm: float = _grpc_helpers.double_field(15) + diluted_eps_ttm: float = _grpc_helpers.double_field(16) + free_cash_flow_ttm: float = _grpc_helpers.double_field(17) + five_year_annual_revenue_growth_rate: float = _grpc_helpers.double_field(18) + three_year_annual_revenue_growth_rate: float = _grpc_helpers.double_field(19) + pe_ratio_ttm: float = _grpc_helpers.double_field(20) + price_to_sales_ttm: float = _grpc_helpers.double_field(21) + price_to_book_ttm: float = _grpc_helpers.double_field(22) + price_to_free_cash_flow_ttm: float = _grpc_helpers.double_field(23) + total_enterprise_value_mrq: float = _grpc_helpers.double_field(24) + ev_to_ebitda_mrq: float = _grpc_helpers.double_field(25) + net_margin_mrq: float = _grpc_helpers.double_field(26) + net_interest_margin_mrq: float = _grpc_helpers.double_field(27) + roe: float = _grpc_helpers.double_field(28) + roa: float = _grpc_helpers.double_field(29) + roic: float = _grpc_helpers.double_field(30) + total_debt_mrq: float = _grpc_helpers.double_field(31) + total_debt_to_equity_mrq: float = _grpc_helpers.double_field(32) + total_debt_to_ebitda_mrq: float = _grpc_helpers.double_field(33) + free_cash_flow_to_price: float = _grpc_helpers.double_field(34) + net_debt_to_ebitda: float = _grpc_helpers.double_field(35) + current_ratio_mrq: float = _grpc_helpers.double_field(36) + fixed_charge_coverage_ratio_fy: float = _grpc_helpers.double_field(37) + dividend_yield_daily_ttm: float = _grpc_helpers.double_field(38) + dividend_rate_ttm: float = _grpc_helpers.double_field(39) + dividends_per_share: float = _grpc_helpers.double_field(40) + five_years_average_dividend_yield: float = _grpc_helpers.double_field(41) + five_year_annual_dividend_growth_rate: float = _grpc_helpers.double_field(42) + dividend_payout_ratio_fy: float = _grpc_helpers.double_field(43) + buy_back_ttm: float = _grpc_helpers.double_field(44) + one_year_annual_revenue_growth_rate: float = _grpc_helpers.double_field(45) + domicile_indicator_code: str = _grpc_helpers.string_field(46) + adr_to_common_share_ratio: float = _grpc_helpers.double_field(47) + number_of_employees: float = _grpc_helpers.double_field(48) + ex_dividend_date: datetime = _grpc_helpers.message_field(49) + fiscal_period_start_date: datetime = _grpc_helpers.message_field(50) + fiscal_period_end_date: datetime = _grpc_helpers.message_field(51) + revenue_change_five_years: float = _grpc_helpers.double_field(53) + eps_change_five_years: float = _grpc_helpers.double_field(54) + ebitda_change_five_years: float = _grpc_helpers.double_field(55) + total_debt_change_five_years: float = _grpc_helpers.double_field(56) + ev_to_sales: float = _grpc_helpers.double_field(57) + + +@dataclass(eq=False, repr=True) +class GetAssetReportsRequest(_grpc_helpers.Message): + instrument_id: str = _grpc_helpers.string_field(1) + from_: datetime = _grpc_helpers.message_field(2) + to: datetime = _grpc_helpers.message_field(3) + + +@dataclass(eq=False, repr=True) +class GetAssetReportsEvent(_grpc_helpers.Message): + instrument_id: str = _grpc_helpers.string_field(1) + report_date: datetime = _grpc_helpers.message_field(2) + period_year: int = _grpc_helpers.int32_field(3) + period_num: int = _grpc_helpers.int32_field(4) + period_type: "AssetReportPeriodType" = _grpc_helpers.enum_field(5) + created_at: datetime = _grpc_helpers.message_field(6) + + +@dataclass(eq=False, repr=True) +class GetAssetReportsResponse(_grpc_helpers.Message): + events: List["GetAssetReportsEvent"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class GetConsensusForecastsRequest(_grpc_helpers.Message): + paging: Optional["Page"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class ConsensusForecastsItem(_grpc_helpers.Message): + uid: str = _grpc_helpers.string_field(1) + asset_uid: str = _grpc_helpers.string_field(2) + created_at: datetime = _grpc_helpers.message_field(3) + best_target_price: "Quotation" = _grpc_helpers.message_field(4) + best_target_low: "Quotation" = _grpc_helpers.message_field(5) + best_target_high: "Quotation" = _grpc_helpers.message_field(6) + total_buy_recommend: int = _grpc_helpers.int32_field(7) + total_hold_recommend: int = _grpc_helpers.int32_field(8) + total_sell_recommend: int = _grpc_helpers.int32_field(9) + currency: str = _grpc_helpers.string_field(10) + consensus: "Recommendation" = _grpc_helpers.message_field(11) + prognosis_date: datetime = _grpc_helpers.message_field(12) + + +@dataclass(eq=False, repr=True) +class GetConsensusForecastsResponse(_grpc_helpers.Message): + items: List["ConsensusForecastsItem"] = _grpc_helpers.message_field(1) + page: "PageResponse" = _grpc_helpers.message_field(2) + + +@dataclass(eq=False, repr=True) +class GetForecastRequest(_grpc_helpers.Message): + instrument_id: str = _grpc_helpers.string_field(1) + + +@dataclass(eq=False, repr=True) +class TargetItem(_grpc_helpers.Message): + uid: str = _grpc_helpers.string_field(1) + ticker: str = _grpc_helpers.string_field(2) + company: str = _grpc_helpers.string_field(3) + recommendation: "Recommendation" = _grpc_helpers.message_field(4) + recommendation_date: datetime = _grpc_helpers.message_field(5) + currency: str = _grpc_helpers.string_field(6) + current_price: "Quotation" = _grpc_helpers.message_field(7) + target_price: "Quotation" = _grpc_helpers.message_field(8) + price_change: "Quotation" = _grpc_helpers.message_field(9) + price_change_rel: "Quotation" = _grpc_helpers.message_field(10) + show_name: str = _grpc_helpers.string_field(11) + + +@dataclass(eq=False, repr=True) +class ConsensusItem(_grpc_helpers.Message): + uid: str = _grpc_helpers.string_field(1) + ticker: str = _grpc_helpers.string_field(2) + recommendation: "Recommendation" = _grpc_helpers.message_field(3) + currency: str = _grpc_helpers.string_field(4) + current_price: "Quotation" = _grpc_helpers.message_field(5) + consensus: "Quotation" = _grpc_helpers.message_field(6) + min_target: "Quotation" = _grpc_helpers.message_field(7) + max_target: "Quotation" = _grpc_helpers.message_field(8) + price_change: "Quotation" = _grpc_helpers.message_field(9) + price_change_rel: "Quotation" = _grpc_helpers.message_field(10) + + +@dataclass(eq=False, repr=True) +class GetForecastResponse(_grpc_helpers.Message): + targets: List["TargetItem"] = _grpc_helpers.message_field(1) + consensus: "ConsensusItem" = _grpc_helpers.message_field(2) + + +@dataclass(eq=False, repr=True) +class RiskRatesRequest(_grpc_helpers.Message): + instrument_id: List[str] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class RiskRatesResponse(_grpc_helpers.Message): + instrument_risk_rates: List["RiskRateResult"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class RiskRateResult(_grpc_helpers.Message): + instrument_uid: str = _grpc_helpers.string_field(1) + short_risk_rate: Optional["RiskRate"] = _grpc_helpers.message_field(2) + long_risk_rate: Optional["RiskRate"] = _grpc_helpers.message_field(3) + short_risk_rates: List["RiskRate"] = _grpc_helpers.message_field(5) + long_risk_rates: List["RiskRate"] = _grpc_helpers.message_field(6) + error: Optional[str] = _grpc_helpers.string_field(9) + + +@dataclass(eq=False, repr=True) +class RiskRate(_grpc_helpers.Message): + risk_level_code: str = _grpc_helpers.string_field(2) + value: Quotation = _grpc_helpers.message_field(5) + + +@dataclass(eq=False, repr=True) +class GetInsiderDealsRequest(_grpc_helpers.Message): + instrument_id: str = _grpc_helpers.string_field(1) + limit: int = _grpc_helpers.int32_field(2) + next_cursor: Optional[str] = _grpc_helpers.string_field(3) + + +@dataclass(eq=False, repr=True) +class GetInsiderDealsResponse(_grpc_helpers.Message): + insider_deals: List["InsiderDeal"] = _grpc_helpers.message_field(1) + next_cursor: Optional[str] = _grpc_helpers.string_field(2) + + +@dataclass(eq=False, repr=True) +class InsiderDeal(_grpc_helpers.Message): + trade_id: int = _grpc_helpers.int64_field(1) + direction: TradeDirection = _grpc_helpers.enum_field(2) + currency: str = _grpc_helpers.string_field(3) + date: datetime = _grpc_helpers.message_field(4) + quantity: int = _grpc_helpers.int64_field(5) + price: Quotation = _grpc_helpers.message_field(6) + instrument_uid: str = _grpc_helpers.string_field(7) + ticker: str = _grpc_helpers.string_field(8) + investor_name: str = _grpc_helpers.string_field(9) + investor_position: str = _grpc_helpers.string_field(10) + percentage: float = _grpc_helpers.float_field(11) + is_option_execution: bool = _grpc_helpers.bool_field(12) + disclosure_date: datetime = _grpc_helpers.message_field(13) + + +@dataclass(eq=False, repr=True) +class TimeInterval(_grpc_helpers.Message): + start_ts: datetime = _grpc_helpers.message_field(1) + end_ts: datetime = _grpc_helpers.message_field(2) + + +@dataclass(eq=False, repr=True) +class TradingInterval(_grpc_helpers.Message): + type: str = _grpc_helpers.string_field(1) + interval: "TimeInterval" = _grpc_helpers.message_field(2) + + +@dataclass(eq=False, repr=True) +class GetMaxLotsRequest(_grpc_helpers.Message): + account_id: str = _grpc_helpers.string_field(1) + instrument_id: str = _grpc_helpers.string_field(2) + price: Optional["Quotation"] = _grpc_helpers.message_field(3) + + +@dataclass(eq=False, repr=True) +class GetMaxLotsResponse(_grpc_helpers.Message): + currency: str = _grpc_helpers.string_field(1) + buy_limits: "BuyLimitsView" = _grpc_helpers.message_field(2) + buy_margin_limits: "BuyLimitsView" = _grpc_helpers.message_field(3) + sell_limits: "SellLimitsView" = _grpc_helpers.message_field(4) + sell_margin_limits: "SellLimitsView" = _grpc_helpers.message_field(5) + + +@dataclass(eq=False, repr=True) +class DfasRequest(_grpc_helpers.Message): + pass + + +@dataclass(eq=False, repr=True) +class DfaResponse(_grpc_helpers.Message): + uid: str = _grpc_helpers.string_field(1) + ticker: str = _grpc_helpers.string_field(2) + name: str = _grpc_helpers.string_field(3) + position_uid: str = _grpc_helpers.string_field(4) + min_price_increment: "Quotation" = _grpc_helpers.message_field(5) + lot: int = _grpc_helpers.int32_field(6) + nominal: "MoneyValue" = _grpc_helpers.message_field(7) + currency: str = _grpc_helpers.string_field(8) + maturity_date: datetime = _grpc_helpers.message_field(9) + short_enabled_flag: bool = _grpc_helpers.bool_field(10) + api_trade_available_flag: bool = _grpc_helpers.bool_field(11) + buy_available_flag: bool = _grpc_helpers.bool_field(12) + sell_available_flag: bool = _grpc_helpers.bool_field(13) + limit_order_available_flag: bool = _grpc_helpers.bool_field(14) + market_order_available_flag: bool = _grpc_helpers.bool_field(15) + bestprice_order_available_flag: bool = _grpc_helpers.bool_field(16) + for_iis_flag: bool = _grpc_helpers.bool_field(17) + for_qual_investor_flag: bool = _grpc_helpers.bool_field(18) + type: str = _grpc_helpers.string_field(19) + basic_assets: List["BasicDfaAsset"] = _grpc_helpers.message_field(20) + forecast_yield: "ForecastYield" = _grpc_helpers.message_field(21) + yield_to_maturity: "Quotation" = _grpc_helpers.message_field(22) + coupon_value: "Quotation" = _grpc_helpers.message_field(23) + coupon_payment_frequency: int = _grpc_helpers.int32_field(24) + coupon_payment_date: datetime = _grpc_helpers.message_field(25) + aci_value: "Quotation" = _grpc_helpers.message_field(26) + + +@dataclass(eq=False, repr=True) +class BasicDfaAsset(_grpc_helpers.Message): + uid: str = _grpc_helpers.string_field(1) + + +@dataclass(eq=False, repr=True) +class ForecastYield(_grpc_helpers.Message): + min_value: "Quotation" = _grpc_helpers.message_field(1) + max_value: "Quotation" = _grpc_helpers.message_field(2) + + +@dataclass(eq=False, repr=True) +class DfasResponse(_grpc_helpers.Message): + instruments: List["DfaResponse"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class BuyLimitsView(_grpc_helpers.Message): + buy_money_amount: "Quotation" = _grpc_helpers.message_field(1) + buy_max_lots: int = _grpc_helpers.int64_field(2) + buy_max_market_lots: int = _grpc_helpers.int64_field(3) + + +@dataclass(eq=False, repr=True) +class SellLimitsView(_grpc_helpers.Message): + sell_max_lots: int = _grpc_helpers.int64_field(1) + + +@dataclass(eq=False, repr=True) +class GetOrderPriceRequest(_grpc_helpers.Message): + account_id: str = _grpc_helpers.string_field(1) + instrument_id: str = _grpc_helpers.string_field(2) + price: "Quotation" = _grpc_helpers.message_field(3) + direction: "OrderDirection" = _grpc_helpers.message_field(12) + quantity: int = _grpc_helpers.int64_field(13) + + +@dataclass(eq=False, repr=True) +class GetOrderPriceResponse(_grpc_helpers.Message): + total_order_amount: "MoneyValue" = _grpc_helpers.message_field(1) + initial_order_amount: "MoneyValue" = _grpc_helpers.message_field(5) + lots_requested: int = _grpc_helpers.int64_field(3) + executed_commission: "MoneyValue" = _grpc_helpers.message_field(7) + executed_commission_rub: "MoneyValue" = _grpc_helpers.message_field(8) + service_commission: "MoneyValue" = _grpc_helpers.message_field(9) + deal_commission: "MoneyValue" = _grpc_helpers.message_field(10) + extra_bond: "ExtraBond" = _grpc_helpers.message_field(12, group="instrument_extra") + extra_future: "ExtraFuture" = _grpc_helpers.message_field( + 13, group="instrument_extra" + ) + + +@dataclass(eq=False, repr=True) +class OrderStateStreamRequest(_grpc_helpers.Message): + accounts: List[str] = _grpc_helpers.message_field(1) + ping_delay_millis: Optional[int] = _grpc_helpers.int32_field(15) + + +@dataclass(eq=False, repr=True) +class ErrorDetail(_grpc_helpers.Message): + code: str = _grpc_helpers.string_field(1) + message: str = _grpc_helpers.string_field(3) + + +@dataclass(eq=False, repr=True) +class SubscriptionResponse(_grpc_helpers.Message): + tracking_id: str = _grpc_helpers.string_field(1) + status: ResultSubscriptionStatus = _grpc_helpers.message_field(2) + stream_id: str = _grpc_helpers.message_field(4) + accounts: List[str] = _grpc_helpers.message_field(5) + error: Optional[ErrorDetail] = _grpc_helpers.message_field(7) + + +@dataclass(eq=False, repr=True) +class OrderStateStreamOrderState(_grpc_helpers.Message): + order_id: str = _grpc_helpers.string_field(1) + order_request_id: Optional[str] = _grpc_helpers.string_field(2) + client_code: str = _grpc_helpers.string_field(3) + created_at: datetime = _grpc_helpers.message_field(4) + execution_report_status: OrderExecutionReportStatus = _grpc_helpers.message_field(5) + status_info: Optional[StatusCauseInfo] = _grpc_helpers.message_field(6) + ticker: str = _grpc_helpers.string_field(7) + class_code: str = _grpc_helpers.string_field(8) + lot_size: int = _grpc_helpers.int32_field(9) + direction: OrderDirection = _grpc_helpers.message_field(10) + time_in_force: TimeInForceType = _grpc_helpers.message_field(11) + order_type: OrderType = _grpc_helpers.message_field(12) + account_id: str = _grpc_helpers.string_field(13) + trade_order_id: str = _grpc_helpers.string_field(14) + initial_order_price: MoneyValue = _grpc_helpers.message_field(22) + order_price: MoneyValue = _grpc_helpers.message_field(23) + amount: Optional[MoneyValue] = _grpc_helpers.message_field(24) + executed_order_price: MoneyValue = _grpc_helpers.message_field(25) + currency: str = _grpc_helpers.string_field(26) + lots_requested: int = _grpc_helpers.int64_field(27) + lots_executed: int = _grpc_helpers.int64_field(28) + lots_left: int = _grpc_helpers.int64_field(29) + lots_cancelled: int = _grpc_helpers.int64_field(30) + marker: Optional[MarkerType] = _grpc_helpers.message_field(31) + trades: List[OrderTrade] = _grpc_helpers.message_field(33) + completion_time: datetime = _grpc_helpers.message_field(35) + exchange: str = _grpc_helpers.string_field(36) + instrument_uid: str = _grpc_helpers.string_field(41) + + +@dataclass(eq=False, repr=True) +class OrderStateStreamResponse(_grpc_helpers.Message): + order_state: "OrderStateStreamOrderState" = _grpc_helpers.message_field( + 1, group="payload" + ) + ping: "Ping" = _grpc_helpers.message_field(2, group="payload") + subscription: "SubscriptionResponse" = _grpc_helpers.message_field( + 3, group="payload" + ) + + +@dataclass(eq=False, repr=True) +class ExtraBond(_grpc_helpers.Message): + aci_value: "MoneyValue" = _grpc_helpers.message_field(2) + nominal_conversion_rate: "Quotation" = _grpc_helpers.message_field(3) + + +@dataclass(eq=False, repr=True) +class ExtraFuture(_grpc_helpers.Message): + initial_margin: "MoneyValue" = _grpc_helpers.message_field(2) + + +@dataclass(eq=False, repr=True) +class GetStrategiesRequest(_grpc_helpers.Message): + strategy_id: Optional[str] = _grpc_helpers.string_field(1) + + +@dataclass(eq=False, repr=True) +class GetStrategiesResponse(_grpc_helpers.Message): + strategies: List["Strategy"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class Strategy(_grpc_helpers.Message): + strategy_id: str = _grpc_helpers.string_field(1) + strategy_name: str = _grpc_helpers.string_field(2) + strategy_description: Optional[str] = _grpc_helpers.string_field(3) + strategy_url: Optional[str] = _grpc_helpers.string_field(4) + strategy_type: "StrategyType" = _grpc_helpers.message_field(5) + active_signals: int = _grpc_helpers.int32_field(6) + total_signals: int = _grpc_helpers.int32_field(7) + time_in_position: int = _grpc_helpers.int64_field(8) + average_signal_yield: "Quotation" = _grpc_helpers.string_field(9) + average_signal_yield_year: "Quotation" = _grpc_helpers.string_field(10) + yield_: "Quotation" = _grpc_helpers.string_field(11) + yield_year: "Quotation" = _grpc_helpers.string_field(12) + + +@dataclass(eq=False, repr=True) +class GetSignalsRequest(_grpc_helpers.Message): + signal_id: Optional[str] = _grpc_helpers.string_field(1) + strategy_id: Optional[str] = _grpc_helpers.string_field(2) + strategy_type: Optional["StrategyType"] = _grpc_helpers.message_field(3) + instrument_uid: Optional[str] = _grpc_helpers.string_field(4) + from_: Optional[datetime] = _grpc_helpers.message_field(5) + to: Optional[datetime] = _grpc_helpers.message_field(6) + direction: Optional["SignalDirection"] = _grpc_helpers.message_field(7) + active: Optional[SignalState] = _grpc_helpers.message_field(8) + paging: Optional["Page"] = _grpc_helpers.message_field(9) + + +@dataclass(eq=False, repr=True) +class GetSignalsResponse(_grpc_helpers.Message): + signals: List["Signal"] = _grpc_helpers.message_field(1) + paging: "PageResponse" = _grpc_helpers.message_field(2) + + +@dataclass(eq=False, repr=True) +class Signal(_grpc_helpers.Message): + signal_id: str = _grpc_helpers.string_field(1) + strategy_id: str = _grpc_helpers.string_field(2) + strategy_name: str = _grpc_helpers.string_field(3) + instrument_uid: str = _grpc_helpers.string_field(4) + create_dt: datetime = _grpc_helpers.message_field(5) + direction: "SignalDirection" = _grpc_helpers.message_field(6) + initial_price: "Quotation" = _grpc_helpers.message_field(7) + info: Optional[str] = _grpc_helpers.string_field(8) + name: str = _grpc_helpers.string_field(9) + target_price: "Quotation" = _grpc_helpers.message_field(10) + end_dt: datetime = _grpc_helpers.message_field(11) + probability: int = _grpc_helpers.int32_field(12) + stoploss: "Quotation" = _grpc_helpers.message_field(13) + close_price: "Quotation" = _grpc_helpers.message_field(14) + close_dt: Optional[datetime] = _grpc_helpers.message_field(15) + + +@dataclass(eq=False, repr=True) +class StructuredNoteResponse(_grpc_helpers.Message): + instrument: "StructuredNote" = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class StructuredNotesResponse(_grpc_helpers.Message): + instruments: List["StructuredNote"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class StructuredNote(_grpc_helpers.Message): + uid: str = _grpc_helpers.string_field(1) + figi: str = _grpc_helpers.string_field(2) + ticker: str = _grpc_helpers.string_field(3) + class_code: str = _grpc_helpers.string_field(4) + isin: str = _grpc_helpers.string_field(5) + name: str = _grpc_helpers.string_field(6) + asset_uid: str = _grpc_helpers.string_field(7) + position_uid: str = _grpc_helpers.string_field(8) + min_price_increment: "Quotation" = _grpc_helpers.message_field(9) + lot: int = _grpc_helpers.int32_field(10) + nominal: "MoneyValue" = _grpc_helpers.message_field(11) + currency: str = _grpc_helpers.string_field(12) + maturity_date: datetime = _grpc_helpers.message_field(13) + placement_date: datetime = _grpc_helpers.message_field(14) + issue_kind: str = _grpc_helpers.string_field(15) + issue_size: int = _grpc_helpers.int32_field(16) + issue_size_plan: int = _grpc_helpers.int32_field(17) + dlong_client: "Quotation" = _grpc_helpers.message_field(18) + dshort_client: "Quotation" = _grpc_helpers.message_field(19) + short_enabled_flag: bool = _grpc_helpers.bool_field(20) + exchange: str = _grpc_helpers.string_field(21) + trading_status: "SecurityTradingStatus" = _grpc_helpers.message_field(22) + api_trade_available_flag: bool = _grpc_helpers.bool_field(23) + buy_available_flag: bool = _grpc_helpers.bool_field(24) + sell_available_flag: bool = _grpc_helpers.bool_field(25) + limit_order_available_flag: bool = _grpc_helpers.bool_field(26) + market_order_available_flag: bool = _grpc_helpers.bool_field(27) + bestprice_order_available_flag: bool = _grpc_helpers.bool_field(28) + weekend_flag: bool = _grpc_helpers.bool_field(29) + liquidity_flag: bool = _grpc_helpers.bool_field(30) + for_iis_flag: bool = _grpc_helpers.bool_field(31) + for_qual_investor_flag: bool = _grpc_helpers.bool_field(32) + pawnshop_list_flag: bool = _grpc_helpers.bool_field(33) + real_exchange: "RealExchange" = _grpc_helpers.message_field(34) + first_1min_candle_date: datetime = _grpc_helpers.message_field(35) + first_1day_candle_date: datetime = _grpc_helpers.message_field(36) + borrow_name: str = _grpc_helpers.string_field(37) + type: str = _grpc_helpers.string_field(38) + logic_portfolio: "LogicPortfolio" = _grpc_helpers.message_field(39) + asset_type: "AssetType" = _grpc_helpers.message_field(40) + basic_assets: List["BasicAsset"] = _grpc_helpers.message_field(41) + safety_barrier: "Quotation" = _grpc_helpers.message_field(42) + coupon_period_base: str = _grpc_helpers.string_field(43) + observation_principle: "ObservationPrinciple" = _grpc_helpers.message_field(44) + observation_frequency: str = _grpc_helpers.string_field(45) + initial_price_fixing_date: datetime = _grpc_helpers.message_field(46) + yield_: List["Yield"] = _grpc_helpers.message_field(47) + coupon_saving_flag: bool = _grpc_helpers.bool_field(48) + sector: str = _grpc_helpers.string_field(49) + country_of_risk: str = _grpc_helpers.string_field(50) + country_of_risk_name: str = _grpc_helpers.string_field(51) + logo_name: str = _grpc_helpers.string_field(52) + required_tests: List[str] = _grpc_helpers.message_field(50) + + +@dataclass(eq=False, repr=True) +class BasicAsset(_grpc_helpers.Message): + uid: str = _grpc_helpers.string_field(1) + type: "AssetType" = _grpc_helpers.message_field(2) + initial_price: "Quotation" = _grpc_helpers.message_field(3) + + +@dataclass(eq=False, repr=True) +class Yield(_grpc_helpers.Message): + type: "YieldType" = _grpc_helpers.message_field(1) + value: "Quotation" = _grpc_helpers.message_field(2) + + +class LogicPortfolio(_grpc_helpers.Enum): + LOGIC_PORTFOLIO_UNSPECIFIED = 0 + LOGIC_PORTFOLIO_VOLATILITY = 1 + LOGIC_PORTFOLIO_CORRELATION = 2 + + +class ObservationPrinciple(_grpc_helpers.Enum): + OBSERVATION_PRINCIPLE_UNSPECIFIED = 0 + OBSERVATION_PRINCIPLE_WORST_BASIC_ASSET = 1 + OBSERVATION_PRINCIPLE_BEST_BASIC_ASSET = 2 + OBSERVATION_PRINCIPLE_AVERAGE_OF_BASIC_ASSETS = 3 + OBSERVATION_PRINCIPLE_SINGLE_BASIC_ASSET_PERFORMANCE = 4 + + +class YieldType(_grpc_helpers.Enum): + YIELD_TYPE_UNSPECIFIED = 0 + YIELD_TYPE_GUARANTED_COUPON = 1 + YIELD_TYPE_CONDITIONAL_COUPON = 2 + YIELD_TYPE_PARTICIPATION = 3 + + +class AccountValue(_grpc_helpers.Enum): + ACCOUNT_VALUE_UNSPECIFIED = 0 + ACCOUNT_VALUE_MARGIN_FEE = 1 + ACCOUNT_VALUE_AMOUNT_WITHOUT_EXTRA_FEE = 2 + + +@dataclass(eq=False, repr=True) +class GetBankAccountsRequest(_grpc_helpers.Message): + pass + + +@dataclass(eq=False, repr=True) +class GetBankAccountsResponse(_grpc_helpers.Message): + bank_accounts: List["BankAccount"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class BankAccount(_grpc_helpers.Message): + id: str = _grpc_helpers.string_field(1) + name: str = _grpc_helpers.string_field(2) + money: List["MoneyValue"] = _grpc_helpers.message_field(3) + opened_date: datetime = _grpc_helpers.message_field(4) + type: "AccountType" = _grpc_helpers.message_field(5) + + +@dataclass(eq=False, repr=True) +class CurrencyTransferRequest(_grpc_helpers.Message): + from_account_id: str = _grpc_helpers.string_field(1) + to_account_id: str = _grpc_helpers.string_field(2) + amount: "MoneyValue" = _grpc_helpers.message_field(3) + transaction_id: str = _grpc_helpers.string_field(4) + + +@dataclass(eq=False, repr=True) +class CurrencyTransferResponse(_grpc_helpers.Message): + pass + + +@dataclass(eq=False, repr=True) +class PayInRequest(_grpc_helpers.Message): + from_account_id: str = _grpc_helpers.string_field(1) + to_account_id: str = _grpc_helpers.string_field(2) + amount: "MoneyValue" = _grpc_helpers.message_field(3) + + +@dataclass(eq=False, repr=True) +class PayInResponse(_grpc_helpers.Message): + pass + + +@dataclass(eq=False, repr=True) +class GetAccountValuesRequest(_grpc_helpers.Message): + accounts: List[str] = _grpc_helpers.message_field(1) + values: List["AccountValue"] = _grpc_helpers.message_field(2) + + +@dataclass(eq=False, repr=True) +class GetAccountValuesResponse(_grpc_helpers.Message): + accounts: List["AccountValuesWithParameters"] = _grpc_helpers.message_field(1) + + +@dataclass(eq=False, repr=True) +class AccountValuesWithParameters(_grpc_helpers.Message): + account_id: str = _grpc_helpers.string_field(1) + values: List["InstrumentParameter"] = _grpc_helpers.message_field(2) + + +@dataclass(eq=False, repr=True) +class InstrumentParameter(_grpc_helpers.Message): + name: AccountValue = _grpc_helpers.message_field(1) + value: "MoneyValue" = _grpc_helpers.message_field(2) diff --git a/invest-python-master/t_tech/invest/services.py b/invest-python-master/t_tech/invest/services.py new file mode 100644 index 0000000..ade6ea1 --- /dev/null +++ b/invest-python-master/t_tech/invest/services.py @@ -0,0 +1,2344 @@ +# pylint:disable=redefined-builtin,too-many-lines +import logging +from datetime import datetime +from typing import Generator, Iterable, Iterator, List, Optional + +import grpc +from deprecation import deprecated + +from . import _grpc_helpers, utils +from ._error_hub import handle_error_hub_gen +from ._errors import handle_request_error, handle_request_error_gen +from .exceptions import RequestError +from .grpc import ( + instruments_pb2, + instruments_pb2_grpc, + marketdata_pb2, + marketdata_pb2_grpc, + operations_pb2, + operations_pb2_grpc, + orders_pb2, + orders_pb2_grpc, + sandbox_pb2, + sandbox_pb2_grpc, + signals_pb2, + signals_pb2_grpc, + stoporders_pb2, + stoporders_pb2_grpc, + users_pb2, + users_pb2_grpc, +) +from .logging import get_tracking_id_from_call, log_request +from .market_data_stream.market_data_stream_manager import MarketDataStreamManager +from .metadata import get_metadata +from .schemas import ( + AssetRequest, + AssetResponse, + AssetsRequest, + AssetsResponse, + BondResponse, + BondsResponse, + Brand, + BrokerReportRequest, + BrokerReportResponse, + CancelOrderRequest, + CancelOrderResponse, + CancelStopOrderRequest, + CancelStopOrderResponse, + CandleInterval, + CandleSource, + CloseSandboxAccountRequest, + CloseSandboxAccountResponse, + CreateFavoriteGroupRequest, + CreateFavoriteGroupResponse, + CurrenciesResponse, + CurrencyResponse, + CurrencyTransferRequest, + CurrencyTransferResponse, + DeleteFavoriteGroupRequest, + DeleteFavoriteGroupResponse, + DfaResponse, + DfasRequest, + DfasResponse, + EditFavoritesActionType, + EditFavoritesRequest, + EditFavoritesRequestInstrument, + EditFavoritesResponse, + EtfResponse, + EtfsResponse, + ExchangeOrderType, + FilterOptionsRequest, + FindInstrumentRequest, + FindInstrumentResponse, + FutureResponse, + FuturesResponse, + GenerateBrokerReportRequest, + GenerateDividendsForeignIssuerReportRequest, + GetAccountsRequest, + GetAccountsResponse, + GetAccountValuesRequest, + GetAccountValuesResponse, + GetAccruedInterestsRequest, + GetAccruedInterestsResponse, + GetAssetFundamentalsRequest, + GetAssetFundamentalsResponse, + GetAssetReportsRequest, + GetAssetReportsResponse, + GetBankAccountsRequest, + GetBankAccountsResponse, + GetBondCouponsRequest, + GetBondCouponsResponse, + GetBondEventsRequest, + GetBondEventsResponse, + GetBrandRequest, + GetBrandsRequest, + GetBrandsResponse, + GetBrokerReportRequest, + GetCandlesRequest, + GetCandlesResponse, + GetClosePricesRequest, + GetClosePricesResponse, + GetConsensusForecastsRequest, + GetConsensusForecastsResponse, + GetCountriesRequest, + GetCountriesResponse, + GetDividendsForeignIssuerReportRequest, + GetDividendsForeignIssuerRequest, + GetDividendsForeignIssuerResponse, + GetDividendsRequest, + GetDividendsResponse, + GetFavoriteGroupsRequest, + GetFavoriteGroupsResponse, + GetFavoritesRequest, + GetFavoritesResponse, + GetForecastRequest, + GetForecastResponse, + GetFuturesMarginRequest, + GetFuturesMarginResponse, + GetInfoRequest, + GetInfoResponse, + GetInsiderDealsRequest, + GetInsiderDealsResponse, + GetLastPricesRequest, + GetLastPricesResponse, + GetLastTradesRequest, + GetLastTradesResponse, + GetMarginAttributesRequest, + GetMarginAttributesResponse, + GetMarketValuesRequest, + GetMarketValuesResponse, + GetMaxLotsRequest, + GetMaxLotsResponse, + GetOperationsByCursorRequest, + GetOperationsByCursorResponse, + GetOrderBookRequest, + GetOrderBookResponse, + GetOrderPriceRequest, + GetOrderPriceResponse, + GetOrdersRequest, + GetOrdersRequestFilters, + GetOrdersResponse, + GetOrderStateRequest, + GetSignalsRequest, + GetSignalsResponse, + GetStopOrdersRequest, + GetStopOrdersResponse, + GetStrategiesRequest, + GetStrategiesResponse, + GetTechAnalysisRequest, + GetTechAnalysisResponse, + GetTradingStatusesRequest, + GetTradingStatusesResponse, + GetTradingStatusRequest, + GetTradingStatusResponse, + GetUserTariffRequest, + GetUserTariffResponse, + HistoricCandle, + IndicativesRequest, + IndicativesResponse, + InstrumentClosePriceRequest, + InstrumentExchangeType, + InstrumentIdType, + InstrumentRequest, + InstrumentResponse, + InstrumentsRequest, + InstrumentStatus, + InstrumentType, + LastPriceType, + MarketDataRequest, + MarketDataResponse, + MarketDataServerSideStreamRequest, + MoneyValue, + OpenSandboxAccountRequest, + OpenSandboxAccountResponse, + OperationsRequest, + OperationsResponse, + OperationsStreamRequest, + OperationsStreamResponse, + OperationState, + OptionResponse, + OptionsResponse, + OrderDirection, + OrderExecutionReportStatus, + OrderIdType, + OrderState, + OrderStateStreamRequest, + OrderStateStreamResponse, + OrderType, + Page, + PayInRequest, + PayInResponse, + PingDelaySettings, + PortfolioRequest, + PortfolioResponse, + PortfolioStreamRequest, + PortfolioStreamResponse, + PositionsRequest, + PositionsResponse, + PositionsStreamRequest, + PositionsStreamResponse, + PostOrderAsyncRequest, + PostOrderAsyncResponse, + PostOrderRequest, + PostOrderResponse, + PostStopOrderRequest, + PostStopOrderRequestTrailingData, + PostStopOrderResponse, + PriceType, + Quotation, + ReplaceOrderRequest, + RiskRatesRequest, + RiskRatesResponse, + SandboxPayInRequest, + SandboxPayInResponse, + ShareResponse, + SharesResponse, + StopOrderDirection, + StopOrderExpirationType, + StopOrderStatusOption, + StopOrderType, + StructuredNoteResponse, + StructuredNotesResponse, + TakeProfitType, + TimeInForceType, + TradeSourceType, + TradesStreamRequest, + TradesStreamResponse, + TradingSchedulesRequest, + TradingSchedulesResponse, + WithdrawLimitsRequest, + WithdrawLimitsResponse, +) +from .typedefs import AccountId +from .utils import get_intervals, now + +__all__ = ( + "Services", + "InstrumentsService", + "MarketDataService", + "MarketDataStreamService", + "OperationsService", + "OperationsStreamService", + "OrdersStreamService", + "OrdersService", + "UsersService", + "SandboxService", + "StopOrdersService", + "SignalService", +) +logger = logging.getLogger(__name__) + + +class Services: + def __init__( + self, + channel: grpc.Channel, + token: str, + sandbox_token: Optional[str] = None, + app_name: Optional[str] = None, + ) -> None: + metadata = get_metadata(token, app_name) + sandbox_metadata = get_metadata(sandbox_token or token, app_name) + self.instruments = InstrumentsService(channel, metadata) + self.market_data = MarketDataService(channel, metadata) + self.market_data_stream = MarketDataStreamService(channel, metadata) + self.operations = OperationsService(channel, metadata) + self.operations_stream = OperationsStreamService(channel, metadata) + self.orders_stream = OrdersStreamService(channel, metadata) + self.orders = OrdersService(channel, metadata) + self.users = UsersService(channel, metadata) + self.sandbox = SandboxService(channel, sandbox_metadata) + self.stop_orders = StopOrdersService(channel, metadata) + self.signals = SignalService(channel, metadata) + + def create_market_data_stream(self) -> MarketDataStreamManager: + return MarketDataStreamManager( + market_data_stream_service=self.market_data_stream + ) + + def cancel_all_orders(self, account_id: AccountId) -> None: + orders_service: OrdersService = self.orders + stop_orders_service: StopOrdersService = self.stop_orders + + orders_response = orders_service.get_orders(account_id=account_id) + for order in orders_response.orders: + orders_service.cancel_order(account_id=account_id, order_id=order.order_id) + + stop_orders_response = stop_orders_service.get_stop_orders( + account_id=account_id + ) + for stop_order in stop_orders_response.stop_orders: + stop_orders_service.cancel_stop_order( + account_id=account_id, stop_order_id=stop_order.stop_order_id + ) + + # pylint:disable=too-many-nested-blocks + def get_all_candles( + self, + *, + from_: datetime, + to: Optional[datetime] = None, + interval: CandleInterval = CandleInterval(0), + figi: str = "", + instrument_id: str = "", + candle_source_type: Optional[CandleSource] = None, + ) -> Generator[HistoricCandle, None, None]: + to = to or now() + + previous_candles = set() + for current_from, current_to in get_intervals(interval, from_, to): + candles_response: GetCandlesResponse = self.market_data.get_candles( + figi=figi, + interval=interval, + from_=current_from, + to=current_to, + instrument_id=instrument_id, + candle_source_type=candle_source_type, + ) + + for candle in candles_response.candles: + if candle not in previous_candles: + yield candle + previous_candles.add(candle) + + previous_candles = set(candles_response.candles) + + +class InstrumentsService(_grpc_helpers.Service): + _stub_factory = instruments_pb2_grpc.InstrumentsServiceStub + + @handle_request_error("TradingSchedules") + def trading_schedules( + self, + *, + exchange: str = "", + from_: Optional[datetime] = None, + to: Optional[datetime] = None, + ) -> TradingSchedulesResponse: + request = TradingSchedulesRequest() + request.exchange = exchange + if from_ is not None: + request.from_ = from_ + if to is not None: + request.to = to + response, call = self.stub.TradingSchedules.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.TradingSchedulesRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "TradingSchedules") + return _grpc_helpers.protobuf_to_dataclass(response, TradingSchedulesResponse) + + @handle_request_error("BondBy") + def bond_by( + self, + *, + id_type: InstrumentIdType = InstrumentIdType(0), + class_code: str = "", + id: str = "", + ) -> BondResponse: + request = InstrumentRequest() + request.id_type = id_type + request.class_code = class_code + request.id = id + response, call = self.stub.BondBy.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "BondBy") + return _grpc_helpers.protobuf_to_dataclass(response, BondResponse) + + @handle_request_error("Bonds") + def bonds( + self, + *, + instrument_status: InstrumentStatus = InstrumentStatus(0), + instrument_exchange: InstrumentExchangeType = InstrumentExchangeType(0), + ) -> BondsResponse: + request = InstrumentsRequest() + request.instrument_status = instrument_status + request.instrument_exchange = instrument_exchange + response, call = self.stub.Bonds.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "Bonds") + return _grpc_helpers.protobuf_to_dataclass(response, BondsResponse) + + @handle_request_error("CurrencyBy") + def currency_by( + self, + *, + id_type: InstrumentIdType = InstrumentIdType(0), + class_code: str = "", + id: str = "", + ) -> CurrencyResponse: + request = InstrumentRequest() + request.id_type = id_type + request.class_code = class_code + request.id = id + response, call = self.stub.CurrencyBy.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "CurrencyBy") + return _grpc_helpers.protobuf_to_dataclass(response, CurrencyResponse) + + @handle_request_error("Currencies") + def currencies( + self, + *, + instrument_status: InstrumentStatus = InstrumentStatus(0), + instrument_exchange: InstrumentExchangeType = InstrumentExchangeType(0), + ) -> CurrenciesResponse: + request = InstrumentsRequest() + request.instrument_status = instrument_status + request.instrument_exchange = instrument_exchange + response, call = self.stub.Currencies.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "Currencies") + return _grpc_helpers.protobuf_to_dataclass(response, CurrenciesResponse) + + @handle_request_error("EtfBy") + def etf_by( + self, + *, + id_type: InstrumentIdType = InstrumentIdType(0), + class_code: str = "", + id: str = "", + ) -> EtfResponse: + request = InstrumentRequest() + request.id_type = id_type + request.class_code = class_code + request.id = id + response, call = self.stub.EtfBy.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "EtfBy") + return _grpc_helpers.protobuf_to_dataclass(response, EtfResponse) + + @handle_request_error("Etfs") + def etfs( + self, + *, + instrument_status: InstrumentStatus = InstrumentStatus(0), + instrument_exchange: InstrumentExchangeType = InstrumentExchangeType(0), + ) -> EtfsResponse: + request = InstrumentsRequest() + request.instrument_status = instrument_status + request.instrument_exchange = instrument_exchange + response, call = self.stub.Etfs.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "Etfs") + return _grpc_helpers.protobuf_to_dataclass(response, EtfsResponse) + + @handle_request_error("FutureBy") + def future_by( + self, + *, + id_type: InstrumentIdType = InstrumentIdType(0), + class_code: str = "", + id: str = "", + ) -> FutureResponse: + request = InstrumentRequest() + request.id_type = id_type + request.class_code = class_code + request.id = id + response, call = self.stub.FutureBy.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "FutureBy") + return _grpc_helpers.protobuf_to_dataclass(response, FutureResponse) + + @handle_request_error("Futures") + def futures( + self, + *, + instrument_status: InstrumentStatus = InstrumentStatus(0), + instrument_exchange: InstrumentExchangeType = InstrumentExchangeType(0), + ) -> FuturesResponse: + request = InstrumentsRequest() + request.instrument_status = instrument_status + request.instrument_exchange = instrument_exchange + response, call = self.stub.Futures.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "Futures") + return _grpc_helpers.protobuf_to_dataclass(response, FuturesResponse) + + @handle_request_error("OptionBy") + def option_by( + self, + *, + id_type: InstrumentIdType = InstrumentIdType(0), + class_code: str = "", + id: str = "", + ) -> OptionResponse: + request = InstrumentRequest() + request.id_type = id_type + request.class_code = class_code + request.id = id + response, call = self.stub.OptionBy.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "OptionBy") + return _grpc_helpers.protobuf_to_dataclass(response, OptionResponse) + + @deprecated(details="Use `Client.instruments.options_by(...)` method instead") + @handle_request_error("Options") + def options( + self, + *, + instrument_status: InstrumentStatus = InstrumentStatus(0), + instrument_exchange: InstrumentExchangeType = InstrumentExchangeType(0), + ) -> OptionsResponse: + request = InstrumentsRequest() + request.instrument_status = instrument_status + request.instrument_exchange = instrument_exchange + response, call = self.stub.Options.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "Options") + return _grpc_helpers.protobuf_to_dataclass(response, OptionsResponse) + + @handle_request_error("OptionsBy") + def options_by( + self, *, basic_asset_uid: str = "", basic_asset_position_uid: str = "" + ) -> OptionsResponse: + request = FilterOptionsRequest() + request.basic_asset_uid = basic_asset_uid + request.basic_asset_position_uid = basic_asset_position_uid + response, call = self.stub.OptionsBy.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.FilterOptionsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "OptionsBy") + return _grpc_helpers.protobuf_to_dataclass(response, OptionsResponse) + + @handle_request_error("ShareBy") + def share_by( + self, + *, + id_type: InstrumentIdType = InstrumentIdType(0), + class_code: str = "", + id: str = "", + ) -> ShareResponse: + request = InstrumentRequest() + request.id_type = id_type + request.class_code = class_code + request.id = id + response, call = self.stub.ShareBy.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "ShareBy") + return _grpc_helpers.protobuf_to_dataclass(response, ShareResponse) + + @handle_request_error("Shares") + def shares( + self, + *, + instrument_status: InstrumentStatus = InstrumentStatus(0), + instrument_exchange: InstrumentExchangeType = InstrumentExchangeType(0), + ) -> SharesResponse: + request = InstrumentsRequest() + request.instrument_status = instrument_status + request.instrument_exchange = instrument_exchange + response, call = self.stub.Shares.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "Shares") + return _grpc_helpers.protobuf_to_dataclass(response, SharesResponse) + + @handle_request_error("Indicatives") + def indicatives( + self, + request: IndicativesRequest, + ) -> IndicativesResponse: + response, call = self.stub.Indicatives.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "Indicatives") + return _grpc_helpers.protobuf_to_dataclass(response, IndicativesResponse) + + @handle_request_error("GetAccruedInterests") + def get_accrued_interests( + self, + *, + figi: str = "", + from_: Optional[datetime] = None, + to: Optional[datetime] = None, + instrument_id: str = "", + ) -> GetAccruedInterestsResponse: + request = GetAccruedInterestsRequest() + request.figi = figi + request.instrument_id = instrument_id + if from_ is not None: + request.from_ = from_ + if to is not None: + request.to = to + response, call = self.stub.GetAccruedInterests.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetAccruedInterestsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetAccruedInterests") + return _grpc_helpers.protobuf_to_dataclass( + response, GetAccruedInterestsResponse + ) + + @handle_request_error("GetFuturesMargin") + def get_futures_margin( + self, *, figi: str = "", instrument_id: str = "" + ) -> GetFuturesMarginResponse: + request = GetFuturesMarginRequest() + request.figi = figi + request.instrument_id = instrument_id + response, call = self.stub.GetFuturesMargin.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetFuturesMarginRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetFuturesMargin") + return _grpc_helpers.protobuf_to_dataclass(response, GetFuturesMarginResponse) + + @handle_request_error("GetInstrumentBy") + def get_instrument_by( + self, + *, + id_type: InstrumentIdType = InstrumentIdType(0), + class_code: str = "", + id: str = "", + ) -> InstrumentResponse: + request = InstrumentRequest() + request.id_type = id_type + request.class_code = class_code + request.id = id + response, call = self.stub.GetInstrumentBy.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetInstrumentBy") + return _grpc_helpers.protobuf_to_dataclass(response, InstrumentResponse) + + @handle_request_error("GetDividends") + def get_dividends( + self, + *, + figi: str = "", + from_: Optional[datetime] = None, + to: Optional[datetime] = None, + instrument_id: str = "", + ) -> GetDividendsResponse: + request = GetDividendsRequest() + request.figi = figi + request.instrument_id = instrument_id + if from_ is not None: + request.from_ = from_ + if to is not None: + request.to = to + response, call = self.stub.GetDividends.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetDividendsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetDividends") + return _grpc_helpers.protobuf_to_dataclass(response, GetDividendsResponse) + + @handle_request_error("GetBondCoupons") + def get_bond_coupons( + self, + *, + figi: str = "", + from_: Optional[datetime] = None, + to: Optional[datetime] = None, + instrument_id: str = "", + ) -> GetBondCouponsResponse: + request = GetBondCouponsRequest() + request.figi = figi + request.instrument_id = instrument_id + if from_ is not None: + request.from_ = from_ + if to is not None: + request.to = to + response, call = self.stub.GetBondCoupons.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetBondCouponsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetBondCoupons") + return _grpc_helpers.protobuf_to_dataclass(response, GetBondCouponsResponse) + + @handle_request_error("GetBondEvents") + def get_bond_events(self, request: GetBondEventsRequest) -> GetBondEventsResponse: + response, call = self.stub.GetBondEvents.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetBondEventsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetBondEvents") + return _grpc_helpers.protobuf_to_dataclass(response, GetBondEventsResponse) + + @handle_request_error("GetAssetBy") + def get_asset_by( + self, + *, + id: str = "", + ) -> AssetResponse: + request = AssetRequest() + request.id = id + response, call = self.stub.GetAssetBy.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.AssetRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetAssetBy") + return _grpc_helpers.protobuf_to_dataclass(response, AssetResponse) + + @handle_request_error("GetAssets") + def get_assets( + self, + request: AssetsRequest, + ) -> AssetsResponse: + if request is None: + request = AssetsRequest() + response, call = self.stub.GetAssets.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.AssetsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetAssets") + return _grpc_helpers.protobuf_to_dataclass(response, AssetsResponse) + + @handle_request_error("GetFavorites") + def get_favorites( + self, + *, + group_id: Optional[str] = None, + ) -> GetFavoritesResponse: + request = GetFavoritesRequest() + if group_id is not None: + request.group_id = group_id + response, call = self.stub.GetFavorites.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetFavoritesRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetFavorites") + return _grpc_helpers.protobuf_to_dataclass(response, GetFavoritesResponse) + + @handle_request_error("EditFavorites") + def edit_favorites( + self, + *, + instruments: Optional[List[EditFavoritesRequestInstrument]] = None, + action_type: Optional[EditFavoritesActionType] = None, + group_id: Optional[str] = None, + ) -> EditFavoritesResponse: + request = EditFavoritesRequest() + if action_type is not None: + request.action_type = action_type + if instruments is not None: + request.instruments = instruments + if group_id is not None: + request.group_id = group_id + response, call = self.stub.EditFavorites.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.EditFavoritesRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "EditFavorites") + return _grpc_helpers.protobuf_to_dataclass(response, EditFavoritesResponse) + + @handle_request_error("CreateFavoriteGroup") + def create_favorite_group( + self, + request: CreateFavoriteGroupRequest, + ) -> CreateFavoriteGroupResponse: + response, call = self.stub.CreateFavoriteGroup.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.CreateFavoriteGroupRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "CreateFavoriteGroup") + return _grpc_helpers.protobuf_to_dataclass( + response, CreateFavoriteGroupResponse + ) + + @handle_request_error("DeleteFavoriteGroup") + def delete_favorite_group( + self, + request: DeleteFavoriteGroupRequest, + ) -> DeleteFavoriteGroupResponse: + response, call = self.stub.DeleteFavoriteGroup.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.DeleteFavoriteGroupRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "DeleteFavoriteGroup") + return _grpc_helpers.protobuf_to_dataclass( + response, DeleteFavoriteGroupResponse + ) + + @handle_request_error("GetFavoriteGroups") + def get_favorite_groups( + self, + request: GetFavoriteGroupsRequest, + ) -> GetFavoriteGroupsResponse: + response, call = self.stub.GetFavoriteGroups.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetFavoriteGroupsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetFavoriteGroups") + return _grpc_helpers.protobuf_to_dataclass(response, GetFavoriteGroupsResponse) + + @handle_request_error("GetCountries") + def get_countries( + self, + ) -> GetCountriesResponse: + request = GetCountriesRequest() + response, call = self.stub.GetCountries.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetCountriesRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetCountries") + return _grpc_helpers.protobuf_to_dataclass(response, GetCountriesResponse) + + @handle_request_error("FindInstrument") + def find_instrument( + self, + *, + query: str = "", + instrument_kind: Optional[InstrumentType] = None, + api_trade_available_flag: Optional[bool] = None, + ) -> FindInstrumentResponse: + request = FindInstrumentRequest() + request.query = query + if instrument_kind is not None: + request.instrument_kind = instrument_kind + if api_trade_available_flag is not None: + request.api_trade_available_flag = api_trade_available_flag + response, call = self.stub.FindInstrument.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.FindInstrumentRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "FindInstrument") + return _grpc_helpers.protobuf_to_dataclass(response, FindInstrumentResponse) + + @handle_request_error("GetBrands") + def get_brands( + self, + paging: Optional[Page] = None, + ) -> GetBrandsResponse: + request = GetBrandsRequest() + if paging is not None: + request.paging = paging + response, call = self.stub.GetBrands.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetBrandsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetBrands") + return _grpc_helpers.protobuf_to_dataclass(response, GetBrandsResponse) + + @handle_request_error("GetBrandBy") + def get_brands_by(self, id: str = "") -> Brand: + request = GetBrandRequest() + request.id = id + response, call = self.stub.GetBrandBy.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetBrandRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetBrandBy") + return _grpc_helpers.protobuf_to_dataclass(response, Brand) + + @handle_request_error("GetAssetFundamentals") + def get_asset_fundamentals( + self, request: GetAssetFundamentalsRequest + ) -> GetAssetFundamentalsResponse: + response, call = self.stub.GetAssetFundamentals.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetAssetFundamentalsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetAssetFundamentals") + return _grpc_helpers.protobuf_to_dataclass( + response, GetAssetFundamentalsResponse + ) + + @handle_request_error("GetAssetReports") + def get_asset_reports( + self, request: GetAssetReportsRequest + ) -> GetAssetReportsResponse: + response, call = self.stub.GetAssetReports.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetAssetReportsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetAssetReports") + return _grpc_helpers.protobuf_to_dataclass(response, GetAssetReportsResponse) + + @handle_request_error("GetConsensusForecasts") + def get_consensus_forecasts( + self, request: GetConsensusForecastsRequest + ) -> GetConsensusForecastsResponse: + response, call = self.stub.GetConsensusForecasts.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetConsensusForecastsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetConsensusForecasts") + return _grpc_helpers.protobuf_to_dataclass( + response, GetConsensusForecastsResponse + ) + + @handle_request_error("GetForecastBy") + def get_forecast_by(self, request: GetForecastRequest) -> GetForecastResponse: + response, call = self.stub.GetForecastBy.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetForecastRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetForecastBy") + return _grpc_helpers.protobuf_to_dataclass(response, GetForecastResponse) + + @handle_request_error("GetRiskRates") + def get_risk_rates(self, request: RiskRatesRequest) -> RiskRatesResponse: + response, call = self.stub.GetRiskRates.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.RiskRatesRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetRiskRates") + return _grpc_helpers.protobuf_to_dataclass(response, RiskRatesResponse) + + @handle_request_error("GetInsiderDeals") + def get_insider_deals( + self, + request: GetInsiderDealsRequest, + ) -> GetInsiderDealsResponse: + response, call = self.stub.GetInsiderDeals.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.GetInsiderDealsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetInsiderDeals") + return _grpc_helpers.protobuf_to_dataclass(response, GetInsiderDealsResponse) + + @handle_request_error("StructuredNoteBy") + def structured_note_by(self, request: InstrumentRequest) -> StructuredNoteResponse: + response, call = self.stub.StructuredNoteBy.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "StructuredNoteBy") + return _grpc_helpers.protobuf_to_dataclass(response, StructuredNoteResponse) + + @handle_request_error("StructuredNotes") + def structured_notes( + self, + request: InstrumentsRequest, + ) -> StructuredNotesResponse: + response, call = self.stub.StructuredNotes.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "StructuredNotes") + return _grpc_helpers.protobuf_to_dataclass(response, StructuredNotesResponse) + + @handle_request_error("Dfas") + def dfas( + self, + ) -> DfasResponse: + response, call = self.stub.Dfas.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + DfasRequest(), instruments_pb2.DfasRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "Dfas") + return _grpc_helpers.protobuf_to_dataclass(response, DfasResponse) + + @handle_request_error("DfaBy") + def dfa_by( + self, + request: InstrumentRequest, + ) -> DfaResponse: + response, call = self.stub.DfaBy.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, instruments_pb2.InstrumentRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "DfaBy") + return _grpc_helpers.protobuf_to_dataclass(response, DfaResponse) + + +class MarketDataService(_grpc_helpers.Service): + _stub_factory = marketdata_pb2_grpc.MarketDataServiceStub + + @handle_request_error("GetCandles") + def get_candles( + self, + *, + figi: str = "", + from_: Optional[datetime] = None, + to: Optional[datetime] = None, + interval: CandleInterval = CandleInterval(0), + instrument_id: str = "", + candle_source_type: Optional[CandleSource] = None, + limit: Optional[int] = None, + ) -> GetCandlesResponse: + request = GetCandlesRequest() + request.figi = figi + request.instrument_id = instrument_id + request.candle_source_type = candle_source_type + if from_ is not None: + request.from_ = from_ + if to is not None: + request.to = to + if limit is not None: + request.limit = limit + request.interval = interval + response, call = self.stub.GetCandles.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, marketdata_pb2.GetCandlesRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetCandles") + return _grpc_helpers.protobuf_to_dataclass(response, GetCandlesResponse) + + @handle_request_error("GetLastPrices") + def get_last_prices( + self, + *, + figi: Optional[List[str]] = None, + instrument_id: Optional[List[str]] = None, + last_price_type: LastPriceType = LastPriceType.LAST_PRICE_UNSPECIFIED, + instrument_status: Optional[InstrumentStatus] = None, + ) -> GetLastPricesResponse: + figi = figi or [] + instrument_id = instrument_id or [] + + request = GetLastPricesRequest() + request.figi = figi + request.instrument_id = instrument_id + request.last_price_type = last_price_type + if instrument_status: + request.instrument_status = instrument_status + response, call = self.stub.GetLastPrices.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, marketdata_pb2.GetLastPricesRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetLastPrices") + return _grpc_helpers.protobuf_to_dataclass(response, GetLastPricesResponse) + + @handle_request_error("GetOrderBook") + def get_order_book( + self, *, figi: str = "", depth: int = 0, instrument_id: str = "" + ) -> GetOrderBookResponse: + request = GetOrderBookRequest() + request.figi = figi + request.instrument_id = instrument_id + request.depth = depth + response, call = self.stub.GetOrderBook.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, marketdata_pb2.GetOrderBookRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetOrderBook") + return _grpc_helpers.protobuf_to_dataclass(response, GetOrderBookResponse) + + @handle_request_error("GetTradingStatus") + def get_trading_status( + self, *, figi: str = "", instrument_id: str = "" + ) -> GetTradingStatusResponse: + request = GetTradingStatusRequest() + request.figi = figi + request.instrument_id = instrument_id + response, call = self.stub.GetTradingStatus.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, marketdata_pb2.GetTradingStatusRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetTradingStatus") + return _grpc_helpers.protobuf_to_dataclass(response, GetTradingStatusResponse) + + @handle_request_error("GetTradingStatuses") + def get_trading_statuses( + self, *, instrument_ids: Optional[List[str]] = None + ) -> GetTradingStatusesResponse: + request = GetTradingStatusesRequest() + if instrument_ids: + request.instrument_id = instrument_ids + response, call = self.stub.GetTradingStatuses.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, marketdata_pb2.GetTradingStatusesRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetTradingStatuses") + return _grpc_helpers.protobuf_to_dataclass(response, GetTradingStatusesResponse) + + @handle_request_error("GetLastTrades") + def get_last_trades( + self, + *, + figi: str = "", + from_: Optional[datetime] = None, + to: Optional[datetime] = None, + instrument_id: str = "", + trade_source: "TradeSourceType" = TradeSourceType.TRADE_SOURCE_UNSPECIFIED, + ) -> GetLastTradesResponse: + request = GetLastTradesRequest() + request.figi = figi + request.instrument_id = instrument_id + if from_ is not None: + request.from_ = from_ + if to is not None: + request.to = to + if trade_source is not None: + request.trade_source = trade_source + response, call = self.stub.GetLastTrades.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, marketdata_pb2.GetLastTradesRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetLastTrades") + return _grpc_helpers.protobuf_to_dataclass(response, GetLastTradesResponse) + + @handle_request_error("GetClosePrices") + def get_close_prices( + self, + *, + instruments: Optional[List[InstrumentClosePriceRequest]] = None, + instrument_status: Optional[InstrumentStatus] = None, + ) -> GetClosePricesResponse: + request = GetClosePricesRequest() + if instruments: + request.instruments = instruments + if instrument_status: + request.instrument_status = instrument_status + response, call = self.stub.GetClosePrices.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, marketdata_pb2.GetClosePricesRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetClosePrices") + return _grpc_helpers.protobuf_to_dataclass(response, GetClosePricesResponse) + + @handle_request_error("GetTechAnalysis") + def get_tech_analysis( + self, + *, + request: GetTechAnalysisRequest, + ) -> GetTechAnalysisResponse: + response, call = self.stub.GetTechAnalysis.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, marketdata_pb2.GetTechAnalysisRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetTechAnalysis") + return _grpc_helpers.protobuf_to_dataclass(response, GetTechAnalysisResponse) + + @handle_request_error("GetMarketValues") + def get_market_values( + self, + *, + request: GetMarketValuesRequest, + ) -> GetMarketValuesResponse: + response, call = self.stub.GetMarketValues.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, marketdata_pb2.GetMarketValuesRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetMarketValues") + return _grpc_helpers.protobuf_to_dataclass(response, GetMarketValuesResponse) + + +class MarketDataStreamService(_grpc_helpers.Service): + _stub_factory = marketdata_pb2_grpc.MarketDataStreamServiceStub + + @staticmethod + def _convert_market_data_stream_request( + request_iterator: Iterable[MarketDataRequest], + ) -> Iterable[marketdata_pb2.MarketDataRequest]: + for request in request_iterator: + yield _grpc_helpers.dataclass_to_protobuff( + request, marketdata_pb2.MarketDataRequest() + ) + + @handle_error_hub_gen() + @handle_request_error_gen("MarketDataStream") + def market_data_stream( + self, + request_iterator: Iterable[MarketDataRequest], + ) -> Iterator[MarketDataResponse]: + for response in self.stub.MarketDataStream( + request_iterator=self._convert_market_data_stream_request(request_iterator), + metadata=self.metadata, + ): + yield _grpc_helpers.protobuf_to_dataclass(response, MarketDataResponse) + + @staticmethod + def _convert_market_data_server_side_stream_request( + request_iterator: Iterable[MarketDataServerSideStreamRequest], + ) -> Iterable[marketdata_pb2.MarketDataServerSideStreamRequest]: + for request in request_iterator: + yield _grpc_helpers.dataclass_to_protobuff( + request, marketdata_pb2.MarketDataServerSideStreamRequest() + ) + + @handle_error_hub_gen() + @handle_request_error_gen("MarketDataServerSideStream") + def market_data_server_side_stream( + self, + request_iterator: Iterable[MarketDataServerSideStreamRequest], + ) -> Iterable[MarketDataResponse]: + for response in self.stub.MarketDataServerSideStream( + request_iterator=self._convert_market_data_server_side_stream_request( + request_iterator + ), + metadata=self.metadata, + ): + yield _grpc_helpers.protobuf_to_dataclass(response, MarketDataResponse) + + +class OperationsService(_grpc_helpers.Service): + _stub_factory = operations_pb2_grpc.OperationsServiceStub + + @handle_request_error("GetOperations") + def get_operations( + self, + *, + account_id: str = "", + from_: Optional[datetime] = None, + to: Optional[datetime] = None, + state: OperationState = OperationState(0), + figi: str = "", + ) -> OperationsResponse: + request = OperationsRequest() + request.account_id = account_id + if from_ is not None: + request.from_ = from_ + if to is not None: + request.to = to + request.state = state + request.figi = figi + response, call = self.stub.GetOperations.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.OperationsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetOperations") + return _grpc_helpers.protobuf_to_dataclass(response, OperationsResponse) + + @handle_request_error("GetPortfolio") + def get_portfolio(self, *, account_id: str = "") -> PortfolioResponse: + request = PortfolioRequest() + request.account_id = account_id + response, call = self.stub.GetPortfolio.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.PortfolioRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetPortfolio") + return _grpc_helpers.protobuf_to_dataclass(response, PortfolioResponse) + + @handle_request_error("GetPositions") + def get_positions(self, *, account_id: str = "") -> PositionsResponse: + request = PositionsRequest() + request.account_id = account_id + response, call = self.stub.GetPositions.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.PositionsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetPositions") + return _grpc_helpers.protobuf_to_dataclass(response, PositionsResponse) + + @handle_request_error("GetWithdrawLimits") + def get_withdraw_limits(self, *, account_id: str = "") -> WithdrawLimitsResponse: + request = WithdrawLimitsRequest() + request.account_id = account_id + response, call = self.stub.GetWithdrawLimits.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.WithdrawLimitsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetWithdrawLimits") + return _grpc_helpers.protobuf_to_dataclass(response, WithdrawLimitsResponse) + + @handle_request_error("GetBrokerReport") + def get_broker_report( + self, + *, + generate_broker_report_request: Optional[GenerateBrokerReportRequest] = None, + get_broker_report_request: Optional[GetBrokerReportRequest] = None, + ) -> BrokerReportResponse: + request = BrokerReportRequest() + if generate_broker_report_request: + request.generate_broker_report_request = generate_broker_report_request + if get_broker_report_request: + request.get_broker_report_request = get_broker_report_request + response, call = self.stub.GetBrokerReport.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.BrokerReportRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetBrokerReport") + return _grpc_helpers.protobuf_to_dataclass(response, BrokerReportResponse) + + @handle_request_error("GetDividendsForeignIssuer") + def get_dividends_foreign_issuer( + self, + *, + generate_div_foreign_issuer_report: Optional[ + GenerateDividendsForeignIssuerReportRequest + ] = None, + get_div_foreign_issuer_report: Optional[ + GetDividendsForeignIssuerReportRequest + ] = None, + ) -> GetDividendsForeignIssuerResponse: + request = GetDividendsForeignIssuerRequest() + if generate_div_foreign_issuer_report is not None: + request.generate_div_foreign_issuer_report = ( + generate_div_foreign_issuer_report + ) + if get_div_foreign_issuer_report is not None: + request.get_div_foreign_issuer_report = get_div_foreign_issuer_report + response, call = self.stub.GetDividendsForeignIssuer.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.GetDividendsForeignIssuerRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetDividendsForeignIssuer") + return _grpc_helpers.protobuf_to_dataclass( + response, GetDividendsForeignIssuerResponse + ) + + @handle_request_error("GetOperationsByCursor") + def get_operations_by_cursor( + self, + request: GetOperationsByCursorRequest, + ) -> GetOperationsByCursorResponse: + response, call = self.stub.GetOperationsByCursor.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.GetOperationsByCursorRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetOperationsByCursor") + return _grpc_helpers.protobuf_to_dataclass( + response, GetOperationsByCursorResponse + ) + + +class OperationsStreamService(_grpc_helpers.Service): + _stub_factory = operations_pb2_grpc.OperationsStreamServiceStub + + @handle_error_hub_gen() + @handle_request_error_gen("PortfolioStream") + def portfolio_stream( + self, + *, + accounts: Optional[List[str]] = None, + ping_delay_ms: Optional[int] = None, + ) -> Iterable[PortfolioStreamResponse]: + request = PortfolioStreamRequest() + ping_settings = PingDelaySettings() + if ping_delay_ms is not None: + ping_settings.ping_delay_ms = ping_delay_ms + request.ping_settings = ping_settings + if accounts: + request.accounts = accounts + else: + raise ValueError("accounts can not be empty") + for response in self.stub.PortfolioStream( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.PortfolioStreamRequest() + ), + metadata=self.metadata, + ): + yield _grpc_helpers.protobuf_to_dataclass(response, PortfolioStreamResponse) + + @handle_error_hub_gen() + @handle_request_error_gen("PositionsStream") + def positions_stream( + self, + *, + accounts: Optional[List[str]] = None, + ping_delay_ms: Optional[int] = None, + with_initial_positions: Optional[bool] = None, + ) -> Iterable[PositionsStreamResponse]: + request = PositionsStreamRequest() + if accounts: + request.accounts = accounts + else: + raise ValueError("accounts can not be empty") + ping_settings = PingDelaySettings() + if ping_delay_ms is not None: + ping_settings.ping_delay_ms = ping_delay_ms + request.ping_settings = ping_settings + if with_initial_positions: + request.with_initial_positions = with_initial_positions + for response in self.stub.PositionsStream( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.PositionsStreamRequest() + ), + metadata=self.metadata, + ): + yield _grpc_helpers.protobuf_to_dataclass(response, PositionsStreamResponse) + + @handle_error_hub_gen() + @handle_request_error_gen("OperationsStream") + def operations_stream( + self, + request: OperationsStreamRequest, + ) -> Iterable[OperationsStreamResponse]: + for response in self.stub.OperationsStream( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.OperationsStreamRequest() + ), + metadata=self.metadata, + ): + yield _grpc_helpers.protobuf_to_dataclass( + response, OperationsStreamResponse + ) + + +class OrdersStreamService(_grpc_helpers.Service): + _stub_factory = orders_pb2_grpc.OrdersStreamServiceStub + + @handle_error_hub_gen() + @handle_request_error_gen("TradesStream") + def trades_stream( + self, + *, + accounts: Optional[List[str]] = None, + ping_delay_ms: Optional[int] = None, + ) -> Iterable[TradesStreamResponse]: + request = TradesStreamRequest() + if ping_delay_ms is not None: + request.ping_delay_ms = ping_delay_ms + if accounts: + request.accounts = accounts + else: + raise ValueError("accounts can not be empty") + for response in self.stub.TradesStream( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.TradesStreamRequest() + ), + metadata=self.metadata, + ): + yield _grpc_helpers.protobuf_to_dataclass(response, TradesStreamResponse) + + @handle_error_hub_gen() + @handle_request_error_gen("OrderStateStream") + def order_state_stream( + self, *, request: OrderStateStreamRequest + ) -> Iterable[OrderStateStreamResponse]: + for response in self.stub.OrderStateStream( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.OrderStateStreamRequest() + ), + metadata=self.metadata, + ): + yield _grpc_helpers.protobuf_to_dataclass( + response, OrderStateStreamResponse + ) + + +class OrdersService(_grpc_helpers.Service): + _stub_factory = orders_pb2_grpc.OrdersServiceStub + + @handle_request_error("PostOrder") + def post_order( + self, + *, + figi: str = "", + quantity: int = 0, + price: Optional[Quotation] = None, + direction: OrderDirection = OrderDirection(0), + account_id: str = "", + order_type: OrderType = OrderType(0), + order_id: str = "", + instrument_id: str = "", + time_in_force: TimeInForceType = TimeInForceType(0), + price_type: PriceType = PriceType(0), + confirm_margin_trade: bool = False, + ) -> PostOrderResponse: + request = PostOrderRequest() + request.figi = figi + request.instrument_id = instrument_id + request.quantity = quantity + if price is not None: + request.price = price + request.direction = direction + request.account_id = account_id + request.order_type = order_type + if not utils.empty_or_uuid(order_id): + raise RequestError( + grpc.StatusCode.INVALID_ARGUMENT, + "order_id should be empty or uuid", + None, + ) + request.order_id = order_id + request.time_in_force = time_in_force + request.price_type = price_type + if confirm_margin_trade: + request.confirm_margin_trade = confirm_margin_trade + response, call = self.stub.PostOrder.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.PostOrderRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "PostOrder") + return _grpc_helpers.protobuf_to_dataclass(response, PostOrderResponse) + + @handle_request_error("PostOrderAsync") + def post_order_async( + self, request: PostOrderAsyncRequest + ) -> PostOrderAsyncResponse: + if not utils.empty_or_uuid(request.order_id): + raise RequestError( + grpc.StatusCode.INVALID_ARGUMENT, + "order_id should be empty or uuid", + None, + ) + response, call = self.stub.PostOrderAsync.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.PostOrderAsyncRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "PostOrderAsync") + return _grpc_helpers.protobuf_to_dataclass(response, PostOrderAsyncResponse) + + @handle_request_error("CancelOrder") + def cancel_order( + self, + *, + account_id: str = "", + order_id: str = "", + order_id_type: Optional["OrderIdType"] = None, + ) -> CancelOrderResponse: + request = CancelOrderRequest() + request.account_id = account_id + request.order_id = order_id + request.order_id_type = order_id_type + response, call = self.stub.CancelOrder.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.CancelOrderRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "CancelOrder") + return _grpc_helpers.protobuf_to_dataclass(response, CancelOrderResponse) + + @handle_request_error("GetOrderState") + def get_order_state( + self, + *, + account_id: str = "", + order_id: str = "", + price_type: PriceType = PriceType(0), + order_id_type: Optional["OrderIdType"] = None, + ) -> OrderState: + request = GetOrderStateRequest() + request.account_id = account_id + request.order_id = order_id + request.price_type = price_type + request.order_id_type = order_id_type + response, call = self.stub.GetOrderState.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.GetOrderStateRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetOrderState") + return _grpc_helpers.protobuf_to_dataclass(response, OrderState) + + @handle_request_error("GetOrders") + def get_orders( + self, + *, + account_id: str = "", + from_: Optional[datetime] = None, + to: Optional[datetime] = None, + execution_status: Optional[List[OrderExecutionReportStatus]] = None, + ) -> GetOrdersResponse: + # noinspection DuplicatedCode + request = GetOrdersRequest() + request.account_id = account_id + request.advanced_filters = GetOrdersRequestFilters() + if from_ is not None: + request.advanced_filters.from_ = from_ + if to is not None: + request.advanced_filters.to = to + if execution_status is not None: + request.advanced_filters.execution_status = execution_status + response, call = self.stub.GetOrders.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.GetOrdersRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetOrders") + return _grpc_helpers.protobuf_to_dataclass(response, GetOrdersResponse) + + @handle_request_error("ReplaceOrder") + def replace_order(self, request: ReplaceOrderRequest) -> PostOrderResponse: + response, call = self.stub.ReplaceOrder.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.ReplaceOrderRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "ReplaceOrder") + return _grpc_helpers.protobuf_to_dataclass(response, PostOrderResponse) + + @handle_request_error("GetMaxLots") + def get_max_lots(self, request: GetMaxLotsRequest) -> GetMaxLotsResponse: + response, call = self.stub.GetMaxLots.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.GetMaxLotsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetMaxLots") + return _grpc_helpers.protobuf_to_dataclass(response, GetMaxLotsResponse) + + @handle_request_error("GetOrderPrice") + def get_order_price(self, request: GetOrderPriceRequest) -> GetOrderPriceResponse: + response, call = self.stub.GetOrderPrice.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.GetOrderPriceRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetOrderPrice") + return _grpc_helpers.protobuf_to_dataclass(response, GetOrderPriceResponse) + + +class UsersService(_grpc_helpers.Service): + _stub_factory = users_pb2_grpc.UsersServiceStub + + @handle_request_error("GetAccounts") + def get_accounts(self) -> GetAccountsResponse: + request = GetAccountsRequest() + response, call = self.stub.GetAccounts.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, users_pb2.GetAccountsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetAccounts") + return _grpc_helpers.protobuf_to_dataclass(response, GetAccountsResponse) + + @handle_request_error("GetMarginAttributes") + def get_margin_attributes( + self, *, account_id: str = "" + ) -> GetMarginAttributesResponse: + request = GetMarginAttributesRequest() + request.account_id = account_id + response, call = self.stub.GetMarginAttributes.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, users_pb2.GetMarginAttributesRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetMarginAttributes") + return _grpc_helpers.protobuf_to_dataclass( + response, GetMarginAttributesResponse + ) + + @handle_request_error("GetUserTariff") + def get_user_tariff(self) -> GetUserTariffResponse: + request = GetUserTariffRequest() + response, call = self.stub.GetUserTariff.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, users_pb2.GetUserTariffRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetUserTariff") + return _grpc_helpers.protobuf_to_dataclass(response, GetUserTariffResponse) + + @handle_request_error("GetInfo") + def get_info(self) -> GetInfoResponse: + request = GetInfoRequest() + response, call = self.stub.GetInfo.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, users_pb2.GetInfoRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetInfo") + return _grpc_helpers.protobuf_to_dataclass(response, GetInfoResponse) + + @handle_request_error("GetBankAccounts") + def get_bank_accounts(self) -> GetBankAccountsResponse: + request = GetBankAccountsRequest() + response, call = self.stub.GetBankAccounts.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, users_pb2.GetBankAccountsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetBankAccounts") + return _grpc_helpers.protobuf_to_dataclass(response, GetBankAccountsResponse) + + @handle_request_error("CurrencyTransfer") + def currency_transfer( + self, request: CurrencyTransferRequest + ) -> CurrencyTransferResponse: + response, call = self.stub.CurrencyTransfer.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, users_pb2.CurrencyTransferRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "CurrencyTransfer") + return _grpc_helpers.protobuf_to_dataclass(response, CurrencyTransferResponse) + + @handle_request_error("PayIn") + def pay_in(self, request: PayInRequest) -> PayInResponse: + response, call = self.stub.PayIn.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, users_pb2.PayInRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "PayIn") + return _grpc_helpers.protobuf_to_dataclass(response, PayInResponse) + + @handle_request_error("GetAccountValues") + def get_account_values( + self, request: GetAccountValuesRequest + ) -> GetAccountValuesResponse: + response, call = self.stub.GetAccountValues.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, users_pb2.GetAccountValuesRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetAccountValues") + return _grpc_helpers.protobuf_to_dataclass(response, GetAccountValuesResponse) + + +class SandboxService(_grpc_helpers.Service): + _stub_factory = sandbox_pb2_grpc.SandboxServiceStub + + @handle_request_error("OpenSandboxAccount") + def open_sandbox_account( + self, name: Optional[str] = "" + ) -> OpenSandboxAccountResponse: + request = OpenSandboxAccountRequest() + request.name = name + response, call = self.stub.OpenSandboxAccount.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, sandbox_pb2.OpenSandboxAccountRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "OpenSandboxAccount") + return _grpc_helpers.protobuf_to_dataclass(response, OpenSandboxAccountResponse) + + @deprecated(details="Use `SandboxClient.users.get_accounts(...)` method instead") + @handle_request_error("GetSandboxAccounts") + def get_sandbox_accounts(self) -> GetAccountsResponse: + request = GetAccountsRequest() + response, call = self.stub.GetSandboxAccounts.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, users_pb2.GetAccountsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetSandboxAccounts") + return _grpc_helpers.protobuf_to_dataclass(response, GetAccountsResponse) + + @handle_request_error("CloseSandboxAccount") + def close_sandbox_account( + self, *, account_id: str = "" + ) -> CloseSandboxAccountResponse: + request = CloseSandboxAccountRequest() + request.account_id = account_id + response, call = self.stub.CloseSandboxAccount.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, sandbox_pb2.CloseSandboxAccountRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "CloseSandboxAccount") + return _grpc_helpers.protobuf_to_dataclass( + response, CloseSandboxAccountResponse + ) + + @deprecated(details="Use `SandboxClient.orders.post_order(...)` method instead") + @handle_request_error("PostSandboxOrder") + def post_sandbox_order( + self, + *, + figi: str = "", + quantity: int = 0, + price: Optional[Quotation] = None, + direction: OrderDirection = OrderDirection(0), + account_id: str = "", + order_type: OrderType = OrderType(0), + order_id: str = "", + instrument_id: str = "", + time_in_force: TimeInForceType = TimeInForceType(0), + price_type: PriceType = PriceType(0), + ) -> PostOrderResponse: + request = PostOrderRequest() + request.figi = figi + request.instrument_id = instrument_id + request.quantity = quantity + if price is not None: + request.price = price + request.direction = direction + request.account_id = account_id + request.order_type = order_type + if not utils.empty_or_uuid(order_id): + raise RequestError( + grpc.StatusCode.INVALID_ARGUMENT, + "order_id should be empty or uuid", + None, + ) + request.order_id = order_id + request.time_in_force = time_in_force + request.price_type = price_type + response, call = self.stub.PostSandboxOrder.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.PostOrderRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "PostSandboxOrder") + return _grpc_helpers.protobuf_to_dataclass(response, PostOrderResponse) + + @deprecated(details="Use `SandboxClient.orders.replace_order(...)` method instead") + @handle_request_error("ReplaceSandboxOrder") + def replace_sandbox_order( + self, + request: "ReplaceOrderRequest", + ) -> PostOrderResponse: + response, call = self.stub.ReplaceSandboxOrder.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.ReplaceOrderRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "ReplaceSandboxOrder") + return _grpc_helpers.protobuf_to_dataclass(response, PostOrderResponse) + + @deprecated(details="Use `SandboxClient.orders.get_orders(...)` method instead") + @handle_request_error("GetSandboxOrders") + def get_sandbox_orders(self, *, account_id: str = "") -> GetOrdersResponse: + request = GetOrdersRequest() + request.account_id = account_id + response, call = self.stub.GetSandboxOrders.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.GetOrdersRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetSandboxOrders") + return _grpc_helpers.protobuf_to_dataclass(response, GetOrdersResponse) + + @deprecated(details="Use `SandboxClient.orders.cancel_order(...)` method instead") + @handle_request_error("CancelSandboxOrder") + def cancel_sandbox_order( + self, + *, + account_id: str = "", + order_id: str = "", + order_id_type: Optional["OrderIdType"] = None, + ) -> CancelOrderResponse: + request = CancelOrderRequest() + request.account_id = account_id + request.order_id = order_id + request.order_id_type = order_id_type + response, call = self.stub.CancelSandboxOrder.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.CancelOrderRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "CancelSandboxOrder") + return _grpc_helpers.protobuf_to_dataclass(response, CancelOrderResponse) + + @deprecated( + details="Use `SandboxClient.orders.get_order_state(...)` method instead" + ) + @handle_request_error("GetSandboxOrderState") + def get_sandbox_order_state( + self, + *, + account_id: str = "", + order_id: str = "", + price_type: PriceType = PriceType(0), + order_id_type: Optional["OrderIdType"] = None, + ) -> OrderState: + request = GetOrderStateRequest() + request.account_id = account_id + request.order_id = order_id + request.price_type = price_type + request.order_id_type = order_id_type + response, call = self.stub.GetSandboxOrderState.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.GetOrderStateRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetSandboxOrderState") + return _grpc_helpers.protobuf_to_dataclass(response, OrderState) + + @deprecated( + details="Use `SandboxClient.operations.get_positions(...)` method instead" + ) + @handle_request_error("GetSandboxPositions") + def get_sandbox_positions(self, *, account_id: str = "") -> PositionsResponse: + request = PositionsRequest() + request.account_id = account_id + response, call = self.stub.GetSandboxPositions.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.PositionsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetSandboxPositions") + return _grpc_helpers.protobuf_to_dataclass(response, PositionsResponse) + + @deprecated( + details="Use `SandboxClient.operations.get_operations(...)` method instead" + ) + @handle_request_error("GetSandboxOperations") + def get_sandbox_operations( + self, + *, + account_id: str = "", + from_: Optional[datetime] = None, + to: Optional[datetime] = None, + state: OperationState = OperationState(0), + figi: str = "", + ) -> OperationsResponse: + request = OperationsRequest() + request.account_id = account_id + if from_ is not None: + request.from_ = from_ + if to is not None: + request.to = to + request.state = state + request.figi = figi + response, call = self.stub.GetSandboxOperations.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.OperationsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetSandboxOperations") + return _grpc_helpers.protobuf_to_dataclass(response, OperationsResponse) + + @deprecated( + details="Use `SandboxClient.operations.get_operations_by_cursor` method instead" + ) + @handle_request_error("GetOperationsByCursor") + def get_operations_by_cursor( + self, + request: GetOperationsByCursorRequest, + ) -> GetOperationsByCursorResponse: + response, call = self.stub.GetSandboxOperationsByCursor.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.GetOperationsByCursorRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetOperationsByCursor") + return _grpc_helpers.protobuf_to_dataclass( + response, GetOperationsByCursorResponse + ) + + @deprecated( + details="Use `SandboxClient.operations.get_portfolio(...)` method instead" + ) + @handle_request_error("GetSandboxPortfolio") + def get_sandbox_portfolio(self, *, account_id: str = "") -> PortfolioResponse: + request = PortfolioRequest() + request.account_id = account_id + response, call = self.stub.GetSandboxPortfolio.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.PortfolioRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetSandboxPortfolio") + return _grpc_helpers.protobuf_to_dataclass(response, PortfolioResponse) + + @handle_request_error("SandboxPayIn") + def sandbox_pay_in( + self, *, account_id: str = "", amount: Optional[MoneyValue] = None + ) -> SandboxPayInResponse: + request = SandboxPayInRequest() + request.account_id = account_id + if amount is not None: + request.amount = amount + response, call = self.stub.SandboxPayIn.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, sandbox_pb2.SandboxPayInRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "SandboxPayIn") + return _grpc_helpers.protobuf_to_dataclass(response, SandboxPayInResponse) + + @deprecated( + details="Use `SandboxClient.operations.get_withdraw_limits(...)` method instead" + ) + @handle_request_error("GetSandboxWithdrawLimits") + def get_sandbox_withdraw_limits( + self, + *, + account_id: str = "", + ) -> WithdrawLimitsResponse: + request = WithdrawLimitsRequest() + request.account_id = account_id + response, call = self.stub.GetSandboxWithdrawLimits.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, operations_pb2.WithdrawLimitsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetSandboxWithdrawLimits") + return _grpc_helpers.protobuf_to_dataclass(response, WithdrawLimitsResponse) + + @handle_request_error("GetSandboxMaxLots") + def get_sandbox_max_lots( + self, + *, + request: GetMaxLotsRequest, + ) -> GetMaxLotsResponse: + response, call = self.stub.GetSandboxMaxLots.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.GetMaxLotsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetSandboxMaxLots") + return _grpc_helpers.protobuf_to_dataclass(response, GetMaxLotsResponse) + + @handle_request_error("PostSandboxOrderAsync") + def post_sandbox_order_async( + self, + *, + request: PostOrderAsyncRequest, + ) -> PostOrderAsyncResponse: + response, call = self.stub.PostSandboxOrderAsync.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.PostOrderAsyncRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "PostSandboxOrderAsync") + return _grpc_helpers.protobuf_to_dataclass(response, PostOrderAsyncResponse) + + @handle_request_error("PostSandboxStopOrder") + def post_sandbox_stop_order( + self, + *, + request: PostStopOrderRequest, + ) -> PostStopOrderResponse: + response, call = self.stub.PostSandboxStopOrder.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, stoporders_pb2.PostStopOrderRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "PostSandboxStopOrder") + return _grpc_helpers.protobuf_to_dataclass(response, PostStopOrderResponse) + + @handle_request_error("GetSandboxStopOrders") + def get_sandbox_stop_orders( + self, + *, + request: GetStopOrdersRequest, + ) -> GetStopOrdersResponse: + response, call = self.stub.GetSandboxStopOrders.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, stoporders_pb2.GetStopOrdersRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetSandboxStopOrders") + return _grpc_helpers.protobuf_to_dataclass(response, GetStopOrdersResponse) + + @handle_request_error("CancelSandboxStopOrder") + def cancel_sandbox_stop_order( + self, + *, + request: CancelStopOrderRequest, + ) -> CancelStopOrderResponse: + response, call = self.stub.CancelSandboxStopOrder.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, stoporders_pb2.CancelStopOrderRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "CancelSandboxStopOrder") + return _grpc_helpers.protobuf_to_dataclass(response, CancelStopOrderResponse) + + @handle_request_error("GetSandboxOrderPrice") + def get_sandbox_order_price( + self, request: GetOrderPriceRequest + ) -> GetOrderPriceResponse: + response, call = self.stub.GetSandboxOrderPrice.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, orders_pb2.GetOrderPriceRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetSandboxOrderPrice") + return _grpc_helpers.protobuf_to_dataclass(response, GetOrderPriceResponse) + + +class StopOrdersService(_grpc_helpers.Service): + _stub_factory = stoporders_pb2_grpc.StopOrdersServiceStub + + @handle_request_error("PostStopOrder") + def post_stop_order( + self, + *, + figi: str = "", + quantity: int = 0, + price: Optional[Quotation] = None, + stop_price: Optional[Quotation] = None, + direction: StopOrderDirection = StopOrderDirection(0), + account_id: str = "", + expiration_type: StopOrderExpirationType = StopOrderExpirationType(0), + stop_order_type: StopOrderType = StopOrderType(0), + expire_date: Optional[datetime] = None, + instrument_id: str = "", + exchange_order_type: ExchangeOrderType = ExchangeOrderType(0), + take_profit_type: TakeProfitType = TakeProfitType(0), + trailing_data: Optional[PostStopOrderRequestTrailingData] = None, + price_type: PriceType = PriceType(0), + order_id: str = "", + confirm_margin_trade: bool = False, + instant_execution: Optional[bool] = None, + ) -> PostStopOrderResponse: + request = PostStopOrderRequest() + request.figi = figi + request.instrument_id = instrument_id + request.quantity = quantity + if price is not None: + request.price = price + if stop_price is not None: + request.stop_price = stop_price + request.direction = direction + request.account_id = account_id + request.expiration_type = expiration_type + request.stop_order_type = stop_order_type + if expire_date is not None: + request.expire_date = expire_date + request.exchange_order_type = exchange_order_type + request.take_profit_type = take_profit_type + if trailing_data is not None: + request.trailing_data = trailing_data + request.price_type = price_type + request.order_id = order_id + if confirm_margin_trade: + request.confirm_margin_trade = confirm_margin_trade + if instant_execution is not None: + request.instant_execution = instant_execution + response, call = self.stub.PostStopOrder.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, stoporders_pb2.PostStopOrderRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "PostStopOrder") + return _grpc_helpers.protobuf_to_dataclass(response, PostStopOrderResponse) + + @handle_request_error("GetStopOrders") + def get_stop_orders( + self, + *, + account_id: str = "", + status: StopOrderStatusOption = StopOrderStatusOption(0), + from_: Optional[datetime] = None, + to: Optional[datetime] = None, + ) -> GetStopOrdersResponse: + request = GetStopOrdersRequest() + request.account_id = account_id + request.status = status + if from_ is not None: + request.from_ = from_ + if to is not None: + request.to = to + response, call = self.stub.GetStopOrders.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, stoporders_pb2.GetStopOrdersRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetStopOrders") + return _grpc_helpers.protobuf_to_dataclass(response, GetStopOrdersResponse) + + @handle_request_error("CancelStopOrder") + def cancel_stop_order( + self, *, account_id: str = "", stop_order_id: str = "" + ) -> CancelStopOrderResponse: + request = CancelStopOrderRequest() + request.account_id = account_id + request.stop_order_id = stop_order_id + response, call = self.stub.CancelStopOrder.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, stoporders_pb2.CancelStopOrderRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "CancelStopOrder") + return _grpc_helpers.protobuf_to_dataclass(response, CancelStopOrderResponse) + + +class SignalService(_grpc_helpers.Service): + _stub_factory = signals_pb2_grpc.SignalServiceStub + + @handle_request_error("GetStrategies") + def get_strategies( + self, + *, + request: GetStrategiesRequest, + ) -> GetStrategiesResponse: + response, call = self.stub.GetStrategies.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, signals_pb2.GetStrategiesRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetStrategies") + return _grpc_helpers.protobuf_to_dataclass(response, GetStrategiesResponse) + + @handle_request_error("GetSignals") + def get_signals( + self, + *, + request: GetSignalsRequest, + ) -> GetSignalsResponse: + response, call = self.stub.GetSignals.with_call( + request=_grpc_helpers.dataclass_to_protobuff( + request, signals_pb2.GetSignalsRequest() + ), + metadata=self.metadata, + ) + log_request(get_tracking_id_from_call(call), "GetSignals") + return _grpc_helpers.protobuf_to_dataclass(response, GetSignalsResponse) diff --git a/invest-python-master/t_tech/invest/strategies/__init__.py b/invest-python-master/t_tech/invest/strategies/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/invest-python-master/t_tech/invest/strategies/base/__init__.py b/invest-python-master/t_tech/invest/strategies/base/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/invest-python-master/t_tech/invest/strategies/base/account_manager.py b/invest-python-master/t_tech/invest/strategies/base/account_manager.py new file mode 100644 index 0000000..39ee1fa --- /dev/null +++ b/invest-python-master/t_tech/invest/strategies/base/account_manager.py @@ -0,0 +1,38 @@ +import logging +from decimal import Decimal + +from t_tech.invest import Quotation +from t_tech.invest.services import Services +from t_tech.invest.strategies.base.errors import ( + InsufficientMarginalTradeFunds, + MarginalTradeIsNotActive, +) +from t_tech.invest.strategies.base.strategy_settings_base import StrategySettings +from t_tech.invest.utils import quotation_to_decimal + +logger = logging.getLogger(__name__) + + +class AccountManager: + def __init__(self, services: Services, strategy_settings: StrategySettings): + self._services = services + self._strategy_settings = strategy_settings + + def get_current_balance(self) -> Decimal: + account_id = self._strategy_settings.account_id + portfolio_response = self._services.operations.get_portfolio( + account_id=account_id + ) + balance = portfolio_response.total_amount_currencies + return quotation_to_decimal(Quotation(units=balance.units, nano=balance.nano)) + + def ensure_marginal_trade(self) -> None: + account_id = self._strategy_settings.account_id + try: + response = self._services.users.get_margin_attributes(account_id=account_id) + except Exception as e: + raise MarginalTradeIsNotActive() from e + value = quotation_to_decimal(response.funds_sufficiency_level) + if value <= 1: + raise InsufficientMarginalTradeFunds() + logger.info("Marginal trade is active") diff --git a/invest-python-master/t_tech/invest/strategies/base/errors.py b/invest-python-master/t_tech/invest/strategies/base/errors.py new file mode 100644 index 0000000..a5a61a9 --- /dev/null +++ b/invest-python-master/t_tech/invest/strategies/base/errors.py @@ -0,0 +1,38 @@ +class StrategyError(Exception): + pass + + +class NotEnoughData(StrategyError): + pass + + +class MarginalTradeIsNotActive(StrategyError): + pass + + +class InsufficientMarginalTradeFunds(StrategyError): + pass + + +class CandleEventForDateNotFound(StrategyError): + pass + + +class UnknownSignal(StrategyError): + pass + + +class OldCandleObservingError(StrategyError): + pass + + +class MarketDataNotAvailableError(StrategyError): + pass + + +class StrategySupervisorError(Exception): + pass + + +class EventsWereNotSupervised(StrategySupervisorError): + pass diff --git a/invest-python-master/t_tech/invest/strategies/base/event.py b/invest-python-master/t_tech/invest/strategies/base/event.py new file mode 100644 index 0000000..1ac21a1 --- /dev/null +++ b/invest-python-master/t_tech/invest/strategies/base/event.py @@ -0,0 +1,21 @@ +from dataclasses import dataclass +from datetime import datetime + +from t_tech.invest.strategies.base.models import CandleEvent +from t_tech.invest.strategies.base.signal import Signal + + +@dataclass +class StrategyEvent: + time: datetime + + +@dataclass +class DataEvent(StrategyEvent): + candle_event: CandleEvent + + +@dataclass +class SignalEvent(StrategyEvent): + signal: Signal + was_executed: bool diff --git a/invest-python-master/t_tech/invest/strategies/base/models.py b/invest-python-master/t_tech/invest/strategies/base/models.py new file mode 100644 index 0000000..b1bb739 --- /dev/null +++ b/invest-python-master/t_tech/invest/strategies/base/models.py @@ -0,0 +1,19 @@ +from dataclasses import dataclass +from datetime import datetime +from decimal import Decimal + + +@dataclass(eq=False, repr=True) +class Candle: + open: Decimal + high: Decimal + low: Decimal + close: Decimal + + +@dataclass(eq=False, repr=True) +class CandleEvent: + candle: Candle + volume: int + time: datetime + is_complete: bool diff --git a/invest-python-master/t_tech/invest/strategies/base/signal.py b/invest-python-master/t_tech/invest/strategies/base/signal.py new file mode 100644 index 0000000..37a6f3c --- /dev/null +++ b/invest-python-master/t_tech/invest/strategies/base/signal.py @@ -0,0 +1,48 @@ +import enum +from dataclasses import dataclass, field + + +class SignalDirection(enum.Enum): + LONG = "LONG" + SHORT = "SHORT" + + +@dataclass +class Signal: + pass + + +@dataclass +class OrderSignal(Signal): + lots: int + direction: SignalDirection + + +@dataclass +class CloseSignal(OrderSignal): + pass + + +@dataclass +class OpenSignal(OrderSignal): + pass + + +@dataclass +class OpenLongMarketOrder(OpenSignal): + direction: SignalDirection = field(default=SignalDirection.LONG) + + +@dataclass +class CloseLongMarketOrder(CloseSignal): + direction: SignalDirection = field(default=SignalDirection.LONG) + + +@dataclass +class OpenShortMarketOrder(OpenSignal): + direction: SignalDirection = field(default=SignalDirection.SHORT) + + +@dataclass +class CloseShortMarketOrder(CloseSignal): + direction: SignalDirection = field(default=SignalDirection.SHORT) diff --git a/invest-python-master/t_tech/invest/strategies/base/signal_executor_base.py b/invest-python-master/t_tech/invest/strategies/base/signal_executor_base.py new file mode 100644 index 0000000..e09f329 --- /dev/null +++ b/invest-python-master/t_tech/invest/strategies/base/signal_executor_base.py @@ -0,0 +1,55 @@ +from t_tech.invest import OrderDirection, OrderType +from t_tech.invest.services import Services +from t_tech.invest.strategies.base.signal import ( + CloseLongMarketOrder, + CloseShortMarketOrder, + OpenLongMarketOrder, + OpenShortMarketOrder, +) +from t_tech.invest.strategies.base.strategy_settings_base import StrategySettings + + +class SignalExecutor: + def __init__( + self, + services: Services, + settings: StrategySettings, + ): + self._services = services + self._settings = settings + + def execute_open_long_market_order(self, signal: OpenLongMarketOrder) -> None: + self._services.orders.post_order( + figi=self._settings.share_id, + quantity=signal.lots, + direction=OrderDirection.ORDER_DIRECTION_BUY, + account_id=self._settings.account_id, + order_type=OrderType.ORDER_TYPE_MARKET, + ) + + def execute_close_long_market_order(self, signal: CloseLongMarketOrder) -> None: + self._services.orders.post_order( + figi=self._settings.share_id, + quantity=signal.lots, + direction=OrderDirection.ORDER_DIRECTION_SELL, + account_id=self._settings.account_id, + order_type=OrderType.ORDER_TYPE_MARKET, + ) + + def execute_open_short_market_order(self, signal: OpenShortMarketOrder) -> None: + self._services.orders.post_order( + figi=self._settings.share_id, + quantity=signal.lots, + direction=OrderDirection.ORDER_DIRECTION_SELL, + account_id=self._settings.account_id, + order_type=OrderType.ORDER_TYPE_MARKET, + ) + + def execute_close_short_market_order(self, signal: CloseShortMarketOrder) -> None: + self._services.orders.post_order( + figi=self._settings.share_id, + quantity=signal.lots, + direction=OrderDirection.ORDER_DIRECTION_BUY, + account_id=self._settings.account_id, + order_type=OrderType.ORDER_TYPE_MARKET, + ) diff --git a/invest-python-master/t_tech/invest/strategies/base/strategy_interface.py b/invest-python-master/t_tech/invest/strategies/base/strategy_interface.py new file mode 100644 index 0000000..4f1eec5 --- /dev/null +++ b/invest-python-master/t_tech/invest/strategies/base/strategy_interface.py @@ -0,0 +1,15 @@ +from typing import Iterable, Protocol + +from t_tech.invest.strategies.base.models import CandleEvent +from t_tech.invest.strategies.base.signal import Signal + + +class InvestStrategy(Protocol): + def fit(self, candles: Iterable[CandleEvent]) -> None: + pass + + def observe(self, candle: CandleEvent) -> None: + pass + + def predict(self) -> Iterable[Signal]: + pass diff --git a/invest-python-master/t_tech/invest/strategies/base/strategy_settings_base.py b/invest-python-master/t_tech/invest/strategies/base/strategy_settings_base.py new file mode 100644 index 0000000..2c39d1d --- /dev/null +++ b/invest-python-master/t_tech/invest/strategies/base/strategy_settings_base.py @@ -0,0 +1,19 @@ +import dataclasses +from datetime import timedelta +from decimal import Decimal + +from t_tech.invest import CandleInterval +from t_tech.invest.typedefs import AccountId, ShareId +from t_tech.invest.utils import candle_interval_to_timedelta + + +@dataclasses.dataclass +class StrategySettings: + share_id: ShareId + account_id: AccountId + max_transaction_price: Decimal + candle_interval: CandleInterval + + @property + def candle_interval_timedelta(self) -> timedelta: + return candle_interval_to_timedelta(self.candle_interval) diff --git a/invest-python-master/t_tech/invest/strategies/base/strategy_supervisor.py b/invest-python-master/t_tech/invest/strategies/base/strategy_supervisor.py new file mode 100644 index 0000000..d2d95d3 --- /dev/null +++ b/invest-python-master/t_tech/invest/strategies/base/strategy_supervisor.py @@ -0,0 +1,29 @@ +import abc +from typing import Iterable, Protocol, Type + +from t_tech.invest.strategies.base.event import StrategyEvent + + +class IStrategySupervisor(Protocol): + def notify(self, event: StrategyEvent) -> None: + pass + + def get_events(self) -> Iterable[StrategyEvent]: + pass + + def get_events_of_type(self, cls: Type[StrategyEvent]) -> Iterable[StrategyEvent]: + pass + + +class StrategySupervisor(abc.ABC, IStrategySupervisor): + @abc.abstractmethod + def notify(self, event: StrategyEvent) -> None: + pass + + @abc.abstractmethod + def get_events(self) -> Iterable[StrategyEvent]: + pass + + @abc.abstractmethod + def get_events_of_type(self, cls: Type[StrategyEvent]) -> Iterable[StrategyEvent]: + pass diff --git a/invest-python-master/t_tech/invest/strategies/base/trader_base.py b/invest-python-master/t_tech/invest/strategies/base/trader_base.py new file mode 100644 index 0000000..40f6b32 --- /dev/null +++ b/invest-python-master/t_tech/invest/strategies/base/trader_base.py @@ -0,0 +1,69 @@ +import abc +import logging +from datetime import timedelta +from typing import Iterable + +import t_tech +from t_tech.invest import HistoricCandle +from t_tech.invest.services import Services +from t_tech.invest.strategies.base.models import Candle, CandleEvent +from t_tech.invest.strategies.base.strategy_interface import InvestStrategy +from t_tech.invest.strategies.base.strategy_settings_base import StrategySettings +from t_tech.invest.strategies.base.trader_interface import ITrader +from t_tech.invest.utils import now, quotation_to_decimal + +logger = logging.getLogger(__name__) + + +class Trader(ITrader, abc.ABC): + def __init__( + self, + strategy: InvestStrategy, + services: Services, + settings: StrategySettings, + ): + self._strategy = strategy + self._services = services + self._settings = settings + + @staticmethod + def _convert_historic_candles_into_candle_events( + historic_candles: Iterable[HistoricCandle], + ) -> Iterable[CandleEvent]: + for candle in historic_candles: + yield CandleEvent( + candle=Candle( + open=quotation_to_decimal(candle.open), + close=quotation_to_decimal(candle.close), + high=quotation_to_decimal(candle.high), + low=quotation_to_decimal(candle.low), + ), + volume=candle.volume, + time=candle.time, + is_complete=candle.is_complete, + ) + + def _load_candles(self, period: timedelta) -> Iterable[CandleEvent]: + logger.info("Loading candles for period %s from %s", period, now()) + + yield from self._convert_historic_candles_into_candle_events( + self._services.get_all_candles( + figi=self._settings.share_id, + from_=now() - period, + interval=self._settings.candle_interval, + ) + ) + + @staticmethod + def _convert_candle(candle: t_tech.invest.schemas.Candle) -> CandleEvent: + return CandleEvent( + candle=Candle( + open=quotation_to_decimal(candle.open), + close=quotation_to_decimal(candle.close), + high=quotation_to_decimal(candle.high), + low=quotation_to_decimal(candle.low), + ), + volume=candle.volume, + time=candle.time, + is_complete=False, + ) diff --git a/invest-python-master/t_tech/invest/strategies/base/trader_interface.py b/invest-python-master/t_tech/invest/strategies/base/trader_interface.py new file mode 100644 index 0000000..6a4364c --- /dev/null +++ b/invest-python-master/t_tech/invest/strategies/base/trader_interface.py @@ -0,0 +1,6 @@ +from typing import Protocol + + +class ITrader(Protocol): + def trade(self): + pass diff --git a/invest-python-master/t_tech/invest/strategies/moving_average/__init__.py b/invest-python-master/t_tech/invest/strategies/moving_average/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/invest-python-master/t_tech/invest/strategies/moving_average/plotter.py b/invest-python-master/t_tech/invest/strategies/moving_average/plotter.py new file mode 100644 index 0000000..543e6d3 --- /dev/null +++ b/invest-python-master/t_tech/invest/strategies/moving_average/plotter.py @@ -0,0 +1,197 @@ +import logging +from datetime import datetime, timedelta +from typing import Any, Dict, List, Optional, Type, cast + +import mplfinance as mpf +import numpy as np +import pandas as pd + +from t_tech.invest.strategies.base.event import DataEvent, SignalEvent, StrategyEvent +from t_tech.invest.strategies.base.signal import ( + CloseLongMarketOrder, + CloseShortMarketOrder, + OpenLongMarketOrder, + OpenShortMarketOrder, + OrderSignal, + Signal, + SignalDirection, +) +from t_tech.invest.strategies.moving_average.strategy_settings import ( + MovingAverageStrategySettings, +) +from t_tech.invest.strategies.plotting.plotter import PlotKwargs, StrategyPlotter + +logger = logging.getLogger(__name__) + + +class MovingAverageStrategyPlotter(StrategyPlotter): + def __init__(self, settings: MovingAverageStrategySettings): + self._was_not_executed_color = "grey" + self._settings = settings + self._signal_type_to_style_map: Dict[Type[Signal], Dict[str, Any]] = { + OpenLongMarketOrder: { + "type": "scatter", + "markersize": 50, + "marker": "^", + "color": "green", + }, + CloseLongMarketOrder: { + "type": "scatter", + "markersize": 50, + "marker": "^", + "color": "black", + }, + OpenShortMarketOrder: { + "type": "scatter", + "markersize": 50, + "marker": "v", + "color": "red", + }, + CloseShortMarketOrder: { + "type": "scatter", + "markersize": 50, + "marker": "v", + "color": "black", + }, + } + + self._signal_type_to_candle_point_map = { + SignalDirection.LONG: lambda candle: candle.low, + SignalDirection.SHORT: lambda candle: candle.high, + } + + def _filter_data_events( + self, strategy_events: List[StrategyEvent] + ) -> List[DataEvent]: + return cast( + List[DataEvent], + list(filter(lambda e: isinstance(e, DataEvent), strategy_events)), + ) + + def _filter_signal_events( + self, strategy_events: List[StrategyEvent] + ) -> List[SignalEvent]: + return cast( + List[SignalEvent], + list(filter(lambda e: isinstance(e, SignalEvent), strategy_events)), + ) + + def _get_interval_count_between_dates( + self, start: datetime, end: datetime, interval_delta: timedelta + ) -> float: + return (end - start) / interval_delta + + def get_candle_plot_kwargs( + self, strategy_events: List[StrategyEvent] + ) -> PlotKwargs: + data_events = self._filter_data_events(strategy_events) + quotes = { + "open": [float(e.candle_event.candle.open) for e in data_events], + "close": [float(e.candle_event.candle.close) for e in data_events], + "high": [float(e.candle_event.candle.high) for e in data_events], + "low": [float(e.candle_event.candle.low) for e in data_events], + "volume": [float(e.candle_event.volume) for e in data_events], + "time": [e.candle_event.time for e in data_events], + } + df = pd.DataFrame(quotes, index=quotes["time"]) + interval_count = self._get_interval_count_between_dates( + start=df["time"].idxmin(), + end=df["time"].idxmax(), + interval_delta=self._settings.candle_interval_timedelta, + ) + non_trading_coefficient = len(data_events) / interval_count + mav = { + "ma_short": int( + self._settings.short_period + / self._settings.candle_interval_timedelta + * non_trading_coefficient + ), + "ma_long": int( + self._settings.long_period + / self._settings.candle_interval_timedelta + * non_trading_coefficient + ), + } + style = mpf.make_mpf_style( + base_mpf_style="charles", mavcolors=["#1f77b4", "#ff7f0e", "#2ca02c"] + ) + return cast( + PlotKwargs, + { + "data": df, + "type": "candle", + "volume": True, + "mav": tuple(mav.values()), + "style": style, + "returnfig": True, + }, + ) + + def _get_plot_for_signal_type( + self, + signal_type: Type[Signal], + signal_event_types_to_event_index: Dict[Type[Signal], Dict[int, SignalEvent]], + data_events: List[DataEvent], + was_executed_flag: bool, + ) -> Optional[PlotKwargs]: + style = self._signal_type_to_style_map[signal_type] + price = [np.nan] * len(data_events) + color = style["color"] + has_signal = False + for index, signal_event in signal_event_types_to_event_index[ + signal_type + ].items(): + if was_executed_flag == signal_event.was_executed: + has_signal = True + candle = data_events[index].candle_event.candle + signal = cast(OrderSignal, signal_event.signal) + price[index] = self._signal_type_to_candle_point_map[signal.direction]( + candle + ) + if not signal_event.was_executed: + color = self._was_not_executed_color + if not has_signal: + return None + style.update({"color": color}) + params = { + "price": price, + "time": [e.candle_event.time for e in data_events], + } + df = pd.DataFrame(params, index=params["time"]) + return cast(PlotKwargs, dict(data=df["price"], **style)) + + def get_signal_plot_kwargs( + self, strategy_events: List[StrategyEvent] + ) -> List[PlotKwargs]: + signal_events = self._filter_signal_events(strategy_events) + data_events = self._filter_data_events(strategy_events) + data_events.sort(key=lambda e: e.time) + first_data_event, last_data_event = data_events[0], data_events[-1] + data_events_timedelta = last_data_event.time - first_data_event.time + + signal_event_types_to_event_index: Dict[ + Type[Signal], Dict[int, SignalEvent] + ] = {} + for signal_event in signal_events: + signal_type = type(signal_event.signal) + event_index = int( + ((signal_event.time - first_data_event.time) / data_events_timedelta) + * len(data_events) + ) + event_index = min(event_index, len(data_events) - 1) + if signal_type not in signal_event_types_to_event_index: + signal_event_types_to_event_index[signal_type] = {} + signal_event_types_to_event_index[signal_type][event_index] = signal_event + + plots = [] + for was_executed_flag in [False, True]: + for signal_type in signal_event_types_to_event_index: + kwargs = self._get_plot_for_signal_type( + signal_type=signal_type, + signal_event_types_to_event_index=signal_event_types_to_event_index, + data_events=data_events, + was_executed_flag=was_executed_flag, + ) + plots.append(kwargs) + + return cast(List[PlotKwargs], list(filter(lambda p: p is not None, plots))) diff --git a/invest-python-master/t_tech/invest/strategies/moving_average/signal_executor.py b/invest-python-master/t_tech/invest/strategies/moving_average/signal_executor.py new file mode 100644 index 0000000..70966b9 --- /dev/null +++ b/invest-python-master/t_tech/invest/strategies/moving_average/signal_executor.py @@ -0,0 +1,65 @@ +import logging +from functools import singledispatchmethod + +from t_tech.invest.services import Services +from t_tech.invest.strategies.base.errors import UnknownSignal +from t_tech.invest.strategies.base.signal import ( + CloseLongMarketOrder, + CloseShortMarketOrder, + OpenLongMarketOrder, + OpenShortMarketOrder, + Signal, +) +from t_tech.invest.strategies.base.signal_executor_base import SignalExecutor +from t_tech.invest.strategies.moving_average.strategy_settings import ( + MovingAverageStrategySettings, +) +from t_tech.invest.strategies.moving_average.strategy_state import ( + MovingAverageStrategyState, +) + +logger = logging.getLogger(__name__) + + +class MovingAverageSignalExecutor(SignalExecutor): + def __init__( + self, + services: Services, + state: MovingAverageStrategyState, + settings: MovingAverageStrategySettings, + ): + super().__init__(services, settings) + self._services = services + self._state = state + + @singledispatchmethod + def execute(self, signal: Signal) -> None: + raise UnknownSignal() + + @execute.register + def _execute_open_long_market_order(self, signal: OpenLongMarketOrder) -> None: + self.execute_open_long_market_order(signal) + self._state.long_open = True + self._state.position = signal.lots + logger.info("Signal executed %s", signal) + + @execute.register + def _execute_close_long_market_order(self, signal: CloseLongMarketOrder) -> None: + self.execute_close_long_market_order(signal) + self._state.long_open = False + self._state.position = 0 + logger.info("Signal executed %s", signal) + + @execute.register + def _execute_open_short_market_order(self, signal: OpenShortMarketOrder) -> None: + self.execute_open_short_market_order(signal) + self._state.short_open = True + self._state.position = signal.lots + logger.info("Signal executed %s", signal) + + @execute.register + def _execute_close_short_market_order(self, signal: CloseShortMarketOrder) -> None: + self.execute_close_short_market_order(signal) + self._state.short_open = False + self._state.position = 0 + logger.info("Signal executed %s", signal) diff --git a/invest-python-master/t_tech/invest/strategies/moving_average/strategy.py b/invest-python-master/t_tech/invest/strategies/moving_average/strategy.py new file mode 100644 index 0000000..49ac8a5 --- /dev/null +++ b/invest-python-master/t_tech/invest/strategies/moving_average/strategy.py @@ -0,0 +1,305 @@ +import logging +from datetime import datetime, timedelta +from decimal import Decimal +from typing import Callable, Iterable, List + +import numpy as np + +from t_tech.invest.strategies.base.account_manager import AccountManager +from t_tech.invest.strategies.base.errors import ( + CandleEventForDateNotFound, + NotEnoughData, + OldCandleObservingError, +) +from t_tech.invest.strategies.base.models import CandleEvent +from t_tech.invest.strategies.base.signal import ( + CloseLongMarketOrder, + CloseShortMarketOrder, + OpenLongMarketOrder, + OpenShortMarketOrder, + Signal, +) +from t_tech.invest.strategies.base.strategy_interface import InvestStrategy +from t_tech.invest.strategies.moving_average.strategy_settings import ( + MovingAverageStrategySettings, +) +from t_tech.invest.strategies.moving_average.strategy_state import ( + MovingAverageStrategyState, +) +from t_tech.invest.utils import ( + candle_interval_to_timedelta, + ceil_datetime, + floor_datetime, + now, +) + +logger = logging.getLogger(__name__) + + +class MovingAverageStrategy(InvestStrategy): + def __init__( + self, + settings: MovingAverageStrategySettings, + account_manager: AccountManager, + state: MovingAverageStrategyState, + ): + self._data: List[CandleEvent] = [] + self._settings = settings + self._account_manager = account_manager + + self._state = state + self._MA_LONG_START: Decimal + self._candle_interval_timedelta = candle_interval_to_timedelta( + self._settings.candle_interval + ) + + def _ensure_enough_candles(self) -> None: + candles_needed = ( + self._settings.short_period + self._settings.long_period + ) / self._settings.candle_interval_timedelta + if candles_needed > len(self._data): + raise NotEnoughData( + f"Got {len(self._data)} candles but needed {candles_needed}" + ) + logger.info("Got enough data for strategy") + + def fit(self, candles: Iterable[CandleEvent]) -> None: + logger.debug("Strategy fitting with candles %s", candles) + for candle in candles: + self.observe(candle) + self._ensure_enough_candles() + + def _append_candle_event(self, candle_event: CandleEvent) -> None: + last_candle_event = self._data[-1] + last_interval_floor = floor_datetime( + last_candle_event.time, self._candle_interval_timedelta + ) + last_interval_ceil = ceil_datetime( + last_candle_event.time, self._candle_interval_timedelta + ) + + if candle_event.time < last_interval_floor: + raise OldCandleObservingError() + if ( + candle_event.time < last_interval_ceil + or candle_event.time == last_interval_floor + ): + self._data[-1] = candle_event + else: + self._data.append(candle_event) + + def observe(self, candle: CandleEvent) -> None: + logger.debug("Observing candle event: %s", candle) + + if len(self._data) > 0: + self._append_candle_event(candle) + else: + self._data.append(candle) + + @staticmethod + def _get_newer_than_datetime_predicate( + anchor: datetime, + ) -> Callable[[CandleEvent], bool]: + def _(event: CandleEvent) -> bool: + return event.time > anchor + + return _ + + def _filter_from_the_end_with_early_stop( + self, predicate: Callable[[CandleEvent], bool] + ) -> Iterable[CandleEvent]: + for event in reversed(self._data): + if not predicate(event): + break + yield event + + def _select_for_period(self, period: timedelta): + predicate = self._get_newer_than_datetime_predicate(now() - period) + return self._filter_from_the_end_with_early_stop(predicate) + + @staticmethod + def _get_prices(events: Iterable[CandleEvent]) -> Iterable[Decimal]: + for event in events: + yield event.candle.close + + def _calculate_moving_average(self, period: timedelta) -> Decimal: + prices = list(self._get_prices(self._select_for_period(period))) + logger.debug("Selected prices: %s", prices) + return np.mean(prices, axis=0) # type: ignore + + def _calculate_std(self, period: timedelta) -> Decimal: + prices = list(self._get_prices(self._select_for_period(period))) + return np.std(prices, axis=0) # type: ignore + + def _get_first_candle_before(self, date: datetime) -> CandleEvent: + predicate = self._get_newer_than_datetime_predicate(date) + for event in reversed(self._data): + if not predicate(event): + return event + raise CandleEventForDateNotFound() + + def _init_MA_LONG_START(self): + date = now() - self._settings.short_period + event = self._get_first_candle_before(date) + self._MA_LONG_START = event.candle.close + + @staticmethod + def _is_long_open_signal( + MA_SHORT: Decimal, + MA_LONG: Decimal, + PRICE: Decimal, + STD: Decimal, + MA_LONG_START: Decimal, + ) -> bool: + logger.debug("Try long opening") + logger.debug("\tMA_SHORT > MA_LONG, %s", MA_SHORT > MA_LONG) + logger.debug( + "\tand abs((PRICE - MA_LONG) / MA_LONG) < STD, %s", + abs((PRICE - MA_LONG) / MA_LONG) < STD, + ) + logger.debug("\tand MA_LONG < MA_LONG_START, %s", MA_LONG > MA_LONG_START) + logger.debug( + "== %s", + MA_SHORT > MA_LONG > MA_LONG_START + and abs((PRICE - MA_LONG) / MA_LONG) < STD, + ) + return ( + MA_SHORT > MA_LONG > MA_LONG_START + and abs((PRICE - MA_LONG) / MA_LONG) < STD + ) + + @staticmethod + def _is_short_open_signal( + MA_SHORT: Decimal, + MA_LONG: Decimal, + PRICE: Decimal, + STD: Decimal, + MA_LONG_START: Decimal, + ) -> bool: + logger.debug("Try short opening") + logger.debug("\tMA_SHORT < MA_LONG, %s", MA_SHORT < MA_LONG) + logger.debug( + "\tand abs((PRICE - MA_LONG) / MA_LONG) < STD, %s", + abs((PRICE - MA_LONG) / MA_LONG) < STD, + ) + logger.debug("\tand MA_LONG > MA_LONG_START, %s", MA_LONG < MA_LONG_START) + logger.debug( + "== %s", + MA_SHORT < MA_LONG < MA_LONG_START + and abs((PRICE - MA_LONG) / MA_LONG) < STD, + ) + return ( + MA_SHORT < MA_LONG < MA_LONG_START + and abs((PRICE - MA_LONG) / MA_LONG) < STD + ) + + @staticmethod + def _is_long_close_signal( + MA_LONG: Decimal, + PRICE: Decimal, + STD: Decimal, + has_short_open_signal: bool, + ) -> bool: + logger.debug("Try long closing") + logger.debug("\tPRICE > MA_LONG + 10 * STD, %s", PRICE > MA_LONG + 10 * STD) + logger.debug("\tor has_short_open_signal, %s", has_short_open_signal) + logger.debug("\tor PRICE < MA_LONG - 3 * STD, %s", PRICE < MA_LONG - 3 * STD) + logger.debug( + "== %s", + PRICE > MA_LONG + 10 * STD + or has_short_open_signal + or PRICE < MA_LONG - 3 * STD, + ) + return ( + PRICE > MA_LONG + 10 * STD + or has_short_open_signal + or PRICE < MA_LONG - 3 * STD + ) + + @staticmethod + def _is_short_close_signal( + MA_LONG: Decimal, + PRICE: Decimal, + STD: Decimal, + has_long_open_signal: bool, + ) -> bool: + logger.debug("Try short closing") + logger.debug("\tPRICE < MA_LONG - 10 * STD, %s", PRICE < MA_LONG - 10 * STD) + logger.debug("\tor has_long_open_signal, %s", has_long_open_signal) + logger.debug("\tor PRICE > MA_LONG + 3 * STD, %s", PRICE > MA_LONG + 3 * STD) + logger.debug( + "== %s", + PRICE < MA_LONG - 10 * STD # кажется, что не работает закрытие + or has_long_open_signal + or PRICE > MA_LONG + 3 * STD, + ) + return ( + PRICE < MA_LONG - 10 * STD + or has_long_open_signal + or PRICE > MA_LONG + 3 * STD + ) + + def predict(self) -> Iterable[Signal]: + logger.info("Strategy predict") + self._init_MA_LONG_START() + MA_LONG_START = self._MA_LONG_START + logger.debug("MA_LONG_START: %s", MA_LONG_START) + PRICE = self._data[-1].candle.close + logger.debug("PRICE: %s", PRICE) + MA_LONG = self._calculate_moving_average(self._settings.long_period) + logger.debug("MA_LONG: %s", MA_LONG) + MA_SHORT = self._calculate_moving_average(self._settings.short_period) + logger.debug("MA_SHORT: %s", MA_SHORT) + STD = self._calculate_std(self._settings.std_period) + logger.debug("STD: %s", STD) + MONEY = self._account_manager.get_current_balance() + logger.debug("MONEY: %s", MONEY) + + has_long_open_signal = False + has_short_open_signal = False + + possible_lots = int(MONEY // PRICE) + + if ( + not self._state.long_open + and self._is_long_open_signal( + MA_SHORT=MA_SHORT, + MA_LONG=MA_LONG, + PRICE=PRICE, + STD=STD, + MA_LONG_START=MA_LONG_START, + ) + and possible_lots > 0 + ): + has_long_open_signal = True + yield OpenLongMarketOrder(lots=possible_lots) + + if ( + not self._state.short_open + and self._is_short_open_signal( + MA_SHORT=MA_SHORT, + MA_LONG=MA_LONG, + PRICE=PRICE, + STD=STD, + MA_LONG_START=MA_LONG_START, + ) + and possible_lots > 0 + ): + has_short_open_signal = True + yield OpenShortMarketOrder(lots=possible_lots) + + if self._state.long_open and self._is_long_close_signal( + MA_LONG=MA_LONG, + PRICE=PRICE, + STD=STD, + has_short_open_signal=has_short_open_signal, + ): + yield CloseLongMarketOrder(lots=self._state.position) + + if self._state.short_open and self._is_short_close_signal( + MA_LONG=MA_LONG, + PRICE=PRICE, + STD=STD, + has_long_open_signal=has_long_open_signal, + ): + yield CloseShortMarketOrder(lots=self._state.position) diff --git a/invest-python-master/t_tech/invest/strategies/moving_average/strategy_settings.py b/invest-python-master/t_tech/invest/strategies/moving_average/strategy_settings.py new file mode 100644 index 0000000..2db3181 --- /dev/null +++ b/invest-python-master/t_tech/invest/strategies/moving_average/strategy_settings.py @@ -0,0 +1,11 @@ +import dataclasses +from datetime import timedelta + +from t_tech.invest.strategies.base.strategy_settings_base import StrategySettings + + +@dataclasses.dataclass +class MovingAverageStrategySettings(StrategySettings): + long_period: timedelta + short_period: timedelta + std_period: timedelta diff --git a/invest-python-master/t_tech/invest/strategies/moving_average/strategy_state.py b/invest-python-master/t_tech/invest/strategies/moving_average/strategy_state.py new file mode 100644 index 0000000..472cba9 --- /dev/null +++ b/invest-python-master/t_tech/invest/strategies/moving_average/strategy_state.py @@ -0,0 +1,29 @@ +class MovingAverageStrategyState: + def __init__(self): + self._long_open: bool = False + self._short_open: bool = False + self._position: int = 0 + + @property + def long_open(self) -> bool: + return self._long_open + + @long_open.setter + def long_open(self, value: bool) -> None: + self._long_open = value + + @property + def short_open(self) -> bool: + return self._short_open + + @short_open.setter + def short_open(self, value: bool) -> None: + self._short_open = value + + @property + def position(self) -> int: + return self._position + + @position.setter + def position(self, value: int) -> None: + self._position = value diff --git a/invest-python-master/t_tech/invest/strategies/moving_average/supervisor.py b/invest-python-master/t_tech/invest/strategies/moving_average/supervisor.py new file mode 100644 index 0000000..76700dd --- /dev/null +++ b/invest-python-master/t_tech/invest/strategies/moving_average/supervisor.py @@ -0,0 +1,24 @@ +from itertools import chain +from typing import Dict, Iterable, List, Type, cast + +from t_tech.invest.strategies.base.errors import EventsWereNotSupervised +from t_tech.invest.strategies.base.event import StrategyEvent +from t_tech.invest.strategies.base.strategy_supervisor import StrategySupervisor + + +class MovingAverageStrategySupervisor(StrategySupervisor): + def __init__(self): + self._events: Dict[Type[StrategyEvent], List[StrategyEvent]] = {} + + def notify(self, event: StrategyEvent) -> None: + if type(event) not in self._events: + self._events[type(event)] = [] + self._events[type(event)].append(event) + + def get_events(self) -> Iterable[StrategyEvent]: + return cast(Iterable[StrategyEvent], chain(*self._events.values())) + + def get_events_of_type(self, cls: Type[StrategyEvent]) -> List[StrategyEvent]: + if cls in self._events: + return self._events[cls] + raise EventsWereNotSupervised() diff --git a/invest-python-master/t_tech/invest/strategies/moving_average/trader.py b/invest-python-master/t_tech/invest/strategies/moving_average/trader.py new file mode 100644 index 0000000..8ac07d1 --- /dev/null +++ b/invest-python-master/t_tech/invest/strategies/moving_average/trader.py @@ -0,0 +1,172 @@ +import logging +import time +from typing import Iterator, List + +import t_tech +from t_tech.invest import ( + CandleInstrument, + InvestError, + MarketDataRequest, + MarketDataResponse, + SubscribeCandlesRequest, + SubscriptionAction, + SubscriptionInterval, +) +from t_tech.invest.services import Services +from t_tech.invest.strategies.base.account_manager import AccountManager +from t_tech.invest.strategies.base.errors import MarketDataNotAvailableError +from t_tech.invest.strategies.base.event import DataEvent, SignalEvent +from t_tech.invest.strategies.base.models import CandleEvent +from t_tech.invest.strategies.base.signal import CloseSignal, OpenSignal, Signal +from t_tech.invest.strategies.base.signal_executor_base import SignalExecutor +from t_tech.invest.strategies.base.trader_base import Trader +from t_tech.invest.strategies.moving_average.strategy import MovingAverageStrategy +from t_tech.invest.strategies.moving_average.strategy_settings import ( + MovingAverageStrategySettings, +) +from t_tech.invest.strategies.moving_average.strategy_state import ( + MovingAverageStrategyState, +) +from t_tech.invest.strategies.moving_average.supervisor import ( + MovingAverageStrategySupervisor, +) +from t_tech.invest.utils import floor_datetime, now + +logger = logging.getLogger(__name__) + + +class MovingAverageStrategyTrader(Trader): + def __init__( + self, + strategy: MovingAverageStrategy, + settings: MovingAverageStrategySettings, + services: Services, + state: MovingAverageStrategyState, + signal_executor: SignalExecutor, + account_manager: AccountManager, + supervisor: MovingAverageStrategySupervisor, + ): + super().__init__(strategy, services, settings) + self._settings: MovingAverageStrategySettings = settings + self._strategy = strategy + self._services = services + self._data: List[CandleEvent] + self._market_data_stream: Iterator[MarketDataResponse] + self._state = state + self._signal_executor = signal_executor + self._account_manager = account_manager + self._supervisor = supervisor + + self._data = list( + self._load_candles( + (self._settings.short_period + self._settings.long_period) * 3 + ) + ) + for candle_event in self._data: + self._supervisor.notify(self._convert_to_data_event(candle_event)) + self._strategy.fit(self._data) + + self._ensure_marginal_trade_active() + self._subscribe() + + def _ensure_marginal_trade_active(self) -> None: + self._account_manager.ensure_marginal_trade() + + def _subscribe(self): + current_instrument = CandleInstrument( + figi=self._settings.share_id, + interval=SubscriptionInterval.SUBSCRIPTION_INTERVAL_ONE_MINUTE, + ) + candle_subscribe_request = MarketDataRequest( + subscribe_candles_request=SubscribeCandlesRequest( + subscription_action=SubscriptionAction.SUBSCRIPTION_ACTION_SUBSCRIBE, + instruments=[current_instrument], + ) + ) + + def request_iterator(): + yield candle_subscribe_request + while True: + time.sleep(1) + + self._market_data_stream = self._services.market_data_stream.market_data_stream( + request_iterator() + ) + + def _is_candle_fresh(self, candle: t_tech.invest.Candle) -> bool: + is_fresh_border = floor_datetime( + now(), delta=self._settings.candle_interval_timedelta + ) + logger.debug( + "Checking if candle is fresh: candle.time=%s > is_fresh_border=%s %s)", + candle.time, + is_fresh_border, + candle.time >= is_fresh_border, + ) + return candle.time >= is_fresh_border + + @staticmethod + def _convert_to_data_event(candle_event: CandleEvent) -> DataEvent: + return DataEvent(candle_event=candle_event, time=candle_event.time) + + def _make_observations(self) -> None: + while True: + market_data_response: MarketDataResponse = next(self._market_data_stream) + logger.debug("got market_data_response: %s", market_data_response) + if market_data_response.candle is None: + logger.debug("market_data_response didn't have candle") + continue + candle = market_data_response.candle + logger.debug("candle extracted: %s", candle) + candle_event = self._convert_candle(candle) + self._strategy.observe(candle_event) + self._supervisor.notify(self._convert_to_data_event(candle_event)) + if self._is_candle_fresh(candle): + logger.info("Data refreshed") + break + + def _refresh_data(self) -> None: + logger.info("Refreshing data") + try: + self._make_observations() + except StopIteration as e: + logger.info("Fresh quotations not available") + raise MarketDataNotAvailableError() from e + + def _filter_closing_signals(self, signals: List[Signal]) -> List[Signal]: + return list(filter(lambda signal: isinstance(signal, CloseSignal), signals)) + + def _filter_opening_signals(self, signals: List[Signal]) -> List[Signal]: + return list(filter(lambda signal: isinstance(signal, OpenSignal), signals)) + + def _execute(self, signal: Signal) -> None: + logger.info("Trying to execute signal %s", signal) + try: + self._signal_executor.execute(signal) # type: ignore + except InvestError: + was_executed = False + else: + was_executed = True + self._supervisor.notify( + SignalEvent(signal=signal, was_executed=was_executed, time=now()) + ) + + def _get_signals(self) -> List[Signal]: + signals = list(self._strategy.predict()) + return [ + *self._filter_closing_signals(signals), + *self._filter_opening_signals(signals), + ] + + def trade(self) -> None: + """Делает попытку следовать стратегии.""" + logger.info("Balance: %s", self._account_manager.get_current_balance()) + self._refresh_data() + + signals = self._get_signals() + if signals: + logger.info("Got signals %s", signals) + for signal in signals: + self._execute(signal) + if self._state.position == 0: + logger.info("Trade try complete") diff --git a/invest-python-master/t_tech/invest/strategies/plotting/__init__.py b/invest-python-master/t_tech/invest/strategies/plotting/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/invest-python-master/t_tech/invest/strategies/plotting/plotter.py b/invest-python-master/t_tech/invest/strategies/plotting/plotter.py new file mode 100644 index 0000000..a5add3b --- /dev/null +++ b/invest-python-master/t_tech/invest/strategies/plotting/plotter.py @@ -0,0 +1,62 @@ +import abc +import logging +from typing import Any, Iterable, List, NewType, Protocol + +import matplotlib.pyplot as plt +import mplfinance as mpf +from IPython.display import clear_output +from matplotlib.gridspec import GridSpec + +from t_tech.invest.strategies.base.event import StrategyEvent + +PlotKwargs = NewType("PlotKwargs", dict) + +logger = logging.getLogger(__name__) + + +class IPlotter(Protocol): + def plot(self, strategy_events: Iterable[StrategyEvent]) -> None: + pass + + +class StrategyPlotter(abc.ABC, IPlotter): + @abc.abstractmethod + def get_candle_plot_kwargs( + self, strategy_events: List[StrategyEvent] + ) -> PlotKwargs: + pass + + @abc.abstractmethod + def get_signal_plot_kwargs( + self, strategy_events: List[StrategyEvent] + ) -> List[PlotKwargs]: + pass + + def get_plot_kwargs( + self, strategy_events: Iterable[StrategyEvent], ax: Any + ) -> PlotKwargs: + strategy_events = list(strategy_events) + candle_plot = self.get_candle_plot_kwargs(strategy_events=strategy_events) + if signal_plots := self.get_signal_plot_kwargs(strategy_events=strategy_events): + add_plots = [] + for signal_plot in signal_plots: + signal_plot.update({"ax": ax}) + ap = mpf.make_addplot(**signal_plot) + add_plots.append(ap) + + candle_plot.update({"addplot": add_plots}) + return candle_plot + + def plot(self, strategy_events: Iterable[StrategyEvent]) -> None: + _fig = plt.figure(figsize=(20, 20)) + gs = GridSpec(2, 1, height_ratios=[3, 1]) + _ax1 = plt.subplot(gs[0]) + _ax2 = plt.subplot(gs[1]) + + candle_plot_kwargs = self.get_plot_kwargs(strategy_events, ax=_ax1) + candle_plot_kwargs.update({"ax": _ax1, "volume": _ax2}) + mpf.plot(**candle_plot_kwargs, warn_too_much_data=999999999) + + clear_output(wait=True) + _fig.canvas.draw() + _fig.canvas.flush_events() diff --git a/invest-python-master/t_tech/invest/typedefs.py b/invest-python-master/t_tech/invest/typedefs.py new file mode 100644 index 0000000..6159a85 --- /dev/null +++ b/invest-python-master/t_tech/invest/typedefs.py @@ -0,0 +1,5 @@ +from typing import Any, NewType, Sequence, Tuple + +AccountId = NewType("AccountId", str) +ShareId = NewType("ShareId", str) +ChannelArgumentType = Sequence[Tuple[str, Any]] diff --git a/invest-python-master/t_tech/invest/utils.py b/invest-python-master/t_tech/invest/utils.py new file mode 100644 index 0000000..bf42534 --- /dev/null +++ b/invest-python-master/t_tech/invest/utils.py @@ -0,0 +1,274 @@ +import ast +import dataclasses +import re +from datetime import datetime, timedelta, timezone +from decimal import Decimal +from enum import Enum +from typing import Any, Callable, Generator, Iterable, List, Protocol, Tuple + +import dateutil.parser + +from .schemas import ( + CandleInterval, + HistoricCandle, + MoneyValue, + Quotation, + SubscriptionInterval, +) + +__all__ = ( + "get_intervals", + "quotation_to_decimal", + "money_to_decimal", + "decimal_to_quotation", + "decimal_to_money", + "candle_interval_to_subscription_interval", + "now", + "candle_interval_to_timedelta", + "ceil_datetime", + "floor_datetime", + "dataclass_from_dict", + "round_datetime_range", + "empty_or_uuid", +) + +DAYS_IN_YEAR = 365 + + +MAX_INTERVALS = { + CandleInterval.CANDLE_INTERVAL_5_SEC: timedelta(minutes=200), + CandleInterval.CANDLE_INTERVAL_10_SEC: timedelta(minutes=200), + CandleInterval.CANDLE_INTERVAL_30_SEC: timedelta(hours=20), + CandleInterval.CANDLE_INTERVAL_1_MIN: timedelta(days=1), + CandleInterval.CANDLE_INTERVAL_2_MIN: timedelta(days=1), + CandleInterval.CANDLE_INTERVAL_3_MIN: timedelta(days=1), + CandleInterval.CANDLE_INTERVAL_5_MIN: timedelta(days=1), + CandleInterval.CANDLE_INTERVAL_10_MIN: timedelta(days=1), + CandleInterval.CANDLE_INTERVAL_15_MIN: timedelta(days=1), + CandleInterval.CANDLE_INTERVAL_30_MIN: timedelta(days=1), + CandleInterval.CANDLE_INTERVAL_HOUR: timedelta(weeks=1), + CandleInterval.CANDLE_INTERVAL_2_HOUR: timedelta(weeks=1), + CandleInterval.CANDLE_INTERVAL_4_HOUR: timedelta(weeks=1), + CandleInterval.CANDLE_INTERVAL_DAY: timedelta(days=DAYS_IN_YEAR), + CandleInterval.CANDLE_INTERVAL_WEEK: timedelta(days=DAYS_IN_YEAR), + CandleInterval.CANDLE_INTERVAL_MONTH: timedelta(days=DAYS_IN_YEAR * 3), +} + +INTERVAL_LENGTHS = { + CandleInterval.CANDLE_INTERVAL_5_SEC: timedelta(seconds=5), + CandleInterval.CANDLE_INTERVAL_10_SEC: timedelta(seconds=10), + CandleInterval.CANDLE_INTERVAL_30_SEC: timedelta(seconds=30), + CandleInterval.CANDLE_INTERVAL_1_MIN: timedelta(minutes=1), + CandleInterval.CANDLE_INTERVAL_2_MIN: timedelta(minutes=2), + CandleInterval.CANDLE_INTERVAL_3_MIN: timedelta(minutes=3), + CandleInterval.CANDLE_INTERVAL_5_MIN: timedelta(minutes=5), + CandleInterval.CANDLE_INTERVAL_10_MIN: timedelta(minutes=10), + CandleInterval.CANDLE_INTERVAL_15_MIN: timedelta(minutes=15), + CandleInterval.CANDLE_INTERVAL_30_MIN: timedelta(minutes=30), + CandleInterval.CANDLE_INTERVAL_HOUR: timedelta(hours=1), + CandleInterval.CANDLE_INTERVAL_2_HOUR: timedelta(hours=2), + CandleInterval.CANDLE_INTERVAL_4_HOUR: timedelta(hours=4), + CandleInterval.CANDLE_INTERVAL_DAY: timedelta(days=1), + CandleInterval.CANDLE_INTERVAL_WEEK: timedelta(days=7), + CandleInterval.CANDLE_INTERVAL_MONTH: timedelta(days=30), +} + + +def get_intervals( + interval: CandleInterval, from_: datetime, to: datetime +) -> Generator[Tuple[datetime, datetime], None, None]: + max_interval = MAX_INTERVALS[interval] + interval_length = INTERVAL_LENGTHS[interval] + local_from = from_ + while local_from <= to: + yield local_from, min(local_from + max_interval, to) + local_from += max_interval + interval_length + + +def quotation_to_decimal(quotation: Quotation) -> Decimal: + return money_to_decimal(quotation) + + +def decimal_to_quotation(decimal: Decimal) -> Quotation: + fractional = decimal % 1 + return Quotation(units=int(decimal // 1), nano=int(fractional * Decimal("10e8"))) + + +def quotation_to_money(quotation: Quotation, currency: str) -> MoneyValue: + return MoneyValue(units=quotation.units, nano=quotation.nano, currency=currency) + + +def decimal_to_money(decimal: Decimal, currency: str) -> MoneyValue: + quotation = decimal_to_quotation(decimal) + return quotation_to_money(quotation, currency) + + +class MoneyProtocol(Protocol): + units: int + nano: int + + +def money_to_decimal(money: MoneyProtocol) -> Decimal: + fractional = money.nano / Decimal("10e8") + return Decimal(money.units) + fractional + + +# fmt: off +_CANDLE_INTERVAL_TO_SUBSCRIPTION_INTERVAL_MAPPING = { + CandleInterval.CANDLE_INTERVAL_1_MIN: + SubscriptionInterval.SUBSCRIPTION_INTERVAL_ONE_MINUTE, + CandleInterval.CANDLE_INTERVAL_5_MIN: + SubscriptionInterval.SUBSCRIPTION_INTERVAL_FIVE_MINUTES, + CandleInterval.CANDLE_INTERVAL_UNSPECIFIED: + SubscriptionInterval.SUBSCRIPTION_INTERVAL_UNSPECIFIED, +} +# fmt: on + + +def candle_interval_to_subscription_interval( + candle_interval: CandleInterval, +) -> SubscriptionInterval: + return _CANDLE_INTERVAL_TO_SUBSCRIPTION_INTERVAL_MAPPING.get( + candle_interval, SubscriptionInterval.SUBSCRIPTION_INTERVAL_UNSPECIFIED + ) + + +def now() -> datetime: + return datetime.utcnow().replace(tzinfo=timezone.utc) + + +_CANDLE_INTERVAL_TO_TIMEDELTA_MAPPING = { + CandleInterval.CANDLE_INTERVAL_5_SEC: timedelta(seconds=5), + CandleInterval.CANDLE_INTERVAL_10_SEC: timedelta(seconds=10), + CandleInterval.CANDLE_INTERVAL_30_SEC: timedelta(seconds=30), + CandleInterval.CANDLE_INTERVAL_1_MIN: timedelta(minutes=1), + CandleInterval.CANDLE_INTERVAL_2_MIN: timedelta(minutes=2), + CandleInterval.CANDLE_INTERVAL_3_MIN: timedelta(minutes=3), + CandleInterval.CANDLE_INTERVAL_5_MIN: timedelta(minutes=5), + CandleInterval.CANDLE_INTERVAL_10_MIN: timedelta(minutes=10), + CandleInterval.CANDLE_INTERVAL_15_MIN: timedelta(minutes=15), + CandleInterval.CANDLE_INTERVAL_30_MIN: timedelta(minutes=30), + CandleInterval.CANDLE_INTERVAL_HOUR: timedelta(hours=1), + CandleInterval.CANDLE_INTERVAL_2_HOUR: timedelta(hours=2), + CandleInterval.CANDLE_INTERVAL_4_HOUR: timedelta(hours=4), + CandleInterval.CANDLE_INTERVAL_DAY: timedelta(days=1), + CandleInterval.CANDLE_INTERVAL_WEEK: timedelta(weeks=1), + CandleInterval.CANDLE_INTERVAL_MONTH: timedelta(days=30), + CandleInterval.CANDLE_INTERVAL_UNSPECIFIED: timedelta(minutes=1), +} + + +def candle_interval_to_timedelta(candle_interval: CandleInterval) -> timedelta: + if delta := _CANDLE_INTERVAL_TO_TIMEDELTA_MAPPING.get(candle_interval): + return delta + raise ValueError(f"Cannot convert {candle_interval} to timedelta") + + +_DATETIME_MIN = datetime.min.replace(tzinfo=timezone.utc) + + +def ceil_datetime(datetime_: datetime, delta: timedelta): + return datetime_ + (_DATETIME_MIN - datetime_) % delta + + +def floor_datetime(datetime_: datetime, delta: timedelta): + return datetime_ - (datetime_ - _DATETIME_MIN) % delta + + +def dataclass_from_dict(klass, d): + if issubclass(int, klass): + return int(d) + if issubclass(bool, klass): + return bool(d) + if issubclass(klass, datetime): + return dateutil.parser.parse(d).replace(tzinfo=timezone.utc) + if issubclass(klass, Quotation): + d = ast.literal_eval(d) + if issubclass(klass, Enum): + return klass(int(d)) + + fieldtypes = {f.name: f.type for f in dataclasses.fields(klass)} + return klass(**{f: dataclass_from_dict(fieldtypes[f], d[f]) for f in d}) + + +_datetime_range_replace_floor_by_interval = { + CandleInterval.CANDLE_INTERVAL_1_MIN: lambda r: r.replace(second=0, microsecond=0), + CandleInterval.CANDLE_INTERVAL_2_MIN: lambda r: r.replace(second=0, microsecond=0), + CandleInterval.CANDLE_INTERVAL_3_MIN: lambda r: r.replace(second=0, microsecond=0), + CandleInterval.CANDLE_INTERVAL_5_MIN: lambda r: r.replace(second=0, microsecond=0), + CandleInterval.CANDLE_INTERVAL_10_MIN: lambda r: r.replace(second=0, microsecond=0), + CandleInterval.CANDLE_INTERVAL_15_MIN: lambda r: r.replace(second=0, microsecond=0), + CandleInterval.CANDLE_INTERVAL_30_MIN: lambda r: r.replace(second=0, microsecond=0), + CandleInterval.CANDLE_INTERVAL_HOUR: lambda r: r.replace( + minute=0, second=0, microsecond=0 + ), + CandleInterval.CANDLE_INTERVAL_2_HOUR: lambda r: r.replace( + minute=0, second=0, microsecond=0 + ), + CandleInterval.CANDLE_INTERVAL_4_HOUR: lambda r: r.replace( + minute=0, second=0, microsecond=0 + ), + CandleInterval.CANDLE_INTERVAL_DAY: lambda r: r.replace( + hour=0, minute=0, second=0, microsecond=0 + ), + CandleInterval.CANDLE_INTERVAL_WEEK: lambda r: r.replace( + hour=0, minute=0, second=0, microsecond=0 + ), + CandleInterval.CANDLE_INTERVAL_MONTH: lambda r: r.replace( + hour=0, minute=0, second=0, microsecond=0 + ), +} + + +def round_datetime_range( + date_range: Tuple[datetime, datetime], + interval: CandleInterval, +) -> Tuple[datetime, datetime]: + """Expand datetime range to nearest round range. + + interval = CandleInterval.CANDLE_INTERVAL_DAY, + date_range = [ + 2023-09-11 21:39:04.988646+00:00 + 2023-09-14 21:39:04.988660+00:00 + ]. + + Returns + ------- + [ + 2023-09-11 00:00:00+00:00 + 2023-09-15 00:00:00+00:00 + ]. + + """ + floor = _datetime_range_replace_floor_by_interval[interval] + start, end = date_range + start = floor(start) + interval_delta = candle_interval_to_timedelta(interval) + end = floor(end + interval_delta) + return start, end + + +def filter_distinct_candles(candles: List[HistoricCandle]) -> List[HistoricCandle]: + filtered = [] + for candle1, candle2 in zip(candles, candles[1:]): + if candle2.time - candle1.time > timedelta(): + filtered.append(candle1) + filtered.extend(candles[-1:]) + return filtered + + +def with_filtering_distinct_candles(f: Callable[[Any], Iterable[HistoricCandle]]): + def _(*args: Any, **kwargs: Any) -> Iterable[HistoricCandle]: + yield from filter_distinct_candles(list(f(*args, **kwargs))) + + return _ + + +def empty_or_uuid(s: str) -> bool: + return ( + s == "" + or re.fullmatch( + r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$", s + ) + is not None + ) diff --git a/invest-python-master/tests/__init__.py b/invest-python-master/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/invest-python-master/tests/caches/__init__.py b/invest-python-master/tests/caches/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/invest-python-master/tests/caches/test_instrument_cache.py b/invest-python-master/tests/caches/test_instrument_cache.py new file mode 100644 index 0000000..e0c82c4 --- /dev/null +++ b/invest-python-master/tests/caches/test_instrument_cache.py @@ -0,0 +1,275 @@ +import random +import uuid +from datetime import timedelta +from typing import Any, Callable, Dict, Iterator, Type +from unittest.mock import Mock + +import pytest +from pytest_freezegun import freeze_time + +from t_tech.invest import ( + Bond, + BondResponse, + BondsResponse, + Client, + CurrenciesResponse, + Currency, + CurrencyResponse, + Etf, + EtfResponse, + EtfsResponse, + Future, + FutureResponse, + FuturesResponse, + InstrumentIdType, + Share, + ShareResponse, + SharesResponse, +) +from t_tech.invest.caching.instruments_cache.instruments_cache import InstrumentsCache +from t_tech.invest.caching.instruments_cache.models import InstrumentsResponse +from t_tech.invest.caching.instruments_cache.settings import InstrumentsCacheSettings +from t_tech.invest.services import Services + + +def uid() -> str: + return uuid.uuid4().hex + + +@pytest.fixture() +def token() -> str: + return uid() + + +@pytest.fixture() +def real_services(token: str) -> Iterator[Services]: + with Client(token) as services: + yield services + + +def gen_meta_ids() -> Dict[str, str]: + return {"class_code": uid(), "figi": uid(), "ticker": uid(), "uid": uid()} + + +def gen_instruments(type_: Type, instrument_count: int = 10): + return [ + type_(name=f"{type_.__name__}_{i}", **gen_meta_ids()) + for i in range(instrument_count) + ] + + +def gen_instruments_response( + response_type: Type, type_: Type, instrument_count: int = 10 +): + return response_type(instruments=gen_instruments(type_, instrument_count)) + + +@pytest.fixture() +def instrument_map(): + return { + Etf: gen_instruments_response(EtfsResponse, Etf), + Share: gen_instruments_response(SharesResponse, Share), + Bond: gen_instruments_response(BondsResponse, Bond), + Currency: gen_instruments_response(CurrenciesResponse, Currency), + Future: gen_instruments_response(FuturesResponse, Future), + } + + +def mock_get_by(instrument_response: InstrumentsResponse, response_type): + type_to_field_extractor = { + InstrumentIdType.INSTRUMENT_ID_UNSPECIFIED: lambda i: i.figi, + InstrumentIdType.INSTRUMENT_ID_TYPE_FIGI: lambda i: i.figi, + InstrumentIdType.INSTRUMENT_ID_TYPE_TICKER: lambda i: i.ticker, + InstrumentIdType.INSTRUMENT_ID_TYPE_UID: lambda i: i.uid, + } + + def _mock_get_by( + *, + id_type: InstrumentIdType = InstrumentIdType(0), + class_code: str = "", + id: str = "", + ): + get_id = type_to_field_extractor[id_type] + + def filter_(instrument): + return get_id(instrument) == id and instrument.class_code == class_code + + (found_instrument,) = filter(filter_, instrument_response.instruments) + return response_type(instrument=found_instrument) + + return Mock(wraps=_mock_get_by) + + +@pytest.fixture() +def mock_instruments_service( + real_services: Services, + mocker, + instrument_map, +) -> Services: + real_services.instruments = mocker.Mock( + wraps=real_services.instruments, + ) + + real_services.instruments.etfs.__name__ = "etfs" + real_services.instruments.etfs.return_value = instrument_map[Etf] + real_services.instruments.etf_by = mock_get_by(instrument_map[Etf], EtfResponse) + + real_services.instruments.shares.__name__ = "shares" + real_services.instruments.shares.return_value = instrument_map[Share] + real_services.instruments.share_by = mock_get_by( + instrument_map[Share], ShareResponse + ) + + real_services.instruments.bonds.__name__ = "bonds" + real_services.instruments.bonds.return_value = instrument_map[Bond] + real_services.instruments.bond_by = mock_get_by(instrument_map[Bond], BondResponse) + + real_services.instruments.currencies.__name__ = "currencies" + real_services.instruments.currencies.return_value = instrument_map[Currency] + real_services.instruments.currency_by = mock_get_by( + instrument_map[Currency], CurrencyResponse + ) + + real_services.instruments.futures.__name__ = "futures" + real_services.instruments.futures.return_value = instrument_map[Future] + real_services.instruments.future_by = mock_get_by( + instrument_map[Future], FutureResponse + ) + + return real_services + + +@pytest.fixture() +def mocked_services( + real_services: Services, + mock_instruments_service, +) -> Services: + return real_services + + +@pytest.fixture() +def settings() -> InstrumentsCacheSettings: + return InstrumentsCacheSettings() + + +@pytest.fixture() +def frozen_datetime(): + with freeze_time() as frozen_datetime: + yield frozen_datetime + + +@pytest.fixture() +def instruments_cache( + settings: InstrumentsCacheSettings, mocked_services, frozen_datetime +) -> InstrumentsCache: + return InstrumentsCache( + settings=settings, instruments_service=mocked_services.instruments + ) + + +@pytest.mark.parametrize( + ("get_instruments_of_type", "get_instrument_of_type_by"), + [ + ( + lambda instruments: instruments.etfs, + lambda instruments: instruments.etf_by, + ), + ( + lambda instruments: instruments.shares, + lambda instruments: instruments.share_by, + ), + ( + lambda instruments: instruments.bonds, + lambda instruments: instruments.bond_by, + ), + ( + lambda instruments: instruments.currencies, + lambda instruments: instruments.currency_by, + ), + ( + lambda instruments: instruments.futures, + lambda instruments: instruments.future_by, + ), + ], +) +@pytest.mark.parametrize( + ("id_type", "get_id"), + [ + ( + InstrumentIdType.INSTRUMENT_ID_UNSPECIFIED, + lambda instrument: instrument.figi, + ), + ( + InstrumentIdType.INSTRUMENT_ID_TYPE_FIGI, + lambda instrument: instrument.figi, + ), + ( + InstrumentIdType.INSTRUMENT_ID_TYPE_TICKER, + lambda instrument: instrument.ticker, + ), + ( + InstrumentIdType.INSTRUMENT_ID_TYPE_UID, + lambda instrument: instrument.uid, + ), + ], +) +class TestInstrumentCache: + def test_gets_from_net_then_cache( + self, + mocked_services: Services, + settings: InstrumentsCacheSettings, + instruments_cache: InstrumentsCache, + get_instruments_of_type, + get_instrument_of_type_by, + id_type: InstrumentIdType, + get_id: Callable[[Any], str], + ): + get_instruments = get_instruments_of_type(mocked_services.instruments) + get_instrument_by = get_instrument_of_type_by(mocked_services.instruments) + get_instrument_by_cached = get_instrument_of_type_by(instruments_cache) + (inst,) = random.sample(get_instruments().instruments, k=1) + from_server = get_instrument_by( + id_type=id_type, + class_code=inst.class_code, + id=get_id(inst), + ) + get_instrument_by.assert_called_once() + get_instrument_by.reset_mock() + + from_cache = get_instrument_by_cached( + id_type=id_type, + class_code=inst.class_code, + id=get_id(inst), + ) + + get_instrument_by.assert_not_called() + assert str(from_server) == str(from_cache) + + @pytest.mark.parametrize( + "settings", [InstrumentsCacheSettings(ttl=timedelta(milliseconds=10))] + ) + def test_refreshes_on_ttl( + self, + mocked_services: Services, + settings: InstrumentsCacheSettings, + instruments_cache: InstrumentsCache, + get_instruments_of_type, + get_instrument_of_type_by, + id_type: InstrumentIdType, + get_id: Callable[[Any], str], + frozen_datetime, + ): + get_instruments = get_instruments_of_type(mocked_services.instruments) + get_instrument_by_cached = get_instrument_of_type_by(instruments_cache) + get_instruments.assert_called_once() + (inst,) = random.sample(get_instruments().instruments, k=1) + get_instruments.reset_mock() + frozen_datetime.tick(timedelta(seconds=10)) + + _ = get_instrument_by_cached( + id_type=id_type, + class_code=inst.class_code, + id=get_id(inst), + ) + + get_instruments.assert_called_once() diff --git a/invest-python-master/tests/caches/test_ttl_cache.py b/invest-python-master/tests/caches/test_ttl_cache.py new file mode 100644 index 0000000..78992b3 --- /dev/null +++ b/invest-python-master/tests/caches/test_ttl_cache.py @@ -0,0 +1,26 @@ +from datetime import timedelta + +from cachetools import TTLCache as StandardTTLCache +from pytest_freezegun import freeze_time + +from t_tech.invest.caching.overrides import TTLCache as OverridenTTLCache + + +class TestTTLCache: + def _assert_ttl_cache(self, ttl_cache_class, expires): + with freeze_time() as frozen_datetime: + ttl = ttl_cache_class( + maxsize=10, + ttl=1, + ) + ttl.update({"1": 1}) + + assert ttl.keys() + frozen_datetime.tick(timedelta(seconds=10000)) + assert not ttl.keys() == expires + + def test_overriden_cache(self): + self._assert_ttl_cache(OverridenTTLCache, expires=True) + + def test_standard_cache(self): + self._assert_ttl_cache(StandardTTLCache, expires=False) diff --git a/invest-python-master/tests/data_loaders/__init__.py b/invest-python-master/tests/data_loaders/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/invest-python-master/tests/data_loaders/test_cached_load.py b/invest-python-master/tests/data_loaders/test_cached_load.py new file mode 100644 index 0000000..ee504fa --- /dev/null +++ b/invest-python-master/tests/data_loaders/test_cached_load.py @@ -0,0 +1,557 @@ +import logging +import tempfile +import uuid +from datetime import datetime, timedelta +from pathlib import Path +from typing import List, Optional, Tuple + +import pytest + +from t_tech.invest import ( + CandleInterval, + Client, + GetCandlesResponse, + HistoricCandle, + Quotation, +) +from t_tech.invest.caching.market_data_cache.cache import MarketDataCache +from t_tech.invest.caching.market_data_cache.cache_settings import ( + FileMetaData, + MarketDataCacheSettings, + meta_file_context, +) +from t_tech.invest.caching.market_data_cache.instrument_market_data_storage import ( + InstrumentMarketDataStorage, +) +from t_tech.invest.schemas import CandleSource +from t_tech.invest.services import MarketDataService +from t_tech.invest.utils import ( + candle_interval_to_timedelta, + ceil_datetime, + floor_datetime, + now, +) + +logging.basicConfig(format="%(asctime)s %(levelname)s:%(message)s", level=logging.DEBUG) +logger = logging.getLogger(__name__) + + +def get_historical_candle( + time: datetime, + is_complete: bool = True, + candle_source: Optional[CandleSource] = None, +): + quotation = Quotation(units=100, nano=0) + if candle_source is None: + candle_source = CandleSource.CANDLE_SOURCE_EXCHANGE + return HistoricCandle( + open=quotation, + high=quotation, + low=quotation, + close=quotation, + volume=100, + time=time, + is_complete=is_complete, + candle_source=candle_source, + volume_buy=45, + volume_sell=55, + ) + + +def get_candles_response( + start: datetime, + end: datetime, + interval: CandleInterval, + candle_source_type: Optional[CandleSource] = None, +): + delta = candle_interval_to_timedelta(interval) + start_ceil = ceil_datetime(start.replace(second=0, microsecond=0), delta) + current_time = start_ceil + candles = [] + while current_time <= end: + candles.append( + get_historical_candle(current_time, candle_source=candle_source_type) + ) + current_time += delta + current_time.replace(second=0, microsecond=0) + + if floor_datetime(end, delta) < end < ceil_datetime(end, delta): + candles.append(get_historical_candle(end, is_complete=False)) + + return GetCandlesResponse(candles=candles) + + +@pytest.fixture() +def market_data_service(mocker) -> MarketDataService: + service = mocker.Mock(spec=MarketDataService) + + def _get_candles( + figi: str, + from_: datetime, + to: datetime, + interval: CandleInterval = CandleInterval(0), + instrument_id: str = "", + candle_source_type: Optional[CandleSource] = None, + ) -> GetCandlesResponse: + return get_candles_response( + start=from_, + end=to, + interval=interval, + candle_source_type=candle_source_type, + ) + + service.get_candles = _get_candles + service.get_candles = mocker.Mock(wraps=service.get_candles) + return service + + +@pytest.fixture() +def client(mocker, market_data_service): + with Client(mocker.Mock()) as client: + client.market_data = market_data_service + yield client + + +@pytest.fixture() +def settings() -> MarketDataCacheSettings: + return MarketDataCacheSettings(base_cache_dir=Path(tempfile.gettempdir())) + + +@pytest.fixture() +def market_data_cache(settings: MarketDataCacheSettings, client) -> MarketDataCache: + return MarketDataCache(settings=settings, services=client) + + +@pytest.fixture() +def log(caplog): # noqa: PT004 + caplog.set_level(logging.DEBUG) + + +@pytest.fixture() +def figi(): + return uuid.uuid4().hex + + +class TestCachedLoad: + def test_loads_from_net(self, market_data_cache: MarketDataCache, figi: str): + result = list( + market_data_cache.get_all_candles( + figi=figi, + from_=now() - timedelta(days=30), + interval=CandleInterval.CANDLE_INTERVAL_HOUR, + ) + ) + + assert result + + def test_loads_from_net_then_from_cache( + self, + market_data_service: MarketDataService, + market_data_cache: MarketDataCache, + log, + figi: str, + ): + interval = CandleInterval.CANDLE_INTERVAL_HOUR + from_, to = self._get_date_point_by_index(0, 3, interval=interval) + from_net = list( + market_data_cache.get_all_candles( + figi=figi, + from_=from_, + to=to, + interval=interval, + ) + ) + self.assert_in_range(from_net, start=from_, end=to, interval=interval) + market_data_service.get_candles.reset_mock() + + from_cache = list( + market_data_cache.get_all_candles( + figi=figi, + from_=from_, + to=to, + interval=interval, + ) + ) + market_data_service.get_candles.assert_not_called() + self.assert_in_range(from_cache, start=from_, end=to, interval=interval) + assert len(from_net) == len(from_cache) + for cached_candle, net_candle in zip(from_cache, from_net): + assert cached_candle.__repr__() == net_candle.__repr__() + + def test_loads_from_cache_and_left_from_net( + self, + market_data_service: MarketDataService, + market_data_cache: MarketDataCache, + figi: str, + ): + interval = CandleInterval.CANDLE_INTERVAL_DAY + from_, to = self._get_date_point_by_index(0, 30, interval=interval) + from_net = list( + market_data_cache.get_all_candles( + figi=figi, + from_=from_, + to=to, + interval=interval, + ) + ) + self.assert_in_range(from_net, start=from_, end=to, interval=interval) + from_cache = list( + market_data_cache.get_all_candles( + figi=figi, + from_=from_, + to=to, + interval=interval, + ) + ) + self.assert_in_range(from_cache, start=from_, end=to, interval=interval) + market_data_service.get_candles.reset_mock() + from_early_uncached = from_ - timedelta(days=7) + + cache_and_net = list( + market_data_cache.get_all_candles( + figi=figi, + from_=from_early_uncached, + to=to, + interval=interval, + ) + ) + + assert len(market_data_service.get_candles.mock_calls) > 0 + self.assert_in_range( + cache_and_net, start=from_early_uncached, end=to, interval=interval + ) + + def assert_distinct_candles( + self, candles: List[HistoricCandle], interval_delta: timedelta + ): + for candle1, candle2 in zip(candles[:-1], candles[1:-1]): + diff_delta = candle2.time - candle1.time + assert timedelta() < diff_delta <= interval_delta + + def assert_in_range(self, result_candles, start, end, interval): + delta = candle_interval_to_timedelta(interval) + assert result_candles[0].time == ceil_datetime( + start, delta + ), "start time assertion error" + assert result_candles[-1].time == end, "end time assertion error" + for candle in result_candles: + assert start <= candle.time <= end + + self.assert_distinct_candles(result_candles, delta) + + def test_loads_from_cache_and_right_from_net( + self, + market_data_service: MarketDataService, + market_data_cache: MarketDataCache, + figi: str, + ): + to = now().replace(second=0, microsecond=0) + from_ = to - timedelta(days=30) + interval = CandleInterval.CANDLE_INTERVAL_DAY + from_net = list( + market_data_cache.get_all_candles( + figi=figi, + from_=from_, + to=to, + interval=interval, + ) + ) + self.assert_in_range(from_net, start=from_, end=to, interval=interval) + market_data_service.get_candles.reset_mock() + to_later_uncached = to + timedelta(days=7) + + cache_and_net = list( + market_data_cache.get_all_candles( + figi=figi, + from_=from_, + to=to_later_uncached, + interval=interval, + ) + ) + + assert len(market_data_service.get_candles.mock_calls) > 0 + self.assert_in_range( + cache_and_net, start=from_, end=to_later_uncached, interval=interval + ) + + def assert_has_cached_ranges(self, cache_storage, ranges): + meta_file = cache_storage._get_metafile(cache_storage._meta_path) + with meta_file_context(meta_file) as meta: + meta: FileMetaData = meta + assert len(meta.cached_range_in_file) == len(ranges) + assert set(meta.cached_range_in_file.keys()) == set(ranges) + + def assert_file_count(self, cache_storage, count): + cached_ls = list(cache_storage._meta_path.parent.glob("*")) + assert len(cached_ls) == count + + def test_loads_cache_miss( + self, + market_data_service: MarketDataService, + market_data_cache: MarketDataCache, + settings: MarketDataCacheSettings, + figi: str, + ): + interval = CandleInterval.CANDLE_INTERVAL_DAY + # [A request B] + # [A cached B] [C request D] + A, B, C, D = self._get_date_point_by_index(0, 3, 6, 9) + self.get_by_range_and_assert_has_cache( + range=(A, B), + has_from_net=True, + figi=figi, + interval=interval, + market_data_cache=market_data_cache, + market_data_service=market_data_service, + ) + self.get_by_range_and_assert_has_cache( + range=(C, D), + has_from_net=True, + figi=figi, + interval=interval, + market_data_cache=market_data_cache, + market_data_service=market_data_service, + ) + + cache_storage = InstrumentMarketDataStorage( + figi=figi, interval=interval, settings=settings + ) + self.assert_has_cached_ranges(cache_storage, [(A, B), (C, D)]) + self.assert_file_count(cache_storage, 3) + + def _get_date_point_by_index( + self, *idx, interval=CandleInterval.CANDLE_INTERVAL_DAY + ): + delta = candle_interval_to_timedelta(interval) + x0 = ceil_datetime(now(), delta).replace(second=0, microsecond=0) + + result = [] + for id_ in idx: + result.append(x0 + id_ * delta) + return result + + def test_loads_cache_merge_out( + self, + market_data_service: MarketDataService, + market_data_cache: MarketDataCache, + settings: MarketDataCacheSettings, + log, + figi: str, + ): + interval = CandleInterval.CANDLE_INTERVAL_DAY + # [A request B] + # [A cached B] [C request D] + # [A cached B] [C cached D] + # [E request F] + # [E cached F] + E, A, B, C, D, F = self._get_date_point_by_index(0, 1, 3, 4, 6, 7) + self.get_by_range_and_assert_has_cache( + range=(A, B), + has_from_net=True, + figi=figi, + interval=interval, + market_data_cache=market_data_cache, + market_data_service=market_data_service, + ) + self.get_by_range_and_assert_has_cache( + range=(C, D), + has_from_net=True, + figi=figi, + interval=interval, + market_data_cache=market_data_cache, + market_data_service=market_data_service, + ) + self.get_by_range_and_assert_has_cache( + range=(E, F), + has_from_net=True, + figi=figi, + interval=interval, + market_data_cache=market_data_cache, + market_data_service=market_data_service, + ) + + cache_storage = InstrumentMarketDataStorage( + figi=figi, interval=interval, settings=settings + ) + self.assert_has_cached_ranges(cache_storage, [(E, F)]) + self.assert_file_count(cache_storage, 2) + + def get_by_range_and_assert_has_cache( + self, + range: Tuple[datetime, datetime], + has_from_net: bool, + figi: str, + interval: CandleInterval, + market_data_cache: MarketDataCache, + market_data_service: MarketDataService, + ): + start, end = range + result = list( + market_data_cache.get_all_candles( + figi=figi, + from_=start, + to=end, + interval=interval, + ) + ) + self.assert_in_range(result, start=start, end=end, interval=interval) + if has_from_net: + assert ( + len(market_data_service.get_candles.mock_calls) > 0 + ), "Net was not used" + else: + assert len(market_data_service.get_candles.mock_calls) == 0, "Net was used" + market_data_service.get_candles.reset_mock() + + def get_by_range_and_assert_ranges( + self, + request_range: Tuple[datetime, datetime], + from_cache_ranges: List[Tuple[datetime, datetime]], + from_net_ranges: List[Tuple[datetime, datetime]], + figi: str, + interval: CandleInterval, + market_data_cache: MarketDataCache, + market_data_service: MarketDataService, + ): + start, end = request_range + result = list( + market_data_cache.get_all_candles( + figi=figi, + from_=start, + to=end, + interval=interval, + ) + ) + net_calls = market_data_service.get_candles.mock_calls + assert len(net_calls) == len(from_net_ranges) + for actual_net_call, expected_net_range in zip(net_calls, from_net_ranges): + kwargs = actual_net_call.kwargs + actual_net_range = kwargs["from_"], kwargs["to"] + assert actual_net_range == expected_net_range + + self.assert_in_range(result, start, end, interval) + + market_data_service.get_candles.reset_mock() + + def test_loads_cache_merge_out_right( + self, + market_data_service: MarketDataService, + market_data_cache: MarketDataCache, + settings: MarketDataCacheSettings, + log, + figi: str, + ): + interval = CandleInterval.CANDLE_INTERVAL_DAY + # [A request B] + # [A cached B] [C request D] + # [A cached B] [C cached D] + # [E request F] + # [A cached F] + A, E, B, C, D, F = self._get_date_point_by_index(0, 1, 3, 4, 6, 7) + self.get_by_range_and_assert_has_cache( + range=(A, B), + has_from_net=True, + figi=figi, + interval=interval, + market_data_cache=market_data_cache, + market_data_service=market_data_service, + ) + self.get_by_range_and_assert_has_cache( + range=(C, D), + has_from_net=True, + figi=figi, + interval=interval, + market_data_cache=market_data_cache, + market_data_service=market_data_service, + ) + self.get_by_range_and_assert_has_cache( + range=(E, F), + has_from_net=True, + figi=figi, + interval=interval, + market_data_cache=market_data_cache, + market_data_service=market_data_service, + ) + + cache_storage = InstrumentMarketDataStorage( + figi=figi, interval=interval, settings=settings + ) + self.assert_has_cached_ranges(cache_storage, [(A, F)]) + self.assert_file_count(cache_storage, 2) + + def test_loads_cache_merge_in_right( + self, + market_data_service: MarketDataService, + market_data_cache: MarketDataCache, + settings: MarketDataCacheSettings, + log, + figi: str, + ): + interval = CandleInterval.CANDLE_INTERVAL_DAY + # [A request B] + # [A cached B] [C request D] + # [A cached B] [C cached D] + # [E request F] + # [A cached B] [C cached F] + A, B, C, E, D, F = self._get_date_point_by_index(0, 1, 3, 4, 6, 7) + self.get_by_range_and_assert_has_cache( + range=(A, B), + has_from_net=True, + figi=figi, + interval=interval, + market_data_cache=market_data_cache, + market_data_service=market_data_service, + ) + self.get_by_range_and_assert_has_cache( + range=(C, D), + has_from_net=True, + figi=figi, + interval=interval, + market_data_cache=market_data_cache, + market_data_service=market_data_service, + ) + self.get_by_range_and_assert_has_cache( + range=(E, F), + has_from_net=True, + figi=figi, + interval=interval, + market_data_cache=market_data_cache, + market_data_service=market_data_service, + ) + + cache_storage = InstrumentMarketDataStorage( + figi=figi, interval=interval, settings=settings + ) + self.assert_has_cached_ranges(cache_storage, [(A, B), (C, F)]) + self.assert_file_count(cache_storage, 3) + + def test_creates_files_with_correct_extensions( + self, + market_data_service: MarketDataService, + market_data_cache: MarketDataCache, + settings: MarketDataCacheSettings, + log, + figi: str, + ): + interval = CandleInterval.CANDLE_INTERVAL_HOUR + + list( + market_data_cache.get_all_candles( + figi=figi, + from_=now() - timedelta(days=30), + interval=interval, + ) + ) + + cache_storage = InstrumentMarketDataStorage( + figi=figi, interval=interval, settings=settings + ) + cached_ls = list(cache_storage._meta_path.parent.glob("*")) + assert len(cached_ls) == 2 + assert any( + str(file).endswith(f".{settings.format_extension.value}") + for file in cached_ls + ) + assert any( + str(file).endswith(f".{settings.meta_extension}") for file in cached_ls + ) diff --git a/invest-python-master/tests/data_loaders/test_get_all_candles.py b/invest-python-master/tests/data_loaders/test_get_all_candles.py new file mode 100644 index 0000000..5f81780 --- /dev/null +++ b/invest-python-master/tests/data_loaders/test_get_all_candles.py @@ -0,0 +1,153 @@ +# pylint:disable=redefined-outer-name +# pylint:disable=too-many-arguments +from copy import copy +from datetime import timedelta + +import pytest + +from t_tech.invest.schemas import ( + CandleInterval, + GetCandlesResponse, + HistoricCandle, + Quotation, +) +from t_tech.invest.services import MarketDataService, Services +from t_tech.invest.utils import now + + +@pytest.fixture() +def figi(): + return "figi" + + +@pytest.fixture() +def from_(): + return now() - timedelta(days=31) + + +@pytest.fixture() +def to(): + return now() + + +@pytest.fixture() +def historical_candle(): + quotation = Quotation(units=100, nano=0) + return HistoricCandle( + open=quotation, + high=quotation, + low=quotation, + close=quotation, + volume=100, + time=now(), + is_complete=False, + ) + + +@pytest.fixture() +def candles_response(historical_candle): + return GetCandlesResponse(candles=[historical_candle]) + + +@pytest.fixture() +def market_data_service(mocker): + return mocker.Mock(spec=MarketDataService) + + +class TestGetAllCandles: + @pytest.mark.parametrize( + ("interval", "call_count"), + [ + (CandleInterval.CANDLE_INTERVAL_5_SEC, 224), + (CandleInterval.CANDLE_INTERVAL_10_SEC, 224), + (CandleInterval.CANDLE_INTERVAL_30_SEC, 38), + (CandleInterval.CANDLE_INTERVAL_1_MIN, 31), + (CandleInterval.CANDLE_INTERVAL_2_MIN, 31), + (CandleInterval.CANDLE_INTERVAL_3_MIN, 31), + (CandleInterval.CANDLE_INTERVAL_5_MIN, 31), + (CandleInterval.CANDLE_INTERVAL_10_MIN, 31), + (CandleInterval.CANDLE_INTERVAL_15_MIN, 31), + (CandleInterval.CANDLE_INTERVAL_HOUR, 5), + (CandleInterval.CANDLE_INTERVAL_2_HOUR, 5), + (CandleInterval.CANDLE_INTERVAL_4_HOUR, 5), + (CandleInterval.CANDLE_INTERVAL_DAY, 1), + (CandleInterval.CANDLE_INTERVAL_WEEK, 1), + (CandleInterval.CANDLE_INTERVAL_MONTH, 1), + ], + ) + @pytest.mark.parametrize("use_to", [True, False]) + @pytest.mark.freeze_time("2023-10-21") + def test_get_all_candles( + self, + figi, + mocker, + market_data_service, + from_, + to, + candles_response, + interval, + call_count, + use_to, + ): + services = mocker.Mock() + services.market_data = market_data_service + market_data_service.get_candles.return_value = candles_response + + to_kwarg = {} + if use_to: + to_kwarg = {"to": to} + result = list( + Services.get_all_candles( + services, + figi=figi, + interval=interval, + from_=from_, + **to_kwarg, + ) + ) + + assert result == candles_response.candles + assert market_data_service.get_candles.call_count == call_count + + @pytest.mark.parametrize( + "interval", + [ + *[ + interval + for interval in CandleInterval + if interval != CandleInterval.CANDLE_INTERVAL_UNSPECIFIED + ], + ], + ) + def test_deduplicates( + self, + figi, + mocker, + market_data_service, + from_, + to, + candles_response, + interval, + historical_candle, + ): + services = mocker.Mock() + services.market_data = market_data_service + + def _get_duplicated_candle_response(*args, **kwargs): + return GetCandlesResponse( + candles=[copy(historical_candle) for _ in range(3)] + ) + + market_data_service.get_candles = _get_duplicated_candle_response + + candles = list( + Services.get_all_candles( + services, + figi=figi, + interval=interval, + from_=from_, + to=to, + ) + ) + + assert len(candles) == 1 diff --git a/invest-python-master/tests/data_loaders/test_round_datetime_range.py b/invest-python-master/tests/data_loaders/test_round_datetime_range.py new file mode 100644 index 0000000..007d64a --- /dev/null +++ b/invest-python-master/tests/data_loaders/test_round_datetime_range.py @@ -0,0 +1,120 @@ +from datetime import datetime +from typing import Tuple + +import pytest + +from t_tech.invest import CandleInterval +from t_tech.invest.utils import round_datetime_range + + +@pytest.mark.parametrize( + ("interval", "date_range", "expected_range"), + [ + ( + CandleInterval.CANDLE_INTERVAL_1_MIN, + ( + datetime( + year=2023, month=1, day=1, hour=1, minute=1, second=1, microsecond=1 + ), + datetime( + year=2023, month=1, day=2, hour=1, minute=1, second=1, microsecond=1 + ), + ), + ( + datetime( + year=2023, month=1, day=1, hour=1, minute=1, second=0, microsecond=0 + ), + datetime( + year=2023, month=1, day=2, hour=1, minute=2, second=0, microsecond=0 + ), + ), + ), + ( + CandleInterval.CANDLE_INTERVAL_HOUR, + ( + datetime( + year=2023, month=1, day=1, hour=1, minute=1, second=1, microsecond=1 + ), + datetime( + year=2023, month=1, day=2, hour=1, minute=1, second=1, microsecond=1 + ), + ), + ( + datetime( + year=2023, month=1, day=1, hour=1, minute=0, second=0, microsecond=0 + ), + datetime( + year=2023, month=1, day=2, hour=2, minute=0, second=0, microsecond=0 + ), + ), + ), + ( + CandleInterval.CANDLE_INTERVAL_DAY, + ( + datetime( + year=2023, month=1, day=1, hour=1, minute=1, second=1, microsecond=1 + ), + datetime( + year=2023, month=1, day=2, hour=1, minute=1, second=1, microsecond=1 + ), + ), + ( + datetime( + year=2023, month=1, day=1, hour=0, minute=0, second=0, microsecond=0 + ), + datetime( + year=2023, month=1, day=3, hour=0, minute=0, second=0, microsecond=0 + ), + ), + ), + ( + CandleInterval.CANDLE_INTERVAL_WEEK, + ( + datetime( + year=2023, month=1, day=1, hour=1, minute=1, second=1, microsecond=1 + ), + datetime( + year=2023, month=1, day=2, hour=1, minute=1, second=1, microsecond=1 + ), + ), + ( + datetime( + year=2023, month=1, day=1, hour=0, minute=0, second=0, microsecond=0 + ), + datetime( + year=2023, month=1, day=9, hour=0, minute=0, second=0, microsecond=0 + ), + ), + ), + ( + CandleInterval.CANDLE_INTERVAL_MONTH, + ( + datetime( + year=2023, month=1, day=1, hour=1, minute=1, second=1, microsecond=1 + ), + datetime( + year=2023, month=1, day=2, hour=1, minute=1, second=1, microsecond=1 + ), + ), + ( + datetime( + year=2023, month=1, day=1, hour=0, minute=0, second=0, microsecond=0 + ), + datetime( + year=2023, month=2, day=1, hour=0, minute=0, second=0, microsecond=0 + ), + ), + ), + ], +) +def test_round_datetime_range( + interval: CandleInterval, + date_range: Tuple[datetime, datetime], + expected_range: Tuple[datetime, datetime], +): + actual_range = round_datetime_range( + date_range=date_range, + interval=interval, + ) + + assert actual_range == expected_range diff --git a/invest-python-master/tests/data_loaders/test_sandbox_cached_load.py b/invest-python-master/tests/data_loaders/test_sandbox_cached_load.py new file mode 100644 index 0000000..ad1c5f8 --- /dev/null +++ b/invest-python-master/tests/data_loaders/test_sandbox_cached_load.py @@ -0,0 +1,132 @@ +# pylint: disable=redefined-outer-name,unused-variable +import datetime +import os +import tempfile +from datetime import timedelta +from pathlib import Path +from typing import Dict, Iterable + +import pytest + +from t_tech.invest import CandleInterval +from t_tech.invest.caching.market_data_cache.cache import MarketDataCache +from t_tech.invest.caching.market_data_cache.cache_settings import ( + MarketDataCacheSettings, +) +from t_tech.invest.sandbox.client import SandboxClient +from t_tech.invest.utils import now + + +@pytest.fixture() +def sandbox_service(): + with SandboxClient(token=os.environ["INVEST_SANDBOX_TOKEN"]) as client: + yield client + + +PROGRAMMERS_DAY = datetime.datetime( + 2023, 1, 1, tzinfo=datetime.timezone.utc +) + timedelta(days=255) + + +@pytest.mark.skipif( + os.environ.get("INVEST_SANDBOX_TOKEN") is None, + reason="INVEST_SANDBOX_TOKEN should be specified", +) +@pytest.mark.skip("todo fix") +class TestSandboxCachedLoad: + @pytest.mark.parametrize( + "calls_kwargs", + [ + ({"from_": now() - timedelta(days=8)},), + ( + { + "from_": datetime.datetime( + 2023, 9, 1, 0, 0, tzinfo=datetime.timezone.utc + ), + "to": datetime.datetime( + 2023, 9, 5, 0, 0, tzinfo=datetime.timezone.utc + ), + }, + ), + ( + { + "from_": now() - timedelta(days=6), + }, + { + "from_": now() - timedelta(days=10), + "to": now() - timedelta(days=7), + }, + { + "from_": now() - timedelta(days=11), + "to": now() - timedelta(days=5), + }, + ), + ( + { + "from_": PROGRAMMERS_DAY - timedelta(days=6), + }, + { + "from_": PROGRAMMERS_DAY - timedelta(days=6), + }, + { + "from_": PROGRAMMERS_DAY - timedelta(days=6), + }, + { + "from_": PROGRAMMERS_DAY - timedelta(days=6), + }, + ), + ( + { + "from_": PROGRAMMERS_DAY - timedelta(days=6), + }, + { + "from_": PROGRAMMERS_DAY - timedelta(days=5), + }, + { + "from_": PROGRAMMERS_DAY - timedelta(days=4), + }, + { + "from_": PROGRAMMERS_DAY - timedelta(days=3), + }, + ), + ( + { + "from_": PROGRAMMERS_DAY - timedelta(days=6), + "to": PROGRAMMERS_DAY, + }, + { + "from_": PROGRAMMERS_DAY - timedelta(days=5), + "to": PROGRAMMERS_DAY, + }, + { + "from_": PROGRAMMERS_DAY - timedelta(days=4), + "to": PROGRAMMERS_DAY, + }, + { + "from_": PROGRAMMERS_DAY - timedelta(days=3), + "to": PROGRAMMERS_DAY, + }, + ), + ], + ) + def test_same_from_net_and_cache( + self, sandbox_service, calls_kwargs: Iterable[Dict[str, datetime.datetime]] + ): + settings = MarketDataCacheSettings(base_cache_dir=Path(tempfile.gettempdir())) + market_data_cache = MarketDataCache(settings=settings, services=sandbox_service) + figi = "BBG004730N88" + for date_range_kwargs in calls_kwargs: + call_kwargs = dict( + figi=figi, + interval=CandleInterval.CANDLE_INTERVAL_DAY, + **date_range_kwargs, + ) + + candles_from_cache = list(market_data_cache.get_all_candles(**call_kwargs)) + candles_from_net = list(sandbox_service.get_all_candles(**call_kwargs)) + assert candles_from_cache + assert candles_from_net + assert candles_from_cache == candles_from_net, ( + candles_from_cache, + candles_from_net, + ) diff --git a/invest-python-master/tests/marketdata/__init__.py b/invest-python-master/tests/marketdata/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/invest-python-master/tests/marketdata/test_async_marketdata.py b/invest-python-master/tests/marketdata/test_async_marketdata.py new file mode 100644 index 0000000..25e0420 --- /dev/null +++ b/invest-python-master/tests/marketdata/test_async_marketdata.py @@ -0,0 +1,72 @@ +from datetime import datetime +from unittest.mock import ANY, call + +import pytest +import pytest_asyncio + +from t_tech.invest import CandleInterval, GetCandlesResponse +from t_tech.invest.async_services import AsyncServices, MarketDataService + + +@pytest_asyncio.fixture +async def marketdata_service(mocker) -> MarketDataService: + return mocker.create_autospec(MarketDataService) + + +@pytest_asyncio.fixture +async def async_services( + mocker, marketdata_service: MarketDataService +) -> AsyncServices: + async_services = mocker.create_autospec(AsyncServices) + async_services.market_data = marketdata_service + return async_services + + +class TestAsyncMarketData: + @pytest.mark.asyncio + @pytest.mark.parametrize( + "candle_interval,from_,to,expected", + [ + ( + CandleInterval.CANDLE_INTERVAL_DAY, + datetime(2020, 1, 1), + datetime(2020, 1, 2), + 1, + ), + ( + CandleInterval.CANDLE_INTERVAL_DAY, + datetime(2020, 1, 1), + datetime(2021, 3, 3), + 2, + ), + ], + ) + async def test_get_candles( + self, + async_services: AsyncServices, + marketdata_service: MarketDataService, + candle_interval: CandleInterval, + from_: datetime, + to: datetime, + expected: int, + ): + marketdata_service.get_candles.return_value = GetCandlesResponse(candles=[]) + [ + candle + async for candle in AsyncServices.get_all_candles( + async_services, interval=candle_interval, from_=from_, to=to + ) + ] + marketdata_service.get_candles.assert_has_calls( + [ + call( + from_=ANY, + to=ANY, + interval=candle_interval, + candle_source_type=None, + figi="", + instrument_id="", + ) + for _ in range(expected) + ] + ) diff --git a/invest-python-master/tests/test_datetime_utils.py b/invest-python-master/tests/test_datetime_utils.py new file mode 100644 index 0000000..bab3227 --- /dev/null +++ b/invest-python-master/tests/test_datetime_utils.py @@ -0,0 +1,25 @@ +from datetime import timedelta + +import pytest + +from t_tech.invest import CandleInterval +from t_tech.invest.utils import ( + candle_interval_to_timedelta, + ceil_datetime, + floor_datetime, + now, +) + + +@pytest.fixture(params=[i.value for i in CandleInterval]) +def interval(request) -> timedelta: + return candle_interval_to_timedelta(request.param) + + +def test_floor_ceil(interval: timedelta): + now_ = now() + + a, b = floor_datetime(now_, interval), ceil_datetime(now_, interval) + + assert a < b + assert b - a == interval diff --git a/invest-python-master/tests/test_instruments.py b/invest-python-master/tests/test_instruments.py new file mode 100644 index 0000000..b913b58 --- /dev/null +++ b/invest-python-master/tests/test_instruments.py @@ -0,0 +1,221 @@ +# pylint: disable=redefined-outer-name,unused-variable +import os +from unittest import mock + +import pytest + +from t_tech.invest import ( + Client, + InstrumentIdType, + InstrumentRequest, + InstrumentsRequest, + InstrumentStatus, +) +from t_tech.invest.schemas import StructuredNote +from t_tech.invest.services import InstrumentsService + + +@pytest.fixture() +def instruments_service(): + return mock.MagicMock(spec=InstrumentsService) + + +@pytest.fixture() +def instruments_client_service(): + with Client(token=os.environ["INVEST_SANDBOX_TOKEN"]) as client: + yield client.instruments + + +def test_trading_schedules(instruments_service): + responce = instruments_service.trading_schedules( # noqa: F841 + exchange=mock.Mock(), + from_=mock.Mock(), + to=mock.Mock(), + ) + instruments_service.trading_schedules.assert_called_once() + + +def test_bond_by(instruments_service): + responce = instruments_service.bond_by( # noqa: F841 + id_type=mock.Mock(), + class_code=mock.Mock(), + id=mock.Mock(), + ) + instruments_service.bond_by.assert_called_once() + + +def test_bonds(instruments_service): + responce = instruments_service.bonds( # noqa: F841 + instrument_status=mock.Mock(), + ) + instruments_service.bonds.assert_called_once() + + +def test_currency_by(instruments_service): + responce = instruments_service.currency_by( # noqa: F841 + id_type=mock.Mock(), + class_code=mock.Mock(), + id=mock.Mock(), + ) + instruments_service.currency_by.assert_called_once() + + +def test_currencies(instruments_service): + responce = instruments_service.currencies( # noqa: F841 + instrument_status=mock.Mock(), + ) + instruments_service.currencies.assert_called_once() + + +def test_etf_by(instruments_service): + responce = instruments_service.etf_by( # noqa: F841 + id_type=mock.Mock(), + class_code=mock.Mock(), + id=mock.Mock(), + ) + instruments_service.etf_by.assert_called_once() + + +def test_etfs(instruments_service): + responce = instruments_service.etfs( # noqa: F841 + instrument_status=mock.Mock(), + ) + instruments_service.etfs.assert_called_once() + + +def test_future_by(instruments_service): + responce = instruments_service.future_by( # noqa: F841 + id_type=mock.Mock(), + class_code=mock.Mock(), + id=mock.Mock(), + ) + instruments_service.future_by.assert_called_once() + + +def test_futures(instruments_service): + responce = instruments_service.futures( # noqa: F841 + instrument_status=mock.Mock(), + ) + instruments_service.futures.assert_called_once() + + +def test_share_by(instruments_service): + responce = instruments_service.share_by( # noqa: F841 + id_type=mock.Mock(), + class_code=mock.Mock(), + id=mock.Mock(), + ) + instruments_service.share_by.assert_called_once() + + +def test_shares(instruments_service): + responce = instruments_service.shares( # noqa: F841 + instrument_status=mock.Mock(), + ) + instruments_service.shares.assert_called_once() + + +def test_get_accrued_interests(instruments_service): + responce = instruments_service.get_accrued_interests( # noqa: F841 + figi=mock.Mock(), + from_=mock.Mock(), + to=mock.Mock(), + ) + instruments_service.get_accrued_interests.assert_called_once() + + +def test_get_futures_margin(instruments_service): + responce = instruments_service.get_futures_margin( # noqa: F841 + figi=mock.Mock(), + ) + instruments_service.get_futures_margin.assert_called_once() + + +def test_get_instrument_by(instruments_service): + responce = instruments_service.get_instrument_by( # noqa: F841 + id_type=mock.Mock(), + class_code=mock.Mock(), + id=mock.Mock(), + ) + instruments_service.get_instrument_by.assert_called_once() + + +def test_get_dividends(instruments_service): + responce = instruments_service.get_dividends( # noqa: F841 + figi=mock.Mock(), + from_=mock.Mock(), + to=mock.Mock(), + ) + instruments_service.get_dividends.assert_called_once() + + +def test_get_favorites(instruments_service): + response = instruments_service.get_favorites() # noqa: F841 + instruments_service.get_favorites.assert_called_once() + + +def test_get_favorites_with_group(instruments_service): + response = instruments_service.get_favorites(group_id=mock.Mock()) # noqa: F841 + instruments_service.get_favorites.assert_called_once() + + +def test_edit_favorites(instruments_service): + response = instruments_service.edit_favorites( # noqa: F841 + instruments=mock.Mock(), + action_type=mock.Mock(), + ) + instruments_service.edit_favorites.assert_called_once() + + +def test_create_favorite_group(instruments_service): + request = mock.Mock() + response = instruments_service.create_favorite_group( # noqa: F841 + request=request, + ) + instruments_service.create_favorite_group.assert_called_once_with(request=request) + + +def test_delete_favorite_group(instruments_service): + request = mock.Mock() + response = instruments_service.delete_favorite_group( # noqa: F841 + request=request, + ) + instruments_service.delete_favorite_group.assert_called_once_with(request=request) + + +def test_get_favorite_groups(instruments_service): + request = mock.Mock() + response = instruments_service.get_favorite_groups( # noqa: F841 + request=request, + ) + instruments_service.get_favorite_groups.assert_called_once_with(request=request) + + +def test_get_risk_rates(instruments_service): + request = mock.Mock() + response = instruments_service.get_risk_rates( # noqa: F841 + request=request, + ) + instruments_service.get_risk_rates.assert_called_once_with(request=request) + + +def test_get_insider_deals(instruments_service): + request = mock.Mock() + response = instruments_service.get_insider_deals(request=request) # noqa: F841 + instruments_service.get_insider_deals.assert_called_once_with(request=request) + + +def test_structured_notes(instruments_client_service): + request = InstrumentsRequest( + instrument_status=InstrumentStatus.INSTRUMENT_STATUS_ALL + ) + response = instruments_client_service.structured_notes(request=request) + assert len(response.instruments) > 0 + + +def test_structured_notes_by(instruments_client_service): + request = InstrumentRequest( + id_type=InstrumentIdType.INSTRUMENT_ID_TYPE_FIGI, id="BBG012S2DCJ8" + ) + response = instruments_client_service.structured_note_by(request=request) + assert isinstance(response.instrument, StructuredNote) diff --git a/invest-python-master/tests/test_marketdata.py b/invest-python-master/tests/test_marketdata.py new file mode 100644 index 0000000..1dd4351 --- /dev/null +++ b/invest-python-master/tests/test_marketdata.py @@ -0,0 +1,85 @@ +# pylint: disable=redefined-outer-name,unused-variable +# pylint: disable=protected-access +from unittest import mock + +import pytest +from google.protobuf.json_format import MessageToDict + +from t_tech.invest._grpc_helpers import dataclass_to_protobuff +from t_tech.invest.grpc import marketdata_pb2 +from t_tech.invest.schemas import ( + GetMySubscriptions, + MarketDataRequest, + SubscribeTradesRequest, + SubscriptionAction, + TradeInstrument, +) +from t_tech.invest.services import MarketDataService + + +@pytest.fixture() +def market_data_service(): + return mock.create_autospec(spec=MarketDataService) + + +def test_get_candles(market_data_service): + response = market_data_service.get_candles( # noqa: F841 + figi=mock.Mock(), + from_=mock.Mock(), + to=mock.Mock(), + interval=mock.Mock(), + ) + market_data_service.get_candles.assert_called_once() + + +def test_get_last_prices(market_data_service): + response = market_data_service.get_last_prices(figi=mock.Mock()) # noqa: F841 + market_data_service.get_last_prices.assert_called_once() + + +def test_get_order_book(market_data_service): + response = market_data_service.get_order_book( # noqa: F841 + figi=mock.Mock(), depth=mock.Mock() + ) + market_data_service.get_order_book.assert_called_once() + + +def test_get_trading_status(market_data_service): + response = market_data_service.get_trading_status(figi=mock.Mock()) # noqa: F841 + market_data_service.get_trading_status.assert_called_once() + + +def test_subscribe_trades_request(): + expected = marketdata_pb2.MarketDataRequest( + subscribe_trades_request=marketdata_pb2.SubscribeTradesRequest( + instruments=[marketdata_pb2.TradeInstrument(figi="figi")], + subscription_action=SubscriptionAction.SUBSCRIPTION_ACTION_SUBSCRIBE, + with_open_interest=True, + ) + ) + + result = dataclass_to_protobuff( + MarketDataRequest( + subscribe_trades_request=SubscribeTradesRequest( + instruments=[TradeInstrument(figi="figi")], + subscription_action=SubscriptionAction.SUBSCRIPTION_ACTION_SUBSCRIBE, + with_open_interest=True, + ) + ), + marketdata_pb2.MarketDataRequest(), + ) + + assert MessageToDict(result) == MessageToDict(expected) + + +def test_market_data_request_get_my_subscriptions(): + expected = marketdata_pb2.MarketDataRequest( + get_my_subscriptions=marketdata_pb2.GetMySubscriptions() + ) + + result = dataclass_to_protobuff( + MarketDataRequest(get_my_subscriptions=GetMySubscriptions()), + marketdata_pb2.MarketDataRequest(), + ) + + assert MessageToDict(result) == MessageToDict(expected) diff --git a/invest-python-master/tests/test_operations.py b/invest-python-master/tests/test_operations.py new file mode 100644 index 0000000..4f1df8b --- /dev/null +++ b/invest-python-master/tests/test_operations.py @@ -0,0 +1,44 @@ +# pylint: disable=redefined-outer-name,unused-variable + +from unittest import mock + +import pytest + +from t_tech.invest.services import OperationsService + + +@pytest.fixture() +def operations_service(): + return mock.create_autospec(spec=OperationsService) + + +def test_get_operations(operations_service): + response = operations_service.get_operations( # noqa: F841 + account_id=mock.Mock(), + from_=mock.Mock(), + to=mock.Mock(), + state=mock.Mock(), + figi=mock.Mock(), + ) + operations_service.get_operations.assert_called_once() + + +def test_get_portfolio(operations_service): + response = operations_service.get_portfolio( # noqa: F841 + account_id=mock.Mock(), + ) + operations_service.get_portfolio.assert_called_once() + + +def test_get_positions(operations_service): + response = operations_service.get_positions( # noqa: F841 + account_id=mock.Mock(), + ) + operations_service.get_positions.assert_called_once() + + +def test_get_withdraw_limits(operations_service): + response = operations_service.get_withdraw_limits( # noqa: F841 + account_id=mock.Mock(), + ) + operations_service.get_withdraw_limits.assert_called_once() diff --git a/invest-python-master/tests/test_orders.py b/invest-python-master/tests/test_orders.py new file mode 100644 index 0000000..d22670a --- /dev/null +++ b/invest-python-master/tests/test_orders.py @@ -0,0 +1,48 @@ +# pylint: disable=redefined-outer-name,unused-variable + +from unittest import mock + +import pytest + +from t_tech.invest.services import OrdersService + + +@pytest.fixture() +def orders_service(): + return mock.create_autospec(spec=OrdersService) + + +def test_post_order(orders_service): + response = orders_service.post_order( # noqa: F841 + figi=mock.Mock(), + quantity=mock.Mock(), + price=mock.Mock(), + direction=mock.Mock(), + account_id=mock.Mock(), + order_type=mock.Mock(), + order_id=mock.Mock(), + ) + orders_service.post_order.assert_called_once() + + +def test_cancel_order(orders_service): + response = orders_service.cancel_order( # noqa: F841 + account_id=mock.Mock(), + order_id=mock.Mock(), + ) + orders_service.cancel_order.assert_called_once() + + +def test_get_order_state(orders_service): + response = orders_service.get_order_state( # noqa: F841 + account_id=mock.Mock(), + order_id=mock.Mock(), + ) + orders_service.get_order_state.assert_called_once() + + +def test_get_orders(orders_service): + response = orders_service.get_orders( # noqa: F841 + account_id=mock.Mock(), + ) + orders_service.get_orders.assert_called_once() diff --git a/invest-python-master/tests/test_orders_canceling/__init__.py b/invest-python-master/tests/test_orders_canceling/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/invest-python-master/tests/test_orders_canceling/test_async_orders_canceler.py b/invest-python-master/tests/test_orders_canceling/test_async_orders_canceler.py new file mode 100644 index 0000000..b6d0bef --- /dev/null +++ b/invest-python-master/tests/test_orders_canceling/test_async_orders_canceler.py @@ -0,0 +1,95 @@ +import uuid +from typing import List +from unittest.mock import call + +import pytest +import pytest_asyncio + +from t_tech.invest import ( + GetOrdersResponse, + GetStopOrdersResponse, + OrderState, + StopOrder, +) +from t_tech.invest.async_services import AsyncServices, OrdersService, StopOrdersService +from t_tech.invest.typedefs import AccountId + + +@pytest_asyncio.fixture() +async def orders_service(mocker) -> OrdersService: + return mocker.create_autospec(OrdersService) + + +@pytest_asyncio.fixture() +async def stop_orders_service(mocker) -> StopOrdersService: + return mocker.create_autospec(StopOrdersService) + + +@pytest_asyncio.fixture() +async def async_services( + mocker, orders_service: OrdersService, stop_orders_service: StopOrdersService +) -> AsyncServices: + async_services = mocker.create_autospec(AsyncServices) + async_services.orders = orders_service + async_services.stop_orders = stop_orders_service + return async_services + + +@pytest.fixture() +def account_id() -> AccountId: + return AccountId(uuid.uuid4().hex) + + +class TestAsyncOrdersCanceling: + @pytest.mark.asyncio + @pytest.mark.parametrize( + "orders", + [ + [ + OrderState(order_id=str(uuid.uuid4())), + OrderState(order_id=str(uuid.uuid4())), + OrderState(order_id=str(uuid.uuid4())), + ], + [OrderState(order_id=str(uuid.uuid4()))], + [], + ], + ) + @pytest.mark.parametrize( + "stop_orders", + [ + [ + StopOrder(stop_order_id=str(uuid.uuid4())), + StopOrder(stop_order_id=str(uuid.uuid4())), + StopOrder(stop_order_id=str(uuid.uuid4())), + ], + [ + StopOrder(stop_order_id=str(uuid.uuid4())), + ], + [], + ], + ) + async def test_cancels_all_orders( + self, + async_services: AsyncServices, + orders_service: OrdersService, + stop_orders_service: StopOrdersService, + account_id: AccountId, + orders: List[OrderState], + stop_orders: List[StopOrder], + ): + orders_service.get_orders.return_value = GetOrdersResponse(orders=orders) + stop_orders_service.get_stop_orders.return_value = GetStopOrdersResponse( + stop_orders=stop_orders + ) + + await AsyncServices.cancel_all_orders(async_services, account_id=account_id) + + orders_service.get_orders.assert_called_once() + orders_service.cancel_order.assert_has_calls( + call(account_id=account_id, order_id=order.order_id) for order in orders + ) + stop_orders_service.get_stop_orders.assert_called_once() + stop_orders_service.cancel_stop_order.assert_has_calls( + call(account_id=account_id, stop_order_id=stop_order.stop_order_id) + for stop_order in stop_orders + ) diff --git a/invest-python-master/tests/test_orders_canceling/test_orders_canceler.py b/invest-python-master/tests/test_orders_canceling/test_orders_canceler.py new file mode 100644 index 0000000..6529579 --- /dev/null +++ b/invest-python-master/tests/test_orders_canceling/test_orders_canceler.py @@ -0,0 +1,93 @@ +import uuid +from typing import List +from unittest.mock import call + +import pytest + +from t_tech.invest import ( + GetOrdersResponse, + GetStopOrdersResponse, + OrderState, + StopOrder, +) +from t_tech.invest.services import OrdersService, Services, StopOrdersService +from t_tech.invest.typedefs import AccountId + + +@pytest.fixture() +def orders_service(mocker) -> OrdersService: + return mocker.create_autospec(OrdersService) + + +@pytest.fixture() +def stop_orders_service(mocker) -> StopOrdersService: + return mocker.create_autospec(StopOrdersService) + + +@pytest.fixture() +def services( + mocker, orders_service: OrdersService, stop_orders_service: StopOrdersService +) -> Services: + services = mocker.create_autospec(Services) + services.orders = orders_service + services.stop_orders = stop_orders_service + return services + + +@pytest.fixture() +def account_id() -> AccountId: + return AccountId(uuid.uuid4().hex) + + +class TestOrdersCanceler: + @pytest.mark.parametrize( + "orders", + [ + [ + OrderState(order_id=str(uuid.uuid4())), + OrderState(order_id=str(uuid.uuid4())), + OrderState(order_id=str(uuid.uuid4())), + ], + [OrderState(order_id=str(uuid.uuid4()))], + [], + ], + ) + @pytest.mark.parametrize( + "stop_orders", + [ + [ + StopOrder(stop_order_id=str(uuid.uuid4())), + StopOrder(stop_order_id=str(uuid.uuid4())), + StopOrder(stop_order_id=str(uuid.uuid4())), + ], + [ + StopOrder(stop_order_id=str(uuid.uuid4())), + ], + [], + ], + ) + def test_cancels_all_orders( + self, + services: Services, + orders_service: OrdersService, + stop_orders_service: StopOrdersService, + account_id: AccountId, + orders: List[OrderState], + stop_orders: List[StopOrder], + ): + orders_service.get_orders.return_value = GetOrdersResponse(orders=orders) + stop_orders_service.get_stop_orders.return_value = GetStopOrdersResponse( + stop_orders=stop_orders + ) + + Services.cancel_all_orders(services, account_id=account_id) + + orders_service.get_orders.assert_called_once() + orders_service.cancel_order.assert_has_calls( + call(account_id=account_id, order_id=order.order_id) for order in orders + ) + stop_orders_service.get_stop_orders.assert_called_once() + stop_orders_service.cancel_stop_order.assert_has_calls( + call(account_id=account_id, stop_order_id=stop_order.stop_order_id) + for stop_order in stop_orders + ) diff --git a/invest-python-master/tests/test_protobuf_to_dataclass.py b/invest-python-master/tests/test_protobuf_to_dataclass.py new file mode 100644 index 0000000..e7bc98a --- /dev/null +++ b/invest-python-master/tests/test_protobuf_to_dataclass.py @@ -0,0 +1,56 @@ +import logging +import os + +import pytest + +from t_tech.invest import ( + EditFavoritesActionType, + EditFavoritesRequest as DataclassModel, +) +from t_tech.invest._grpc_helpers import protobuf_to_dataclass +from t_tech.invest.grpc.instruments_pb2 import EditFavoritesRequest as ProtoModel + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture() +def unsupported_model() -> ProtoModel: + pb_obj = ProtoModel() + pb_obj.action_type = 137 + return pb_obj + + +class TestProtobufToDataclass: + def test_protobuf_to_dataclass_does_not_raise_by_default( + self, unsupported_model: ProtoModel, caplog + ): + expected = EditFavoritesActionType.EDIT_FAVORITES_ACTION_TYPE_UNSPECIFIED + + actual = protobuf_to_dataclass( + pb_obj=unsupported_model, dataclass_type=DataclassModel + ).action_type + + assert expected == actual + + @pytest.mark.parametrize("use_default_enum_if_error", ["True", "true", "1"]) + def test_protobuf_to_dataclass_does_not_raise_when_set_true( + self, unsupported_model: ProtoModel, use_default_enum_if_error: str + ): + expected = EditFavoritesActionType.EDIT_FAVORITES_ACTION_TYPE_UNSPECIFIED + + os.environ["USE_DEFAULT_ENUM_IF_ERROR"] = use_default_enum_if_error + actual = protobuf_to_dataclass( + pb_obj=unsupported_model, dataclass_type=DataclassModel + ).action_type + + assert expected == actual + + @pytest.mark.parametrize("use_default_enum_if_error", ["False", "false", "0"]) + def test_protobuf_to_dataclass_does_raise_when_set_false( + self, unsupported_model: ProtoModel, use_default_enum_if_error: str + ): + os.environ["USE_DEFAULT_ENUM_IF_ERROR"] = use_default_enum_if_error + with pytest.raises(ValueError): + _ = protobuf_to_dataclass( + pb_obj=unsupported_model, dataclass_type=DataclassModel + ).action_type diff --git a/invest-python-master/tests/test_quotation_convert.py b/invest-python-master/tests/test_quotation_convert.py new file mode 100644 index 0000000..28f47fe --- /dev/null +++ b/invest-python-master/tests/test_quotation_convert.py @@ -0,0 +1,239 @@ +from decimal import Decimal +from random import randrange + +import pytest + +from t_tech.invest import Quotation +from t_tech.invest.utils import decimal_to_quotation, quotation_to_decimal + +MAX_UNITS = 999_999_999_999 +MAX_NANO = 999_999_999 + + +@pytest.fixture() +def quotation(request) -> Quotation: + raw = request.param + return Quotation(units=raw["units"], nano=raw["nano"]) + + +class TestQuotationArithmetic: + @pytest.mark.parametrize( + ("quotation", "decimal"), + [ + ({"units": 114, "nano": 250000000}, Decimal("114.25")), + ({"units": -200, "nano": -200000000}, Decimal("-200.20")), + ({"units": -0, "nano": -10000000}, Decimal("-0.01")), + ], + indirect=["quotation"], + ) + def test_quotation_to_decimal(self, quotation: Quotation, decimal: Decimal): + actual = quotation_to_decimal(quotation) + + assert actual == decimal + + @pytest.mark.parametrize( + ("quotation", "decimal"), + [ + ({"units": 114, "nano": 250000000}, Decimal("114.25")), + ({"units": -200, "nano": -200000000}, Decimal("-200.20")), + ({"units": -0, "nano": -10000000}, Decimal("-0.01")), + ], + indirect=["quotation"], + ) + def test_decimal_to_quotation(self, decimal: Decimal, quotation: Quotation): + actual = decimal_to_quotation(decimal) + + assert actual.units == quotation.units + assert actual.nano == quotation.nano + + @pytest.mark.parametrize( + ("quotation_left", "quotation_right"), + [ + ( + Quotation( + units=randrange(-MAX_UNITS, MAX_UNITS), + nano=randrange(-MAX_NANO, MAX_NANO), + ), + Quotation( + units=randrange(-MAX_UNITS, MAX_UNITS), + nano=randrange(-MAX_NANO, MAX_NANO), + ), + ), + ( + Quotation( + units=randrange(-MAX_UNITS, MAX_UNITS), + nano=randrange(-MAX_NANO, MAX_NANO), + ), + Quotation(units=0, nano=0), + ), + ( + Quotation(units=0, nano=0), + Quotation( + units=randrange(-MAX_UNITS, MAX_UNITS), + nano=randrange(-MAX_NANO, MAX_NANO), + ), + ), + ( + Quotation(units=-0, nano=-200000000), + Quotation( + units=randrange(-MAX_UNITS, MAX_UNITS), + nano=randrange(-MAX_NANO, MAX_NANO), + ), + ), + ( + Quotation( + units=randrange(-MAX_UNITS, MAX_UNITS), + nano=randrange(-MAX_NANO, MAX_NANO), + ), + Quotation(units=-0, nano=-200000000), + ), + ( + Quotation( + units=MAX_UNITS, + nano=MAX_NANO, + ), + Quotation( + units=MAX_UNITS, + nano=MAX_NANO, + ), + ), + ], + ) + @pytest.mark.parametrize( + "operation", + [ + lambda x, y: x - y, + lambda x, y: x + y, + ], + ) + def test_operations( + self, quotation_left: Quotation, quotation_right: Quotation, operation + ): + decimal_left = quotation_to_decimal(quotation_left) + decimal_right = quotation_to_decimal(quotation_right) + + quotation = operation(quotation_left, quotation_right) + + expected_decimal = operation(decimal_left, decimal_right) + actual_decimal = quotation_to_decimal(quotation) + assert actual_decimal == expected_decimal + + @pytest.mark.parametrize( + ("quotation_left", "quotation_right"), + [ + ( + Quotation( + units=randrange(-MAX_UNITS, MAX_UNITS), + nano=randrange(-MAX_NANO, MAX_NANO), + ), + Quotation( + units=randrange(-MAX_UNITS, MAX_UNITS), + nano=randrange(-MAX_NANO, MAX_NANO), + ), + ), + ( + Quotation( + units=randrange(-MAX_UNITS, MAX_UNITS), + nano=randrange(-MAX_NANO, MAX_NANO), + ), + Quotation(units=0, nano=0), + ), + ( + Quotation(units=0, nano=0), + Quotation( + units=randrange(-MAX_UNITS, MAX_UNITS), + nano=randrange(-MAX_NANO, MAX_NANO), + ), + ), + ( + Quotation(units=0, nano=0), + Quotation(units=0, nano=0), + ), + ( + Quotation(units=-10, nano=0), + Quotation(units=10, nano=0), + ), + ( + Quotation(units=0, nano=-200000000), + Quotation(units=0, nano=-200000000), + ), + ( + Quotation( + units=MAX_UNITS, + nano=MAX_NANO, + ), + Quotation( + units=MAX_UNITS, + nano=MAX_NANO, + ), + ), + ], + ) + @pytest.mark.parametrize( + "comparator", + [ + lambda x, y: x > y, + lambda x, y: x >= y, + lambda x, y: x < y, + lambda x, y: x <= y, + lambda x, y: x == y, + lambda x, y: x != y, + lambda y, x: x > y, + lambda y, x: x >= y, + lambda y, x: x < y, + lambda y, x: x <= y, + lambda y, x: x == y, + lambda y, x: x != y, + ], + ) + def test_comparison( + self, quotation_left: Quotation, quotation_right: Quotation, comparator + ): + decimal_left = quotation_to_decimal(quotation_left) + decimal_right = quotation_to_decimal(quotation_right) + + actual_comparison = comparator(quotation_left, quotation_right) + + expected_comparison = comparator(decimal_left, decimal_right) + assert actual_comparison == expected_comparison + + @pytest.mark.parametrize( + "quotation", + [ + Quotation( + units=randrange(-MAX_UNITS, MAX_UNITS), + nano=randrange(-MAX_NANO, MAX_NANO), + ), + Quotation( + units=randrange(-MAX_UNITS, 0), + nano=randrange(-MAX_NANO, 0), + ), + Quotation( + units=randrange(0, MAX_UNITS), + nano=randrange(0, MAX_NANO), + ), + ], + ) + def test_abs(self, quotation: Quotation): + decimal = quotation_to_decimal(quotation) + + actual = abs(decimal) + + expected = abs(decimal) + assert actual == expected + + @pytest.mark.parametrize( + ("units", "nano"), + [ + (-MAX_UNITS, MAX_NANO * 1000), + (MAX_UNITS, -MAX_NANO + 1123123), + (0, MAX_NANO + 1121201203123), + (MAX_UNITS * 100, -MAX_UNITS - 121201203123), + ], + ) + def test_nano_overfill_transfers(self, units: int, nano: int): + quotation = Quotation(units=units, nano=nano) + if abs(nano) >= 1e9: + assert quotation.nano < 1e9 + assert quotation.units - units == nano // 1_000_000_000 + assert quotation.nano == nano % 1_000_000_000 diff --git a/invest-python-master/tests/test_sandbox.py b/invest-python-master/tests/test_sandbox.py new file mode 100644 index 0000000..e245054 --- /dev/null +++ b/invest-python-master/tests/test_sandbox.py @@ -0,0 +1,334 @@ +# pylint: disable=redefined-outer-name,unused-variable + +import os +import uuid +from datetime import datetime + +import pytest +from _decimal import Decimal + +from examples.sandbox.sandbox_cancel_stop_order import cancel_stop_order +from examples.sandbox.sandbox_get_order_price import get_order_price +from examples.sandbox.sandbox_get_stop_orders import get_stop_orders +from examples.sandbox.sandbox_post_stop_order import post_stop_order +from t_tech.invest import ( + Account, + CloseSandboxAccountResponse, + MoneyValue, + OperationState, + OrderDirection, + OrderType, + Quotation, + RequestError, + utils, +) +from t_tech.invest.sandbox.client import SandboxClient +from t_tech.invest.schemas import ( + GetOrderPriceResponse, + OrderExecutionReportStatus, + PostOrderAsyncRequest, + StopOrderDirection, + StopOrderStatusOption, +) +from t_tech.invest.utils import money_to_decimal +from tests.utils import skip_when + + +@pytest.fixture() +def sandbox_service(): + with SandboxClient(token=os.environ["INVEST_SANDBOX_TOKEN"]) as client: + yield client + + +@pytest.fixture() +def initial_balance_pay_in() -> MoneyValue: + return MoneyValue(currency="rub", units=1000000, nano=0) + + +@pytest.fixture() +def account_id(sandbox_service, initial_balance_pay_in: MoneyValue): + response = sandbox_service.sandbox.open_sandbox_account() + sandbox_service.sandbox.sandbox_pay_in( + account_id=response.account_id, + amount=initial_balance_pay_in, + ) + yield response.account_id + sandbox_service.sandbox.close_sandbox_account( + account_id=response.account_id, + ) + + +@pytest.fixture() +def figi() -> str: + return "BBG333333333" + + +@pytest.fixture() +def instrument_id() -> str: + return "f509af83-6e71-462f-901f-bcb073f6773b" + + +@pytest.fixture() +def quantity() -> int: + return 10 + + +@pytest.fixture() +def price() -> Quotation: + return Quotation(units=6, nano=500000000) + + +@pytest.fixture() +def direction() -> OrderDirection: + return OrderDirection.ORDER_DIRECTION_BUY + + +@pytest.fixture() +def stop_order_direction() -> StopOrderDirection: + return StopOrderDirection.STOP_ORDER_DIRECTION_BUY + + +@pytest.fixture() +def stop_order_status() -> StopOrderStatusOption: + return StopOrderStatusOption.STOP_ORDER_STATUS_ACTIVE + + +@pytest.fixture() +def order_type() -> OrderType: + return OrderType.ORDER_TYPE_LIMIT + + +@pytest.fixture() +def order_id() -> str: + return "" + + +@pytest.fixture() +def async_order_id() -> str: + return str(uuid.uuid4()) + + +@pytest.fixture() +def order(instrument_id, quantity, price, direction, account_id, order_type, order_id): + return { + "instrument_id": instrument_id, + "quantity": quantity, + "price": price, + "direction": direction, + "account_id": account_id, + "order_type": order_type, + "order_id": order_id, + } + + +@pytest.fixture() +def async_order( + instrument_id, quantity, price, direction, account_id, order_type, async_order_id +): + return { + "instrument_id": instrument_id, + "quantity": quantity, + "price": price, + "direction": direction, + "account_id": account_id, + "order_type": order_type, + "order_id": async_order_id, + } + + +skip_when_exchange_closed = skip_when( + RequestError, + lambda msg: "Instrument is not available for trading" in msg, + reason="Skipping during closed exchange", +) + + +@pytest.mark.skipif( + os.environ.get("INVEST_SANDBOX_TOKEN") is None, + reason="INVEST_SANDBOX_TOKEN should be specified", +) +class TestSandboxOperations: + def test_open_sandbox_account(self, sandbox_service): + response = sandbox_service.sandbox.open_sandbox_account() + assert isinstance(response.account_id, str) + sandbox_service.sandbox.close_sandbox_account( + account_id=response.account_id, + ) + + def test_get_sandbox_accounts(self, sandbox_service, account_id): + response = sandbox_service.users.get_accounts() + assert isinstance(response.accounts, list) + assert isinstance(response.accounts[0], Account) + assert ( + len( + [ + _account + for _account in response.accounts + if _account.id == account_id + ] + ) + == 1 + ) + + def test_close_sandbox_account(self, sandbox_service): + response = sandbox_service.sandbox.open_sandbox_account() + response = sandbox_service.sandbox.close_sandbox_account( + account_id=response.account_id, + ) + assert isinstance(response, CloseSandboxAccountResponse) + + @skip_when_exchange_closed + def test_post_sandbox_order( + self, sandbox_service, order, instrument_id, direction, quantity + ): + response = sandbox_service.orders.post_order(**order) + assert isinstance(response.order_id, str) + assert response.instrument_uid == instrument_id + assert response.direction == direction + assert response.lots_requested == quantity + + @skip_when_exchange_closed + def test_post_sandbox_order_async( + self, + sandbox_service, + async_order, + instrument_id, + direction, + quantity, + async_order_id, + ): + request = PostOrderAsyncRequest(**async_order) + response = sandbox_service.orders.post_order_async(request) + assert isinstance(response.order_request_id, str) + assert ( + response.execution_report_status + == OrderExecutionReportStatus.EXECUTION_REPORT_STATUS_NEW + ) + assert response.order_request_id == async_order_id + + @skip_when_exchange_closed + def test_get_sandbox_orders(self, sandbox_service, order, account_id): + response = sandbox_service.orders.post_order(**order) + assert response + + @skip_when_exchange_closed + @pytest.mark.skip(reason="Order executes faster than cancel") + def test_cancel_sandbox_order(self, sandbox_service, order, account_id): + response = sandbox_service.orders.post_order(**order) + response = sandbox_service.orders.cancel_order( + account_id=account_id, + order_id=response.order_id, + ) + assert isinstance(response.time, datetime) + + @skip_when_exchange_closed + def test_get_sandbox_order_state( + self, sandbox_service, order, account_id, instrument_id, direction, quantity + ): + response = sandbox_service.orders.post_order(**order) + + response = sandbox_service.orders.get_order_state( + account_id=account_id, + order_id=response.order_id, + ) + assert response.instrument_uid == instrument_id + assert response.direction == direction + assert response.lots_requested == quantity + + @pytest.mark.parametrize("order_type", [OrderType.ORDER_TYPE_MARKET]) + @skip_when_exchange_closed + def test_get_sandbox_positions( + self, sandbox_service, account_id, order, order_type + ): + _ = sandbox_service.orders.post_order(**order) + + response = sandbox_service.operations.get_positions(account_id=account_id) + + assert isinstance(response.money[0], MoneyValue) + assert response.money[0].currency == "rub" + + def test_get_sandbox_operations(self, sandbox_service, account_id, order, figi): + response = sandbox_service.operations.get_operations( + account_id=account_id, + from_=datetime(2000, 2, 2), + to=datetime(2022, 2, 2), + state=OperationState.OPERATION_STATE_EXECUTED, + figi=figi, + ) + assert isinstance(response.operations, list) + + def test_get_sandbox_portfolio( + self, sandbox_service, account_id, initial_balance_pay_in: MoneyValue + ): + response = sandbox_service.operations.get_portfolio( + account_id=account_id, + ) + assert str(response.total_amount_bonds) == str( + MoneyValue(currency="rub", units=0, nano=0) + ) + assert str(response.total_amount_currencies) == str( + initial_balance_pay_in, + ) + assert str(response.total_amount_etf) == str( + MoneyValue(currency="rub", units=0, nano=0) + ) + assert str(response.total_amount_futures) == str( + MoneyValue(currency="rub", units=0, nano=0) + ) + assert str(response.total_amount_shares) == str( + MoneyValue(currency="rub", units=0, nano=0) + ) + + def test_sandbox_pay_in( + self, sandbox_service, account_id, initial_balance_pay_in: MoneyValue + ): + amount = MoneyValue(currency="rub", units=1234, nano=0) + response = sandbox_service.sandbox.sandbox_pay_in( + account_id=account_id, + amount=amount, + ) + + assert money_to_decimal(response.balance) == ( + money_to_decimal(initial_balance_pay_in) + money_to_decimal(amount) + ) + + @skip_when_exchange_closed + def test_sandbox_post_stop_order( + self, + sandbox_service, + account_id, + instrument_id, + stop_order_direction, + quantity, + price, + ): + response = post_stop_order( + sandbox_service, + account_id, + instrument_id, + stop_order_direction, + quantity, + price, + ) + assert response.order_request_id is not None + assert response.stop_order_id is not None + + def test_sandbox_get_stop_orders( + self, sandbox_service, account_id, stop_order_status + ): + response = get_stop_orders(sandbox_service, account_id, stop_order_status) + assert isinstance(response.stop_orders, list) + + def test_sandbox_cancel_stop_order(self, sandbox_service, account_id): + stop_orders = get_stop_orders( + sandbox_service, account_id, StopOrderStatusOption.STOP_ORDER_STATUS_ACTIVE + ) + if len(stop_orders.stop_orders) > 0: + stop_order_id = stop_orders.stop_orders[0].stop_order_id + response = cancel_stop_order(sandbox_service, account_id, stop_order_id) + assert isinstance(response.time, datetime) + + def test_sandbox_get_order_prices(self, sandbox_service, account_id, instrument_id): + response = get_order_price(sandbox_service, account_id, instrument_id, 100) + assert isinstance(response, GetOrderPriceResponse) + assert utils.money_to_decimal(response.total_order_amount) == Decimal(100) diff --git a/invest-python-master/tests/test_signals.py b/invest-python-master/tests/test_signals.py new file mode 100644 index 0000000..c68e90a --- /dev/null +++ b/invest-python-master/tests/test_signals.py @@ -0,0 +1,22 @@ +# pylint: disable=redefined-outer-name,unused-variable + +from unittest import mock + +import pytest + +from t_tech.invest.services import SignalService + + +@pytest.fixture() +def signals_service(): + return mock.create_autospec(spec=SignalService) + + +def test_get_signals(signals_service): + response = signals_service.get_signals(request=mock.Mock()) # noqa: F841 + signals_service.get_signals.assert_called_once_with(request=mock.ANY) + + +def test_get_strategies(signals_service): + response = signals_service.get_strategies(request=mock.Mock()) # noqa: F841 + signals_service.get_strategies.assert_called_once_with(request=mock.ANY) diff --git a/invest-python-master/tests/test_stoporders.py b/invest-python-master/tests/test_stoporders.py new file mode 100644 index 0000000..f9b01ad --- /dev/null +++ b/invest-python-master/tests/test_stoporders.py @@ -0,0 +1,43 @@ +# pylint: disable=redefined-outer-name,unused-variable + +from unittest import mock + +import pytest + +from t_tech.invest.services import StopOrdersService + + +@pytest.fixture() +def stop_orders_service(): + return mock.create_autospec(spec=StopOrdersService) + + +def test_post_stop_order(stop_orders_service): + response = stop_orders_service.post_stop_order( # noqa: F841 + figi=mock.Mock(), + quantity=mock.Mock(), + price=mock.Mock(), + stop_price=mock.Mock(), + direction=mock.Mock(), + account_id=mock.Mock(), + expiration_type=mock.Mock(), + stop_order_type=mock.Mock(), + expire_date=mock.Mock(), + order_id=mock.Mock(), + ) + stop_orders_service.post_stop_order.assert_called_once() + + +def test_get_stop_orders(stop_orders_service): + response = stop_orders_service.get_stop_orders( # noqa: F841 + account_id=mock.Mock(), + ) + stop_orders_service.get_stop_orders.assert_called_once() + + +def test_cancel_stop_order(stop_orders_service): + response = stop_orders_service.cancel_stop_order( # noqa: F841 + account_id=mock.Mock(), + stop_order_id=mock.Mock(), + ) + stop_orders_service.cancel_stop_order.assert_called_once() diff --git a/invest-python-master/tests/test_strategies/__init__.py b/invest-python-master/tests/test_strategies/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/invest-python-master/tests/test_strategies/test_moving_average/__init__.py b/invest-python-master/tests/test_strategies/test_moving_average/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/invest-python-master/tests/test_strategies/test_moving_average/conftest.py b/invest-python-master/tests/test_strategies/test_moving_average/conftest.py new file mode 100644 index 0000000..243b27c --- /dev/null +++ b/invest-python-master/tests/test_strategies/test_moving_average/conftest.py @@ -0,0 +1,385 @@ +import logging +from datetime import timedelta +from decimal import Decimal +from math import exp, sqrt +from random import gauss, seed +from typing import Callable, Dict, Iterable, Iterator, List, Optional + +import pytest +from grpc import StatusCode + +from t_tech.invest import ( + Candle, + Client, + GetCandlesResponse, + GetMarginAttributesResponse, + HistoricCandle, + MarketDataResponse, + MoneyValue, + OrderDirection, + OrderType, + PortfolioPosition, + PortfolioResponse, + Quotation, + RequestError, +) +from t_tech.invest.services import Services +from t_tech.invest.strategies.base.account_manager import AccountManager +from t_tech.invest.strategies.moving_average.plotter import MovingAverageStrategyPlotter +from t_tech.invest.strategies.moving_average.signal_executor import ( + MovingAverageSignalExecutor, +) +from t_tech.invest.strategies.moving_average.strategy import MovingAverageStrategy +from t_tech.invest.strategies.moving_average.strategy_settings import ( + MovingAverageStrategySettings, +) +from t_tech.invest.strategies.moving_average.strategy_state import ( + MovingAverageStrategyState, +) +from t_tech.invest.strategies.moving_average.supervisor import ( + MovingAverageStrategySupervisor, +) +from t_tech.invest.strategies.moving_average.trader import MovingAverageStrategyTrader +from t_tech.invest.utils import ( + candle_interval_to_subscription_interval, + candle_interval_to_timedelta, + decimal_to_quotation, + now, + quotation_to_decimal, +) + +logging.basicConfig(format="%(asctime)s %(levelname)s:%(message)s", level=logging.INFO) +logger = logging.getLogger(__name__) + +seed(1338) + + +def create_noise(s0, mu, sigma) -> Callable[[int], Iterable[float]]: + """Create Noise. + + Generates a price following a geometric brownian motion process based on the input. + - s0: Asset initial price. + - mu: Interest rate expressed annual terms. + - sigma: Volatility expressed annual terms. + """ + st = s0 + + def generate_range(limit: int): + nonlocal st + + for _ in range(limit): + st *= exp( + (mu - 0.5 * sigma**2) * (1.0 / 365.0) + + sigma * sqrt(1.0 / 365.0) * gauss(mu=0, sigma=1) + ) + yield st + + return generate_range + + +@pytest.fixture() +def stock_prices_generator() -> Callable[[int], Iterable[float]]: + return create_noise(100, 0.01, 0.1) + + +@pytest.fixture() +def stock_volume_generator() -> Callable[[int], Iterable[float]]: + return create_noise(1000, 0.9, 1.1) + + +@pytest.fixture() +def initial_candles( + settings: MovingAverageStrategySettings, + stock_prices_generator: Callable[[int], Iterable[float]], + stock_volume_generator: Callable[[int], Iterable[float]], +) -> Iterable[HistoricCandle]: + candles = [] + intervals = 365 + interval_delta = candle_interval_to_timedelta(settings.candle_interval) + base = now() - interval_delta * intervals + (close,) = stock_prices_generator(1) + for i in range(intervals): + open_ = close + low, high, close = stock_prices_generator(3) + low, high = min(low, high, open_, close), max(low, high, open_, close) + (volume,) = stock_volume_generator(1) + candle = HistoricCandle( + open=decimal_to_quotation(Decimal(open_)), + high=decimal_to_quotation(Decimal(high)), + low=decimal_to_quotation(Decimal(low)), + close=decimal_to_quotation(Decimal(close)), + volume=int(volume), + time=base + interval_delta * i, + is_complete=True, + ) + candles.append(candle) + return candles + + +@pytest.fixture() +def real_services(token: str) -> Iterator[Services]: + with Client(token) as services: + yield services + + +@pytest.fixture() +def mock_market_data_service( + real_services: Services, + mocker, + initial_candles: List[HistoricCandle], +) -> Services: + real_services.market_data = mocker.Mock(wraps=real_services.market_data) + + real_services.market_data.get_candles = mocker.Mock() + real_services.market_data.get_candles.return_value = GetCandlesResponse( + candles=initial_candles + ) + + return real_services + + +@pytest.fixture() +def current_market_data() -> List[Candle]: + return [] + + +@pytest.fixture() +def mock_market_data_stream_service( + real_services: Services, + mocker, + figi: str, + stock_prices_generator: Callable[[int], Iterable[float]], + stock_volume_generator: Callable[[int], Iterable[float]], + settings: MovingAverageStrategySettings, + current_market_data: List[Candle], + freezer, +) -> Services: + real_services.market_data_stream = mocker.Mock( + wraps=real_services.market_data_stream + ) + + def _market_data_stream(*args, **kwargs): + yield MarketDataResponse(candle=None) # type: ignore + + (close,) = stock_prices_generator(1) + while True: + open_ = close + low, high, close = stock_prices_generator(3) + low, high = min(low, high, open_, close), max(low, high, open_, close) + (volume,) = stock_volume_generator(1) + candle = Candle( + figi=figi, + interval=candle_interval_to_subscription_interval( + settings.candle_interval + ), + open=decimal_to_quotation(Decimal(open_)), + high=decimal_to_quotation(Decimal(high)), + low=decimal_to_quotation(Decimal(low)), + close=decimal_to_quotation(Decimal(close)), + volume=int(volume), + time=now(), + ) + current_market_data.append(candle) + yield MarketDataResponse(candle=candle) + freezer.move_to(now() + timedelta(minutes=1)) + + real_services.market_data_stream.market_data_stream = _market_data_stream + + return real_services + + +@pytest.fixture() +def mock_operations_service( + real_services: Services, + mocker, + portfolio_response: PortfolioResponse, +) -> Services: + real_services.operations = mocker.Mock(wraps=real_services.operations) + real_services.operations.get_portfolio.return_value = portfolio_response + + return real_services + + +@pytest.fixture() +def mock_users_service( + real_services: Services, + mocker, + marginal_trade_active: bool, +) -> Services: + real_services.users = mocker.Mock(wraps=real_services.users) + if marginal_trade_active: + real_services.users.get_margin_attributes.return_value = ( + GetMarginAttributesResponse( + liquid_portfolio=MoneyValue(currency="", units=0, nano=0), + starting_margin=MoneyValue(currency="", units=0, nano=0), + minimal_margin=MoneyValue(currency="", units=0, nano=0), + funds_sufficiency_level=Quotation(units=322, nano=0), + amount_of_missing_funds=MoneyValue(currency="", units=0, nano=0), + ) + ) + else: + real_services.users.get_margin_attributes.side_effect = RequestError( + code=StatusCode.PERMISSION_DENIED, + details="Marginal trade disabled", + metadata=None, + ) + + return real_services + + +@pytest.fixture() +def marginal_trade_active() -> bool: + return True + + +@pytest.fixture() +def mock_orders_service( + real_services: Services, + mocker, + portfolio_positions: Dict[str, PortfolioPosition], + balance: MoneyValue, + current_market_data: List[Candle], + settings: MovingAverageStrategySettings, + marginal_trade_active: bool, +) -> Services: + real_services.orders = mocker.Mock(wraps=real_services.orders) + + def _post_order( + *, + figi: str = "", + quantity: int = 0, + price: Optional[Quotation] = None, + direction: OrderDirection = OrderDirection(0), + account_id: str = "", + order_type: OrderType = OrderType(0), + order_id: str = "", + ): + assert figi == settings.share_id + assert quantity > 0 + assert account_id == settings.account_id + assert order_type.ORDER_TYPE_MARKET + + last_candle = current_market_data[-1] + last_market_price = quotation_to_decimal(last_candle.close) + + position = portfolio_positions.get(figi) + if position is None: + position = PortfolioPosition( + figi=figi, + quantity=decimal_to_quotation(Decimal(0)), + ) + + if direction == OrderDirection.ORDER_DIRECTION_SELL: + quantity_delta = -quantity + balance_delta = last_market_price * quantity + elif direction == OrderDirection.ORDER_DIRECTION_BUY: + quantity_delta = +quantity + balance_delta = -(last_market_price * quantity) + + else: + raise AssertionError("Incorrect direction") + + logger.warning("Operation: %s, %s", direction, balance_delta) + + old_quantity = quotation_to_decimal(position.quantity) + new_quantity = decimal_to_quotation(old_quantity + quantity_delta) + + position.quantity.units = new_quantity.units + position.quantity.nano = new_quantity.nano + + old_balance = quotation_to_decimal( + Quotation(units=balance.units, nano=balance.nano) + ) + new_balance = decimal_to_quotation(old_balance + balance_delta) + + balance.units = new_balance.units + balance.nano = new_balance.nano + + portfolio_positions[figi] = position + + real_services.orders.post_order = _post_order + + return real_services + + +@pytest.fixture() +def mocked_services( + real_services: Services, + mock_market_data_service, + mock_market_data_stream_service, + mock_operations_service, + mock_users_service, + mock_orders_service, +) -> Services: + return real_services + + +@pytest.fixture() +def account_manager( + mocked_services: Services, settings: MovingAverageStrategySettings +) -> AccountManager: + return AccountManager(services=mocked_services, strategy_settings=settings) + + +@pytest.fixture() +def state() -> MovingAverageStrategyState: + return MovingAverageStrategyState() + + +@pytest.fixture() +def strategy( + settings: MovingAverageStrategySettings, + account_manager: AccountManager, + state: MovingAverageStrategyState, +) -> MovingAverageStrategy: + return MovingAverageStrategy( + settings=settings, + account_manager=account_manager, + state=state, + ) + + +@pytest.fixture() +def signal_executor( + mocked_services: Services, + state: MovingAverageStrategyState, + settings: MovingAverageStrategySettings, +) -> MovingAverageSignalExecutor: + return MovingAverageSignalExecutor( + services=mocked_services, + state=state, + settings=settings, + ) + + +@pytest.fixture() +def supervisor() -> MovingAverageStrategySupervisor: + return MovingAverageStrategySupervisor() + + +@pytest.fixture() +def moving_average_strategy_trader( + strategy: MovingAverageStrategy, + settings: MovingAverageStrategySettings, + mocked_services: Services, + state: MovingAverageStrategyState, + signal_executor: MovingAverageSignalExecutor, + account_manager: AccountManager, + supervisor: MovingAverageStrategySupervisor, +) -> MovingAverageStrategyTrader: + return MovingAverageStrategyTrader( + strategy=strategy, + settings=settings, + services=mocked_services, + state=state, + signal_executor=signal_executor, + account_manager=account_manager, + supervisor=supervisor, + ) + + +@pytest.fixture() +def plotter( + settings: MovingAverageStrategySettings, +) -> MovingAverageStrategyPlotter: + return MovingAverageStrategyPlotter(settings=settings) diff --git a/invest-python-master/tests/test_strategies/test_moving_average/test_trader.py b/invest-python-master/tests/test_strategies/test_moving_average/test_trader.py new file mode 100644 index 0000000..4654c9e --- /dev/null +++ b/invest-python-master/tests/test_strategies/test_moving_average/test_trader.py @@ -0,0 +1,133 @@ +import logging +from datetime import timedelta +from decimal import Decimal +from typing import Dict + +import matplotlib.pyplot as plt +import pytest + +from t_tech.invest import ( + CandleInterval, + MoneyValue, + PortfolioPosition, + PortfolioResponse, + Quotation, +) +from t_tech.invest.strategies.base.account_manager import AccountManager +from t_tech.invest.strategies.moving_average.plotter import MovingAverageStrategyPlotter +from t_tech.invest.strategies.moving_average.signal_executor import ( + MovingAverageSignalExecutor, +) +from t_tech.invest.strategies.moving_average.strategy import MovingAverageStrategy +from t_tech.invest.strategies.moving_average.strategy_settings import ( + MovingAverageStrategySettings, +) +from t_tech.invest.strategies.moving_average.supervisor import ( + MovingAverageStrategySupervisor, +) +from t_tech.invest.strategies.moving_average.trader import MovingAverageStrategyTrader +from t_tech.invest.typedefs import AccountId, ShareId + +logging.basicConfig(format="%(asctime)s %(levelname)s:%(message)s", level=logging.INFO) +logger = logging.getLogger(__name__) + + +@pytest.fixture() +def token() -> str: + return "some" + + +@pytest.fixture() +def portfolio_positions() -> Dict[str, PortfolioPosition]: + return { + "BBG004730N88": PortfolioPosition( + figi="BBG004730N88", + instrument_type="share", + quantity=Quotation(units=110, nano=0), + average_position_price=MoneyValue( + currency="rub", units=261, nano=800000000 + ), + expected_yield=Quotation(units=-106, nano=-700000000), + current_nkd=MoneyValue(currency="", units=0, nano=0), + average_position_price_pt=Quotation(units=0, nano=0), + current_price=MoneyValue(currency="rub", units=260, nano=830000000), + ) + } + + +@pytest.fixture() +def balance() -> MoneyValue: + return MoneyValue(currency="rub", units=20050, nano=690000000) + + +@pytest.fixture() +def portfolio_response( + portfolio_positions: Dict[str, PortfolioPosition], + balance: MoneyValue, +) -> PortfolioResponse: + return PortfolioResponse( + total_amount_shares=MoneyValue(currency="rub", units=28691, nano=300000000), + total_amount_bonds=MoneyValue(currency="rub", units=0, nano=0), + total_amount_etf=MoneyValue(currency="rub", units=0, nano=0), + total_amount_currencies=balance, + total_amount_futures=MoneyValue(currency="rub", units=0, nano=0), + expected_yield=Quotation(units=0, nano=-350000000), + positions=list(portfolio_positions.values()), + ) + + +@pytest.fixture() +def figi() -> str: + return "BBG0047315Y7" + + +@pytest.fixture() +def account_id() -> str: + return AccountId("1337007228") + + +@pytest.fixture() +def settings(figi: str, account_id: AccountId) -> MovingAverageStrategySettings: + return MovingAverageStrategySettings( + share_id=ShareId(figi), + account_id=account_id, + max_transaction_price=Decimal(10000), + candle_interval=CandleInterval.CANDLE_INTERVAL_1_MIN, + long_period=timedelta(minutes=100), + short_period=timedelta(minutes=20), + std_period=timedelta(minutes=30), + ) + + +class TestMovingAverageStrategyTrader: + @pytest.mark.freeze_time() + def test_trade( + self, + moving_average_strategy_trader: MovingAverageStrategyTrader, + strategy: MovingAverageStrategy, + account_manager: AccountManager, + signal_executor: MovingAverageSignalExecutor, + plotter: MovingAverageStrategyPlotter, + supervisor: MovingAverageStrategySupervisor, + caplog, + freezer, + ): + caplog.set_level(logging.DEBUG) + caplog.set_level(logging.INFO) + + initial_balance = account_manager.get_current_balance() + + for i in range(50): + logger.info("Trade %s", i) + moving_average_strategy_trader.trade() + + current_balance = account_manager.get_current_balance() + assert initial_balance != current_balance + logger.info("Initial balance %s", initial_balance) + logger.info("Current balance %s", current_balance) + + events = supervisor.get_events() + plotter.plot(events) + plt.show(block=False) + plt.pause(1) + plt.close() diff --git a/invest-python-master/tests/test_strategies/test_moving_average/test_trader_in_sandbox.py b/invest-python-master/tests/test_strategies/test_moving_average/test_trader_in_sandbox.py new file mode 100644 index 0000000..4a0edb0 --- /dev/null +++ b/invest-python-master/tests/test_strategies/test_moving_average/test_trader_in_sandbox.py @@ -0,0 +1,216 @@ +import logging +import os +from datetime import timedelta +from decimal import Decimal +from typing import Iterator + +import matplotlib.pyplot as plt +import pytest + +from t_tech.invest import ( + CandleInterval, + Client, + GetMarginAttributesResponse, + InstrumentIdType, + MoneyValue, + OpenSandboxAccountResponse, + Quotation, + ShareResponse, + TradingSchedulesResponse, +) +from t_tech.invest.exceptions import UnauthenticatedError +from t_tech.invest.services import SandboxService, Services +from t_tech.invest.strategies.base.account_manager import AccountManager +from t_tech.invest.strategies.base.errors import MarketDataNotAvailableError +from t_tech.invest.strategies.moving_average.plotter import MovingAverageStrategyPlotter +from t_tech.invest.strategies.moving_average.signal_executor import ( + MovingAverageSignalExecutor, +) +from t_tech.invest.strategies.moving_average.strategy import MovingAverageStrategy +from t_tech.invest.strategies.moving_average.strategy_settings import ( + MovingAverageStrategySettings, +) +from t_tech.invest.strategies.moving_average.supervisor import ( + MovingAverageStrategySupervisor, +) +from t_tech.invest.strategies.moving_average.trader import MovingAverageStrategyTrader +from t_tech.invest.typedefs import AccountId, ShareId +from t_tech.invest.utils import now + +logging.basicConfig(format="%(asctime)s %(levelname)s:%(message)s", level=logging.DEBUG) +logger = logging.getLogger(__name__) + + +@pytest.fixture() +def token() -> str: + return os.environ["INVEST_SANDBOX_TOKEN"] + + +@pytest.fixture() +def account( + token: str, real_services: Services, balance: MoneyValue +) -> Iterator[OpenSandboxAccountResponse]: + sandbox: SandboxService = real_services.sandbox + account_response = sandbox.open_sandbox_account() + account_id = account_response.account_id + sandbox.sandbox_pay_in(account_id=account_id, amount=balance) + + yield account_response + + sandbox.close_sandbox_account(account_id=account_id) + + +@pytest.fixture() +def account_id(account: OpenSandboxAccountResponse) -> str: + return account.account_id + + +@pytest.fixture() +def mock_market_data_service(real_services: Services) -> Services: + return real_services + + +@pytest.fixture() +def mock_market_data_stream_service(real_services: Services) -> Services: + return real_services + + +@pytest.fixture() +def mock_operations_service(real_services: Services) -> Services: + real_services.operations.get_portfolio = real_services.sandbox.get_sandbox_portfolio + real_services.operations.get_operations = ( + real_services.sandbox.get_sandbox_operations + ) + return real_services + + +@pytest.fixture() +def mock_users_service( + real_services: Services, + mocker, +) -> Services: + real_services.users = mocker.Mock(wraps=real_services.users) + real_services.users.get_margin_attributes.return_value = ( + GetMarginAttributesResponse( + liquid_portfolio=MoneyValue(currency="", units=0, nano=0), + starting_margin=MoneyValue(currency="", units=0, nano=0), + minimal_margin=MoneyValue(currency="", units=0, nano=0), + funds_sufficiency_level=Quotation(units=322, nano=0), + amount_of_missing_funds=MoneyValue(currency="", units=0, nano=0), + ) + ) + return real_services + + +@pytest.fixture() +def mock_orders_service(real_services: Services) -> Services: + real_services.orders.post_order = real_services.sandbox.post_sandbox_order + real_services.orders.get_orders = real_services.sandbox.get_sandbox_orders + real_services.orders.cancel_order = real_services.sandbox.cancel_sandbox_order + real_services.orders.get_order_state = real_services.sandbox.get_sandbox_order_state + return real_services + + +@pytest.fixture() +def mocked_services( + real_services: Services, + mock_market_data_service, + mock_market_data_stream_service, + mock_operations_service, + mock_users_service, + mock_orders_service, +) -> Services: + return real_services + + +@pytest.fixture() +def figi() -> str: + return "BBG004730N88" + + +@pytest.fixture() +def balance() -> MoneyValue: + return MoneyValue(currency="rub", units=20050, nano=690000000) + + +@pytest.fixture() +def settings(figi: str, account_id: AccountId) -> MovingAverageStrategySettings: + return MovingAverageStrategySettings( + share_id=ShareId(figi), + account_id=account_id, + max_transaction_price=Decimal(10000), + candle_interval=CandleInterval.CANDLE_INTERVAL_HOUR, + long_period=timedelta(hours=200), + short_period=timedelta(hours=50), + std_period=timedelta(hours=30), + ) + + +@pytest.fixture(autouse=True) +def _ensure_is_market_active( + settings: MovingAverageStrategySettings, +): + token = os.environ.get("INVEST_SANDBOX_TOKEN") + if token is None: + pytest.skip("INVEST_SANDBOX_TOKEN should be specified") + + with Client(token) as client: + share_response: ShareResponse = client.instruments.share_by( + id_type=InstrumentIdType.INSTRUMENT_ID_TYPE_FIGI, id=settings.share_id + ) + logger.debug("Instrument = %s", share_response.instrument.name) + response: TradingSchedulesResponse = client.instruments.trading_schedules( + exchange=share_response.instrument.exchange, + from_=now(), + to=now(), + ) + (exchange,) = response.exchanges + logger.debug("Exchange = %s", exchange.exchange) + (day,) = exchange.days + if day.is_trading_day and day.start_time < now() < day.end_time: + return + + pytest.skip("test skipped because market is closed") + + +@pytest.mark.test_sandbox() +@pytest.mark.skipif( + os.environ.get("INVEST_SANDBOX_TOKEN") is None, + reason="INVEST_SANDBOX_TOKEN should be specified", +) +@pytest.mark.xfail( + raises=UnauthenticatedError, + reason="INVEST_SANDBOX_TOKEN is incorrect", +) +class TestMovingAverageStrategyTraderInSandbox: + def test_trade( + self, + moving_average_strategy_trader: MovingAverageStrategyTrader, + strategy: MovingAverageStrategy, + account_manager: AccountManager, + signal_executor: MovingAverageSignalExecutor, + plotter: MovingAverageStrategyPlotter, + supervisor: MovingAverageStrategySupervisor, + caplog, + ): + caplog.set_level(logging.DEBUG) + caplog.set_level(logging.INFO) + + initial_balance = account_manager.get_current_balance() + + try: + for i in range(50): + logger.info("Trade %s", i) + moving_average_strategy_trader.trade() + except MarketDataNotAvailableError: + pass + + current_balance = account_manager.get_current_balance() + logger.info("Initial balance %s", initial_balance) + logger.info("Current balance %s", current_balance) + + events = supervisor.get_events() + plotter.plot(events) + plt.show(block=False) + plt.pause(1) + plt.close() diff --git a/invest-python-master/tests/test_strategies/test_moving_average/test_trader_on_real_market_data.py b/invest-python-master/tests/test_strategies/test_moving_average/test_trader_on_real_market_data.py new file mode 100644 index 0000000..f161220 --- /dev/null +++ b/invest-python-master/tests/test_strategies/test_moving_average/test_trader_on_real_market_data.py @@ -0,0 +1,267 @@ +import logging +import os +from datetime import datetime, timedelta, timezone +from decimal import Decimal +from typing import Dict, Iterable, List + +import pytest +from matplotlib import pyplot as plt + +from t_tech.invest import ( + Candle, + CandleInterval, + HistoricCandle, + MarketDataResponse, + MoneyValue, + PortfolioPosition, + PortfolioResponse, + Quotation, +) +from t_tech.invest.services import Services +from t_tech.invest.strategies.base.account_manager import AccountManager +from t_tech.invest.strategies.moving_average.plotter import MovingAverageStrategyPlotter +from t_tech.invest.strategies.moving_average.signal_executor import ( + MovingAverageSignalExecutor, +) +from t_tech.invest.strategies.moving_average.strategy import MovingAverageStrategy +from t_tech.invest.strategies.moving_average.strategy_settings import ( + MovingAverageStrategySettings, +) +from t_tech.invest.strategies.moving_average.supervisor import ( + MovingAverageStrategySupervisor, +) +from t_tech.invest.strategies.moving_average.trader import MovingAverageStrategyTrader +from t_tech.invest.typedefs import AccountId, ShareId +from t_tech.invest.utils import candle_interval_to_subscription_interval, now + +logging.basicConfig(format="%(asctime)s %(levelname)s:%(message)s", level=logging.INFO) +logger = logging.getLogger(__name__) + + +@pytest.fixture() +def token() -> str: + return os.environ["INVEST_SANDBOX_TOKEN"] + + +@pytest.fixture() +def real_market_data_test_from(request) -> datetime: + return request.param + + +@pytest.fixture() +def real_market_data_test_start(request) -> datetime: + return request.param + + +@pytest.fixture() +def real_market_data_test_end(request) -> datetime: + return request.param + + +@pytest.fixture() +def real_market_data( + real_services: Services, + real_market_data_test_from: datetime, + real_market_data_test_end: datetime, + figi: str, + settings: MovingAverageStrategySettings, +) -> Iterable[HistoricCandle]: + candles = [] + for candle in real_services.get_all_candles( + figi=figi, + from_=real_market_data_test_from, + to=real_market_data_test_end, + interval=settings.candle_interval, + ): + candles.append(candle) + return candles + + +@pytest.fixture() +def initial_candles( + real_market_data_test_start: datetime, + real_market_data: Iterable[HistoricCandle], +) -> Iterable[HistoricCandle]: + return [ + candle + for candle in real_market_data + if candle.time < real_market_data_test_start + ] + + +@pytest.fixture() +def after_start_candles( + real_market_data_test_start: datetime, + real_market_data: Iterable[HistoricCandle], +) -> Iterable[HistoricCandle]: + return [ + candle + for candle in real_market_data + if candle.time >= real_market_data_test_start + ] + + +@pytest.fixture() +def current_market_data() -> List[Candle]: + return [] + + +@pytest.fixture() +def mock_market_data_stream_service( + real_services: Services, + mocker, + figi: str, + settings: MovingAverageStrategySettings, + current_market_data: List[Candle], + freezer, + after_start_candles: Iterable[HistoricCandle], + real_market_data_test_from: datetime, + real_market_data_test_start: datetime, + real_market_data_test_end: datetime, +) -> Services: + real_services.market_data_stream = mocker.Mock( + wraps=real_services.market_data_stream + ) + freezer.move_to(real_market_data_test_start) + + def _market_data_stream(*args, **kwargs): + yield MarketDataResponse(candle=None) # type: ignore + + interval = candle_interval_to_subscription_interval(settings.candle_interval) + for historic_candle in after_start_candles: + candle = Candle( + figi=figi, + interval=interval, + open=historic_candle.open, + high=historic_candle.high, + low=historic_candle.low, + close=historic_candle.close, + volume=historic_candle.volume, + time=historic_candle.time, + ) + current_market_data.append(candle) + yield MarketDataResponse(candle=candle) + freezer.move_to(now() + timedelta(minutes=1)) + + real_services.market_data_stream.market_data_stream = _market_data_stream + + return real_services + + +@pytest.fixture() +def portfolio_positions() -> Dict[str, PortfolioPosition]: + return { + "BBG004730N88": PortfolioPosition( + figi="BBG004730N88", + instrument_type="share", + quantity=Quotation(units=110, nano=0), + average_position_price=MoneyValue( + currency="rub", units=261, nano=800000000 + ), + expected_yield=Quotation(units=-106, nano=-700000000), + current_nkd=MoneyValue(currency="", units=0, nano=0), + average_position_price_pt=Quotation(units=0, nano=0), + current_price=MoneyValue(currency="rub", units=260, nano=830000000), + ) + } + + +@pytest.fixture() +def balance() -> MoneyValue: + return MoneyValue(currency="rub", units=20050, nano=690000000) + + +@pytest.fixture() +def portfolio_response( + portfolio_positions: Dict[str, PortfolioPosition], + balance: MoneyValue, +) -> PortfolioResponse: + return PortfolioResponse( + total_amount_shares=MoneyValue(currency="rub", units=28691, nano=300000000), + total_amount_bonds=MoneyValue(currency="rub", units=0, nano=0), + total_amount_etf=MoneyValue(currency="rub", units=0, nano=0), + total_amount_currencies=balance, + total_amount_futures=MoneyValue(currency="rub", units=0, nano=0), + expected_yield=Quotation(units=0, nano=-350000000), + positions=list(portfolio_positions.values()), + ) + + +@pytest.fixture() +def figi() -> str: + return "BBG0047315Y7" + + +@pytest.fixture() +def account_id() -> str: + return AccountId("1337007228") + + +@pytest.fixture() +def settings(figi: str, account_id: AccountId) -> MovingAverageStrategySettings: + return MovingAverageStrategySettings( + share_id=ShareId(figi), + account_id=account_id, + max_transaction_price=Decimal(10000), + candle_interval=CandleInterval.CANDLE_INTERVAL_1_MIN, + long_period=timedelta(minutes=100), + short_period=timedelta(minutes=50), + std_period=timedelta(minutes=30), + ) + + +def start_datetime() -> datetime: + return datetime(year=2022, month=2, day=16, hour=17, tzinfo=timezone.utc) + + +@pytest.mark.skipif( + os.environ.get("INVEST_SANDBOX_TOKEN") is None, + reason="INVEST_SANDBOX_TOKEN should be specified", +) +class TestMovingAverageStrategyTraderRealMarketData: + @pytest.mark.freeze_time() + @pytest.mark.parametrize( + ( + "real_market_data_test_from", + "real_market_data_test_start", + "real_market_data_test_end", + ), + [ + ( + start_datetime() - timedelta(days=1), + start_datetime(), + start_datetime() + timedelta(days=3), + ) + ], + indirect=True, + ) + def test_trade( + self, + moving_average_strategy_trader: MovingAverageStrategyTrader, + strategy: MovingAverageStrategy, + account_manager: AccountManager, + signal_executor: MovingAverageSignalExecutor, + plotter: MovingAverageStrategyPlotter, + supervisor: MovingAverageStrategySupervisor, + caplog, + freezer, + ): + caplog.set_level(logging.DEBUG) + caplog.set_level(logging.INFO) + + initial_balance = account_manager.get_current_balance() + + for i in range(50): + logger.info("Trade %s", i) + moving_average_strategy_trader.trade() + + current_balance = account_manager.get_current_balance() + assert initial_balance != current_balance + logger.info("Initial balance %s", initial_balance) + logger.info("Current balance %s", current_balance) + + events = supervisor.get_events() + plotter.plot(events) + plt.show(block=False) + plt.pause(1) + plt.close() diff --git a/invest-python-master/tests/test_users.py b/invest-python-master/tests/test_users.py new file mode 100644 index 0000000..cf5e192 --- /dev/null +++ b/invest-python-master/tests/test_users.py @@ -0,0 +1,44 @@ +# pylint: disable=redefined-outer-name,unused-variable + +from unittest import mock + +import pytest + +from t_tech.invest.services import UsersService + + +@pytest.fixture() +def users_service(): + return mock.create_autospec(spec=UsersService) + + +def test_get_accounts(users_service): + response = users_service.get_accounts() # noqa: F841 + users_service.get_accounts.assert_called_once() + + +def test_get_margin_attributes(users_service): + response = users_service.get_margin_attributes( # noqa: F841 + account_id=mock.Mock(), + ) + users_service.get_margin_attributes.assert_called_once() + + +def test_get_user_tariff(users_service): + response = users_service.get_user_tariff() # noqa: F841 + users_service.get_user_tariff.assert_called_once() + + +def test_get_info(users_service): + response = users_service.get_info() # noqa: F841 + users_service.get_info.assert_called_once() + + +def test_get_bank_accounts(users_service): + users_service.get_bank_accounts() + users_service.get_bank_accounts.assert_called_once() + + +def test_currency_transfer(users_service): + response = users_service.currency_transfer(request=mock.Mock()) # noqa: F841 + users_service.currency_transfer.assert_called_once() diff --git a/invest-python-master/tests/test_utils.py b/invest-python-master/tests/test_utils.py new file mode 100644 index 0000000..6ec363c --- /dev/null +++ b/invest-python-master/tests/test_utils.py @@ -0,0 +1,85 @@ +# pylint:disable=protected-access +from datetime import datetime + +import pytest + +from t_tech.invest.schemas import CandleInterval +from t_tech.invest.utils import empty_or_uuid, get_intervals + + +@pytest.mark.parametrize( + ("candle_interval", "interval", "intervals"), + [ + ( + CandleInterval.CANDLE_INTERVAL_DAY, + (datetime(2021, 1, 25, 0, 0), datetime(2022, 1, 25, 0, 1)), + [ + ( + datetime(2021, 1, 25, 0, 0), + datetime(2022, 1, 25, 0, 0), + ) + ], + ), + ( + CandleInterval.CANDLE_INTERVAL_DAY, + (datetime(2021, 1, 25, 0, 0), datetime(2023, 2, 26, 0, 1)), + [ + ( + datetime(2021, 1, 25, 0, 0), + datetime(2022, 1, 25, 0, 0), + ), + ( + datetime(2022, 1, 26, 0, 0), + datetime(2023, 1, 26, 0, 0), + ), + ( + datetime(2023, 1, 27, 0, 0), + datetime(2023, 2, 26, 0, 1), + ), + ], + ), + ( + CandleInterval.CANDLE_INTERVAL_DAY, + (datetime(2021, 1, 25, 0, 0), datetime(2022, 1, 25, 0, 0)), + [ + ( + datetime(2021, 1, 25, 0, 0), + datetime(2022, 1, 25, 0, 0), + ), + ], + ), + ( + CandleInterval.CANDLE_INTERVAL_DAY, + (datetime(2021, 1, 25, 0, 0), datetime(2022, 1, 24, 0, 0)), + [ + ( + datetime(2021, 1, 25, 0, 0), + datetime(2022, 1, 24, 0, 0), + ), + ], + ), + ], +) +def test_get_intervals(candle_interval, interval, intervals): + result = list( + get_intervals( + candle_interval, + *interval, + ) + ) + + assert result == intervals + + +@pytest.mark.parametrize( + "s, expected", + [ + ("", True), + ("123", False), + ("1234567890", False), + ("12345678-1234-1234-1234-abcdabcdabcd", True), + ("12345678-12g4-1234-1234-abcdabcdabcd", False), + ], +) +def test_is_empty_or_uuid(s: str, expected: bool): + assert expected == empty_or_uuid(s) diff --git a/invest-python-master/tests/utils.py b/invest-python-master/tests/utils.py new file mode 100644 index 0000000..5e18c4d --- /dev/null +++ b/invest-python-master/tests/utils.py @@ -0,0 +1,24 @@ +from functools import wraps + +import pytest + + +def skip_when( + exception_type, + is_error_message_expected, + reason="Skipping because of the exception", +): + def decorator_func(f): + @wraps(f) + def wrapper(*args, **kwargs): + try: + return f(*args, **kwargs) + except exception_type as error: + if is_error_message_expected(str(error)): + pytest.skip(reason) + else: + raise error + + return wrapper + + return decorator_func diff --git a/russian_trusted_root_ca_pem.crt b/russian_trusted_root_ca_pem.crt new file mode 100644 index 0000000..a9b27a7 --- /dev/null +++ b/russian_trusted_root_ca_pem.crt @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIIFwjCCA6qgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwcDELMAkGA1UEBhMCUlUx +PzA9BgNVBAoMNlRoZSBNaW5pc3RyeSBvZiBEaWdpdGFsIERldmVsb3BtZW50IGFu +ZCBDb21tdW5pY2F0aW9uczEgMB4GA1UEAwwXUnVzc2lhbiBUcnVzdGVkIFJvb3Qg +Q0EwHhcNMjIwMzAxMjEwNDE1WhcNMzIwMjI3MjEwNDE1WjBwMQswCQYDVQQGEwJS +VTE/MD0GA1UECgw2VGhlIE1pbmlzdHJ5IG9mIERpZ2l0YWwgRGV2ZWxvcG1lbnQg +YW5kIENvbW11bmljYXRpb25zMSAwHgYDVQQDDBdSdXNzaWFuIFRydXN0ZWQgUm9v +dCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMfFOZ8pUAL3+r2n +qqE0Zp52selXsKGFYoG0GM5bwz1bSFtCt+AZQMhkWQheI3poZAToYJu69pHLKS6Q +XBiwBC1cvzYmUYKMYZC7jE5YhEU2bSL0mX7NaMxMDmH2/NwuOVRj8OImVa5s1F4U +zn4Kv3PFlDBjjSjXKVY9kmjUBsXQrIHeaqmUIsPIlNWUnimXS0I0abExqkbdrXbX +YwCOXhOO2pDUx3ckmJlCMUGacUTnylyQW2VsJIyIGA8V0xzdaeUXg0VZ6ZmNUr5Y +Ber/EAOLPb8NYpsAhJe2mXjMB/J9HNsoFMBFJ0lLOT/+dQvjbdRZoOT8eqJpWnVD +U+QL/qEZnz57N88OWM3rabJkRNdU/Z7x5SFIM9FrqtN8xewsiBWBI0K6XFuOBOTD +4V08o4TzJ8+Ccq5XlCUW2L48pZNCYuBDfBh7FxkB7qDgGDiaftEkZZfApRg2E+M9 +G8wkNKTPLDc4wH0FDTijhgxR3Y4PiS1HL2Zhw7bD3CbslmEGgfnnZojNkJtcLeBH +BLa52/dSwNU4WWLubaYSiAmA9IUMX1/RpfpxOxd4Ykmhz97oFbUaDJFipIggx5sX +ePAlkTdWnv+RWBxlJwMQ25oEHmRguNYf4Zr/Rxr9cS93Y+mdXIZaBEE0KS2iLRqa +OiWBki9IMQU4phqPOBAaG7A+eP8PAgMBAAGjZjBkMB0GA1UdDgQWBBTh0YHlzlpf +BKrS6badZrHF+qwshzAfBgNVHSMEGDAWgBTh0YHlzlpfBKrS6badZrHF+qwshzAS +BgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsF +AAOCAgEAALIY1wkilt/urfEVM5vKzr6utOeDWCUczmWX/RX4ljpRdgF+5fAIS4vH +tmXkqpSCOVeWUrJV9QvZn6L227ZwuE15cWi8DCDal3Ue90WgAJJZMfTshN4OI8cq +W9E4EG9wglbEtMnObHlms8F3CHmrw3k6KmUkWGoa+/ENmcVl68u/cMRl1JbW2bM+ +/3A+SAg2c6iPDlehczKx2oa95QW0SkPPWGuNA/CE8CpyANIhu9XFrj3RQ3EqeRcS +AQQod1RNuHpfETLU/A2gMmvn/w/sx7TB3W5BPs6rprOA37tutPq9u6FTZOcG1Oqj +C/B7yTqgI7rbyvox7DEXoX7rIiEqyNNUguTk/u3SZ4VXE2kmxdmSh3TQvybfbnXV +4JbCZVaqiZraqc7oZMnRoWrXRG3ztbnbes/9qhRGI7PqXqeKJBztxRTEVj8ONs1d +WN5szTwaPIvhkhO3CO5ErU2rVdUr89wKpNXbBODFKRtgxUT70YpmJ46VVaqdAhOZ +D9EUUn4YaeLaS8AjSF/h7UkjOibNc4qVDiPP+rkehFWM66PVnP1Msh93tc+taIfC +EYVMxjh8zNbFuoc7fzvvrFILLe7ifvEIUqSVIC/AzplM/Jxw7buXFeGP1qVCBEHq +391d/9RAfaZ12zkwFsl+IKwE/OZxW8AHa9i1p4GO0YSNuczzEm4= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/scan_accounts.py b/scan_accounts.py new file mode 100644 index 0000000..5026502 --- /dev/null +++ b/scan_accounts.py @@ -0,0 +1,47 @@ +import os +from dotenv import load_dotenv +from t_tech.invest import Client + +# Настройка SSL для российских сертификатов +os.environ['SSL_CERT_FILE'] = '/etc/ssl/certs/ca-certificates.crt' +os.environ['GRPC_DEFAULT_SSL_ROOTS_FILE_PATH'] = '/etc/ssl/certs/ca-certificates.crt' + +load_dotenv("tok.env") +TOKEN = os.getenv("TINKOFF_TOKEN") +SBER_UID = "a78b8349-a1dc-447d-9277-1d75826d089a" + +print("\n--- ПОИСК РЕАЛЬНЫХ ТОРГОВЫХ СЧЕТОВ ---") + +try: + with Client(TOKEN, target="invest-public-api.tbank.ru:443") as client: + # 1. Запрашиваем цену и ВРЕМЯ этой цены из общего потока + price_resp = client.market_data.get_last_prices(instrument_id=[SBER_UID]) + lp = price_resp.last_prices[0] + actual_price = lp.price.units + lp.price.nano / 1e9 + price_date = lp.time + + print(f"🌍 ТЕКУЩАЯ ЦЕНА В API: {actual_price} руб.") + print(f"📅 ДАТА ЭТОЙ ЦЕНЫ: {price_date.strftime('%Y-%m-%d %H:%M:%S')} UTC") + + if actual_price < 310: + print("\n🚨 ВНИМАНИЕ: Сервер все еще выдает СТАРУЮ цену (симуляция).") + else: + print("\n✅ API выдает АКТУАЛЬНУЮ рыночную цену!") + + # 2. Получаем список всех доступных счетов + accounts = client.users.get_accounts().accounts + print("\n--- СПИСОК ВАШИХ СЧЕТОВ ---") + for acc in accounts: + try: + # Проверяем баланс каждого счета + portfolio = client.operations.get_portfolio(account_id=acc.id) + balance = portfolio.total_amount_currencies.units + except: + balance = "Ошибка доступа" + + print(f"🔹 Имя: {acc.name:15} | ID: {acc.id}") + print(f" Тип: {acc.type.name:20} | Баланс: {balance} руб.") + print("-" * 50) + +except Exception as e: + print(f"\n❌ ОШИБКА: {e}") diff --git a/tatn_audit.py b/tatn_audit.py new file mode 100644 index 0000000..7c50bd9 --- /dev/null +++ b/tatn_audit.py @@ -0,0 +1,37 @@ +import os +from datetime import datetime, timedelta, timezone +from dotenv import load_dotenv +from t_tech.invest import Client + +os.environ['SSL_CERT_FILE'] = '/etc/ssl/certs/ca-certificates.crt' +os.environ['GRPC_DEFAULT_SSL_ROOTS_FILE_PATH'] = '/etc/ssl/certs/ca-certificates.crt' + +load_dotenv("/root/sber_bot/tok.env") +TOKEN = os.getenv("TINKOFF_TOKEN") +TATN_FIGI = "BBG004730RP6" + +def q_to_f(q): return q.units + q.nano/1e9 if q else 0 + +with Client(TOKEN, target="invest-public-api.tbank.ru:443") as client: + accounts = client.users.get_accounts().accounts + + print(f"\n--- ИСТОРИЯ СДЕЛОК ПО ТАТНЕФТИ (ЗА 10 ДНЕЙ) ---") + print(f"{'Дата (MSK)':<15} | {'Счет':<12} | {'Тип':<5} | {'Цена':<8} | {'Кол':<4} | {'Сумма':<10}") + print("-" * 75) + + for acc in accounts: + ops = client.operations.get_operations( + account_id=acc.id, + from_=datetime.now(timezone.utc) - timedelta(days=10), + to=datetime.now(timezone.utc), + figi=TATN_FIGI # Фильтруем сразу на уровне сервера + ).operations + + for o in ops: + if "TYPE_BUY" in o.operation_type.name or "TYPE_SELL" in o.operation_type.name: + date = o.date.astimezone(timezone(timedelta(hours=3))).strftime("%d.%m %H:%M") + op_type = "BUY" if "BUY" in o.operation_type.name else "SELL" + price = q_to_f(o.price) + payment = q_to_f(o.payment) + + print(f"{date:<15} | {acc.name[:12]:<12} | {op_type:<5} | {price:<8.2f} | {int(o.quantity):<4} | {payment:<10.2f}") diff --git a/tatn_audit_v2.py b/tatn_audit_v2.py new file mode 100644 index 0000000..2a514cb --- /dev/null +++ b/tatn_audit_v2.py @@ -0,0 +1,47 @@ +import os +from datetime import datetime, timedelta, timezone +from dotenv import load_dotenv +from t_tech.invest import Client + +os.environ['SSL_CERT_FILE'] = '/etc/ssl/certs/ca-certificates.crt' +os.environ['GRPC_DEFAULT_SSL_ROOTS_FILE_PATH'] = '/etc/ssl/certs/ca-certificates.crt' + +load_dotenv("/root/sber_bot/tok.env") +TOKEN = os.getenv("TINKOFF_TOKEN") + +# Константы для поиска +TATN_TICKER = "TATN" +TATN_UID = "88468f6c-c67a-4fb4-a006-53eed803883c" + +def q_to_f(q): return q.units + q.nano/1e9 if q else 0 + +with Client(TOKEN, target="invest-public-api.tbank.ru:443") as client: + # Загружаем карту инструментов для опознания + shares = client.instruments.shares().instruments + figi_to_ticker = {s.figi: s.ticker for s in shares} + uid_to_ticker = {s.uid: s.ticker for s in shares} + + accounts = client.users.get_accounts().accounts + + print(f"\n--- ПОИСК СДЕЛОК ПО ТАТНЕФТИ (TATN) ---") + print(f"{'Дата (MSK)':<15} | {'Счет':<12} | {'Тип':<5} | {'Цена':<8} | {'Кол':<4} | {'Сумма':<10}") + print("-" * 75) + + for acc in accounts: + # Запрашиваем ВСЕ операции без фильтра по FIGI на сервере + ops = client.operations.get_operations( + account_id=acc.id, + from_=datetime.now(timezone.utc) - timedelta(days=10), + to=datetime.now(timezone.utc) + ).operations + + for o in ops: + # Проверяем, Татнефть ли это (по FIGI или UID) + ticker = figi_to_ticker.get(o.figi) or uid_to_ticker.get(o.instrument_uid) + if ticker == TATN_TICKER: + if "TYPE_BUY" in o.operation_type.name or "TYPE_SELL" in o.operation_type.name: + date = o.date.astimezone(timezone(timedelta(hours=3))).strftime("%d.%m %H:%M") + op_type = "BUY" if "BUY" in o.operation_type.name else "SELL" + price = q_to_f(o.price) + payment = q_to_f(o.payment) + print(f"{date:<15} | {acc.name[:12]:<12} | {op_type:<5} | {price:<8.2f} | {int(o.quantity):<4} | {payment:<10.2f}") diff --git a/test_api.py b/test_api.py new file mode 100644 index 0000000..043510d --- /dev/null +++ b/test_api.py @@ -0,0 +1,19 @@ +import os, requests +from dotenv import load_dotenv +load_dotenv("tok.env") + +TOKEN = os.getenv("TINKOFF_TOKEN") +UID = "a78b8349-a1dc-447d-9277-1d75826d089a" +# ВНИМАНИЕ: исправлен URL (добавлен / перед tinkoff) +URL = "https://invest-public-api.tinkoff.ru/rest/tinkoff.public.invest.api.marketdata.v1.MarketDataService/GetLastPrices" + +headers = {"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"} +# ВАЖНО: убедитесь, что в json передается именно "instrumentId": [UID] +r = requests.post(URL, json={"instrumentId": [UID]}, headers=headers) + +print(f"Статус: {r.status_code}") +if r.status_code == 200: + print("✅ Успех! Цена получена.") + print(f"Данные: {r.json()}") +else: + print(f"❌ Ошибка: {r.text}") diff --git a/test_new_uid.py b/test_new_uid.py new file mode 100644 index 0000000..002432f --- /dev/null +++ b/test_new_uid.py @@ -0,0 +1,19 @@ +import os +from datetime import datetime, timezone +from dotenv import load_dotenv +from t_tech.invest import Client + +os.environ['SSL_CERT_FILE'] = '/etc/ssl/certs/ca-certificates.crt' +os.environ['GRPC_DEFAULT_SSL_ROOTS_FILE_PATH'] = '/etc/ssl/certs/ca-certificates.crt' + +load_dotenv("tok.env") +TOKEN = os.getenv("TINKOFF_TOKEN") +# НОВЫЙ UID ОТ ПОДДЕРЖКИ +SBER_UID = "e6123145-9665-43e0-8413-cd61b8aa9b13" + +with Client(TOKEN, target="invest-public-api.tbank.ru:443") as client: + lp = client.market_data.get_last_prices(instrument_id=[SBER_UID]).last_prices[0] + price = lp.price.units + lp.price.nano / 1e9 + print(f"\n--- РЕЗУЛЬТАТ ---") + print(f"Актуальная цена SBER: {price} руб.") + print(f"Дата и время цены: {lp.time.strftime('%Y-%m-%d %H:%M:%S')} UTC")