masyasmv / finam-sdk-laravel
PHP SDK for Finam Trade API with Laravel integration (REST).
Requires
- php: ^8.0
- ext-json: *
- guzzlehttp/guzzle: ^7.0
- illuminate/contracts: ^8.0
- illuminate/support: ^8.0
- psr/log: ^1.1 || ^2.0 || ^3.0
- psr/simple-cache: ^1.0 || ^2.0 || ^3.0
Requires (Dev)
- mockery/mockery: ^1.6
- orchestra/testbench: ^6.0
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^9.5
- vimeo/psalm: ^5.26
This package is auto-updated.
Last update: 2026-04-03 11:54:57 UTC
README
PHP SDK для Finam Trade API с удобной работой через Laravel facade и без Laravel.
Пакет решает две задачи:
- даёт простой high-level API для типовых сценариев;
- оставляет низкоуровневый клиент, если нужен прямой доступ к REST-методам.
Документация Finam: https://tradeapi.finam.ru/docs/about/
Для кого пакет
Пакет подойдёт, если ты хочешь:
- быстро получить котировки, инструменты, операции и заявки;
- работать не с сырыми массивами, а с DTO и коллекциями;
- использовать Laravel facade
Finam::...; - подключить тот же SDK в обычном PHP-проекте без Laravel.
Что уже умеет пакет
- выпуск session token через
Finam::issueToken($secret) - подключение через secret одной командой:
Finam::connectSecret($secret) - подключение сессии через
Finam::connect($token) - низкоуровневый клиент через
Finam::client($token) - операции по счёту
- список заявок и получение одной заявки
- размещение market/limit orders
- размещение SL/TP orders
- инструменты, биржи, расписание, часы рынка
- котировки, свечи, стакан, последние сделки
- usage metrics
- создание отчёта и получение информации по отчёту
- typed DTO и typed collections
- Laravel service provider и facade
Требования
- PHP
^8.0 - Laravel
^8.0для Laravel-режима ext-json
Установка
composer require masyasmv/finam-sdk-laravel
Если ты используешь Laravel, service provider и facade подключатся автоматически.
Быстрый старт
Самый короткий путь
use MasyaSmv\FinamSdk\Facades\Finam; $session = Finam::connectSecret($secret); $details = $session->sessionDetails(); $accountIds = $details->accountIds();
Если нужен явный двухшаговый flow
use MasyaSmv\FinamSdk\Facades\Finam; $issued = Finam::issueToken($secret); $sessionToken = $issued->token(); $session = Finam::connect($sessionToken); $details = $session->sessionDetails(); $accountIds = $details->accountIds(); $quotes = $session->getLatestQuotes(['SBER@MISX', 'GAZP@MISX']); $orders = $session->getOrders();
3. Получить счёт и использовать его дальше
Если в сессии только один счёт, accountId можно не передавать в часть методов.
Если счетов несколько, передавай accountId явно.
/** @var string $accountId */ $accountId = $details->accountIds()->first(); $operations = $session->getOperationsByDate( new DateTimeImmutable('2026-04-01'), new DateTimeImmutable('2026-04-03'), $accountId, ); $order = $session->getOrder('123456789', $accountId);
Примеры
Laravel: котировки и стакан
use MasyaSmv\FinamSdk\Facades\Finam; $session = Finam::connect($token); $quotes = $session->getLatestQuotes(['SBER@MISX', 'GAZP@MISX']); $sber = $quotes->first(); $orderBook = $session->getOrderBook('SBER@MISX'); $bestRow = $orderBook->rows()->first();
Laravel: свечи
use DateTimeImmutable; use MasyaSmv\FinamSdk\Dto\Market\CandlesQueryDto; use MasyaSmv\FinamSdk\Facades\Finam; $session = Finam::connect($token); $candles = $session->getCandles(new CandlesQueryDto( symbol: 'SBER@MISX', timeframe: 'M1', startDate: new DateTimeImmutable('-1 hour'), endDate: new DateTimeImmutable('now'), ));
Laravel: размещение заявки
use MasyaSmv\FinamSdk\Dto\Order\PlaceOrderInputDto; use MasyaSmv\FinamSdk\Facades\Finam; $session = Finam::connect($token); $order = $session->placeOrder( new PlaceOrderInputDto( symbol: 'SBER@MISX', quantity: '1', side: 'BUY', type: 'LIMIT', timeInForce: 'TIME_IN_FORCE_DAY', limitPrice: '250.00', ), '1930918', );
Laravel: SL/TP заявка
use MasyaSmv\FinamSdk\Dto\Order\PlaceSlTpOrderInputDto; use MasyaSmv\FinamSdk\Facades\Finam; $session = Finam::connect($token); $order = $session->placeSlTpOrder( new PlaceSlTpOrderInputDto( symbol: 'SBER@MISX', side: 'SELL', quantitySl: '1', slPrice: '240.00', quantityTp: '1', tpPrice: '270.00', ), '1930918', );
Laravel: инструменты
use MasyaSmv\FinamSdk\Facades\Finam; $session = Finam::connect($token); $instrument = $session->getInstrument('SBER@MISX', '1930918'); $allInstruments = $session->getInstruments(); $exchanges = $session->getExchanges(); $schedule = $session->getSchedule('SBER@MISX');
Laravel: usage metrics
use MasyaSmv\FinamSdk\Facades\Finam; $session = Finam::connect($token); $usage = $session->getUsageMetrics(); foreach ($usage->quotas() as $quota) { echo $quota->name() . ': ' . $quota->remaining() . PHP_EOL; }
Laravel: отчёты
use DateTimeImmutable; use MasyaSmv\FinamSdk\Dto\Report\CreateAccountReportInputDto; use MasyaSmv\FinamSdk\Dto\Report\ReportDateRangeDto; use MasyaSmv\FinamSdk\Facades\Finam; $session = Finam::connect($token); $created = $session->createAccountReport(new CreateAccountReportInputDto( accountId: '1930918', reportForm: 'REPORT_FORM_PDF', dateRange: new ReportDateRangeDto( from: new DateTimeImmutable('2026-04-01'), to: new DateTimeImmutable('2026-04-03'), ), )); $info = $session->getAccountReportInfo($created->reportId());
Обычный PHP без Laravel
Самый простой способ в обычном PHP-проекте: использовать низкоуровневый клиент.
Низкоуровневый клиент
use MasyaSmv\FinamSdk\Client\FinamClient; $client = FinamClient::make($token); $response = $client->get('/sessions/details'); if ($response->ok()) { $data = $response->data(); }
Если тебе нужен именно high-level session API вне Laravel, это тоже можно собрать вручную, но это уже более продвинутый сценарий. Для большинства plain PHP-проектов проще и понятнее начать с low-level клиента. Подробности есть в docs/low-level-client.md.
Конфигурация
Пакет не хранит токен в конфиге.
Токен всегда передаётся явно в runtime:
Finam::issueToken($secret)Finam::connectSecret($secret)Finam::connect($token)Finam::client($token)
config/finam.php хранит только настройки транспорта:
return [ 'base_url' => 'https://tradeapi.finam.ru/v1', 'http' => [ 'timeout' => 10.0, 'connect_timeout' => 5.0, 'retries' => 0, 'retry_delay_ms' => 200, 'user_agent' => 'finam-sdk-laravel', ], ];
Опубликовать конфиг в Laravel можно так:
php artisan vendor:publish --tag=finam-config
High-level API
Основной интерфейс сессии:
sessionDetails()getOperationsByDate($startDate, $endDate, ?$accountId = null, ?$limit = null)getOrders(?$accountId = null)getOrder($orderId, ?$accountId = null)placeOrder(PlaceOrderInputDto $order, ?$accountId = null)placeSlTpOrder(PlaceSlTpOrderInputDto $order, ?$accountId = null)getAllInstruments(?$cursor = null, bool $onlyActive = false, bool $onlyDisabled = false)getInstruments()getInstrument($symbol, ?$accountId = null)getExchanges()getClock()getSchedule($symbol)getLatestQuotes(array $symbols)getCandles(CandlesQueryDto $query)getOrderBook($symbol)getLatestTrades($symbol)getUsageMetrics()createAccountReport(CreateAccountReportInputDto $report)getAccountReportInfo($reportId)
Все эти методы возвращают DTO или typed collections.
Для входа в high-level API есть два варианта:
- короткий shortcut:
Finam::connectSecret($secret) - явный вариант:
Finam::issueToken($secret)и потомFinam::connect($token)
Typed collections
Коллекции наследуются от Illuminate\Support\Collection, поэтому доступны привычные методы:
first()count()map()filter()pluck()all()
Плюс у части коллекций есть удобные методы:
OrderCollection::findById($orderId)InstrumentCollection::findBySymbol($symbol)
Низкоуровневый клиент
Если high-level API тебе не подходит, можно работать напрямую через REST-клиент:
use MasyaSmv\FinamSdk\Facades\Finam; $client = Finam::client($token); $response = $client->get('/accounts/1930918/orders');
Доступные resource wrappers:
$client->auth()$client->connect()$client->account()$client->order()$client->instrument()$client->market()$client->usageMetrics()$client->reports()
Ошибки
Основные типы исключений:
InvalidRequestException
Когда входные данные некорректны ещё до отправки запроса.ApiHttpException
Когда Finam вернул HTTP-ошибку и её нужно обработать как ответ API.ApiRequestFailedException
Когда сломался transport-уровень: сеть, таймаут, невозможность выполнить запрос.InvalidResponseException
Когда сервер вернул битый или неожиданный ответ.ResponseMappingException
Когда ответ пришёл, но не соответствует ожидаемому shape.AccountResolutionException
Когда пакет не может сам выбрать счёт.
Пример:
use MasyaSmv\FinamSdk\Exceptions\ApiHttpException; use MasyaSmv\FinamSdk\Exceptions\InvalidRequestException; try { $quotes = Finam::connect($token)->getLatestQuotes(['SBER@MISX']); } catch (InvalidRequestException $e) { report($e); } catch (ApiHttpException $e) { report($e); }
Где смотреть полную документацию
- Полная карта документации
- Установка и настройка
- Быстрый старт
- High-level session API
- Низкоуровневый клиент
- Ошибки и диагностика
- FAQ
Тесты и качество
composer test
composer analyse
composer psalm
CI проверяет:
composer validate --strictphpunitphpstanpsalm- матрицу
prefer-stableиprefer-lowest
Ограничения и честные ожидания
- пакет не делает бизнес-логику стратегии за тебя
- пакет не хранит токены
- пакет не открывает browser login flow сам
- для некоторых broker-side сценариев Finam может возвращать ограничения по правам, даже если SDK работает корректно
- отчёты уже поддерживаются, но конкретные значения
reportFormстоит сверять с актуальной документацией и правами твоего аккаунта
Лицензия
MIT. См. LICENSE.