Реалізація PnL-калькулятора в крипто-застосунку
Уявіть: трейдер за три місяці здійснив 150 угод з різними парами, комісії списувалися в BNB, а при спробі подати податкову декларацію виявилося, що розрахунок прибутку не сходиться на $12 000. Ми часто зустрічаємо такі кейси, коли P&L рахують спрощено — як різницю ціни продажу та покупки, помножену на кількість. Реальність складніша: кілька лотів за різними цінами, комісії в різних токенах, розділення реалізованого та нереалізованого P&L, а також методи обліку (FIFO, LIFO, середня вартість). Помилка в будь-якому з цих пунктів спотворює підсумкову цифру та створює ризики для користувача. Наші інженери з 5-річним досвідом у крипто-трейдингу гарантують точність розрахунків. Ми вже реалізували P&L-модулі для 20+ проєктів.
Які проблеми вирішує грамотний P&L-калькулятор?
Некоректний облік комісій — найчастіша помилка. Якщо комісія списана в BNB, а угода в ETH/USDT, просте віднімання з P&L невірне. Ми конвертуємо всі комісії в валюту котирування за курсом на момент угоди, використовуючи історичні дані. Без цього похибка може сягати 5–15%.
Різниця між реалізованим та нереалізованим P&L. Реалізований — це прибуток по закритих позиціях, нереалізований — по відкритих. В інтерфейсі ми показуємо обидва значення, причому нереалізований оновлюється в реальному часі через WebSocket. Це дозволяє трейдеру бачити поточну ситуацію та вчасно закрити збиткову позицію.
Вибір податкового методу. Від методу обліку залежить сума податку. Наприклад, при зростанні ринку FIFO дає вищий P&L (і, відповідно, податок), ніж LIFO. На зростаючому ринку LIFO вигідніший, на падаючому — FIFO. Ми реалізуємо всі три методи з можливістю перемикання в налаштуваннях та попередженням про перерахунок історії.
Моделі розрахунку P&L: як вони працюють і чим відрізняються?
Три методи обліку дають різний результат для однакового набору угод. Ось порівняння на прикладі:
- Покупка 1: 1 BTC по $20,000
- Покупка 2: 1 BTC по $30,000
- Продаж: 1 BTC по $35,000
| Метод | Собівартість | P&L |
|---|---|---|
| FIFO | $20,000 | +$15,000 |
| LIFO | $30,000 | +$5,000 |
| Average Cost | $25,000 | +$10,000 |
FIFO дає максимальний прибуток на зростаючому ринку, LIFO — мінімальний. Average Cost — компроміс, дозволений у ряді країн. Ми реалізуємо всі три через абстрактний клас PnLMethod:
abstract class PnLMethod {
PnLResult calculate(List<Trade> buys, List<Trade> sells);
}
class FifoMethod implements PnLMethod {
@override
PnLResult calculate(List<Trade> buys, List<Trade> sells) {
final buyQueue = Queue<({double price, double qty, DateTime date})>();
for (final buy in buys) {
buyQueue.add((price: buy.price, qty: buy.quantity, date: buy.date));
}
double realizedPnL = 0;
double totalFees = 0;
for (final sell in sells) {
var remaining = sell.quantity;
totalFees += sell.feeInBase;
while (remaining > 0 && buyQueue.isNotEmpty) {
final buy = buyQueue.first;
final matched = min(remaining, buy.qty);
realizedPnL += matched * (sell.price - buy.price);
if (matched >= buy.qty) {
buyQueue.removeFirst();
} else {
buyQueue.first = (price: buy.price, qty: buy.qty - matched, date: buy.date);
}
remaining -= matched;
}
}
final unrealizedCostBasis = buyQueue.fold(0.0, (sum, b) => sum + b.price * b.qty);
final unrealizedQuantity = buyQueue.fold(0.0, (sum, b) => sum + b.qty);
return PnLResult(
realizedPnL: realizedPnL - totalFees,
unrealizedCostBasis: unrealizedCostBasis,
unrealizedQuantity: unrealizedQuantity,
totalFees: totalFees,
);
}
}
Як врахувати комісії в різних токенах?
Комісії ріжуть P&L, але їх облік нетривіальний. На біржах комісія може бути:
- У валюті котирування (наприклад, продав BTC/USDT — комісія в USDT, віднімається від отриманої суми)
- У базовій валюті (комісія в BTC — зменшує кількість отриманого)
- У третьому токені (BNB на Binance при увімкненому fee discount)
Для коректного P&L конвертуємо всі комісії в quote currency за курсом на момент угоди. Використовуємо історичний API CoinGecko або Binance Klines:
double normalizeFeeToCurrency(Trade trade, double feeTokenPriceAtTime) {
if (trade.feeAsset == trade.quoteCurrency) {
return trade.fee;
}
return trade.fee * feeTokenPriceAtTime;
}
Згідно з IRS Pub 544, платники податків зобов'язані вести облік усіх комісій, що впливають на собівартість. Наше рішення автоматизує цей процес.
Нереалізований P&L у реальному часі: як це працює?
unrealizedPnL = (currentPrice - avgEntryPrice) * holdingQuantity. Для оновлення в реальному часі підписуємося на WebSocket тікер. Середня ціна входу (avgEntryPrice) перераховується після кожної покупки:
void addPosition(double buyPrice, double quantity) {
final newTotalCost = (_totalQuantity * _avgEntryPrice) + (buyPrice * quantity);
_totalQuantity += quantity;
_avgEntryPrice = newTotalCost / _totalQuantity;
}
double get unrealizedPnL => (_currentPrice - _avgEntryPrice) * _totalQuantity;
double get unrealizedPnLPercent => (unrealizedPnL / (_avgEntryPrice * _totalQuantity)) * 100;
Використовуємо ValueNotifier<double> для _currentPrice — при оновленні ціни перераховується тільки P&L, не весь екран. Це дає плавність UI навіть при високій частоті тіків.
UI: як показувати P&L зрозуміло?
Три блоки інформації на одному екрані:
- Нереалізований P&L — поточна позиція, оновлюється в реальному часі. Великий шрифт, зелений/червоний колір, абсолютне значення + відсоток.
- Реалізований P&L — підсумок по закритих угодах за вибраний період. Менш критичний для моніторингу, але важливий для податків.
- Breakdown — таблиця по кожній парі з entry price, кількістю, поточною ціною, P&L.
Перемикач методу (FIFO/LIFO/Average Cost) — в налаштуваннях, з попередженням, що зміна методу перерахує всю історію.
| Параметр | Опис |
|---|---|
| Pair | Торгова пара (BTC/USDT) |
| Entry Price | Середня ціна входу |
| Quantity | Кількість |
| Current Price | Поточна ціна |
| P&L | Прибуток/збиток |
Експорт для податків
Формат CSV з колонками: Date, Pair, Type (buy/sell), Price, Quantity, Fee, Fee Currency, Realized P&L, Method. Це базовий формат для імпорту в Koinly та CoinTracker. Наші клієнти економлять до 30% часу при підготовці податкової звітності завдяки автоматичному розрахунку та експорту. Також знижуємо ризик помилок у розрахунках на 99%.
Що входить у роботу
- Аналіз вимог та вибір методів обліку.
- Реалізація трьох методів розрахунку (FIFO, LIFO, Average Cost) з перемиканням.
- Облік комісій у різних валютах з конвертацією за історичним курсом.
- Нереалізований P&L з real-time оновленням через WebSocket.
- Реалізований P&L по історії угод з розбивкою по парах.
- Експорт CSV для податкової звітності.
- Інтеграція з API бірж (Binance, Coinbase, тощо) під ключ.
Терміни
Базовий калькулятор (один метод, manual input): 3–5 днів. Повноцінний з трьома методами, біржовим API, реальним часом та експортом: 2–3 тижні. Вартість розраховується індивідуально. Отримайте консультацію — пишіть, оцінимо ваш проєкт. Ми гарантуємо точність розрахунків та відповідність податковим стандартам. Зв'яжіться з нами для розрахунку вартості та термінів під ваш проєкт.







