metaseller//tinkoff-invest-api-v2-php

Tinkoff Invest API v2 的非官方 PHP SDK

0.4.12 2024-09-19 05:51 UTC

This package is auto-updated.

Last update: 2024-09-19 05:52:02 UTC


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 文档。

  1. 使用 PHP 快速入门 -> https://grpc.org.cn/docs/languages/php/quickstart/
  2. 基本教程 -> 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 的内容未使用。

如果您想自行生成模型,则需要

  1. 安装 protoc
  2. 构建 grpc_php_plugin 插件(见 https://grpc.org.cn/docs/languages/php/basics/#setup
  3. 调用如下
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();