def do_request(ctx: typer.Context, method, *args, **kwargs): if ctx.obj.use_sandbox: client = ti.SyncClient(ctx.obj.sandbox_token, use_sandbox=True) else: client = ti.SyncClient(ctx.obj.token) try: return method(client, *args, **kwargs).payload except ti.BadRequestError as e: typer.echo(f'500 {e.response.payload}') raise typer.Exit(code=1)
def do_request(ctx: typer.Context, method, *args, **kwargs): if ctx.obj.use_sandbox: client = ti.SyncClient(ctx.obj.sandbox_token, use_sandbox=True) else: client = ti.SyncClient(ctx.obj.token) base_api = BaseApi() base_api.client = client response = method(base_api, *args, **kwargs) if response.status_code == http.HTTPStatus.OK: return response.parse_json().payload typer.echo(f'{response.status_code} {response.parse_error().payload}') raise typer.Exit(code=1)
def get_data_by_ticker_and_period( ticker: str, period_in_days: int = 365, freq: tinvest.CandleResolution = tinvest.CandleResolution.day ) -> pd.DataFrame: client = tinvest.SyncClient(**_get_api_params_from_config()) figi = get_figi_from_ticker(ticker) raw_data = client.get_market_candles( figi, datetime.now() - timedelta(days=period_in_days), datetime.now() - timedelta(days=1), freq, ) return pd.DataFrame( data=( ( candle.time, candle.o, candle.h, candle.l, candle.c, candle.v, ) for candle in raw_data.payload.candles ), columns=( 'time', 'open', 'high', 'low', 'close', 'volume', ) )
def get_figi_history_price(figi, date=datetime.now()): # возвращает историческую цену актива # опеределяется запросом свечи за день и усреднением верхней и нижней цены date = datetime(date.year, date.month, date.day) if date == datetime.now().date(): return get_current_market_price(figi) price = database.get_exchange_rate(date, figi) if price: # Если цена есть в локальной базе - не надо запрашивать API return price try: date_to = date + timedelta(days=1) client = tinvest.SyncClient(config.token) result = client.get_market_candles(figi, date, date_to, tinvest.CandleResolution.day) price = (result.payload.candles[0].h + result.payload.candles[0].l) / 2 except tinvest.exceptions.TooManyRequestsError: logger.warning("Превышена частота запросов API. Пауза выполнения.") time.sleep(0.5) return get_figi_history_price(figi, date) except IndexError: instrument = get_instrument_by_figi(figi) logger.error( "Что-то не то со свечами! В этот день было IPO? Или размещение средств?" ) logger.error(f"{date} - {figi} - {instrument.ticker}") logger.error(result) return None database.put_exchange_rate(date, figi, price) return price
def sync_lists(TOKEN, name_file='list_instruments.json'): list = {} client = ti.SyncClient(TOKEN, use_sandbox=True) bonds = client.get_market_bonds() list['bonds'] = [] for i in bonds.payload.instruments: figi_bonds = {} figi_bonds['figi'] = i.figi figi_bonds['status'] = False list['bonds'].append(figi_bonds) print(list) etfs = client.get_market_etfs() list['etfs'] = [] for i in etfs.payload.instruments: figi_etfs = {} figi_etfs['figi'] = i.figi figi_etfs['status'] = False list['etfs'].append(figi_etfs) print(list['etfs']) stocks = client.get_market_stocks() list['stocks'] = [] for i in stocks.payload.instruments: figi_stocks = {} figi_stocks['figi'] = i.figi figi_stocks['status'] = False list['stocks'].append(figi_stocks) print(list['stocks']) save_to_file(list, name_file) return list
def __init__(self, token) -> None: self.Stock = apps.get_model('core', 'Stock') self.DayCandle = apps.get_model('core', 'DayCandle') self.sandbox = tinvest.SyncClient(token, use_sandbox=True) self._is_init = False self.account = None
def get_info(): client = tinvest.SyncClient(settings.TOKEN) response = client.get_accounts() accounts = response.payload.accounts positions = defaultdict(list) for account in accounts: for pos in client.get_portfolio(account.broker_account_id).payload.positions: positions[pos.figi].append(pos) query = sa.select([ sa.func.sum(Operation.payment).label("payment"), sa.func.sum(Operation.commission).label("commission"), Operation.figi ]).select_from(Operation).group_by(Operation.figi) with get_db_typer() as db: db_execute = db.execute(sa.select(MarketInstrument)) instruments = {x.figi: x for x in db_execute.scalars().all()} db_execute = db.execute(query) result = [] for payment, commission, figi in db_execute.all(): if figi not in instruments: continue pos = positions[figi] result.append([ figi, instruments[figi].name, payment - commission, pos[0].lots if len(pos) else "", pos[0].average_position_price.value if len(pos) else "", (payment + commission) / pos[0].lots if len(pos) else "", ]) typer.echo(tabulate(result, headers=['figi', 'name', "result", "lots", "avg", "avg true"]))
def greeting(): client = tinvest.SyncClient(TOKEN) api = tinvest.PortfolioApi(client) response = api.portfolio_get() # requests.Response if response.status_code == 200: print(response.parse_json()) # tinvest.PortfolioResponse
def import_operations(): with get_db_typer() as db: client = tinvest.SyncClient(settings.TOKEN) response = client.get_accounts() accounts = response.payload.accounts for account in accounts: response = client.get_operations( from_=datetime.datetime.min, to=datetime.datetime.max, broker_account_id=account.broker_account_id, ) ops = [x for x in response.payload.operations if x.operation_type in allowed_operation_types and x.status == OperationStatus.done] for chunk in grouper(ops, 100): Operation.sync_bulk_insert( db, [ dict( **x.dict(exclude={"trades", "commission"}), broker_account_id=account.broker_account_id, commission=getattr(x.commission, "value", 0), ) for x in chunk ] ) typer.echo(f"{len(ops)} operations returned")
def get_position_by_ticker(ticker: str) -> Optional[tinvest.PortfolioPosition]: client = tinvest.SyncClient(**_get_api_params_from_config()) positions = client.get_portfolio().payload.positions filtered_positions = list(filter(lambda x: x.ticker.lower() == ticker.lower(), positions)) if len(filtered_positions) == 0: return None return filtered_positions[0]
def get_current_balance(currency_type: str) -> float: client = tinvest.SyncClient(**_get_api_params_from_config()) currencies = client.get_portfolio_currencies().payload.currencies filtered_currencies = list( filter(lambda x: x.currency.lower() == currency_type.lower(), currencies) ) if len(filtered_currencies) == 0: return 0.0 return float(filtered_currencies[0].balance)
def get_accounts(): logger.info('getting accounts') client = tinvest.SyncClient(config.token) accounts = client.get_accounts() logging.debug(accounts) logger.info('accounts received') # проверяем/создаем разделы для счетов в конфигурации # если завели новый счет - добавит с дефолтным конфигом, # если новые настройки были добавлены в коде - так же добавит config.check_accounts_config(accounts.payload.accounts) return accounts.payload.accounts
def get_user_positions(user: schemas.User) -> List[schemas.PortfolioPosition]: """ Return positions for a given user together with current market price and candle prices for the past day, week and month. """ client = tinvest.SyncClient(user.token) response = client.get_portfolio() portfolio_markets = get_portfolio_markets_from_response(response) market_values = get_market_values(client, portfolio_markets) portfolio_positions = get_portfolio_positions_from_response(response, market_values) return portfolio_positions
def __init__(self, api_token: str, account_type: str): self._client = tinvest.SyncClient(api_token) self._account_type = account_type self._account_id = None accounts = self._client.get_accounts().payload.accounts #pprint(accounts) for account in accounts: if account.broker_account_type == self._account_type: self._account_id = account.broker_account_id
def import_instruments(): exclude_keys = {"isin", "lot", "min_price_increment", "min_quantity"} with get_db_typer() as db: client = tinvest.SyncClient(settings.TOKEN) response = client.get_market_stocks() instruments = response.payload.instruments for chunk in grouper(instruments, 100): MarketInstrument.sync_bulk_insert( db, [x.dict(exclude=exclude_keys) for x in chunk] ) typer.echo(f"{len(instruments)} instruments returned")
def get_current_market_price(figi, depth=0, max_age=10 * 60): price = database.get_market_price_by_figi(figi, max_age) if price: return price try: client = tinvest.SyncClient(config.token) book = client.get_market_orderbook(figi=figi, depth=depth) price = book.payload.last_price except tinvest.exceptions.TooManyRequestsError: logger.warn("Превышена частота запросов API. Пауза выполнения.") time.sleep(0.5) return get_current_market_price(figi, depth, max_age) database.put_market_price(figi, price) return price
def get_instrument_by_figi(figi, max_age=7 * 24 * 60 * 60): # max_age - timeout for getting old, default - 1 week instrument = database.get_instrument_by_figi(figi, max_age) if instrument: logger.debug(f"Instrument for {figi} found") return instrument logger.debug(f"Need to query instrument for {figi} from API") try: client = tinvest.SyncClient(config.token) position_data = client.get_market_search_by_figi(figi) except tinvest.exceptions.TooManyRequestsError: logger.warn("Превышена частота запросов API. Пауза выполнения.") time.sleep(0.5) return get_instrument_by_figi(figi, max_age) database.put_instrument(position_data.payload) return position_data.payload
def create_limit_order_by_figi( figi: str, lots: int, price: float, op_type: str = 'Buy' ) -> None: if op_type not in ('Buy', 'Sell'): raise ValueError('Operation type must be Sell or Buy with upper-case first letter') client = tinvest.SyncClient(**_get_api_params_from_config()) client.post_orders_limit_order( figi=figi, body=tinvest.schemas.LimitOrderRequest( lots=lots, operation=tinvest.schemas.OperationType(value=op_type), price=price ) )
async def main(): keys = {'token_tinkoff_real': '', 'token_tinkoff_demo': ''} support.get_all_keys(keys) path_data_dir = os.path.join(os.curdir, 'data') path_stocks_usd = os.path.join(path_data_dir, 'stocks_usd' + '.json') if not os.path.isdir(path_data_dir): os.mkdir(path_data_dir) scanning_stocks = {} client = tinvest.SyncClient(keys['token_tinkoff_real']) instruments = [ client.get_market_search_by_ticker(ticker).payload.instruments[0] for ticker in ('CCL', 'UAL', 'AAPL') ] stocks = [Stock(i.ticker, i.figi, i.isin, i.currency) for i in instruments] fill_candles(client, stocks) save_frames(stocks, path_data_dir)
def get_api_data(broker_account_id): logger.info("authorization..") client = tinvest.SyncClient(config.token) logger.info("authorization success") positions = client.get_portfolio(broker_account_id=broker_account_id) operations = client.get_operations(from_=config.start_date, to=config.now_date, broker_account_id=broker_account_id) market_rate_today = {} for currency, data in currencies_data.items(): if 'figi' in data.keys(): market_rate_today[currency] = get_current_market_price( figi=data['figi'], depth=0) else: market_rate_today[currency] = 1 currencies = client.get_portfolio_currencies( broker_account_id=broker_account_id) logger.info("portfolio received") return positions, operations, market_rate_today, currencies
def __init__(self): self.a_client = ti.AsyncClient(TOKEN) self.s_client = ti.SyncClient(TOKEN)
import pandas as pd import numpy as np import tinvest as ti from datetime import datetime, timedelta import plotly.graph_objects as go from os import walk from config import token client = ti.SyncClient(token) # Function for creating DataFrame of portfolio def get_portfolio() -> pd.DataFrame: data_raw = client.get_portfolio().payload data_clear = { p.name: { "currency": p.average_position_price.currency.value, "price": float(p.average_position_price.value), "amount": float(p.balance), "figi": p.figi } for p in data_raw.positions } dataframe = pd.DataFrame.from_dict(data_clear, orient='index') return dataframe # Stocks history def get_figi_data(figi: str, days=1, time_now=datetime.now()) -> pd.DataFrame: interval = ti.CandleResolution.hour if days == 1 else ti.CandleResolution.day
import argparse import pickle import time from datetime import datetime from typing import List import tinvest from constants import (TOKEN, MAX_PRICE_USD, USD_TO_RUB, PARSED_BONDS_FILE, MIN_RATIO, DEBUG) from tinvest.schemas import (LimitOrderRequest, MarketInstrument, OperationType, Currency, OperationStatus, OrderResponse, Orderbook) client = tinvest.SyncClient(TOKEN) portfolio = tinvest.PortfolioApi(client) market = tinvest.MarketApi(client) orders = tinvest.OrdersApi(client) def round_float(x: float): return round(x, 3) def print_log(param: str): if DEBUG: print(param) class CompanyData: def __init__(self, figi: str,
import os from datetime import datetime, timedelta from typing import List, Tuple import pandas as pd import plotly.graph_objects as go import tinvest as ti client = ti.SyncClient(os.getenv("TINVEST_TOKEN", '')) interval = ti.CandleResolution.day ma_period = [5, 50] def get_figure(figis: List[Tuple[str, str]], period: int) -> go.Figure: return go.Figure( data=[get_candlesstick(get_figi_data(figi, period), figi, name) for figi, name in figis] ) def get_figi_by_ticker(ticker: str): return client.get_market_search_by_ticker(ticker).payload.instruments[0].figi def get_graph_by_ticker(ticker: str, period: int): get = client.get_market_search_by_ticker(ticker) get = [(get.payload.instruments[0].figi, get.payload.instruments[0].name)] fig = get_figure(get, period) ma = get_figi_data(get[0], period) for per in ma_period: fig.add_scatter(name="EMoving average " + str(per), y=ma["c"].ewm(span=per, adjust=False).mean(), x=ma["time"]) fig.add_scatter(name="Moving average " + str(per), y=ma["c"].rolling(window=per).mean(), x=ma["time"])
def get_figi_from_ticker(ticker: str) -> str: client = tinvest.SyncClient(**_get_api_params_from_config()) ticker_data = client.get_market_search_by_ticker(ticker) return ticker_data.payload.instruments[0].figi
import tinvest client = tinvest.SyncClient(TOKEN, use_sandbox=True) # tmp = client.get_market_currencies() # print(tmp) tmp = client.get_market_candles('BBG0013HGFT4', '2020-12-25T10:10:00.131642+03:00', '2020-12-25T11:00:00.131642+03:00', tinvest.CandleResolution('1min')) # print(type(tmp)) print(tmp.payload.candles[0]) # print(tmp.payload.candles)
def __init__(self, token: str) -> None: self.client = tinvest.SyncClient(token) self.portfolio = self.client.get_portfolio().payload.positions
def __init__(self): self.client = tinvest.SyncClient(TINKOFF_TOKEN)
"""Show portfolio candles. python -m examples.portfolio_candles """ import os from datetime import datetime, timedelta from typing import List, Tuple import pandas as pd import plotly.graph_objects as go import tinvest as ti client = ti.SyncClient(os.getenv('TINVEST_TOKEN', '')) def main() -> None: payload = client.get_portfolio().payload figis = [(p.figi, p.name) for p in payload.positions] fig = get_figure(figis) fig.update_layout(xaxis_rangeslider_visible=False) fig.show() def get_figure(figis: List[Tuple[str, str]]) -> go.Figure: return go.Figure(data=[ get_candlesstick(get_figi_data(figi), figi, name) for figi, name in figis ])
def __init__(self, api_token: str, broker_account_id: int): self._client = tinvest.SyncClient(api_token) self._broker_account_id = broker_account_id