metaseller/ /tinkoff-invest-api-v2-php
Tinkoff Invest API v2 的非官方 PHP SDK
Requires
- php: >=7.4.0
- ext-bcmath: *
- ext-grpc: ^1.43
- google/protobuf: ^3.19
- grpc/grpc: ^1.42
README
Tinkoff Invest API v2 的非官方 PHP SDK
Tinkoff Invest Api 开发者文档可通过以下链接访问: https://tinkoff.github.io/investAPI/
Telegram 开发者社区: https://t.me/joinchat/VaW05CDzcSdsPULM
简介
由于 Tinkoff Invest API v2 目前定位为 gRPC 接口以与 Tinkoff Invest Trading Platform 交互,因此我们首先需要的是 gRPC 文档。
- 使用 PHP 快速入门 -> https://grpc.org.cn/docs/languages/php/quickstart/
- 基本教程 -> https://grpc.org.cn/docs/languages/php/basics/
当前仓库结构
etc - Директория, которая содержит сертификаты для подключения к сервису с использованием SSL
examples - Директория с примерами подключения к сервису и выполнением простейших запросов
library - Это фактически копия репозитория https://github.com/Tinkoff/investAPI/
library/src/docs/contracts - Директория, которая содержит proto файлы
src/models - Директория, которая содержит сгенерированные через protoc модели
安装要求
开始工作,我们需要以下内容
- PHP 7.1 或更高版本(我在 php 7.4 / Ubuntu 18.04.5 上进行了构建和测试)
- PECL, Composer
重要:此仓库包含从 proto 文件生成的模型。目录 library/src/docs/contracts 的内容未使用。
如果您想自行生成模型,则需要
- 安装 protoc
- 构建 grpc_php_plugin 插件(见 https://grpc.org.cn/docs/languages/php/basics/#setup)
- 调用如下
sudo protoc --proto_path=~/contracts_dir/ --php_out=~/models_dic/ --grpc_out=~/models_dir/ --plugin=protoc-gen-grpc=./grpc_php_plugin ~/contracts_dir/*
替换为您需要的目录。
接下来,我们需要 PHP 的 grps.so 扩展(https://cloud.google.com/php/grpc)。
sudo pecl install grpc
之后不要忘记在 php.ini 中添加
extension=grpc.so
如果需要记录执行日志,也可以在 php.ini 中添加
grpc.grpc_verbosity=debug
grpc.grpc_trace=all,-polling,-polling_api,-pollable_refcount,-timer,-timer_check
grpc.log_filename=/var/log/grpc.log
当然,别忘了
sudo touch /var/log/grpc.log
sudo chmod 666 /var/log/grpc.log
通过 composer 安装
PS:如果您计划在基于 Yii2 Framework 的项目中使用,则可以使用包装器 metaseller/tinkoff-invest-api-v2-yii2。
或者通过 composer 安装 SDK
$ composer require metaseller/tinkoff-invest-api-v2-php
或者
$ git clone git@github.com:metaseller/tinkoff-invest-api-v2-php.git .
composer update
编写自己的 Tinkoff Invest API v2 token
$ vim examples/example.php
/** * Ваш токен доступа к API * * @see https://tinkoff.github.io/investAPI/token/ */ $token = 't.ZEbUT................................................7dA';
并进行测试
$ php examples/example.php
测试示例
可以使用创建 Tinkoff Invest Api V2 服务访问客户端的工厂
/** * Ваш токен доступа к API * * @see https://tinkoff.github.io/investAPI/token/ */ $token = '<Your Tinkoff Invest Account Token>'; $tinkoff_api = TinkoffClientsFactory::create($token); /** * Создаем экземпляр запроса информации об аккаунте к сервису * * Запрос не принимает никаких параметров на вход * * @see https://tinkoff.github.io/investAPI/users/#getinforequest */ $request = new GetInfoRequest(); /** * @var GetInfoResponse $response - Получаем ответ, содержащий информацию о пользователе */ list($response, $status) = $tinkoff_api->usersServiceClient->GetInfo($request)->wait(); /** Выводим полученную информацию */ var_dump(['user_info' => [ 'prem_status' => $response->getPremStatus(), 'qual_status' => $response->getQualStatus(), 'qualified_for_work_with' => $response->getQualifiedForWorkWith(), ]]); /** * @var GetInfoResponse $response - Получаем ответ, содержащий информацию о пользователе */ list($response, $status) = $tinkoff_api->usersServiceClient->GetInfo($request)->wait(); /** Выводим полученную информацию */ var_dump(['user_info' => [ 'prem_status' => $response->getPremStatus(), 'qual_status' => $response->getQualStatus(), 'qualified_for_work_with' => $response->getQualifiedForWorkWith(), ]]);
或者直接创建服务访问客户端
/** * Ваш токен доступа к API * * @see https://tinkoff.github.io/investAPI/token/ */ $token = '<Your Tinkoff Invest Account Token>'; /** * Создаем экземпляр подключения к сервису, используя {@link UsersServiceClient} */ $user_service_client = new UsersServiceClient(ClientConnection::getHostname(), ClientConnection::getOptions($token)); /** * Создаем экземпляр запроса информации об аккаунте к сервису * * Запрос не принимает никаких параметров на вход * * @see https://tinkoff.github.io/investAPI/users/#getinforequest */ $request = new GetInfoRequest(); /** * @var GetInfoResponse $response - Получаем ответ, содержащий информацию о пользователе */ list($response, $status) = $user_service_client->GetInfo($request)->wait(); /** Выводим полученную информацию */ var_dump(['user_info' => [ 'prem_status' => $response->getPremStatus(), 'qual_status' => $response->getQualStatus(), 'qualified_for_work_with' => $response->getQualifiedForWorkWith(), ]]);
基于 MarketDataStreamClient 的简单连接和读取数据示例(以深度 10 的股票 FB 申报单为例)
/** * Ваш токен доступа к API * * @see https://tinkoff.github.io/investAPI/token/ */ $token = '<Your Tinkoff Invest Account Token>'; /** Пример получения обновляемого через Stream ({@link MarketDataStreamServiceClient}) стакана по тикеру FB */ $factory = TinkoffClientsFactory::create($token); /** * Пример получения справочника всех Shares инструментов * * PS: Само собой, если вам нужен только один инструмент, разумнее использовать метод GetInstrumentBy * * @see https://tinkoff.github.io/investAPI/instruments/#getinstrumentby * @see https://tinkoff.github.io/investAPI/instruments/#instrumentrequest */ $instruments_request = new InstrumentsRequest(); $instruments_request->setInstrumentStatus(InstrumentStatus::INSTRUMENT_STATUS_ALL); /** @var SharesResponse $response */ list($response, $status) = $factory->instrumentsServiceClient->Shares($instruments_request) ->wait(); /** @var Instrument[] $instruments_dict */ $instruments_dict = $response->getInstruments(); /** * Находим в справочнике (коль он у нас весь есть) нужный нам инструмент */ foreach ($instruments_dict as $instrument) { if ($instrument->getTicker() === 'FB') { $meta_instrument = $instrument; break; } } if (empty($meta_instrument)) { echo('Instrument not found'); die(); } /** Создаем подписку на данные {@link MarketDataRequest}, конкретно по {@link SubscribeOrderBookRequest} по FIGI инструмента META/FB */ $subscription = (new MarketDataRequest()) ->setSubscribeOrderBookRequest( (new SubscribeOrderBookRequest()) ->setSubscriptionAction(SubscriptionAction::SUBSCRIPTION_ACTION_SUBSCRIBE) ->setInstruments([ (new OrderBookInstrument()) ->setFigi($meta_instrument->getFigi()) ->setDepth(10) ]) ); $stream = $factory->marketDataStreamServiceClient->MarketDataStream(); $stream->write($subscription); /** В цикле получаем данные от сервера */ /** @var MarketDataResponse $market_data_response */ while ($market_data_response = $stream->read()) { if ($orderbook = $market_data_response->getOrderbook()) { /** @var Order[] $asks */ $asks = $orderbook->getAsks(); /** @var Order[] $bids */ $bids = $orderbook->getBids(); foreach ($asks as $ask) { $price = $ask->getPrice() ->getUnits() + $ask->getPrice() ->getNano() / pow(10, 9) ; echo 'ASK ' . $price . ' - ' . $ask->getQuantity() . PHP_EOL; } foreach ($bids as $bid) { $price = $bid->getPrice() ->getUnits() + $bid->getPrice() ->getNano() / pow(10, 9) ; echo 'BID ' . $price . ' - ' . $bid->getQuantity() . PHP_EOL; } echo 'Orderbook response finished' . PHP_EOL . PHP_EOL; } } $stream->cancel();