Appearance
Модель данных портфолио
Хранение транзакций в 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:
| Ключ | Полное имя | Тип | Описание |
|---|---|---|---|
qtt | quantity | number | Количество монет в транзакции |
ca | createdAt | number | Дата сделки (Unix timestamp, секунды) |
tt | transactionType | number | Тип транзакции (1–5) |
ci | currencyId | string | ID парной валюты/монеты |
tp | transactionPrice | number | Цена монеты на момент сделки (в USD) |
ppc | pricePerCoin | number | Цена за монету в парной валюте |
mp | marketPrice | number | Рыночная цена на момент сделки (USD) |
inv | invested | number | Затраты на добычу (только Mining) |
nt | note | string | Заметка к транзакции |
fe | feeValue | number | Значение комиссии |
fec | feeCurrency | string | Валюта комиссии (% / монета / фиат) |
lnk | link | string | Ссылка на связанную транзакцию (coin vs coin) |
Типы транзакций
Определены в tools/transactions/transactionType.js:
| Код | Тип | Класс | Влияние на баланс | Описание |
|---|---|---|---|---|
| 1 | Sell | TransactionSell | − | Продажа монет за фиат или другую крипту |
| 2 | Buy | TransactionBuy | + | Покупка монет за фиат или другую крипту |
| 3 | Transfer In | TransactionTransferIn | + | Ввод средств (бесплатные монеты) |
| 4 | Transfer Out | TransactionTransferOut | − | Вывод средств |
| 5 | Mining/Airdrop | TransactionMining | + | Майнинг или аирдроп (с/без инвестиций) |
Обязательные поля по типам
| Тип | Обязательные поля |
|---|---|
| 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, // Нереализованная прибыль (от холдингов)
}
}Формат связанных транзакций (link)
При сделке крипта ↔ крипта создаются две транзакции, связанные полем 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=falseisMain=1— главная транзакция, скрывается в UIisMain=0— зависимая, показывается с объединёнными данными
При парсинге учитываются монеты с дефисами в ID (напр. token-huobi): coinId извлекается как всё до последних двух сегментов.
Хранение заметок
Независимые заметки (не привязанные к транзакциям) хранятся в localStorage под ключом "notes":
json
[
{ "cnt": "Текст заметки (макс. 100 символов)", "ca": 1700000000 },
{ "cnt": "Вторая заметка", "ca": 1700100000 }
]Специальные монеты
При инициализации портфолио автоматически добавляются специальные монеты (pirate, cosa) из конфигурации config/coinsConfigs.js — если они отсутствуют в кластере и пользователь ещё не прошёл онбординг.