BudgetTracker — ещё один open-source инструмент для личного учета финансов

в 15:17, , рубрики: .net, .net core, C#, finance, open source, svelte, финансы в IT

Почему?

Несколько лет назад я заинтересовался получением пассивного дохода и решил попробовать инвестировать с помощью p2b-площадок. Через некоторое время стало заметно, что денежные средства оказались очень сильно фрагментированы по площадкам, банкам, долгам, и это затрудняло понимание ситуации. Я не мог ответить на два самых главных вопроса:
Сколько у меня денег?
Какой тренд? Я богатею, или беднею?

КДПВ

image

Нужно было как-то собрать информацию воедино и поддерживать ее в актуальном виде.

Варианты решения проблемы были следующие:

Таблица в Google Sheets

Преимущества: делается быстро, гибко, бесплатно
Недостатки: необходимость обновлять данные вручную

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

Специализированные решения

В большинстве случаев это те же таблицы, только с симпатичным/удобным интерфейсом.
В редких случаях есть интеграция с несколькими банками, но во всех случаях что я пробовал — она была нестабильной и ненадежной. Также отпугивала необходимость отдавать свой логин/пароль от интернет-банка и отсутствие интеграции с нестандартными источниками данных.

Стало очевидно, что подходящий сервис придется писать самому — только так можно полностью автоматизировать получение финансовых данных, и в то же время не беспокоиться о передаче реквизитов третьей стороне. Кроме того, это позволило бы реализовать любой желаемый интерфейс. Так начался проект BudgetTracker, которым я успешно пользуюсь уже два года. Его можно скачать в виде исходников и/или установить на собственный сервер как готовый docker-контейнер.

Основная идея

Есть две разные стороны, как можно смотреть на финансы. С одной стороны есть текущее состояние (условно — сейчас на счету “Х” находится “У” денег), с другой стороны есть транзакции (условно — покупка “ХХ” за “УУУ” денег в момент времени Т).

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

Источники данных

Существуют разные провайдеры — источники данных, например собирающие данные из банк-клиента.

Поддерживаемый список провайдеров

  • FX — курсы валют: EUR, USD
  • LiveCoin — криптобиржа
  • Penenza
  • АльфаБанк
  • АльфаКапитал
  • АльфаДирект
  • АльфаПоток
  • МодульБанк
  • МодульДеньги
  • Райффайзен
  • Долги и ссуды (для вручную заведенных долгов)
  • POST-api для получения произвольных данных из внешних систем

Так как часть провайдеров требуют SMS-аутентификацию, то есть также интеграция с SMS через IFTTT (только для Android-телефонов).

Провайдер каждые сутки собирает состояние каждого из счетов и список всех транзакций и сохраняет их в базу. Для этого запускается Chrome, и с помощью Selenium извлекаются нужные данные из онлайн-банков.

Счета

Состояния каждого из счетов формируют таблицу вида:

image

Это дает возможность видеть детали и состояние каждого из счетов, но это не помогает видеть общую картину, и не дает ответа на простой вопрос "сколько у меня денег?".
Для того, чтобы ответить на этот вопрос была добавлена поддержка “вычисляемых столбцов”, в которых можно задать формулу, например:

image

Но помимо конкретного значения хочется видеть также тренд, выбросы, прогнозы — иными словами видеть динамику этого значения (а иногда и не только его одного).

Для этого существует концепт “главной страницы” где можно настраивать отдельные виджеты для того, чтобы акцентировать внимание на конкретных столбцах / трендах.

Виджеты

image

Существуют несколько видов виджетов:

  • “Пончик” с тратами (из транзакций)
  • “Последнее значение” — график-линия для произвольных столбцов, показывает прогнозируемое изменение в годовых (%), и фактическое за последний день (%). Бывает так же в "компактном" режиме, когда показывает только текущее(последнее) значение.
  • “Дельта” — показывает изменения столбца в цифрах за последние 24ч, 48ч, 1 неделю и 1 месяц
  • “Пончик” — для вычисляемых столбцов
  • “График” — для вычисляемых столбцов

Каждый тип виджета имеет свой размер, и их можно двигать относительно друг друга, используя "стрелочки". По-умолчанию они скрыты, и появляются по нажатию кнопки "глаз" в верхней части страницы:
image

Также при создании или редактирования виджета есть возможность изменить какие-либо его настройки:
image

Транзакции

Для работы с транзакциями, или ДДС, есть отдельная страница, где видно все транзакции, сгруппированные по категориям.
image

У каждой транзакции есть “тип” транзакции — это “доход”, “расход”, или “перевод”. Перевод выставляется вручную, чтобы исключить переводы из графиков с главной страницы.

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

Если в провайдере данных нет поддержки транзакций

В таком случае удобно добавить автогенерацию транзакций в свойствах столбца, и в момент покупки отредактировать транзакцию в которой покупали акции и поставить ей тип “перевод”.

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

Также существует отдельный раздел “Долги”, куда можно вносить вручную долги. Для каждого долга можно аналогично установить шаблон для транзакции, чтобы при появлении новых ДДС, относящихся к этому долгу — оставшаяся сумма обновлялась.
image

Технологический стек

В настоящий момент бекенд работает на .NET Core 3, фронтенд на Svelte 3.
Для хранения данных используется ObjectRepository + LiteDB.
Для интеграции с источниками данных используется связка Selenium + Chrome.

Изначально всё писалось полностью на .NET Core, но некоторое время назад фронтенд был переписан на Svelte.
Из-за этого наследия — общение с сервером было сделано не оптимально и есть планы переписать эту часть проекта на реактивную модель.

Как попробовать

docker-compose.yml файл в репозитории поможет:

version: "3.3"
services:
  budgettracker:
    image: diverofdark/budgettracker:master
    restart: unless-stopped
    environment:
      Properties__IsProduction: 'true' # true если необходимо сохранять изменения в базу. 
      ConnectionStrings__LiteDb: '/data/budgettracker.db' 
    volumes:
      - /dev/shm:/dev/shm # Для использования Google Chrome
      - /root/bt:/data
    ports:
      - "80:80"
    networks:
      public: {}

networks:
  public:
    driver: bridge

Автор: DiverOfDark

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js