PHPackages                             masyasmv/aton-statement-parser - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [PDF &amp; Document Generation](/categories/documents)
4. /
5. masyasmv/aton-statement-parser

ActiveLibrary[PDF &amp; Document Generation](/categories/documents)

masyasmv/aton-statement-parser
==============================

Parser and normalizer for ATON broker XML statements. Converts raw XML reports into structured DTOs for convenient data access.

v0.2.0(1mo ago)00MITPHPPHP ^8.0CI passing

Since Feb 10Pushed 1mo agoCompare

[ Source](https://github.com/MasyaSmv/aton-statement-parser)[ Packagist](https://packagist.org/packages/masyasmv/aton-statement-parser)[ Docs](https://github.com/MasyaSmv/aton-statement-parser)[ RSS](/packages/masyasmv-aton-statement-parser/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (3)Dependencies (7)Versions (9)Used By (0)

aton-statement-parser
=====================

[](#aton-statement-parser)

Пакет для парсинга XML-отчётов брокера **Атон** в удобную доменную структуру данных. Сейчас библиотека ориентирована на поддержку:

- старого BIS-формата `BIS:BISPeriod`,
- нового XML-формата на основе ``.

Цель та же: привести оба формата к единой модели отчёта, чтобы в проекте можно было:

- передать путь до XML-файла,
- получить объект отчёта (`ReportInterface`),
- быстро выбрать нужный блок (`Trades`, `MoneyInOut`, `StockInOut`, `TradesRegRepo`, `ClientMoneyConvert`, `StockPayingOff`, …),
- найти операцию по `OperID`,
- собрать список всех `OperID` (например, для сверки с БД),
- работать с атрибутами строк через удобные геттеры (строки/даты/числа) без «магических» индексов массива,
- получать диагностику по новым или неожиданным структурам отчёта,
- сохранять derived legacy-совместимые секции для modern XML там, где прямого источника нет.

> Цель: минимальная боль при работе с реальными отчётами старого и нового форматов, сохраняя единый API.

---

Быстрый старт
-------------

[](#быстрый-старт)

```
use MasyaSmv\AtonStatementParser\AtonStatementParser;

$report = AtonStatementParser::fromFile('/path/to/report.xml');

// Доступ к секциям (универсально)
$trades = $report->section('Trades')->rows();      // RowCollection
$money  = $report->section('MoneyInOut')->rows();  // RowCollection

// DTO-уровень для типовых сценариев
$commonData = $report->commonData();               // ?CommonData
$tradeDtos  = $report->trades();                   // TradeCollection
$moneyDtos  = $report->moneyInOut();               // MoneyOperationCollection
$moneyState = $report->moneyOnDate();              // MoneyBalanceCollection
$stockState = $report->stockOnDate();              // StockBalanceCollection
$fxDtos     = $report->moneyConvert();             // MoneyConvertCollection
$stockDtos  = $report->stockInOut();               // StockTransferCollection
$payoffDtos = $report->stockPayingOff();           // StockPayingOffCollection
$corpInDtos = $report->corporateActionsIn();       // CorporateActionCollection
$corpOutDtos = $report->corporateActionsOut();     // CorporateActionCollection

// Поиск по OperID
$row = $report->findOperId('567890123');           // Row|null

// Список всех OperID (для сверки)
$ids = $report->operIds();                         // OperIdCollection

// Диагностика неизвестных структур и ключей
$diagnostics = $report->diagnostics();             // DiagnosticCollection
$hasWarnings = $report->hasDiagnostics();          // bool

// Удобные геттеры атрибутов
$type = $report->section('Trades')->rows()->get(0)->getString('TradeType');
$date = $report->section('Trades')->rows()->get(0)->getDate('OperDateSort'); // DateTimeImmutable|null
```

---

Проблемы, которые решает пакет
------------------------------

[](#проблемы-которые-решает-пакет)

### 1) Два формата отчёта

[](#1-два-формата-отчёта)

Старые отчёты используют `BIS:BISPeriod`, новые идут через ``. Библиотека должна уметь читать оба формата и сводить их к одной модели.

### 2) Namespace BIS

[](#2-namespace-bis)

XML использует `xmlns:BIS=...`, значит нельзя просто «по имени тега» — нужен XPath с корректной регистрацией namespace.

### 3) Кодировка windows-1251 и UTF-8 BOM

[](#3-кодировка-windows-1251-и-utf-8-bom)

В старых отчётах встречается `encoding="windows-1251"`, а в новых возможен `utf-8` с BOM. Пакет должен безопасно привести документ к корректному виду перед парсингом.

### 4) Разные форматы дат

[](#4-разные-форматы-дат)

В отчётах встречаются:

- `29.12.2023`
- `02.10.24`
- `16.11.18`
- `26.12.24 / ` (мусорные хвосты)

Нужен нормализатор даты: трим + поддержка `d.m.Y` и `d.m.y`.

В новом формате встречаются и ISO-значения, например `2024-02-01T00:00:00`.

### 5) Десятичные числа

[](#5-десятичные-числа)

Количество и суммы — строки с точностью (`100000.00000000`). Базовый слой хранит как string, а геттеры умеют приводить к float/int при необходимости.

### 6) Новые структуры и неожиданные ключи

[](#6-новые-структуры-и-неожиданные-ключи)

Если брокер меняет XML и в отчёте появляется:

- новый `source` в modern-формате,
- неизвестная legacy-секция,
- неожиданный ключ внутри уже известной структуры,

библиотека не теряет данные молча. Она продолжает парсинг и добавляет предупреждения в `Report->diagnostics()`.

---

Архитектура (как планируем)
---------------------------

[](#архитектура-как-планируем)

### Основные сущности

[](#основные-сущности)

- **Report** — весь отчёт, доступ к секциям и общим данным.
- **Section** — один блок внутри отчёта (например `Trades`, `MoneyInOut`).
- **Row** — одна строка секции в каноническом виде. Хранит имя секции, исходный тип записи, immutable-атрибуты и типовые геттеры.
- **RowCollection / OperIdCollection / AttributeBag** — immutable коллекции и value objects для публичной модели.

### Уровни удобства

[](#уровни-удобства)

1. **Базовый (универсальный)**: `Report/Section/Row` — работает для любых секций без генерации десятков DTO.
2. **Продвинутый (DTO для популярных секций)**: `CommonData`, `Trade`, `MoneyOperation` и т.п. — добавляются постепенно поверх канонической модели. На текущем этапе доступны также DTO для `MoneyOnDate`, `StockOnDate*`, `MoneyConvert`, `StockInOut`, `StockPayingOff`, `CorpActionIn`, `CorpActionOut`.

---

Структура проекта (план)
------------------------

[](#структура-проекта-план)

```
src/
  AtonStatementParser.php          // fromFile/fromString
  Collections/
    CorporateActionCollection.php   // immutable коллекция корпоративных действий
    MoneyBalanceCollection.php      // immutable коллекция денежных остатков
    MoneyConvertCollection.php      // immutable коллекция конверсионных операций
    MoneyOperationCollection.php    // immutable коллекция денежных операций
    RowCollection.php              // immutable коллекция строк
    OperIdCollection.php           // immutable коллекция OperID
    StockBalanceCollection.php     // immutable коллекция остатков по бумагам
    StockPayingOffCollection.php   // immutable коллекция погашений/выплат
    StockTransferCollection.php    // immutable коллекция переводов бумаг
    TradeCollection.php            // immutable коллекция сделок
  Contracts/
    Mappers/
      ...MapperInterface.php       // интерфейсы DTO-мапперов
  Dto/
    CommonData.php                 // DTO общих данных отчёта
    CorporateAction.php            // DTO корпоративного действия
    MoneyBalance.php               // DTO денежного остатка
    MoneyConvertOperation.php      // DTO валютной конверсии
    Trade.php                      // DTO сделки
    MoneyOperation.php             // DTO денежной операции
    StockBalance.php               // DTO остатка по бумаге
    StockPayingOff.php             // DTO погашения/выплаты по бумаге
    StockTransfer.php              // DTO перевода/списания бумаги
  Mappers/
    CommonDataMapper.php           // Row -> CommonData
    CorporateActionMapper.php      // Row -> CorporateAction
    MoneyBalanceMapper.php         // Row -> MoneyBalance
    MoneyConvertMapper.php         // Row -> MoneyConvertOperation
    TradeMapper.php                // Row -> Trade
    MoneyOperationMapper.php       // Row -> MoneyOperation
    StockBalanceMapper.php         // Row -> StockBalance
    StockPayingOffMapper.php       // Row -> StockPayingOff
    StockTransferMapper.php        // Row -> StockTransfer
  Parsing/
    ReportParserResolver.php       // выбор парсера по формату документа
    LegacyBisReportParser.php      // старый BIS-формат
    ModernXmlReportParser.php      // новый root/source формат
    KnownLegacySchema.php          // known-schema legacy секций и ключей
    KnownModernSchema.php          // known-schema modern source и ключей
    SectionNameResolver.php        // канонизация имён секций
  Report/
    Report.php                     // секции отчёта
    Section.php                    // имя секции + RowCollection
    Row.php                        // строка секции + геттеры
    AttributeBag.php               // immutable-атрибуты строки
    ParseDiagnostic.php            // диагностика структуры парсинга
    DiagnosticCollection.php       // immutable коллекция диагностик
  Support/
    DecimalStringMath.php          // точная строковая арифметика для derived aggregate-секций
  Xml/
    XmlLoader.php                  // чтение файла, encoding -> utf8, DOM
    XPathFactory.php               // DOMXPath + регистрация namespace
  Normalizers/
    DateNormalizer.php             // даты (d.m.y / d.m.Y, мусорные хвосты)
    NumberNormalizer.php           // числа/десятичные строки
    StringNormalizer.php           // trim/cleanup
  Exceptions/
    ParseException.php
    InvalidXmlException.php

tests/
  Fixtures/
    aton/
      ...xml
  ...

```

---

Roadmap / План работ
--------------------

[](#roadmap--план-работ)

### ✅ Уже сделано

[](#-уже-сделано)

- Базовый каркас пакета (autoload, тесты)
- Fixtures подключены в тесты
- Скрипты composer для `test`, `cs:*`, `stan` (если настроено)
- Поддержка старого BIS-формата
- Базовая поддержка нового root/source формата
- Immutable collections в публичной модели

### 🚧 Этап A — «сразу полезно»

[](#-этап-a--сразу-полезно)

- `AtonStatementParser::fromFile(string $path): ReportInterface`
- `AtonStatementParser::fromString(string $xml): ReportInterface`
- `Report->section(string $name): Section`
- `Section->rows(): RowCollection`
- `Report->operIds(): OperIdCollection`
- `Report->findOperId(string $id): ?Row`
- Unit-тесты на fixtures (operIds/findOperId/section)

### 🚧 Этап B — нормализация типов

[](#-этап-b--нормализация-типов)

- `Row->getString($key)` / `getInt($key)` / `getFloat($key)`
- `Row->getDecimalString($key)` (без потери точности)
- `Row->getDate($key): ?DateTimeImmutable` (с поддержкой форматов)
- Базовые тесты на даты/числа
- Фактический coverage доведён до `100%` по строкам/методам/классам
- Подтверждена паритетная канонизация core-секций на парных real fixtures `old/new`
- `PortfolioMoney` нового формата разложен на `MoneyOnDate`, `MoneyOnDate_MarketPrc`, `MoneyOnDate_ByOperPlace`
- Для `MoneyInOut_io` добавлено схлопывание строго симметричных `+/-` дублей до legacy-compatible результата
- `StockOnDate_Exg_Sum` нового формата вычисляется как derived aggregate по строкам `StockOnDate_Exg`
- Synthetic legacy-совместимые секции помечаются диагностикой `synthetic_legacy_section`
- Уточнить бизнес-смысл `MoneyOnDate_single`, если для него появится прямой modern-источник или подтверждённая формула

### 🚧 Этап C — DTO (точечно, только нужное)

[](#-этап-c--dto-точечно-только-нужное)

- `Report->trades(): TradeCollection`
- `Report->moneyInOut(): MoneyOperationCollection`
- `Report->moneyOnDate(): MoneyBalanceCollection`
- `Report->stockOnDate(): StockBalanceCollection`
- `Report->moneyConvert(): MoneyConvertCollection`
- `Report->stockInOut(): StockTransferCollection`
- `Report->stockPayingOff(): StockPayingOffCollection`
- `Report->corporateActionsIn(): CorporateActionCollection`
- `Report->corporateActionsOut(): CorporateActionCollection`
- Базовые мапперы секций → DTO
- Расширить DTO-покрытие на дополнительные секции
- Довести базовые тесты DTO-маппинга

### 🚧 Этап D — удобства для больших отчётов

[](#-этап-d--удобства-для-больших-отчётов)

- Фильтры/поиск: `section()->where(fn(Row $r) => ...)`
- Индексация по `OperID` (лениво или при первом вызове)
- Сортировка операций по дате/времени
- Поиск по бумаге по названию и `ISIN`
- Collection-style методы в духе ORM/Laravel: `count()`, `sum()`, `filter()`, `map()`, `firstWhere()`, `sortBy()`
- Улучшение ошибок парсинга (контекст, позиция)

---

Fixtures и безопасность
-----------------------

[](#fixtures-и-безопасность)

- В репозиторий коммитим **только обезличенные** XML.
- Реальные отчёты для локальной отладки — держать в `tests/FixturesLocal/` (и добавить в `.gitignore`).

Рекомендуется добавить `.gitattributes`, чтобы не ловить «невидимые» правки концов строк (LF/CRLF).

---

Installation
------------

[](#installation)

```
composer require masyasmv/aton-statement-parser
```

---

Development
-----------

[](#development)

```
composer install
composer test
composer deptrac
composer cs:fix
composer cs:check
composer stan
composer psalm
composer test:coverage
composer coverage:check
```

Mutation testing вынесен в отдельный workflow и отдельную команду:

```
composer infection
```

Локально `composer infection` и `composer test:coverage` требуют coverage driver (`pcov` или `xdebug`). В CI они запускаются через `setup-php` с `pcov`.

Текущее состояние локального test coverage:

- строки: `100%`
- методы: `100%`
- классы: `100%`

Documentation
-------------

[](#documentation)

Подробная карта библиотеки, слоёв, канонических секций, DTO API и точек расширения:

- [docs/LibraryGuide.md](docs/LibraryGuide.md)

Versioning
----------

[](#versioning)

Проект следует Semantic Versioning.

- `MAJOR` для несовместимых изменений API
- `MINOR` для обратно совместимого функционала
- `PATCH` для обратно совместимых исправлений

Формат релизного тега:

```
vX.Y.Z
```

Releases
--------

[](#releases)

- `CHANGELOG.md` ведётся в репозитории и должен обновляться перед релизом.
- GitHub Release создаётся автоматически при push тега формата `v*.*.*`.
- Для выпуска релиза достаточно создать и отправить тег:

```
git tag v0.1.1
git push origin v0.1.1
```

---

License
-------

[](#license)

MIT. См. файл [LICENSE](LICENSE).

###  Health Score

34

—

LowBetter than 77% of packages

Maintenance90

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity34

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

2

Last Release

49d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/f29a405df86487468d199f9525b44185d3bd3a81ccca962f75e0517a9ea44682?d=identicon)[MasyaSmv](/maintainers/MasyaSmv)

---

Top Contributors

[![MasyaSmv](https://avatars.githubusercontent.com/u/61746307?v=4)](https://github.com/MasyaSmv "MasyaSmv (32 commits)")

---

Tags

xmlparserreportdtofinancestatementbrokeraton

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan, Psalm

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/masyasmv-aton-statement-parser/health.svg)

```
[![Health](https://phpackages.com/badges/masyasmv-aton-statement-parser/health.svg)](https://phpackages.com/packages/masyasmv-aton-statement-parser)
```

###  Alternatives

[smalot/pdfparser

Pdf parser library. Can read and extract information from pdf file.

2.7k34.5M216](/packages/smalot-pdfparser)[mledoze/countries

List of world countries in JSON, CSV, XML and YAML

6.2k699.7k6](/packages/mledoze-countries)[shuchkin/simplexlsx

Parse and retrieve data from Excel XLSx files. MS Excel 2007 workbooks PHP reader.

1.8k3.8M21](/packages/shuchkin-simplexlsx)[faisalman/simple-excel-php

Easily parse / convert / write between Microsoft Excel XML / CSV / TSV / HTML / JSON / etc formats

582599.4k1](/packages/faisalman-simple-excel-php)[rodenastyle/stream-parser

PHP Multiformat Streaming Parser

443195.7k2](/packages/rodenastyle-stream-parser)[netcarver/textile

Textile markup language parser

2311.5M16](/packages/netcarver-textile)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
