Skip to content

Модель данных портфолио

Хранение транзакций в localStorage

Транзакции хранятся под ключом "transactions" как JSON-объект (кластер), сгруппированный по coinId:

json
{
  "bitcoin": [
    { "qtt": 0.5, "ca": 1700000000, "ci": "usd", "tp": 35000, "ppc": 35000, "mp": 34800, "tt": 2, "nt": "Первая покупка" },
    { "qtt": 0.2, "ca": 1705000000, "ci": "usd", "tp": 42000, "ppc": 42000, "mp": 41500, "tt": 1 }
  ],
  "ethereum": [
    { "qtt": 5, "ca": 1702000000, "tt": 3 }
  ],
  "pirate": [],
  "cosa": []
}

Ключи объекта транзакции

Для экономии пространства в localStorage используются сокращённые ключи. Определены в tools/transactions/utils.js:

КлючПолное имяТипОписание
qttquantitynumberКоличество монет в транзакции
cacreatedAtnumberДата сделки (Unix timestamp, секунды)
tttransactionTypenumberТип транзакции (1–5)
cicurrencyIdstringID парной валюты/монеты
tptransactionPricenumberЦена монеты на момент сделки (в USD)
ppcpricePerCoinnumberЦена за монету в парной валюте
mpmarketPricenumberРыночная цена на момент сделки (USD)
invinvestednumberЗатраты на добычу (только Mining)
ntnotestringЗаметка к транзакции
fefeeValuenumberЗначение комиссии
fecfeeCurrencystringВалюта комиссии (% / монета / фиат)
lnklinkstringСсылка на связанную транзакцию (coin vs coin)

Типы транзакций

Определены в tools/transactions/transactionType.js:

КодТипКлассВлияние на балансОписание
1SellTransactionSellПродажа монет за фиат или другую крипту
2BuyTransactionBuy+Покупка монет за фиат или другую крипту
3Transfer InTransactionTransferIn+Ввод средств (бесплатные монеты)
4Transfer OutTransactionTransferOutВывод средств
5Mining/AirdropTransactionMining+Майнинг или аирдроп (с/без инвестиций)

Обязательные поля по типам

ТипОбязательные поля
Buy (2)qtt, ca, ci, tp, ppc, mp
Sell (1)qtt, ca, ci, tp, ppc, mp
Transfer In (3)qtt, ca, tt
Transfer Out (4)qtt, ca
Mining (5)qtt, ca

Структура результата расчёта ассета

Объект assetData, вычисляемый классом TransactionAssets:

javascript
{
  avg: 0,                      // Средняя цена покупки (средневзвешенная)
  holdings: {
    coins: 0,                  // Общее количество монет на балансе
    cash: 0,                   // Текущая стоимость в фиате = marketPrice × coins
    buyOrSell: 0,              // Баланс от покупок/продаж
    transfer: 0,               // Баланс от «бесплатных» монет (transfer in, mining без inv)
  },
  total: {
    profit: 0,                 // Итоговая прибыль = (incomeCash + cash) − invested
    profitPercent: 0,          // Процент прибыли
    buyCoins: 0,               // Всего купленных монет
    buyCash: 0,                // Стоимость купленных монет по рынку
    invested: 0,               // Всего инвестировано (buy + mining с inv)
    incomeCash: 0,             // Доход от продаж в фиат
  },
  profit: {
    current: 0,                // Текущая потенциальная прибыль
    realised: 0,               // Реализованная прибыль (от продаж)
    unrealised: 0,             // Нереализованная прибыль (от холдингов)
  }
}

При сделке крипта ↔ крипта создаются две транзакции, связанные полем lnk. Формат определён в tools/transactions/transactionLink.js:

"{coinId}-{createdAt}-{isMain}"

Примеры:
  "bitcoin-1700000000-1"   → coinId=bitcoin, createdAt=1700000000, isMain=true
  "ethereum-1700000000-0"  → coinId=ethereum, createdAt=1700000000, isMain=false
  • isMain=1 — главная транзакция, скрывается в UI
  • isMain=0 — зависимая, показывается с объединёнными данными

При парсинге учитываются монеты с дефисами в ID (напр. token-huobi): coinId извлекается как всё до последних двух сегментов.

Хранение заметок

Независимые заметки (не привязанные к транзакциям) хранятся в localStorage под ключом "notes":

json
[
  { "cnt": "Текст заметки (макс. 100 символов)", "ca": 1700000000 },
  { "cnt": "Вторая заметка", "ca": 1700100000 }
]

Специальные монеты

При инициализации портфолио автоматически добавляются специальные монеты (pirate, cosa) из конфигурации config/coinsConfigs.js — если они отсутствуют в кластере и пользователь ещё не прошёл онбординг.