### Run Client Examples Source: https://github.com/invest/invest-python/blob/master/examples/README.md Execute the provided example script to verify the installation. ```console $ python examples/client.py ``` -------------------------------- ### Manage user accounts and clients in Python Source: https://github.com/invest/invest-python/blob/master/docs/examples.md Demonstrates how to initialize a client and retrieve user account information. Includes both standard and asynchronous client patterns. ```python {% include "../examples/client.py" %} ``` ```python {% include "../examples/async_client.py" %} ``` -------------------------------- ### Sandbox and utility operations in Python Source: https://github.com/invest/invest-python/blob/master/docs/examples.md Demonstrates usage of the sandbox environment for testing and provides a template for logging API errors. ```python {% include "../examples/sandbox_client.py" %} ``` ```python {% include "../examples/logger.py" %} ``` -------------------------------- ### Manage instruments and market data retrieval in Python Source: https://github.com/invest/invest-python/blob/master/docs/examples.md Scripts for caching instruments, searching for instruments by query, and downloading historical candle data with retry logic. ```python {% include "../examples/instrument_cache.py" %} ``` ```python {% include "../examples/instruments/instruments.py" %} ``` ```python {% include "../examples/download_all_candles.py" %} ``` ```python {% include "../examples/async_retrying_client.py" %} ``` ```python {% include "../examples/retrying_client.py" %} ``` -------------------------------- ### Install T-Invest library Source: https://github.com/invest/invest-python/blob/master/README.md Installs the T-Invest Python package from the specified private package repository using pip. ```bash pip install t-tech-investments --index-url https://opensource.tbank.ru/api/v4/projects/238/packages/pypi/simple ``` -------------------------------- ### Fetch and display hourly candles in Python Source: https://github.com/invest/invest-python/blob/master/docs/examples.md Retrieves and prints hourly candles for a specified period. Demonstrates both synchronous and asynchronous approaches for market data fetching. ```python {% include "../examples/all_candles.py" %} ``` ```python {% include "../examples/async_all_candles.py" %} ``` -------------------------------- ### Cancel All Stop Orders (Python) Source: https://github.com/invest/invest-python/blob/master/docs/examples.md Provides a Python example for canceling all currently active stop orders using the invest-python library. This is crucial for risk management and adjusting trading strategies. ```python from tinkoff.invest import Client # Assuming you have your token token = "YOUR_TOKEN" with Client(token) as client: # Example: Cancel all stop orders for a specific account # This is a simplified example, actual implementation may require account_id # response = client.orders.cancel_all_stop_orders(account_id="YOUR_ACCOUNT_ID") # print(response) print("Example of canceling all stop orders. Requires account ID.") ``` -------------------------------- ### Manage Sandbox Balance and Accounts (Python) Source: https://github.com/invest/invest-python/blob/master/docs/examples.md Demonstrates how to interact with the trading sandbox using invest-python. This includes setting/getting balance, closing existing sandboxes, and creating new ones for testing purposes. ```python from tinkoff.invest import Client # Assuming you have your token token = "YOUR_TOKEN" with Client(token) as client: # Example: Get sandbox balance # response_balance = client.sandbox.get_sandbox_balance(account_id="YOUR_ACCOUNT_ID") # print("Sandbox Balance:", response_balance) # Example: Create a new sandbox account # response_create = client.sandbox.open_sandbox_account() # print("Opened Sandbox Account:", response_create) # Example: Close a sandbox account # response_close = client.sandbox.close_sandbox_account(account_id="YOUR_ACCOUNT_ID") # print("Closed Sandbox Account:", response_close) print("Examples for managing sandbox accounts. Requires API calls and account IDs.") ``` -------------------------------- ### Handle orders and operations in Python Source: https://github.com/invest/invest-python/blob/master/docs/examples.md Provides utilities for managing trading operations, including cancelling all active orders and fetching paginated operation history. ```python {% include "../examples/cancel_orders.py" %} ``` ```python {% include "../examples/get_operations_by_cursor.py" %} ``` -------------------------------- ### Stream market data and portfolio updates in Python Source: https://github.com/invest/invest-python/blob/master/docs/examples.md Implements streaming clients to receive real-time updates for candles, portfolios, and positions. Covers both simple and robust asynchronous streaming implementations. ```python {% include "../examples/async_stream_client.py" %} ``` ```python {% include "../examples/easy_async_stream_client.py" %} ``` ```python {% include "../examples/easy_stream_client.py" %} ``` ```python {% include "../examples/porfolio_stream_client.py" %} ``` ```python {% include "../examples/positions_stream.py" %} ``` ```python {% include "../examples/stream_client.py" %} ``` -------------------------------- ### Create Take-Profit Stop Order (Python) Source: https://github.com/invest/invest-python/blob/master/docs/examples.md Demonstrates how to create a take-profit stop order using the invest-python library. This functionality is useful for setting automated exit points for trades. ```python from tinkoff.invest import Client, OrderDirection, OrderType, StopOrder, StopOrderType # Assuming you have your token token = "YOUR_TOKEN" with Client(token) as client: # Example: Create a take-profit stop order for a specific instrument # This is a simplified example, actual implementation may require more parameters stop_order_request = StopOrder( quantity=10, price=100.0, stop_price=105.0, direction=OrderDirection.ORDER_DIRECTION_BUY, order_type=OrderType.ORDER_TYPE_STOP_LIMIT, stop_order_type=StopOrderType.STOP_ORDER_TYPE_TAKE_PROFIT ) # The actual API call to create the order would go here, e.g.: # response = client.orders.stop_order(figi='BBG000B9XRY5', stop_order=stop_order_request) # print(response) print("Example of creating a take-profit stop order structure.") print(stop_order_request) ``` -------------------------------- ### Get FIGI for Ticker (Python) Source: https://github.com/invest/invest-python/blob/master/docs/examples.md Shows how to retrieve the Financial Instrument Global Identifier (FIGI) for a given stock ticker using the invest-python library. FIGI is essential for identifying specific financial instruments in trading. ```python from tinkoff.invest import Client # Assuming you have your token token = "YOUR_TOKEN" with Client(token) as client: # Example: Get FIGI for a specific ticker ticker = "AAPL" # response = client.instruments.find_instrument( # query=ticker, # instrument_kind="stock" # ) # if response.instruments: # figi = response.instruments[0].figi # print(f"FIGI for {ticker}: {figi}") # else: # print(f"Could not find FIGI for {ticker}") print(f"Example of finding instrument for ticker: {ticker}. Requires API call.") ``` -------------------------------- ### Moving Average Strategy for Stock Signals (Python) Source: https://github.com/invest/invest-python/blob/master/docs/robots.md This Python code snippet implements a trading strategy based on moving averages to generate buy (long) or sell (short) signals for stocks. It creates an additional column for actions and aggregates data to list stocks with signals in descending order of signal date. This example is suitable for users looking to implement basic technical analysis strategies. ```python from tinkoff.invest import Client, CandleInterval from datetime import datetime, timedelta import pandas as pd # Replace with your actual token TOKEN = "YOUR_API_TOKEN" def moving_average_strategy(figi: str, interval: CandleInterval = CandleInterval.CANDLE_INTERVAL_DAY): """ Generates buy/sell signals based on a 200-day moving average. """ with Client(TOKEN) as client: # Get historical data for the last 200 days + buffer end_date = datetime.utcnow() start_date = end_date - timedelta(days=250) candles = client.get_candles( figi=figi, from_=start_date, to=end_date, interval=interval ).candles if not candles: return pd.DataFrame() df = pd.DataFrame({ 'time': [candle.time for candle in candles], 'close': [candle.close for candle in candles] }) df['time'] = pd.to_datetime(df['time']) df.set_index('time', inplace=True) # Calculate 200-day moving average df['ma200'] = df['close'].rolling(window=200).mean() # Generate signals df['ma200_support_action'] = '' # For simplicity, let's assume a crossover strategy # A more robust strategy would involve comparing current price to MA # This is a placeholder for signal generation logic # Example: if close > ma200 and previous close <= previous ma200 -> BUY signal # Example: if close < ma200 and previous close >= previous ma200 -> SELL signal # Placeholder for actual signal generation logic # For demonstration, let's just mark the last row if it has a MA value if df['ma200'].iloc[-1] > 0: df.loc[df.index[-1], 'ma200_support_action'] = 'SIGNAL_GENERATED' # Replace with actual signal type # Filter for rows with signals signals_df = df[df['ma200_support_action'] != ''] # Add date of signal for sorting signals_df['signal_date'] = signals_df.index return signals_df[['ma200_support_action', 'signal_date']] if __name__ == '__main__': # Example usage for a specific FIGI (e.g., SBER for Sberbank) sber_figi = "BBG004730686" sber_signals = moving_average_strategy(sber_figi) if not sber_signals.empty: print(f"Signals for {sber_figi}:") # Sort signals by date in descending order sorted_signals = sber_signals.sort_values(by='signal_date', ascending=False) print(sorted_signals) else: print(f"No signals generated for {sber_figi} or insufficient data.") ``` -------------------------------- ### Live Strategy OHLCV Printing (Python) Source: https://github.com/invest/invest-python/blob/master/docs/examples.md Illustrates a live trading strategy in Python that prints Open, High, Low, Close, and Volume (OHLCV) data for multiple tickers as each candle forms. This is useful for real-time market analysis. ```python from tinkoff.invest import Client, CandleInterval # Assuming you have your token token = "YOUR_TOKEN" # Example tickers tickers = ["AAPL", "GOOG"] with Client(token) as client: # This example outlines the structure for a live strategy. # Actual implementation would involve subscribing to candle streams # and processing the data as it arrives. print("Example structure for a live strategy printing OHLCV data.") print(f"Monitoring tickers: {', '.join(tickers)}") # Placeholder for subscription logic # for ticker in tickers: # figi = client.instruments.find_instrument(query=ticker, instrument_kind='stock').instruments[0].figi # client. சந்தை_data. சந்தை_data_subscribe( # சந்தை_data_subscribe_request=( # { # "subscribe_candles_request": { # "instruments": [ # { # "figi": figi, # "interval": CandleInterval.CANDLE_INTERVAL_1_MIN # } # ] # } # } # ) # ) # Placeholder for processing incoming candle data # def on_candle(candle): # print(f"Candle for {candle.figi}: O={candle.open}, H={candle.high}, L={candle.low}, C={candle.close}, V={candle.volume}") # This would typically run in a loop or as part of an event-driven system. ``` -------------------------------- ### Configure Backtesting Time Intervals Source: https://github.com/invest/invest-python/blob/master/examples/strategies/param-search.ipynb Defines the temporal boundaries for backtesting, including the start date for indicators, the strategy activation point, and the end date. It uses timedelta to calculate offsets based on historical data requirements. ```python from datetime import timedelta # Calculate start date for indicators based on interval requirements real_market_data_test_from = start_datetime() - timedelta( minutes=(n + m) * 2 ) # Define strategy start and end dates real_market_data_test_start = start_datetime() real_market_data_test_end = start_datetime() + timedelta(days=2) ``` -------------------------------- ### Get Instrument Information by ID (Python) Source: https://context7.com/invest/invest-python/llms.txt Fetches detailed information for a specific instrument using its FIGI, ticker, or UID. Requires an Invest API token. ```python import os from t_tech.invest import Client, InstrumentIdType TOKEN = os.environ["INVEST_TOKEN"] with Client(TOKEN) as client: # По FIGI instrument = client.instruments.get_instrument_by( id_type=InstrumentIdType.INSTRUMENT_ID_TYPE_FIGI, id="BBG004730N88" ) print(f"Name: {instrument.instrument.name}") print(f"Ticker: {instrument.instrument.ticker}") print(f"Currency: {instrument.instrument.currency}") print(f"Trading status: {instrument.instrument.trading_status}") # По тикеру и class_code instrument = client.instruments.get_instrument_by( id_type=InstrumentIdType.INSTRUMENT_ID_TYPE_TICKER, class_code="TQBR", id="SBER" ) print(f"Found: {instrument.instrument.name}") ``` -------------------------------- ### Get List of Shares (Python) Source: https://context7.com/invest/invest-python/llms.txt Retrieves a full list of available shares on the platform. Allows filtering by instrument status and exchange type. Requires an Invest API token. ```python import os from t_tech.invest import Client, InstrumentStatus, InstrumentExchangeType TOKEN = os.environ["INVEST_TOKEN"] with Client(TOKEN) as client: # Получение всех активных акций response = client.instruments.shares( instrument_status=InstrumentStatus.INSTRUMENT_STATUS_BASE ) print(f"Total shares: {len(response.instruments)}") # Фильтрация и вывод первых 5 акций for share in response.instruments[:5]: print(f"Ticker: {share.ticker}, Name: {share.name}") print(f"Currency: {share.currency}, Lot: {share.lot}") print(f"Min price increment: {share.min_price_increment}") print("---") ``` -------------------------------- ### Get All Historical Candles (Python) Source: https://context7.com/invest/invest-python/llms.txt Loads historical candle data for a specified period, automatically handling API request segmentation. Supports various candle intervals and sources. Requires an Invest API token. ```python import os from datetime import timedelta from t_tech.invest import Client, CandleInterval from t_tech.invest.schemas import CandleSource from t_tech.invest.utils import now, quotation_to_decimal TOKEN = os.environ["INVEST_TOKEN"] with Client(TOKEN) as client: # Загрузка часовых свечей за последний год candles = list(client.get_all_candles( instrument_id="BBG004730N88", from_=now() - timedelta(days=365), to=now(), interval=CandleInterval.CANDLE_INTERVAL_HOUR, candle_source_type=CandleSource.CANDLE_SOURCE_EXCHANGE )) print(f"Loaded {len(candles)} candles") # Вывод последних 3 свечей for candle in candles[-3:]: print(f"Time: {candle.time}") print(f"Open: {quotation_to_decimal(candle.open)}") print(f"High: {quotation_to_decimal(candle.high)}") print(f"Low: {quotation_to_decimal(candle.low)}") print(f"Close: {quotation_to_decimal(candle.close)}") print(f"Volume: {candle.volume}") print("---") ``` -------------------------------- ### Cancel All Orders with Services Source: https://context7.com/invest/invest-python/llms.txt Cancels all active orders and stop-orders for a given account. It requires the account ID. The example logs the number of active orders before and after the cancellation to verify the operation. ```python import logging import os from t_tech.invest import Client TOKEN = os.environ["INVEST_TOKEN"] logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) with Client(TOKEN) as client: accounts = client.users.get_accounts() account_id = accounts.accounts[0].id # Получение текущих ордеров orders_before = client.orders.get_orders(account_id=account_id) logger.info(f"Active orders before: {len(orders_before.orders)}") # Отмена всех ордеров (обычных и стоп-ордеров) client.cancel_all_orders(account_id=account_id) # Проверка после отмены orders_after = client.orders.get_orders(account_id=account_id) logger.info(f"Active orders after: {len(orders_after.orders)}") ``` -------------------------------- ### Get Candles with Limit (Python) Source: https://context7.com/invest/invest-python/llms.txt Retrieves a limited number of candles for a specified period, useful for fetching recent data without loading the entire history. Requires an Invest API token. ```python import os from datetime import timedelta from t_tech.invest import Client, CandleInterval from t_tech.invest.utils import now TOKEN = os.environ["INVEST_TOKEN"] with Client(TOKEN) as client: # Получение последних 100 минутных свечей response = client.market_data.get_candles( instrument_id="BBG004730N88", from_=now() - timedelta(hours=2), to=now(), interval=CandleInterval.CANDLE_INTERVAL_1_MIN, limit=100 ) print(f"Received {len(response.candles)} candles") # Последняя свеча if response.candles: last_candle = response.candles[-1] print(f"Last candle time: {last_candle.time}") print(f"Is complete: {last_candle.is_complete}") ``` -------------------------------- ### Simplified Market Data Streaming with MarketDataStreamManager (Python) Source: https://context7.com/invest/invest-python/llms.txt This code provides a high-level API for market data streaming using MarketDataStreamManager. It simplifies subscription to candles and allows for dynamic subscription to other instruments like info. The example shows how to subscribe to minute candles and process incoming market data, including stopping the stream conditionally. ```python import os from t_tech.invest import Client, CandleInstrument, InfoInstrument, SubscriptionInterval from t_tech.invest.services import MarketDataStreamManager TOKEN = os.environ["INVEST_TOKEN"] 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) # Динамическая подписка на дополнительные данные if marketdata.candle: market_data_stream.info.subscribe([ InfoInstrument(figi="BBG004730N88") ]) # Остановка потока по условию if marketdata.subscribe_info_response: market_data_stream.stop() break ``` -------------------------------- ### Get Last Prices (Python) Source: https://context7.com/invest/invest-python/llms.txt Retrieves the latest prices for a list of instruments. Returns the last trade or closing price. Requires an Invest API token and uses a utility function to convert quotations to decimals. ```python import os from t_tech.invest import Client, InstrumentStatus from t_tech.invest.utils import quotation_to_decimal TOKEN = os.environ["INVEST_TOKEN"] with Client(TOKEN) as client: # Получение цен по списку FIGI response = client.market_data.get_last_prices( figi=["BBG004730ZJ9", "BBG004730N88"], instrument_status=InstrumentStatus.INSTRUMENT_STATUS_BASE ) for price in response.last_prices: price_decimal = quotation_to_decimal(price.price) print(f"FIGI: {price.figi}") print(f"Price: {price_decimal}") print(f"Time: {price.time}") print("---") ``` -------------------------------- ### Get Order Book with MarketDataService Source: https://context7.com/invest/invest-python/llms.txt Retrieves the current order book for a specified instrument with a given depth. It requires the instrument ID and depth as input. The output includes FIGI, depth, last price, and lists of asks and bids. ```python import os from t_tech.invest import Client from t_tech.invest.utils import quotation_to_decimal TOKEN = os.environ["INVEST_TOKEN"] with Client(TOKEN) as client: # Получение стакана с глубиной 20 order_book = client.market_data.get_order_book( instrument_id="BBG004730N88", depth=20 ) print(f"FIGI: {order_book.figi}") print(f"Depth: {order_book.depth}") print(f"Last price: {quotation_to_decimal(order_book.last_price)}") print("\nAsks (продажа):") for ask in order_book.asks[:5]: print(f" Price: {quotation_to_decimal(ask.price)}, Qty: {ask.quantity}") print("\nBids (покупка):") for bid in order_book.bids[:5]: print(f" Price: {quotation_to_decimal(bid.price)}, Qty: {bid.quantity}") ``` -------------------------------- ### Manage Sandbox Accounts and Balances with SandboxClient Source: https://context7.com/invest/invest-python/llms.txt Demonstrates how to initialize a sandbox environment, create accounts, fund them with virtual currency, and perform basic portfolio operations. It requires a valid API token and uses utility functions to convert decimal values to the required quotation format. ```python import os 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"] def add_money_sandbox(client, account_id, money, currency="rub"): """Пополнение баланса песочницы.""" 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) ) with SandboxClient(TOKEN) as client: sandbox_accounts = client.users.get_accounts() print(f"Existing accounts: {len(sandbox_accounts.accounts)}") new_account = client.sandbox.open_sandbox_account(name="test_strategy") account_id = new_account.account_id print(f"Created account: {account_id}") add_money_sandbox(client, account_id, 2_000_000) positions = client.operations.get_positions(account_id=account_id) balance = quotation_to_decimal(positions.money[0]) print(f"Balance: {balance} RUB") portfolio = client.operations.get_portfolio(account_id=account_id) print(f"Portfolio value: {portfolio.total_amount_portfolio}") client.sandbox.close_sandbox_account(account_id=account_id) print("Account closed") ``` -------------------------------- ### Switching Between Production and Sandbox Environments (Python) Source: https://context7.com/invest/invest-python/llms.txt Illustrates how to switch between the production Invest API and the sandbox environment. It shows using the `target` parameter with `Client` for production and using `SandboxClient` for the sandbox. ```python import os from t_tech.invest import Client from t_tech.invest.constants import INVEST_GRPC_API, INVEST_GRPC_API_SANDBOX from t_tech.invest.sandbox.client import SandboxClient TOKEN = os.environ["INVEST_TOKEN"] # Способ 1: Явное указание target для боевого контура with Client(TOKEN, target=INVEST_GRPC_API) as client: print(client.users.get_accounts()) # Способ 2: Использование SandboxClient для песочницы with SandboxClient(TOKEN) as sandbox_client: # Открытие тестового аккаунта new_account = sandbox_client.sandbox.open_sandbox_account(name="test_account") print(f"Created sandbox account: {new_account.account_id}") # Получение информации о пользователе user_info = sandbox_client.users.get_info() print(user_info) ``` -------------------------------- ### Configure Environment Variable Source: https://github.com/invest/invest-python/blob/master/examples/README.md Set the authentication token required for API access. ```console $ export INVEST_TOKEN=YOUR_TOKEN ``` -------------------------------- ### Synchronous Client Usage (Python) Source: https://context7.com/invest/invest-python/llms.txt Demonstrates how to use the synchronous `Client` for interacting with the T-Invest API. It utilizes a context manager for connection handling and shows how to retrieve account information. ```python import os from t_tech.invest import Client TOKEN = os.environ["INVEST_TOKEN"] def main(): with Client(TOKEN) as client: # Получение списка аккаунтов accounts_response = client.users.get_accounts() print(accounts_response) # GetAccountsResponse(accounts=[Account(id='...', type=ACCOUNT_TYPE_TINKOFF, ...)]) for account in accounts_response.accounts: print(f"Account ID: {account.id}, Type: {account.type}") if __name__ == "__main__": main() ``` -------------------------------- ### Configure API target environment Source: https://github.com/invest/invest-python/blob/master/README.md Shows how to switch between the production ('INVEST_GRPC_API') and sandbox ('INVEST_GRPC_API_SANDBOX') environments by passing a target parameter to the client constructor. ```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()) ``` -------------------------------- ### Retrieve account list using Python client Source: https://github.com/invest/invest-python/blob/master/README.md Demonstrates how to initialize the T-Invest client with an authentication token and retrieve a list of available trading accounts. ```python from t_tech.invest import Client TOKEN = 'token' with Client(TOKEN) as client: print(client.users.get_accounts()) ``` -------------------------------- ### Implement Moving Average Trading Strategy Source: https://context7.com/invest/invest-python/llms.txt Demonstrates how to configure and execute a moving average crossover strategy. It initializes the strategy components, runs trading iterations, and visualizes the results using the provided plotter. ```python 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 TOKEN = os.environ["INVEST_TOKEN"] FIGI = os.environ["INVEST_FIGI"] ACCOUNT_ID = os.environ["INVEST_ACCOUNT_ID"] 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): trader.trade() current_balance = account_manager.get_current_balance() print(f"Initial balance: {initial_balance}") print(f"Current balance: {current_balance}") print(f"Profit/Loss: {current_balance - initial_balance}") events = supervisor.get_events() plotter.plot(events) plt.show() ``` -------------------------------- ### Real-time Market Data Streaming with MarketDataStreamService (Python) Source: https://context7.com/invest/invest-python/llms.txt This snippet demonstrates how to subscribe to real-time market data, specifically minute candles, using the MarketDataStreamService. It requires an INVEST_TOKEN environment variable and utilizes the `t_tech.invest` library. The output includes candle FIGI, closing price, and volume. ```python import os import time from t_tech.invest import ( Client, CandleInstrument, 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() ): if marketdata.candle: candle = marketdata.candle print(f"Candle: {candle.figi}, Close: {candle.close}, Volume: {candle.volume}") if __name__ == "__main__": main() ``` -------------------------------- ### Asynchronous Client Usage (Python) Source: https://context7.com/invest/invest-python/llms.txt Shows how to use the asynchronous `AsyncClient` for non-blocking operations, suitable for high-performance applications. It demonstrates fetching accounts and performing parallel requests using `asyncio.gather`. ```python import asyncio import os from t_tech.invest import AsyncClient TOKEN = os.environ["INVEST_TOKEN"] async def main(): async with AsyncClient(TOKEN) as client: # Асинхронное получение аккаунтов accounts = await client.users.get_accounts() print(accounts) # Параллельные запросы accounts_task = client.users.get_accounts() info_task = client.users.get_info() accounts, user_info = await asyncio.gather(accounts_task, info_task) print(f"User: {user_info.prem_status}, Accounts: {len(accounts.accounts)}") if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------- ### Find Instrument by Query (Python) Source: https://context7.com/invest/invest-python/llms.txt Demonstrates using `InstrumentsService.find_instrument` to search for financial instruments. It shows searching by FIGI, and by name with filters for instrument type and API trade availability. ```python import os from t_tech.invest import Client, InstrumentType TOKEN = os.environ["INVEST_TOKEN"] with Client(TOKEN) as client: # Поиск по FIGI result = client.instruments.find_instrument(query="BBG004730N88") for instrument in result.instruments: print(f"Name: {instrument.name}") print(f"Ticker: {instrument.ticker}") print(f"FIGI: {instrument.figi}") print(f"Type: {instrument.instrument_type}") print(f"Class Code: {instrument.class_code}") print("---") # Поиск только акций, доступных для торговли через API shares = client.instruments.find_instrument( query="Сбербанк", instrument_kind=InstrumentType.INSTRUMENT_TYPE_SHARE, api_trade_available_flag=True ) print(f"Found {len(shares.instruments)} shares") ``` -------------------------------- ### Manage Stop-Orders with StopOrdersService Source: https://context7.com/invest/invest-python/llms.txt Demonstrates how to place take-profit and stop-loss orders for specific instruments and retrieve a list of active stop-orders. It utilizes the StopOrdersService to automate position closing based on target price thresholds. ```python import os import uuid from datetime import timedelta from decimal import Decimal from t_tech.invest import ( Client, StopOrderDirection, StopOrderExpirationType, StopOrderType, ) from t_tech.invest.utils import decimal_to_quotation, now TOKEN = os.environ["INVEST_TOKEN"] with Client(TOKEN) as client: accounts = client.users.get_accounts() account_id = accounts.accounts[0].id # Take-profit ордер: продать при цене 300 рублей take_profit_price = decimal_to_quotation(Decimal("300.00")) tp_response = client.stop_orders.post_stop_order( quantity=1, price=take_profit_price, stop_price=take_profit_price, direction=StopOrderDirection.STOP_ORDER_DIRECTION_SELL, account_id=account_id, stop_order_type=StopOrderType.STOP_ORDER_TYPE_TAKE_PROFIT, instrument_id="BBG004730N88", expire_date=now() + timedelta(hours=24), expiration_type=StopOrderExpirationType.STOP_ORDER_EXPIRATION_TYPE_GOOD_TILL_DATE, order_id=str(uuid.uuid4()) ) print(f"Take-profit order ID: {tp_response.stop_order_id}") # Stop-loss ордер: продать при падении до 240 рублей stop_loss_price = decimal_to_quotation(Decimal("240.00")) sl_response = client.stop_orders.post_stop_order( quantity=1, stop_price=stop_loss_price, direction=StopOrderDirection.STOP_ORDER_DIRECTION_SELL, account_id=account_id, stop_order_type=StopOrderType.STOP_ORDER_TYPE_STOP_LOSS, instrument_id="BBG004730N88", expire_date=now() + timedelta(hours=24), expiration_type=StopOrderExpirationType.STOP_ORDER_EXPIRATION_TYPE_GOOD_TILL_DATE, order_id=str(uuid.uuid4()) ) print(f"Stop-loss order ID: {sl_response.stop_order_id}") # Получение списка стоп-ордеров stop_orders = client.stop_orders.get_stop_orders(account_id=account_id) for so in stop_orders.stop_orders: print(f"Stop order: {so.stop_order_id}, Type: {so.stop_order_type}") ``` -------------------------------- ### Place Market Order with OrdersService Source: https://context7.com/invest/invest-python/llms.txt Places a market order (buy or sell) for a specified instrument. It requires the account ID, instrument ID, quantity, and order type. The response includes the order ID, execution status, executed price, total amount, and commission. ```python import os from uuid import uuid4 from t_tech.invest import Client, OrderDirection, OrderType from t_tech.invest.utils import quotation_to_decimal TOKEN = os.environ["INVEST_TOKEN"] with Client(TOKEN) as client: accounts = client.users.get_accounts() account_id = accounts.accounts[0].id # Рыночный ордер на покупку 1 лота 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(f"Order ID: {response.order_id}") print(f"Status: {response.execution_report_status}") print(f"Executed price: {quotation_to_decimal(response.executed_order_price)}") print(f"Total cost: {quotation_to_decimal(response.total_order_amount)}") print(f"Commission: {quotation_to_decimal(response.executed_commission)}") ``` -------------------------------- ### Implement Resilient API Requests with RetryingClient Source: https://context7.com/invest/invest-python/llms.txt Shows how to configure and use the RetryingClient to automatically handle transient network errors. By defining RetryClientSettings, developers can specify the number of retry attempts for all API calls. ```python import os from t_tech.invest.retrying.sync.client import RetryingClient from t_tech.invest.retrying.settings import RetryClientSettings TOKEN = os.environ["INVEST_TOKEN"] settings = RetryClientSettings( use_retry=True, max_retry_attempt=3 ) with RetryingClient(TOKEN, settings=settings) as client: accounts = client.users.get_accounts() print(f"Accounts: {len(accounts.accounts)}") instruments = client.instruments.shares() print(f"Shares available: {len(instruments.instruments)}") ``` -------------------------------- ### Real-time Portfolio Updates with OperationsStreamService (Python) Source: https://context7.com/invest/invest-python/llms.txt This snippet demonstrates how to subscribe to real-time portfolio updates using the `portfolio_stream` method of `OperationsStreamService`. It requires an INVEST_TOKEN and retrieves account IDs to monitor. The output includes account ID, total portfolio amount, and the number of positions. ```python import os from t_tech.invest import Client TOKEN = os.environ["INVEST_TOKEN"] with Client(TOKEN) as client: accounts = client.users.get_accounts() account_ids = [acc.id for acc in accounts.accounts] # Подписка на обновления портфеля for portfolio_update in client.operations_stream.portfolio_stream( accounts=account_ids, ping_delay_ms=60_000 # Пинг каждые 60 секунд ): if portfolio_update.portfolio: p = portfolio_update.portfolio print(f"Account: {p.account_id}") print(f"Total value: {p.total_amount_portfolio}") print(f"Positions count: {len(p.positions)}") if portfolio_update.ping: print("Ping received, connection alive") ``` -------------------------------- ### Convert Price Formats with SDK Utilities Source: https://context7.com/invest/invest-python/llms.txt Provides utility functions to convert between API-native formats like Quotation and MoneyValue and standard Python Decimal types. This is essential for accurate financial calculations within the SDK. ```python from decimal import Decimal from t_tech.invest import MoneyValue, Quotation from t_tech.invest.utils import ( quotation_to_decimal, decimal_to_quotation, money_to_decimal, now ) quotation = Quotation(units=100, nano=500_000_000) decimal_price = quotation_to_decimal(quotation) print(f"Quotation to Decimal: {decimal_price}") price = Decimal("250.75") quotation = decimal_to_quotation(price) print(f"Decimal to Quotation: units={quotation.units}, nano={quotation.nano}") money = MoneyValue(currency="rub", units=1000, nano=0) money_decimal = money_to_decimal(money) print(f"MoneyValue to Decimal: {money_decimal}") current_time = now() print(f"Current time: {current_time}") ``` -------------------------------- ### Place Limit Order with OrdersService Source: https://context7.com/invest/invest-python/llms.txt Places a limit order with a specified execution price for a given instrument. It requires the account ID, instrument ID, quantity, price, and order type. The response contains the order ID, execution status, and a message. ```python import os from uuid import uuid4 from decimal import Decimal from t_tech.invest import Client, OrderDirection, OrderType from t_tech.invest.utils import decimal_to_quotation TOKEN = os.environ["INVEST_TOKEN"] with Client(TOKEN) as client: accounts = client.users.get_accounts() account_id = accounts.accounts[0].id # Лимитный ордер на покупку по цене 250 рублей price = decimal_to_quotation(Decimal("250.50")) response = client.orders.post_order( order_type=OrderType.ORDER_TYPE_LIMIT, direction=OrderDirection.ORDER_DIRECTION_BUY, instrument_id="BBG004730N88", quantity=1, price=price, account_id=account_id, order_id=str(uuid4()) ) print(f"Order ID: {response.order_id}") print(f"Status: {response.execution_report_status}") print(f"Message: {response.message}") ``` -------------------------------- ### Fetch Paginated Operations History Source: https://context7.com/invest/invest-python/llms.txt Demonstrates how to retrieve historical operations using cursor-based pagination. This approach is efficient for processing large datasets by iteratively requesting chunks of operations until all data is retrieved or a limit is reached. ```python import os 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=10 ) # Первый запрос operations = client.operations.get_operations_by_cursor(get_request()) all_operations = list(operations.items) # Пагинация while operations.has_next: request = get_request(cursor=operations.next_cursor) operations = client.operations.get_operations_by_cursor(request) all_operations.extend(operations.items) if len(all_operations) >= 50: # Ограничение для примера break print(f"Total loaded operations: {len(all_operations)}") for op in all_operations[:5]: print(f"Date: {op.date}, Type: {op.type}, State: {op.state}") ``` -------------------------------- ### Execute Moving Average Trading Strategy Simulation Source: https://github.com/invest/invest-python/blob/master/examples/strategies/param-search.ipynb This snippet initializes the Moving Average strategy with specific timeframes and periods, runs a simulation using a mocked client, and identifies the best performing stock based on final account balances. ```python balances = {} for stock in stocks: figi = ShareId(stocks[stock]["figi"]) balance = MoneyValue(currency="rub", units=20050, nano=690000000) account_id = AccountId("1337007228") settings = MovingAverageStrategySettings( share_id=figi, account_id=account_id, max_transaction_price=Decimal(10000), candle_interval=tf, long_period=timedelta(minutes=n * period), short_period=timedelta(minutes=m * period), std_period=timedelta(minutes=s * period), ) with MockedClient( token=token, settings=settings, 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, ) as mocked_services: account_manager = AccountManager(services=mocked_services, strategy_settings=settings) state = MovingAverageStrategyState() strategy = MovingAverageStrategy(settings=settings, account_manager=account_manager, state=state) supervisor = MovingAverageStrategySupervisor() signal_executor = MovingAverageSignalExecutor(services=mocked_services, state=state, settings=settings) moving_average_strategy_trader = MovingAverageStrategyTrader( strategy=strategy, settings=settings, services=mocked_services, state=state, signal_executor=signal_executor, account_manager=account_manager, supervisor=supervisor ) for i in range(50): logger.info("Trade %s", i) moving_average_strategy_trader.trade() balances[stock] = balance.units best_stock = max(balances, key=balances.get) ``` -------------------------------- ### Retrieve Portfolio Status with OperationsService Source: https://context7.com/invest/invest-python/llms.txt Retrieves the current state of an investment portfolio, including total value, expected yield, and detailed position information. It uses helper utilities to convert API quotation and money formats to standard decimals. ```python import os from t_tech.invest import Client from t_tech.invest.utils import quotation_to_decimal, money_to_decimal TOKEN = os.environ["INVEST_TOKEN"] with Client(TOKEN) as client: accounts = client.users.get_accounts() account_id = accounts.accounts[0].id portfolio = client.operations.get_portfolio(account_id=account_id) print(f"Total value: {money_to_decimal(portfolio.total_amount_portfolio)}") print(f"Expected yield: {quotation_to_decimal(portfolio.expected_yield)}") print("\nPositions:") for position in portfolio.positions: print(f" FIGI: {position.figi}") print(f" Quantity: {quotation_to_decimal(position.quantity)}") print(f" Current price: {money_to_decimal(position.current_price)}") print(f" Expected yield: {quotation_to_decimal(position.expected_yield)}") print(" ---") ``` -------------------------------- ### Добавление директории проекта в PATH Source: https://github.com/invest/invest-python/blob/master/examples/strategies/param-search.ipynb Этот блок кода добавляет директорию основного проекта в переменную окружения PATH. Это необходимо, чтобы Python мог находить и импортировать необходимые библиотеки из главной папки репозитория. Код исполняется один раз для настройки окружения. ```python import sys import os path = os.getcwd() repo_folder = os.path.dirname(os.path.dirname(path)) sys.path.append(repo_folder) !set PATH=%PATH%;%APPDATA%\Python\Scripts ``` -------------------------------- ### Загрузка токена для доступа к API Source: https://github.com/invest/invest-python/blob/master/examples/strategies/param-search.ipynb Этот блок кода предназначен для загрузки токена, необходимого для аутентификации при работе с API. Указывается, что для работы требуется sandbox токен, который можно получить по предоставленной ссылке. Sandbox среда позволяет тестировать стратегию без риска для реальных средств. ```python # sandbox token token = "" ```