masyasmv/finam-sdk-laravel
Finam SDK for Laravel and PHP
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.
Related Packages
Helps building nice, normalized and easy to consume Laravel REST API.
This package is wrapper for php Ebay sdk for laravel to automate all the configu...
Easy way to interact with ExactTarget REST API in Laravel