Розробка дашборду статистики криптобота з real-time аналітикою

Торговий бот — чорний ящик, поки у вас немає дашборду. Ви бачите лише кінцевий PnL, але не знаєте, як стратегія поводиться всередині дня. Просадка в 35% може залишитися непоміченою, якщо дивитися тільки на win rate. Дашборд статистики криптобота дає прозорість: **equity curve**, drawdown, реальний [

Напрямки блокчейн-розробки

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1450
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1308
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1003
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1269
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    719
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    1009

Торговий бот — чорний ящик, поки у вас немає дашборду. Ви бачите лише кінцевий PnL, але не знаєте, як стратегія поводиться всередині дня. Просадка в 35% може залишитися непоміченою, якщо дивитися тільки на win rate. Дашборд статистики криптобота дає прозорість: equity curve, drawdown, реальний Sharpe ratio. Без цього ви ризикуєте втратити депозит. Наші дашборди будуються на real-time WebSocket і REST API, оновлюються кожні 5 секунд. Результат — миттєва реакція на зміни ринку та своєчасна зупинка збиткових стратегій.

Проблеми, які вирішує дашборд

Перша проблема — приховані просадки. Бот може показувати 70% win rate, але рідкісні великі втрати з'їдають весь прибуток. Equity curve візуалізує реальний стан депозиту. Друга — відсутність контексту. Без метрик ризику (Sharpe, drawdown) неможливо порівняти дві стратегії об'єктивно. Третя — затримки в моніторингу. REST polling раз на хвилину пропускає важливі сигнали: прослизання (slippage) або атаки MEV на DEX. Real-time WebSocket вирішує це.

Чому equity curve — головний графік криптобота?

Win rate 80% може приховувати рідкісні великі втрати. Equity curve показує реальну динаміку капіталу. Хороша крива — плавний ріст з контрольованими просадками. Погана — різкі падіння на 30-40%, після яких бот не відновлюється. Саме equity curve дозволяє побачити true drawdown, який не видно в зведених метриках. Додатково будуємо криву з урахуванням slippage та комісій — це дає чесну картину.

Які метрики обов'язкові в дашборді?

Ми виділяємо п'ять ключових:

  • Profit factor — відношення прибуткових угод до збиткових. Значення >2 означає $2 прибутку на кожен $1 ризику.
  • Sharpe ratio — дохідність з поправкою на ризик. Чим вищий, тим стабільніша стратегія.
  • Max drawdown — максимальна просадка від піку до дна. Дозволяє оцінити ризик депозиту.
  • Average trade duration — середній час утримання позиції. Важливо для high-frequency стратегій.
  • Consecutive losses — серія збиткових угод. Виявляє періоди нестабільності.

Ці метрики допомагають вчасно помітити, що бот починає деградувати — наприклад, зростає max drawdown або падає profit factor. Замовте консультацію інженера, щоб підібрати оптимальний набір під вашу стратегію.

Реалізація на Python з Decimal

Для точного розрахунку метрик використовуємо Decimal. Нижче — ключові методи з нашого класу PerformanceCalculator:

from decimal import Decimal from typing import List import statistics import math class PerformanceCalculator: def __init__(self, trades: list[ClosedTrade], initial_capital: Decimal): self.trades = sorted(trades, key=lambda t: t.closed_at) self.initial_capital = initial_capital def total_pnl(self) -> Decimal: return sum(t.pnl for t in self.trades) def total_roi(self) -> float: return float(self.total_pnl() / self.initial_capital * 100) def win_rate(self) -> float: if not self.trades: return 0 wins = sum(1 for t in self.trades if t.pnl > 0) return wins / len(self.trades) * 100 def profit_factor(self) -> float: gross_profit = sum(float(t.pnl) for t in self.trades if t.pnl > 0) gross_loss = abs(sum(float(t.pnl) for t in self.trades if t.pnl < 0)) return gross_profit / gross_loss if gross_loss > 0 else float('inf') def max_drawdown(self) -> float: equity = float(self.initial_capital) peak = equity max_dd = 0 for trade in self.trades: equity += float(trade.pnl) if equity > peak: peak = equity dd = (peak - equity) / peak max_dd = max(max_dd, dd) return max_dd * 100 def sharpe_ratio(self, risk_free_rate: float = 0.05) -> float: if len(self.trades) < 2: return 0 daily_returns = self.build_daily_returns() if not daily_returns: return 0 avg_daily_return = statistics.mean(daily_returns) std_daily_return = statistics.stdev(daily_returns) if std_daily_return == 0: return 0 daily_rf = risk_free_rate / 365 sharpe = (avg_daily_return - daily_rf) / std_daily_return * math.sqrt(365) return round(sharpe, 2) def avg_trade_duration_hours(self) -> float: if not self.trades: return 0 durations = [(t.closed_at - t.opened_at).total_seconds() / 3600 for t in self.trades] return statistics.mean(durations) def consecutive_losses(self) -> int: max_streak = 0 current_streak = 0 for trade in self.trades: if trade.pnl < 0: current_streak += 1 max_streak = max(max_streak, current_streak) else: current_streak = 0 return max_streak def build_equity_curve(self) -> list[dict]: equity = float(self.initial_capital) curve = [{'date': self.trades[0].opened_at, 'equity': equity}] for trade in self.trades: equity += float(trade.pnl) curve.append({ 'date': trade.closed_at, 'equity': equity, 'pnl': float(trade.pnl), 'cumulative_roi': (equity / float(self.initial_capital) - 1) * 100 }) return curve 

Backend API на FastAPI

FastAPI-ендпоінти для отримання статистики та списку угод з пагінацією.

from fastapi import FastAPI, Query from datetime import datetime, timedelta app = FastAPI() @app.get("/api/bot/{bot_id}/stats") async def get_bot_stats(bot_id: str, period: str = Query("30d", regex="^(7d|30d|90d|all)$")): days = {'7d': 7, '30d': 30, '90d': 90, 'all': None}[period] since = datetime.utcnow() - timedelta(days=days) if days else None trades = await db.get_closed_trades(bot_id, since=since) initial_capital = await db.get_initial_capital(bot_id) open_positions = await db.get_open_positions(bot_id) calc = PerformanceCalculator(trades, initial_capital) return { "period": period, "summary": { "total_pnl_usdt": str(calc.total_pnl()), "total_roi_percent": round(calc.total_roi(), 2), "win_rate_percent": round(calc.win_rate(), 1), "profit_factor": round(calc.profit_factor(), 2), "sharpe_ratio": calc.sharpe_ratio(), "max_drawdown_percent": round(calc.max_drawdown(), 2), "total_trades": len(trades), "avg_trade_duration_hours": round(calc.avg_trade_duration_hours(), 1), "max_consecutive_losses": calc.consecutive_losses(), }, "equity_curve": calc.build_equity_curve(), "open_positions": [p.to_dict() for p in open_positions], "current_status": await get_bot_status(bot_id) } @app.get("/api/bot/{bot_id}/trades") async def get_trades(bot_id: str, page: int = 1, limit: int = 50, symbol: str = None): trades = await db.get_trades_paginated(bot_id, page, limit, symbol) return { "trades": [t.to_dict() for t in trades.items], "total": trades.total, "page": page, "pages": math.ceil(trades.total / limit) } 

Frontend на React

Компоненти для візуалізації: графік equity curve та KPI-картки.

import { LineChart, Line, XAxis, YAxis, Tooltip, ReferenceLine } from 'recharts'; const EquityCurveChart: React.FC<{data: EquityPoint[]}> = ({ data }) => { const initialEquity = data[0]?.equity || 0; return ( <LineChart width={800} height={300} data={data}> <XAxis dataKey="date" tickFormatter={d => format(new Date(d), 'MM/dd')} /> <YAxis tickFormatter={v => `$${(v/1000).toFixed(1)}k`} /> <Tooltip formatter={(value: number) => [`$${value.toFixed(2)}`, 'Equity']} labelFormatter={d => format(new Date(d), 'PPpp')} /> <ReferenceLine y={initialEquity} stroke="#888" strokeDasharray="3 3" label="Start" /> <Line type="monotone" dataKey="equity" stroke={data[data.length-1]?.equity >= initialEquity ? '#22c55e' : '#ef4444'} dot={false} strokeWidth={2} /> </LineChart> ); }; const StatCard: React.FC<{label: string; value: string; positive?: boolean}> = ({ label, value, positive }) => ( <div className="bg-white rounded-xl p-4 shadow-sm border"> <div className="text-sm text-gray-500">{label}</div> <div className={`text-2xl font-bold mt-1 ${positive === true ? 'text-green-600' : positive === false ? 'text-red-600' : 'text-gray-900'}`}>{value}</div> </div> ); 

Real-time моніторинг через WebSocket

Оновлення поточного стану бота кожні 5 секунд.

class BotStatusWebSocket: async def stream_status(self, websocket, bot_id: str): while True: status = { "bot_running": await is_bot_running(bot_id), "open_positions": await get_open_positions_summary(bot_id), "today_pnl": str(await get_today_pnl(bot_id)), "last_trade_at": await get_last_trade_time(bot_id), "api_latency_ms": await get_avg_latency(bot_id), "errors_last_hour": await get_error_count(bot_id, hours=1), } await websocket.send_json(status) await asyncio.sleep(5) 

Порівняння методів отримання даних

Характеристика WebSocket REST polling (щохвилини)
Затримка даних 5 секунд 60 секунд
Навантаження на сервер Низька (постійне з'єднання) Висока (часті запити)
Складність реалізації Середня Низька

Наш дашборд на WebSocket оновлюється в 10 разів швидше, ніж REST polling раз на хвилину. Це критично для high-frequency стратегій, де кожна секунда впливає на PnL.

Етапи розробки дашборду

Етап Тривалість Результат
Консультація та збір вимог 1-2 дні Технічне завдання
Прототипування інтерфейсу 3-5 днів Макет дашборду
Backend (API, агрегація, WebSocket) 5-10 днів Робочі ендпоінти
Frontend (графіки, картки, фільтри) 5-10 днів Інтерфейс дашборду
Інтеграція та тестування 3-5 днів Приймання, навчання

Середній клієнт після впровадження дашборду збільшує прибуток на 15% за рахунок своєчасної зупинки збиткових стратегій. Ми більше 5 років в блокчейні, розробили дашборди для 50+ торгових ботів. Гарантуємо коректність метрик та 99.9% uptime.

Приклад розрахунку на реальних даних

Розглянемо бота на Binance з депозитом $10 000. За місяць здійснено 200 угод: 120 прибуткових (середній прибуток $50) і 80 збиткових (середній збиток $30). Profit factor = (12050)/(8030) = 6000/2400 = 2.5. Max drawdown = -8% (пік $11 200, дно $10 304). Sharpe ratio = 1.8. Такі метрики свідчать про стабільну стратегію.

Що входить в роботу

  • Аналіз ваших поточних даних та метрик.
  • Проектування API (REST + WebSocket).
  • Розробка backend на Python (FastAPI, PostgreSQL, Redis).
  • Frontend на React (Recharts, Tailwind).
  • Інтеграція real-time моніторингу.
  • Документація, навчання команди, підтримка 30 днів.

Замовте розробку дашборду для вашого криптобота — отримайте консультацію інженера безкоштовно. Зв'яжіться з нами для аудиту метрик вашого бота. Економія на комісіях та своєчасне виявлення проблем окупають впровадження протягом першого місяця.