Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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

English | Русский | Українська | Srpski | Српски

Автоматическая генерация налоговых деклараций ППДГ-3Р (прирост капитала) и ПП ОПО (доходы от капитала) для пользователей Interactive Brokers в Сербии.

Программа загружает ваши сделки из Interactive Brokers и создаёт готовый XML-файл для ePorezi. Она отслеживает всю цепочку покупок и продаж по каждой бумаге, рассчитывает прибыль и убытки, и пересчитывает все суммы в динары по официальному курсу НБС на дату каждой сделки — именно так, как требует декларация.

Установка

⚠️ Windows и macOS заблокируют загрузку или запуск — программа распространяется бесплатно, и платить ~100 евро в год за сертификат разработчика нет возможности. В инструкции по установке написано как это обойти — прочитайте её перед скачиванием.

Инструкция по установке ↗

Как пользоваться

  1. Откройте программу — она запустится с графическим интерфейсом.
  2. Нажмите Config и введите ваши данные Interactive Brokers.
  3. Нажмите Sync now — программа загрузит последние сделки и создаст декларации.
  4. Загрузите созданный XML-файл на портал ePorezi (раздел ППДГ-3Р).

ППДГ-3Р

💡 После этого, пока программа открыта, она сама проверяет наличие новых данных — раз в день, в фоновом режиме, повторяя попытки до успеха. Статус последней попытки всегда виден в верхней части окна.

ℹ️ Если у вас больше года истории сделок в Interactive Brokers — перед первым Sync нужно загрузить старые данные вручную. Как это сделать ↗


Подробная документация по командной строке и другим возможностям — в разделе Использование ↗.

English | Русский | Українська | Srpski | Српски

Установка

Инсталлятор

Скачайте готовый инсталлятор со страницы релизов:

https://github.com/andgineer/ibkr-porez/releases

macOS

Скачайте последний .pkg файл. Поскольку инсталлятор не подписан сертификатом Apple, macOS заблокирует его при открытии.

“IBKR Porez” повреждён и не может быть открыт. Следует переместить его в корзину.

Не перемещайте в корзину. Вместо этого:

  1. Откройте Системные настройки → Конфиденциальность и безопасность
  2. В нижней части раздела «Безопасность» появится сообщение о заблокированном приложении — нажмите «Открыть всё равно»
  3. В следующем диалоге подтвердите открытие

Может потребоваться повторить эти шаги два раза:

  • сначала при открытии скачанного установщика (.dmg)
  • и затем при первом запуске установленного приложения из /Applications

После этого приложение должно запускаться без предупреждений.

Windows

Скачайте последний .msi файл. Поскольку инсталлятор не подписан цифровой подписью, Windows может показать предупреждения безопасности.

Если браузер блокирует загрузку (например, в Microsoft Edge):

  1. Откройте панель загрузок браузера (Ctrl+J)
  2. Найдите заблокированную загрузку .msi
  3. Нажмите «Сохранить»«Показать больше»«Сохранить всё равно»

При запуске инсталлятора Windows может показать сообщение Windows защитил ваш компьютер:

  1. Нажмите «Подробнее»
  2. Нажмите «Выполнить в любом случае»

Также может появиться окно контроля учетных записей с текстом Неизвестный издатель. Если файл загружен с официальной страницы релизов, нажмите «Да» для продолжения.

После установки IBKR Porez появится в меню Пуск.


Для продвинутых пользователей

Инсталлятор помимо GUI также устанавливает команду ibkr-porez для терминала (может потребоваться перезапуск терминала после установки).

Скачать готовый бинарный файл

Также можно скачать бинарные файлы для вашей платформы со страницы релизов:

https://github.com/andgineer/ibkr-porez/releases

Архив содержит оба бинарных файла: ibkr-porez (CLI) и ibkr-porez-gui (GUI). Распакуйте архив и поместите файлы в директорию, указанную в PATH.

Сборка из исходников

Если у вас установлен Rust:

cargo install ibkr-porez

English | Русский | Українська | Srpski | Српски

Использование

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

Если вы хотите быстро создать конкретную декларацию:

  1. Настройте данные (config) ↗ — один раз при первом запуске
  2. Загрузите последние данные (fetch) ↗
  3. Создайте отчет (report) ↗
  4. Загрузите созданный XML на портал ePorezi (раздел ППДГ-3Р)

Если нужно автоматически получать все декларации и вести учёт их статусов — используйте sync вместо шагов 2–3.


Настройка (config)

ibkr-porez config

Создание или изменение личных данных и настроек доступа к IBKR.

Вам будет предложено ввести:

  • IBKR Flex Token: Получение токена ↗
  • IBKR Query ID: Создание Flex Query ↗
  • Personal ID: JMBG / EBS
  • Full Name: Имя и Фамилия
  • Address: Адрес регистрации
  • City Code: 3-значный код муниципалитета. Пример: 223 (Нови Сад). Код можно найти в справочнике (смотрите колонку “Шифра”). Также код доступен в выпадающем списке на портале ePorezi.
  • Phone: Телефон
  • Email: Email
  • Data Directory: Абсолютный путь к папке с файлами данных (transactions.json, declarations.json, rates.json и т.д.). По умолчанию: ibkr-porez-data в папке приложения.
  • Output Folder: Абсолютный путь к папке для сохранения файлов из команд sync, export, export-flex, report. По умолчанию: папка Downloads вашей системы.

Получение данных (fetch)

ibkr-porez fetch

Загружает последние данные из IBKR и синхронизирует курсы валют с НБС (Национальный банк Сербии).

Сохраняет их в локальное хранилище.

Импорт исторических данных (import)

ibkr-porez import /path/to/activity_statement.csv

Загрузка истории транзакций старше 365 дней, которые невозможно получить через Flex Query (fetch).

Чтобы создать файл с транзакциями на портале Interactive Brokers смотрите Экспорт всей истории ↗

⚠️ Не забудьте после import выполнить fetch чтобы приложение добавило максимум деталей хотя бы за последний год в менее подробные данные загруженные из CSV.

Логика синхронизации (import + fetch)

При загрузке данных из CSV (import) и Flex Query (fetch) система отдает приоритет более полным данным Flex Query:

  • Данные Flex Query (fetch) являются источником правды. Они перезаписывают данные CSV за любые совпадающие даты.
  • Если запись Flex Query совпадает с CSV по смыслу (Дата, Тикер, Цена, Количество), это считается обновлением (заменой на официальный ID).
  • Если структура данных отличается (например, сплит ордеров в Flex Query против “склеенной” записи в CSV), старая запись CSV удаляется, а новые записи Flex Query добавляются.
  • Полностью идентичные записи пропускаются.

Синхронизация данных и создание деклараций (sync)

ibkr-porez sync

Делает все то же, что и fetch:

  • Загружает последние транзакции из IBKR через Flex Query
  • Синхронизирует курсы валют с НБС

После чего создает все необходимые декларации за последние 45 дней (если они уже не были созданы).

Доход, попавший в приложение с опозданием — после неудачного соединения, из-за отсутствующего курса или просто потому, что IBKR сообщил о нём через несколько дней, — будет подхвачен следующим sync, пока его дата остаётся внутри этих 45 дней. Отметки «синхронизировано до такого-то дня» не существует, поэтому запоздавшие данные не теряются.

Более старый доход приложение не декларирует по собственной инициативе: срок подачи по нему уже прошёл, поэтому подавать его — ваше решение. Попросите об этом явно, расширив окно:

# задекларировать незадекларированный доход за последние 400 дней
ibkr-porez sync --lookback 400

💡 Если соединение с IBKR не удалось, sync всё равно создаёт декларации из уже сохранённых локально транзакций и выводит предупреждение; команда завершается успешно, а в GUI повтор за свежими данными продолжается автоматически на следующем цикле.

Далее вы можете Управлять созданными декларациями.

💡 Если вы запустили sync в первый раз и она создала декларации которые вы уже подали до начала использования приложения вы можете быстро пометить их все как оплаченные и убрать из выдачи list:

ibkr-porez list --status submitted -1 | ibkr-porez pay

Синхронизация из скачанного XML файла (sync --file)

Если IBKR API временно недоступен, вы можете вручную скачать XML Flex Query с сайта IBKR и использовать его:

ibkr-porez sync --file /path/to/report.xml

Делает всё то же, что и sync — сохраняет транзакции, создаёт все необходимые декларации — но читает данные из локального файла, не обращаясь к IBKR API.

Смотрите как скачать XML Flex Query ↗.

В GUI та же возможность доступна в меню как Sync from Flex Query XML….

Измененные декларации

Удержанный за рубежом налог не окончательный. После закрытия года американский фонд сообщает брокеру окончательный налоговый характер прошлогодних выплат, и брокер сторнирует удержанное — обычный случай для казначейского ETF, выплата которого оказалась процентным дивидендом, — а если новый характер того требует, удерживает заново. Это происходит в срок от нескольких недель до примерно пятнадцати месяцев после выплаты.

Когда суммы, на которых построена уже созданная декларация PP OPO, меняются, следующий sync создает измененную декларацию (измењена пријава). Это обычная декларация во всем: она попадает в list, получает свой XML в папке вывода, подается и оплачивается как любая другая. Под строкой о созданной декларации sync печатает дату получения дохода и номер оригинала — то, по чему оригинал находится в таблице ePorezi.

Измененную декларацию нужно подать: она заменяет первоначальную. Если номер оригинала записан через submit --number, он уже в документе; иначе впишите его в ePorezi, найдя оригинал по дате получения дохода.

Сравнение делается в валюте дохода, поэтому изменившийся курс никогда не приводит к измененной декларации. Такие изменения sync ищет до 1 января предыдущего года, каким бы ни было окно создания новых деклараций.

Просмотр статистики (stat)

ibkr-porez stat --year 2025
ibkr-porez stat --ticker AAPL
ibkr-porez stat --month 2025-01

Показывает:

  • Полученные дивиденды (в RSD)
  • Количество продаж (налогооблагаемых событий)
  • Оценку реализованного P/L (Капитальный доход) (в RSD)
  • Детальную разбивку по тикерам или месяцам (при использовании фильтров)

Генерация налогового отчета (report)

ibkr-porez report

Если не указать тип отчета и период то по умоланию генерируется ППДГ-3Р за последнее полное полугодие

  • Создаст ppdg3r_XXXX_HY.xml в Output Folder
  • Импортируйте этот файл на портал Налоговой администрации Сербии (ePorezi)
  • Вручную загрузите в пункт 8 файл с Документ подтверждения

Как выбрать другой тип декларации или период времени смотрите в документации

ibkr-porez report --help

ПП ОПО за период (report --type income)

# доход текущего месяца по сегодняшний день
ibkr-porez report --type income

# явно заданный период
ibkr-porez report --type income --start 2025-07-01 --end 2025-12-31

Записывает в папку вывода по одному XML ПП ОПО на каждую группу дохода и больше ничего не делает: декларация при этом не создаётся, поэтому такие файлы не попадают в list, не сверяются с тем, что уже создал sync, и никогда не приводят к изменённым декларациям. Декларации, которые вы собираетесь вести, создаёт sync.

Группа, по которой ещё не пришёл удержанный налог, не записывается. Вместо файла команда печатает, с какой даты она будет задекларирована: налог обычно проводится в течение нескольких дней после дохода, и документ с зачётом, который брокер ещё не досчитал, стоит подождать. После этой даты группа записывается с нулевым зачётом и полными 15% к уплате — именно это вы подаёте, если налог так и не придёт.

--force это ожидание не сокращает. Он означает только «сгенерировать по приблизительным данным»: если у Народного банка нет курса на дату, берётся ближайший из кэша, а если нет данных о праздниках за год, срок уплаты считается только по будним дням.

Управление декларациями

После создания деклараций через команду sync вы можете просматривать их, изменять статус и экспортировать для загрузки на налоговый портал.

Список деклараций (list)

Показывает список всех деклараций с возможностью фильтрации по статусу.

# Показать активные декларации (по умолчанию):
# draft + submitted + pending
ibkr-porez list

# Показать все декларации
ibkr-porez list --all

# Фильтр по статусу
ibkr-porez list --status draft
ibkr-porez list --status submitted
ibkr-porez list --status pending
ibkr-porez list --status finalized

# Только ID деклараций (для использования в пайпах)
ibkr-porez list --ids-only
ibkr-porez list --status draft -1

Пример использования в linux-стиле:

# Отправить все черновики
ibkr-porez list --status draft -1 | ibkr-porez submit

Просмотр деталей декларации (show)

Показывает подробную информацию о конкретной декларации.

ibkr-porez show <declaration_id>

Отображает:

  • Тип декларации (PPDG-3R или PP OPO)
  • Период декларации
  • Статус (черновик, отправлена, ожидает решения, завершена)
  • Детали транзакций и расчетов
  • Для PPDG-3R: признанные налоговой доход/убыток рядом с расчётными, использованный перенос капитальных убытков (открытый/использованный/ скорректированный/закрытый остаток) и из каких “порций” он списан
  • Прикрепленные файлы

Подача декларации (submit)

ibkr-porez submit <id> [<id> ...]

# записать номер, присвоенный декларации налоговым порталом
ibkr-porez submit <id> --number 1234567890

Отмечает декларацию как поданную (импортированную на налоговый портал).

Поведение зависит от типа декларации:

  • PPDG-3R после submit переходит в статус pending (ожидание решения налоговой по сумме налога).
  • PP OPO после submit:
    • переходит в submitted, если есть налог к уплате;
    • сразу переходит в finalized, если налог к уплате 0.

--number записывает номер декларации на налоговом портале — от 1 до 19 цифр, для одной декларации за раз. Если декларацию потом придется изменить, измененная декларация несет этот номер, чтобы налоговая понимала, какую декларацию она заменяет. Без него измененная декларация все равно создается, а номер вы вписываете в ePorezi.

В GUI кнопка Submit открывает диалог подтверждения с тем же необязательным полем.

Оплата декларации (pay)

ibkr-porez pay <id> [<id> ...]
ibkr-porez pay <id> --tax 1234.56

Отмечает декларацию как завершенную (finalized) и сохраняет дату оплаты.

Опция --tax позволяет сразу зафиксировать сумму налога при оплате, без отдельного шага assess.

После этого декларация исчезнет из списка показываемого list (без --all)

Фиксация суммы по решению налоговой (assess)

# Записать сумму налога по решению
ibkr-porez assess <declaration_id> --tax 1234.56

# Записать сумму и сразу отметить как уже оплаченную
ibkr-porez assess <declaration_id> --tax 1234.56 --paid

# Записать признанный налоговой убыток (только для PPDG-3R)
ibkr-porez assess <declaration_id> --loss 50000.00 \
    --reference "RES-123/2025" --date 2025-09-01

# Записать признанный налоговой доход (только для PPDG-3R)
ibkr-porez assess <declaration_id> --gain 12000.00

Команда нужна в первую очередь для PPDG-3R, где сумма налога, а также признанный капитальный доход/убыток определяются налоговой после подачи декларации.

Что делает команда:

  • записывает официальную сумму налога в метаданные декларации (--tax);
  • при --paid сразу переводит декларацию в finalized;
  • без --paid:
    • если сумма больше нуля, оставляет декларацию активной (submitted) для последующей оплаты;
    • если сумма равна нулю, переводит декларацию в finalized.

Должна быть указана хотя бы одна из опций: --tax, --gain, --loss.

--gain и --loss доступны только для PPDG-3R и записывают признанные налоговой капитальный доход/убыток — они сохраняются рядом с расчётными значениями приложения и могут от них отличаться (из-за CPI-корректировок или методики налоговой). Одно решение не может одновременно признавать и доход, и убыток.

--reference, --date и --notes — данные о решении (номер, дата, заметки). Они отображаются в show, а для признанного убытка номер и дата решения дополнительно подставляются в часть 7 будущих деклараций ППДГ-3Р (см. перенос капитальных убытков), поэтому их стоит записывать.

Если решение признаёт убыток (--loss больше нуля), создаётся (или обновляется) запись в реестре переноса капитальных убытков. Перенос всегда строится на признанном налоговой убытке, а не на расчётном.

⚠️ После того как перенесённый убыток хотя бы частично использован в одной из последующих деклараций, изменить признанный убыток через assess уже нельзя — команда вернёт ошибку.

Перенос капитальных убытков (carryforward)

ibkr-porez carryforward

Показывает список всех “порций” (vintages) признанных налоговой капитальных убытков, доступных для переноса на будущие периоды:

  • декларация-источник и период, за который убыток признан;
  • признанная и оставшаяся (неиспользованная) сумма;
  • налоговый год, после которого перенос “сгорает” (убыток можно переносить на 5 лет вперёд);
  • статус: Active (можно использовать), Exhausted (использован полностью), Expired (истёк срок).

В GUI тот же список доступен в меню Capital loss carryforward….

Каждая декларация ППДГ-3Р, создаваемая через sync, автоматически уменьшает расчётную налоговую базу за счёт доступных переносов (от старых периодов к новым), пока база не обнулится или переносы не закончатся. Предпросмотр report показывает использованную и оставшуюся после этого сумму переноса. Сумма списывается из реестра один раз — при сохранении декларации; повторный sync за тот же период ничего не списывает повторно.

Переносимые убытки также заявляются в самой декларации: в XML ППДГ-3Р заполняется часть 7 («Капитални губици») — по строке на каждый действующий перенос, с номером и датой решения налоговой (7.2/7.3) и оставшейся суммой убытка (7.4). Итоговые Osnovica и PorezZaUplatu в XML тоже учитывают применённый перенос. Заявить убыток в части 7 обязан сам налогоплательщик — без этого налоговая не применит его в решении.

Номер и дата решения берутся из assess (--reference и --date). Если они не записаны, поля 7.2/7.3 в XML останутся пустыми, а report выведет предупреждение — запишите их через assess и сгенерируйте отчёт заново, либо заполните эти поля на портале вручную.

Экспорт декларации (export)

ibkr-porez export <declaration_id>
ibkr-porez export <declaration_id> -o /path/to/output

Копирует XML и все прикрепленные файлы (attach) в Output Folder или в указанный в параметрах каталог.

Откат статуса декларации (revert)

# Откатить к черновику (по умолчанию)
ibkr-porez revert <id> [<id> ...]

# Откатить к отправленной
ibkr-porez revert <id> [<id> ...] --to submitted

Откатывает статус декларации.

Удаление декларации (delete)

# Предпросмотр плана (ничего не меняет)
ibkr-porez delete <id>

# Удалить декларацию
ibkr-porez delete <id> --yes

# Разрешить удаление не-черновой декларации
ibkr-porez delete <id> --yes --force

Удаляет декларацию и откатывает её влияние на леджер переносов: перенос убытков, который она использовала, возвращается исходным «траншам», а её собственный «транш» признанного убытка (созданный через assess) удаляется. Если вы удалили декларацию, чтобы исправить ошибку, затем запустите sync, чтобы пересоздать период из сохранённых транзакций — для PP OPO с датой дохода старше 45 дней до неё дотянется sync --lookback N.

Без --yes только выводит, что будет удалено. --force требуется для удаления не-черновой декларации. Удалить можно только самый последний PPDG-3R — удаление более раннего оставило бы «висящим» перенос у более поздних деклараций; декларации PP OPO можно удалять в любое время.

Так же исправляется признанный убыток предыдущей декларации, который уже использовала более поздняя: удалите более позднюю декларацию (освобождая перенос), заново выполните assess на ранней, затем sync для пересоздания.

В GUI то же действие доступно кнопкой Delete в строке декларации: она открывает диалог-подтверждение (вместо --yes) с галочкой Force для не-черновых деклараций.

Прикрепление файла к декларации (attach)

# Прикрепить файл
ibkr-porez attach <declaration_id> /path/to/file.pdf

# Удалить прикрепленный файл
ibkr-porez attach <declaration_id> <file_id> --delete
ibkr-porez attach <declaration_id> --delete --file-id <file_id>

Прикрепляет файл к декларации или удаляет прикрепленный файл из хранилища деклараций.

Для сохранения в хранилище деклараций используется только имя файла (путь отбрасывается), поэтому имена должны быть уникальные - иначе файл с тем же именем перезатрет ранее загруженный с таким же именем пусть и из другого пути

💡 Прикрепленные файлы копируются как и XML декаларации при экспорте (export)

Экспорт Flex Query (export-flex)

ibkr-porez export-flex 2025-01-15
ibkr-porez export-flex 2025-01-15 -o /path/to/output.xml
ibkr-porez export-flex 2025-01-15 -o -  # Вывод в stdout (для пайпов)

Экспортирует XML файл Flex Query полученный при fetch или sync в указанную дату.

Пример использования в linux-стиле:

ibkr-porez export-flex 2025-01-15 | ibkr-porez sync --file -

English | Русский | Українська | Srpski | Српски

Interactive Brokers (IBKR)

Flex Web Service

  1. Performance & Reports > Flex Queries.
  2. Нажмите на значок Настроек (шестеренка) в “Flex Web Service Configuration”.
  3. Включите Flex Web Service.
  4. Сгенерируйте Токен (Generate Token).
    • Важно: Скопируйте этот токен сразу. Вы не сможете увидеть его полностью снова.
    • Установите срок действия (рекомендуется максимум - 1 год).

Flex Query

  1. Performance & Reports > Flex Queries.
  2. Нажмите +, чтобы создать новый Activity Flex Query.
  3. Name: например, ibkr-porez-data.
  4. Delivery Configuration (внизу страницы):
    • Period: Выберите Last 365 Calendar Days.
  5. Format: XML.

Разделы для включения (Sections):

Включите следующие разделы и отметьте Select All (Выбрать все) для колонок.

Если вы никому не доверяете 8-) вместо Select All выберите как минимум поля, перечисленные в Обязательные колонки.

Trades - Сделки

Находится в разделе Trade Confirmations или Activity.

Обязательные колонки
  • Symbol
  • Description
  • Currency
  • Quantity
  • TradePrice
  • TradeDate
  • TradeID
  • OrigTradeDate
  • OrigTradePrice
  • AssetClass
  • Buy/Sell

Cash Transactions - Денежные транзакции

Обязательные колонки
  • Type
  • Amount
  • Currency
  • DateTime / Date
  • Symbol
  • Description
  • TransactionID

Сохраните и получите Query ID

Запишите Query ID (число, которое обычно отображается рядом с именем запроса в списке).

Вам понадобятся Token и Query ID для настройки ibkr-porez.

Документ подтверждения

Для Пункта 8 (Докази уз пријаву) налоговой декларации ППДГ-3Р вам потребуется PDF-отчет от брокера. Его надо прикрепить вручную на портале ePorezi после импорта XML.

Как скачать подходящий отчет:

  1. В IBKR перейдите в Performance & Reports > Statements > Activity Statement.
  2. Period: Выберите Custom Date Range.
  3. Укажите даты, соответствующие вашему налоговому периоду (например, 01-01-2024 по 30-06-2024 для первого полугодия).
  4. Нажмите Download PDF.
  5. На портале ePorezi, в разделе 8. Докази уз пријаву загрузите этот файл.

Скачивание XML Flex Query (для sync --file)

Если IBKR API (sync / fetch) временно недоступен, вы можете запустить Flex Query вручную через сайт IBKR:

  1. В IBKR перейдите в Performance & Reports > Statements > Flex Queries.
  2. Найдите запрос, созданный для ibkr-porez (например, ibkr-porez-data).
  3. Нажмите Run (синяя стрелка справа от названия запроса).
  4. Выберите формат XML и скачайте файл.
  5. Используйте файл с командой sync --file или опцией Sync from Flex Query XML… в меню ☰ в GUI.

Экспорт всей истории (для команды import)

Если вам нужно загрузить историю транзакций за период более 1 года (что недоступно через Flex Web Service), экспортируйте даные в CSV:

  1. В IBKR перейдите в Performance & Reports > Statements > Activity Statement.
  2. Period: Выберите Custom Date Range и укажите весь период с момента открытия счета.
  3. Нажмите Download CSV.
  4. Этот файл можно использовать с командой import ↗.

Импорт CSV поставляет историю покупок для расчёта прироста капитала и больше ничего. Дивиденды, проценты и удержанный налог из него никогда не порождают декларации о доходах (PP OPO) — они формируются только из отчёта Flex Query.