PDF-отчёты клиентам за 30 минут вместо 12 часов
Один раз сел и прописал структуру отчёта — Claude Code запомнил. Каждый месяц одна команда «собери отчёт за май». HTML → Playwright SCALE=3 → PDF. Кейс: клиент $3M в DeFi, от дня работы к 30 минутам.
Что внутри гайда
- Memory один раз — прописал структуру клиентского отчёта, разделы, источники, формулы — Claude запомнил. На следующий месяц не объясняешь заново ни слова
- Одна команда в месяц — «собери отчёт для клиента M за май» → CC идёт в DeBank/Etherscan/Dune сам, ты не участвуешь 15–20 минут
- HTML сначала, PDF потом — открыл в браузере, поправил за 5 минут, сказал «конвертируй» — 30 секунд до готового файла клиенту
- Playwright SCALE=3, не page.pdf — без кривых теней, градиентов и съехавшего aspect-ratio. Разбор 7 конкретных проблем page.pdf — с симптомами и фиксами
- Полный memory-template — 50 строк markdown, всё что нужно прописать один раз: разделы, формулы, форматы, тон, источники данных
- Метрики по типам клиентов — DeFi-инвестор / трейдер / passive / DAO — для каждого по 6–8 ключевых метрик, и почему именно эти
- Чек-лист первой настройки — 7 шагов от нуля до первого PDF с тайтингом каждого
Memory один раз, потом не объясняй
Самая большая трата времени при регулярных отчётах — не сбор данных. Это объяснения. Каждый раз заново: какие разделы нужны, откуда брать цифры, в каком формате считать доходность. CC не помнит — ты объясняешь. CC не помнит — ты объясняешь снова. Это заканчивается один раз.
Создаёшь файл в memory один раз. Например: memory/clients/client-M.md. Прописываешь всё — разделы, источники данных, формулы, форматирование, тон. После этого CC знает всё о клиенте. В следующем месяце — команда из 5 слов. Ни вводных вопросов, ни итераций туда-обратно.
Полный memory-template
Скопируй и адаптируй под конкретного клиента. Один раз заполняешь — потом работает всё время, пока клиент с тобой.
# Client: M — Monthly Report Configuration
<!-- Версия: 1.0 | Создан: 2025-01-01 | Обновлён: 2025-01-01 -->
## Identity
- **client_id:** M
- **full_name:** [имя/псевдоним]
- **capital_usd:** 3_000_000
- **profile:** Опытный DeFi-инвестор, понимает механизмы протоколов
- **risk_tolerance:** medium-high
- **investment_horizon:** долгосрочный (3-5 лет)
- **primary_language:** ru
- **report_frequency:** monthly
- **report_day:** 1-е число каждого месяца
## Wallet Addresses
- **EVM main:** `0x...` (основной, Ethereum)
- **EVM L2:** `0x...` (Arbitrum, Optimism)
- **Solana:** [если есть]
## Report Sections (ordered)
1. Title Page — клиент, период, дата генерации
2. Executive Summary — 4-5 KPI крупно + 3 ключевых события месяца
3. Portfolio State — текущие позиции по протоколам и чейнам
4. Performance — динамика за месяц + сравнение с бенчмарком
5. Risk Overview — концентрация, IL, ликвидность
6. Rebalancing — target vs actual с отклонениями
7. Recommendations — приоритеты HIGH/MED/LOW на следующий месяц
## Data Sources
- **DeBank MCP** → текущий снапшот позиций (вызывать в начале)
- **Etherscan API** → on-chain activity за период (транзакции, gas)
- **Dune Analytics** → APY по LP-позициям, impermanent loss в USD
- **CoinGecko** → исторические цены для расчёта benchmark
## Formulas
### PnL (месячный)
pnl_usd = portfolio_end_usd - portfolio_start_usd - deposits_usd + withdrawals_usd
pnl_pct = pnl_usd / portfolio_start_usd * 100
### Benchmark comparison (ETH+BTC 50/50)
benchmark_return = (eth_end/eth_start - 1) * 0.5 + (btc_end/btc_start - 1) * 0.5
alpha = pnl_pct - benchmark_return * 100
### Target allocation deviation
delta_pct = actual_pct - target_pct
# Подсветить красным если abs(delta_pct) > 5%
### Impermanent Loss
il_usd = initial_lp_value_usd * il_ratio
# il_ratio взять из Dune по пулу
## Target Allocation
| Category | Target % | Rebalance threshold |
|--------------|----------|---------------------|
| ETH staking | 30% | ±5% |
| DeFi LP | 25% | ±5% |
| Stablecoins | 20% | ±3% |
| BTC | 15% | ±5% |
| Altcoins | 10% | ±7% |
## Number Formatting
- Суммы: `$1,234,567.89` (USD, 2 знака после запятой)
- Проценты: `+12.34%` / `-3.21%` (знак обязателен, 2 знака)
- Даты: `DD.MM.YYYY` (01.05.2025)
- Большие числа: тысячи через запятую ($3,000,000)
- Отрицательные PnL: красный цвет, знак минус
## Tone & Style
- Профессиональный, конкретный, без воды
- Цифры важнее слов — в каждом абзаце есть число
- Рекомендации: конкретные действия, не «возможно стоит рассмотреть»
- Пример плохо: «портфель показал умеренные результаты»
- Пример хорошо: «портфель вырос на 4.7%, ETH benchmark +3.2%, alpha +1.5%»
## Report File Naming
- HTML: `report-client-M-{YYYY-MM}.html`
- PDF: `report-client-M-{YYYY-MM}.pdf`
- Папка: `reports/client-M/`
Структура финального HTML-отчёта
- Title Page — логотип/watermark, имя клиента (анонимизировано), период, дата генерации, конфиденциальность
- Executive Summary — 4-5 KPI-карточек крупно (Portfolio Value, Monthly PnL, Alpha vs Benchmark, Best Protocol, Worst Metric), 3 главных события месяца в 1 строку каждое
- Current State — таблица позиций по протоколам с полями: Protocol, Chain, Asset, Value USD, % of portfolio, APY
- Performance — линейный график динамики портфеля за месяц vs benchmark ETH+BTC 50/50; таблица: Start / End / PnL USD / PnL % / Benchmark / Alpha
- Risk Overview — концентрация топ-3 позиций в % от портфеля, IL в USD по каждой LP-позиции, ликвидность (% в stables + что можно вывести за 24ч)
- Rebalancing — таблица target → actual → delta с подсветкой отклонений >5%
- Recommendations — нумерованный список: HIGH (срочно до 7 дней) / MED (до следующего отчёта) / LOW (рассмотреть при ребалансировке)
- Appendix — полный список транзакций за период, источники данных, дата генерации
Setup-промпт для нового клиента
Создай файл memory/clients/client-M.md для нового клиента.
Используй этот шаблон как основу:
[вставь шаблон выше]
Данные клиента:
- Капитал: $3,000,000
- Адреса: 0x...
- Профиль: опытный DeFi-инвестор
- Бенчмарк: ETH+BTC 50/50
- Целевое распределение: ETH staking 30%, DeFi LP 25%,
Stables 20%, BTC 15%, Altcoins 10%
После сохранения подтверди: "Memory для клиента M готова.
Следующая команда: собери отчёт за [месяц]."
memory/clients/client-M.md — это project-level memory. CC читает её при каждом запросе в рамках проекта. Отдельный файл на каждого клиента. Глобальная memory (~/.claude/CLAUDE.md) — для общих правил форматирования и стека; project-level — для специфики клиента. Никогда не смешивай: иначе CC начнёт переносить детали одного клиента в отчёт другого.«Собери отчёт для клиента M за май» → HTML
Первое число месяца. Открываешь CC, пишешь один промпт. Дальше ждёшь — CC работает сам. В этом весь смысл.
Ниже — полный месячный промпт. Его можно параметризовать: {{client_id}}, {{month}}, {{year}} — подставляй и отправляй. Промпт рассчитан на то, что memory-файл уже написан.
Monthly prompt template
Собери ежемесячный отчёт для клиента {{client_id}} за {{month}} {{year}}.
# Конфигурация
Читай все параметры из memory/clients/client-{{client_id}}.md:
разделы, источники данных, формулы расчётов, форматирование, тон.
# Сбор данных (последовательно)
1. DeBank MCP — снапшот текущих позиций:
все кошельки из memory, все чейны, все протоколы
2. Etherscan API — on-chain activity за {{month}} {{year}}:
входящие/исходящие, gas-расходы, новые протоколы
3. Dune Analytics — LP-позиции за период:
APY по каждому пулу, impermanent loss в USD
4. CoinGecko — исторические цены ETH и BTC:
первое и последнее число {{month}} для benchmark
# Расчёты
- Считай PnL по формуле из memory (realized + unrealized)
- Считай alpha vs benchmark ETH+BTC 50/50
- Считай отклонения от target allocation
- Суммируй IL по всем LP-позициям
# Выход
Создай файл reports/client-{{client_id}}/report-client-{{client_id}}-{{year}}-{{month_num}}.html
Используй Chart.js CDN для графиков (pie chart + line chart).
Используй Tailwind CSS CDN — никакой локальной сборки.
Все числа форматируй по правилам из memory.
Разделы в порядке из memory: Title Page → Executive Summary →
Current State → Performance → Risk → Rebalancing → Recommendations → Appendix.
По завершении выведи:
- путь к HTML-файлу
- 3 ключевых числа: PnL USD, PnL %, Alpha
- список найденных аномалий (если есть)
MCP-источники данных
- DeBank MCP — полный снапшот DeFi-позиций по EVM-адресу: протоколы, токены, чейны, оценка в USD в реальном времени. Главный источник «сколько стоит портфель сейчас».
- Etherscan API — on-chain activity: транзакции за период, gas-расходы, взаимодействия с контрактами. Бесплатный план: 5 req/sec, 100K req/день. Хватает на 20+ клиентов.
- Dune Analytics — кастомные SQL-запросы к on-chain данным: APY по LP-пулам, IL, объёмы, fees earned. Бесплатный план: 2500 req/мес — хватает на 1-2 клиентов; дальше Pro $349/мес.
- Alchemy / Infura — альтернатива Etherscan для raw RPC: getLogs, getBalance, eth_call. Нужен для нестандартных запросов или если Etherscan упёрся в rate-limit.
Workflow первого числа месяца
- Отправляешь месячный промпт → CC начинает работу
- CC параллельно дёргает DeBank + Etherscan + Dune (15–20 минут — можно идти за кофе)
- CC генерирует HTML-файл с графиками и таблицами → открываешь в браузере
- Читаешь Executive Summary, проверяешь ключевые числа (обычно 1–2 правки формулировок)
- Пишешь CC правку → он исправляет за 30 секунд → HTML готов к конвертации
Фрагмент сгенерированного HTML
<!-- Executive Summary block -->
<section class="exec-summary">
<div class="kpi-grid">
<div class="kpi-card">
<div class="kpi-label">Стоимость портфеля</div>
<div class="kpi-value">$3,141,200</div>
<div class="kpi-delta positive">+$141,200 с начала года</div>
</div>
<div class="kpi-card">
<div class="kpi-label">PnL за май</div>
<div class="kpi-value positive">+$47,300</div>
<div class="kpi-delta positive">+4.7% / Benchmark +3.2% / Alpha +1.5%</div>
</div>
<div class="kpi-card">
<div class="kpi-label">Лучший протокол</div>
<div class="kpi-value">GMX</div>
<div class="kpi-delta positive">+12.4% за месяц</div>
</div>
<div class="kpi-card">
<div class="kpi-label">IL за май</div>
<div class="kpi-value negative">-$2,340</div>
<div class="kpi-delta muted">Uniswap V3 ETH/USDC</div>
</div>
</div>
</section>
47300 вместо $47,300, нужен явный форматтер в memory; (3) Dune-запросы — если пул нестандартный, CC может не найти IL и написать «данные недоступны» — нужно указывать конкретный address пула в memory.Playwright скриншот SCALE=3 — не page.pdf
HTML согласован. Одна команда — и через 30 секунд у тебя PDF. Но только если делаешь через screenshot, а не через page.pdf(). Разница принципиальная.
Ниже — полный Python-скрипт. Он делает ровно то, что нужно: открывает HTML, ждёт загрузки шрифтов и Chart.js, снимает полностраничный скриншот с device_scale_factor=3, конвертирует PNG → PDF через Pillow. Работает на любом HTML-отчёте.
html_to_pdf.py — полный скрипт
#!/usr/bin/env python3
"""
html_to_pdf.py — конвертация HTML-отчёта в PDF через Playwright screenshot.
Использование:
python html_to_pdf.py report-client-M-2025-05.html
python html_to_pdf.py report.html --out custom-name.pdf --scale 3
Зависимости:
pip install playwright Pillow
playwright install chromium
"""
import argparse
from pathlib import Path
from playwright.sync_api import sync_playwright
from PIL import Image
import io
def html_to_pdf(html_path: str, out_path: str | None = None, scale: int = 3) -> str:
src = Path(html_path).resolve()
if not src.exists():
raise FileNotFoundError(f"HTML not found: {src}")
dst = Path(out_path) if out_path else src.with_suffix(".pdf")
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
# Устанавливаем deviceScaleFactor — это и есть SCALE=3.
# Даёт тройную пиксельную плотность: текст и цифры острые при печати.
context = browser.new_context(
viewport={"width": 1200, "height": 900},
device_scale_factor=scale,
)
page = context.new_page()
# Открываем локальный HTML-файл
page.goto(f"file://{src}", wait_until="networkidle")
# Ждём загрузки Chart.js и шрифтов — критично для корректного рендера
page.wait_for_timeout(2000)
# Полностраничный скриншот — снимает весь документ, не только viewport
png_bytes = page.screenshot(full_page=True)
browser.close()
# Конвертируем PNG в PDF через Pillow
img = Image.open(io.BytesIO(png_bytes))
# Переводим в RGB (PDF не поддерживает RGBA)
if img.mode in ("RGBA", "LA", "P"):
img = img.convert("RGB")
img.save(str(dst), "PDF", resolution=300, save_all=False)
print(f"PDF сохранён: {dst} ({dst.stat().st_size // 1024} KB)")
return str(dst)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="HTML → PDF через Playwright screenshot")
parser.add_argument("html", help="Путь к HTML-файлу")
parser.add_argument("--out", help="Путь к выходному PDF (по умолчанию: рядом с HTML)")
parser.add_argument("--scale", type=int, default=3, help="deviceScaleFactor (default: 3)")
args = parser.parse_args()
html_to_pdf(args.html, args.out, args.scale)
Почему scale=3, а не 1 или 4
- Scale=1 — стандартный дисплей. Текст читаем, но цифры в таблицах выглядят размыто при печати или зуме клиента. Не премиум.
- Scale=2 — Retina/HiDPI. Приемлемо, но при A4 печати 300dpi всё ещё заметна пикселизация в мелких элементах (подписи к графикам, footnotes).
- Scale=3 — оптимум: изображение 3600×N пикселей при viewport 1200px. При конвертации в PDF A4 (595×842pt) → ~100dpi эффективного разрешения с запасом. Текст острый, тени сглаженные, Chart.js-графики без алиасинга.
- Scale=4 — избыточно: PNG-файл ~50–80 MB, время генерации x2, а визуальная разница с Scale=3 при печати неразличима. Польза нулевая, накладные расходы большие.
page.pdf() для отчётов с CSS-тенями, градиентами, Chart.js/Recharts-графиками и Google Fonts. Результат непредсказуем: кривые блоки, съехавшие пропорции, слетевшие цвета, пропавшие шрифты. Это не баг — это by design: page.pdf() использует print-режим браузера, который намеренно упрощает рендер для A4. Playwright screenshot снимает то, что видит пользователь — ровно то, что ты согласовал в браузере. Один-в-один.7 проблем page.pdf() — симптомы и фиксы
- box-shadow исчезает или становится резким. Симптом: карточки с тенями в браузере → в PDF тень пропала или превратилась в чёрную рамку. Причина: Chromium print-mode отключает некоторые CSS-эффекты для оптимизации печати. Фикс со стороны
page.pdf():@media print { .card { box-shadow: none; border: 1px solid #eee; } }— но это меняет дизайн. Фикс Playwright screenshot: проблемы нет, рендерит как браузер. - Градиенты теряют плавность (ступеньки). Симптом:
linear-gradientв заголовках → видны 8–16 полос вместо плавного перехода. Причина:page.pdf()использует ограниченное цветовое пространство для градиентов. Фикс Playwright screenshot: рендер через GPU, полный цветовой диапазон. - Chart.js / Recharts — съехавший aspect-ratio. Симптом: горизонтальный bar chart в браузере → в PDF сжат вертикально или обрезан. Причина:
page.pdf()задаёт другой viewport до рендера; Chart.js пересчитывает размеры. Фикс Playwright screenshot: Chart.js уже отрендерен в нужных размерах до скриншота. - Межстрочные интервалы схлопываются. Симптом: таблицы с
line-height: 1.5→ в PDF строки слипаются, текст нечитаем. Причина:page.pdf()применяет print-stylesheet поверх основных стилей. Фикс Playwright screenshot: проблемы нет. - Шрифты заменяются системными. Симптом: Inter/JetBrains Mono в браузере → в PDF Times New Roman или Arial. Причина:
page.pdf()иногда не ждёт полной загрузки Google Fonts CDN. Фикс Playwright screenshot:wait_until="networkidle"+wait_for_timeout(2000)— надёжно. - Многостраничные разрывы ломают блоки. Симптом: таблица разрезана пополам между страницами; график разрывается посередине. Причина:
page.pdf()делит на страницы, не учитывая CSSpage-break-inside: avoid. Фикс Playwright screenshot: одна длинная страница → нет разрывов, клиент скроллит. - Прозрачность и blur теряются. Симптом:
backdrop-filter: blur()/ rgba() фоны → в PDF сплошной цвет или артефакты. Причина: ограниченная поддержка CSS-фильтров в print-режиме Chromium. Фикс Playwright screenshot: проблемы нет.
Альтернативы — что ещё пробовали
- Playwright screenshot (наш метод) — Pro: пиксель-перфект, полная поддержка CSS/JS/Fonts, Chart.js рендерится правильно, SCALE=3 = retina-качество. Con: большой файл (5–20 MB при SCALE=3), одна длинная страница без page-breaks, нужен chromium (~150 MB).
- page.pdf() (встроенный Playwright) — Pro: нативные страницы A4, меньший размер файла. Con: ломает тени, градиенты, Charts, шрифты — непредсказуемо для сложных CSS. Не для дизайнерских отчётов.
- WeasyPrint — Pro: чистый Python, нет Chromium, хорошая поддержка CSS Paged Media, маленькие PDF (8–21 KB). Con: нет JS — Chart.js не работает, нет box-shadow, нет backdrop-filter. Подходит для простых текстовых отчётов, не для дашбордов.
- wkhtmltopdf — Pro: быстро, широко используется. Con: устаревший движок (Qt WebKit 2012 года), плохая поддержка flexbox/grid, официально deprecated. Не рекомендуется для новых проектов.
- Puppeteer (Node.js) — Pro: та же логика что Playwright, хорошая экосистема. Con: Node.js стек — если весь стек Python, дополнительная зависимость. Для Python-проектов Playwright предпочтительнее.
Структура «который не выглядит как Word»
Отчёт в Word или Figma → клиент видит, что это «шаблон». HTML-отчёт с Chart.js и правильной типографикой → клиент видит продукт. Разница не в цене стека (оба бесплатно), а в том, как сделан макет.
Секции HTML-шаблона в порядке рендера
- Title Page — полноширинный блок: логотип компании (top-left), watermark «CONFIDENTIAL» (diagonal, opacity 0.06), имя клиента, отчётный период (MMM YYYY), дата генерации, версия документа
- Top CTA Bar — узкая полоска сверху: ссылка на telegram-бот или контакт аналитика (скрыть при конвертации в PDF через
@media print { .top-bar { display: none; } }) - Executive Summary — 4–5 KPI-карточек в CSS Grid (2×2 или 2×3): Portfolio Value, Monthly PnL (+ цвет: зелёный/красный), Alpha vs Benchmark, Best Protocol, Worst Metric. Ниже — 3 события месяца в 1 строку
- Portfolio State — таблица текущих позиций: Protocol / Chain / Asset / Value USD / % of Portfolio / APY; строки зебра; подсветка топ-3 позиций золотым
border-left - Performance Chart — линейный Chart.js: две линии (Portfolio vs Benchmark), ось Y в USD, ось X по дням месяца, легенда, точки при hover
- Performance Table — рядом с графиком или ниже: Start Value / End Value / PnL USD / PnL % / Benchmark % / Alpha
- Risk Overview — три блока: (1) концентрация топ-3 позиций в %, (2) IL по LP-позициям таблицей, (3) liquidity score — % портфеля доступного за 24ч
- Rebalancing — таблица: Category / Target % / Actual % / Delta / Action; delta подсвечена: зелёный если <3%, жёлтый 3–5%, красный >5%
- Recommendations — три группы: HIGH (срочно, красный), MED (до следующего отчёта, жёлтый), LOW (при возможности, серый). Каждый пункт: действие + обоснование + deadline
- Appendix — свёрнутый
<details>с полным списком транзакций; источники данных с датой запроса; время генерации отчёта
Выбор библиотеки для графиков
- Chart.js v4 (CDN) — лучший выбор для статических отчётов. Минималистичный API, работает через CDN без сборки, рендерится в Canvas (PNG-совместим с Playwright screenshot). Поддерживает pie/doughnut, line, bar. Размер: ~200 KB. Для отчётов — идеально. Подключение:
<script src="https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.min.js"></script> - Recharts v3 — для React-стека. Если отчёт генерируется как React-приложение (Next.js) и рендерится Playwright — отличный выбор: богатая кастомизация, SVG (масштабируется без артефактов). Но требует сборки — не подходит для простого CDN-HTML.
- D3.js — максимальный контроль над графиками. Подходит если нужны кастомные визуализации (tree map аллокации, custom waterfall PnL). Крутая кривая обучения — для CC-генерации лучше Chart.js.
- Lightweight SVG (inline) — для простых вещей (pie chart с 5 сегментами, horizontal bar) можно генерировать SVG inline без библиотек. CC отлично справляется. Плюс: нет внешних зависимостей, мгновенный рендер. Минус: сложные интерактивные графики не сделать.
- Рекомендация: Chart.js CDN для 90% отчётов. Inline SVG для простых диаграмм (target vs actual allocation в виде horizontal bars).
Брендинг и переменные стиля
/* CSS-переменные бренда — меняй только здесь */
:root {
--brand-primary: #1F4F86; /* основной цвет */
--brand-accent: #8B5CF6; /* акцент (CTA, badges) */
--brand-positive: #16A34A; /* рост, зелёный */
--brand-negative: #DC2626; /* убыток, красный */
--brand-gold: #F59E0B; /* предупреждение, highlight */
--brand-bg: #F8FAFC; /* фон страницы */
--brand-card: #FFFFFF; /* фон карточек */
--font-main: 'Inter', -apple-system, sans-serif;
--font-mono: 'JetBrains Mono', Menlo, monospace;
}
- Логотип — разместить top-left title page, размер 120×40px. SVG предпочтительнее PNG (масштаб без потерь при SCALE=3). В Playwright screenshot отображается корректно.
- Watermark — диагональный текст «CONFIDENTIAL» через CSS
transform: rotate(-45deg),position: fixedилиabsoluteна весь документ,opacity: 0.04–0.06. Не мешает чтению, но сигнализирует статус документа. - Favicon — добавить
<link rel="icon">с favicon клиента или своим — отображается при открытии HTML в браузере. - Шрифты — Inter (основной текст) + JetBrains Mono (числа, коды транзакций). Подгружать через Google Fonts CDN. В Playwright:
wait_until="networkidle"+wait_for_timeout(2000)гарантирует загрузку перед скриншотом. - Цветовое кодирование — единая система: зелёный = рост/ок, красный = убыток/проблема, жёлтый = внимание, серый = нейтральный. Прописать в memory-файле клиента, чтобы CC всегда применял одинаково.
@media (max-width: 640px) в отчёте — лишний код. Клиент открывает PDF в Adobe Acrobat, Preview или печатает на A4. Таблицы должны помещаться по ширине. Шрифт — минимум 13px (=10pt в печати при 96dpi). Числа — минимум 15px, лучше 17–18px.Что замерять для разных DeFi-портфелей
Ошибка — делать один шаблон на всех. Пассивный LP-фармер и активный трейдер смотрят на разные вещи. Прописывай нужные метрики в memory-файле клиента — CC будет собирать именно их.
DeFi-инвестор (capital allocation, $500K+)
Фокус: сохранение капитала + стабильный доход. Горизонт 12–36 месяцев.
- Total Portfolio Value (USD) — главное число, сколько стоит всё
- Monthly PnL (USD + %) — абсолютный результат за период
- Alpha vs ETH+BTC 50/50 — обгоняет ли стратегия простой бенчмарк
- Concentration risk — топ-3 позиции, % от портфеля; если >60% в 3 активах — риск-сигнал
- Stablecoin ratio — % от портфеля, буфер ликвидности и риск-балансировка
- Target allocation deviation — что отклонилось >5% — сигнал к ребалансировке
- Annualized yield — % годовых на весь портфель, сравнимо с TradFi (S&P, bonds)
- Gas-расходы за период (USD) — часто недооценивают; влияет на net PnL
Активный трейдер (DeFi perpetuals, spot, leverage)
Фокус: краткосрочный P&L, управление рисками позиций, win rate.
- Realized PnL за период (USD) — закрытые сделки, реальные деньги
- Unrealized PnL — открытые позиции, текущий риск
- Win rate (% прибыльных сделок) — качество торговых решений
- Avg profit / Avg loss ratio — risk/reward профиль стратегии
- Max drawdown за период — максимальное просадение, психологический и риск-показатель
- Funding rate расходы (perpetuals, USD) — скрытая стоимость удержания позиций
- Protocol fees paid (USD) — trading fees суммарно, часть себестоимости
- Liquidation distance — ближайшая позиция, % до margin call
Passive Yield (staking, LP, lending, yield aggregators)
Фокус: стабильный доход, минимизация IL, риск протокола.
- Total yield earned (USD + % APY realized) — реально заработанное, не теоретическое
- Impermanent loss — USD по каждому пулу, главная скрытая стоимость LP
- Net yield = fees earned − IL (USD) — реальная прибыль LP после IL
- Protocol TVL trend (Dune) — падение TVL → растёт риск протокола
- Smart contract risk score — возраст контракта, аудиты, incidents
- Reward token price change — если фарминг: APY может быть высоким, но token −90%
- Auto-compound events — когда последний раз реинвестировалось
- Liquidity depth — насколько просто выйти: время и slippage
DAO / Treasury Management
Фокус: подотчётность перед участниками, диверсификация казны, runway.
- Treasury balance (USD + по активам) — общее состояние казны
- Runway — месяцев при текущих расходах, сколько времени до нулевого баланса
- Native token % of treasury — если >70% в нативном токене — концентрация риска
- Stablecoin runway — только stables, месяцев операционного запаса независимо от рынка
- Monthly spend (USD, по категориям) — прозрачность трат для участников DAO
- Yield on idle assets — % годовых на неиспользуемых stables, они должны работать
- Diversification events — что продали/купили для ребалансировки
- Governance proposals executed — активность DAO в управлении казной
Сколько стоит месячный отчёт
Когда отчёт делается за 30 минут — соблазн поставить низкую цену. Это ошибка. Клиент платит не за твоё время. Он платит за экспертизу, за надёжность, за то что кто-то следит за его $3M портфелем. Ценность не уменьшилась от того, что инструменты ускорились.
Три тира с экономикой
- Starter — $300/месяц. Для небольшого портфеля ($50K–$300K), 1 адрес, 3–5 протоколов, базовая аллокация. Входит: ежемесячный PDF-отчёт (6–8 страниц) — Executive Summary, Performance, Allocation, 3 рекомендации; 1 раунд правок; delivery в течение 3 рабочих дней после конца месяца; email/Telegram с файлом. Не входит: on-demand вопросы, ребалансировка, налоговый отчёт. Экономика для тебя: 1 час работы = $300, рейт $300/час.
- Pro — $800/месяц. Для серьёзного DeFi-портфеля ($300K–$2M), несколько адресов, cross-chain, LP-позиции. Входит: полный PDF-отчёт (12–15 страниц) — все разделы включая Risk Overview и детальный Rebalancing; 2 раунда правок; 1 звонок (30 минут) для обсуждения рекомендаций; delivery в течение 2 рабочих дней; уведомления при аномалиях (>10% движение в портфеле). Экономика для тебя: 1.5 часа работы = $800, рейт $533/час.
- Enterprise — $1,500–$3,000/месяц. Для крупного портфеля ($2M+), DAO treasury, family office с DeFi-экспозицией. Входит (зависит от объёма): полный отчёт + кастомные секции (налоговая база, отчёт для соинвесторов); еженедельные flash-апдейты (2–3 строки: PnL, ключевые события); on-demand вопросы без ограничений (в рабочее время); delivery в течение 1 рабочего дня; приоритет при market events (FUD, exploit в протоколе — звонок в день события). Экономика для тебя: 3–5 часов работы = $1,500–$3,000, рейт $300–$1,000/час.
Позиционирование — как продать
- Не продавай «отчёт» — продавай «ты знаешь что происходит с твоими деньгами каждый месяц». Отчёт — это инструмент. Ценность — спокойствие и контроль.
- Якорь на TradFi — финансовый советник в TradFi берёт 0.5–1% AUM в год = $5,000–$10,000 на $1M портфеле. Ежемесячный DeFi-отчёт за $800/мес = $9,600/год = ~0.5% на $2M. То же самое, но в DeFi, где сложность выше.
- Первый отчёт бесплатно — дай пробный за май бесплатно (стоит тебе 30 минут). Клиент видит качество → оплачивает подписку. Конверсия из пробного в платный у персонализированных услуг высокая.
- Квалификационный фильтр — не берись за портфели <$50K. Это не высокомерие — просто $300/мес = 0.6% на $50K = дорого для клиента. Адекватная аудитория: от $200K портфеля.
Договорные пункты — что включить в оферту
- Data ownership — все данные клиента (адреса, портфель) используются только для генерации его отчёта. Не передаются третьим лицам.
- Confidentiality — отчёты помечены CONFIDENTIAL, не публикуются без согласия клиента.
- Refresh frequency — данные актуальны на дату генерации отчёта (указывается в Appendix). Не является инвестиционной рекомендацией в юридическом смысле.
- Disclaimer — «Отчёт носит информационный характер. Не является инвестиционным советом. Инвестиции в DeFi несут высокие риски, включая полную потерю средств.»
- Cancellation — уведомление за 15 дней. Оплата за начатый месяц не возвращается.
- Data accuracy — аналитик не несёт ответственности за неточности в данных DeBank/Etherscan/Dune (указывается как источник). Клиент несёт ответственность за корректность предоставленных адресов.
От нуля до первого PDF — 7 шагов
Первый клиент занимает больше всего времени — примерно 2–3 часа. Второй — час (копируешь структуру). Третий — 30 минут (уже всё знаешь). Вот точный порядок шагов.
- Kickoff с клиентом (~30 минут). Собери все EVM-адреса (кошельки, cold storage, все чейны). Узнай target allocation: сколько % в чём хочет держать. Согласуй разделы: что хочет видеть в отчёте, что лишнее. Договорись о дне delivery (обычно 3–5 число месяца). Результат: вся информация для memory-файла.
- Создаёшь memory-файл (~20 минут). Скопируй шаблон из Шага 1 в
memory/clients/client-X.md. Заполни: адреса, capital, target allocation, тон. Пропиши формулы (PnL, benchmark, IL) — важно сделать один раз правильно. Результат: CC знает всё о клиенте. - Устанавливаешь стек (~15 минут, один раз).
pip install playwright Pillow→playwright install chromium→ сохрани скриптhtml_to_pdf.pyиз Шага 3. Результат: конвейер HTML → PDF готов. - Тестовый запрос без данных (~20 минут). Дай CC команду: «собери структуру отчёта для клиента X за тестовый период, данные не нужны — сделай заглушки». Проверь HTML: разделы на месте, форматирование правильное, Chart.js рендерится. Результат: шаблон HTML валидирован, можно запускать с реальными данными.
- Первый реальный отчёт (~30–45 минут CC + 10 минут ревью). Отправь месячный промпт из Шага 2. Дождись завершения, открой HTML в браузере. Проверь 5 точек: даты, ключевые числа (PnL, allocation), форматирование валют, Chart.js отображение, рекомендации. Результат: HTML-черновик.
- Review и правки (~10–20 минут). Отметь правки: обычно 1–3 (уточнить формулировку рекомендации, исправить число, добавить контекст). Скажи CC что править — он исправляет за 30–60 секунд. Результат: финальный HTML.
- Конвертация в PDF и отправка (~5 минут).
python html_to_pdf.py report-client-X-2025-05.html→ открой PDF, визуальная проверка (1 минута) → отправь клиенту (email/Telegram). Результат: отчёт у клиента, первый цикл закрыт.
7 граблей с практики — и как их обойти
Ошибки в автоматизации отчётов делятся на два типа: те, что видит клиент (плохо), и те, что замечаешь только ты (терпимо). Ниже — оба типа, с фиксами.
- PDF разрывается посередине таблицы (клиент видит). Симптом: таблица в Reports разрезана между страницами — заголовок на одной странице, данные на другой. Причина:
page.pdf()— или если используешь Playwright screenshot с жёстким разделением на A4. Фикс: Playwright screenshot = одна длинная страница без разрывов. Клиент скроллит PDF. Если нужны A4-страницы — добавьpage-break-before: alwaysвручную между разделами в HTML. Источник:feedback/pdf-one-page.mdв памяти Тимура — именно про это. - Дата в отчёте неправильная или локаль не та. Симптом: «May 2025» вместо «Май 2025», или «05/01/2025» вместо «01.05.2025». Причина: CC использует дефолтный locale, не следует правилам из memory. Фикс: прописать в memory явно:
Dates: DD.MM.YYYY, no English month names, always Russian; в промпте всегда указывать месяц по-русски. - Валюты без форматирования ($47300 вместо $47,300). Симптом: числа без разделителей тысяч, или смешанные форматы ($47,300 и 47300 в одном отчёте). Причина: CC генерирует числа без явного форматтера, особенно при расчётах. Фикс: добавить JS-форматтер в HTML-шаблон.
Или: инструктировать CC через memory «форматируй все суммы через// Вставить в <script> отчёта document.querySelectorAll('.currency').forEach(el => { const val = parseFloat(el.dataset.value); el.textContent = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', maximumFractionDigits: 0 }).format(val); });JS Intl.NumberFormat». - Chart.js не отрисовался (пустой canvas). Симптом: в PDF — пустой белый прямоугольник вместо графика. Причина: Playwright сделал screenshot до загрузки Chart.js CDN или до инициализации canvas. Фикс: в
html_to_pdf.pyувеличить timeout:page.wait_for_timeout(3000)вместо 2000; добавитьpage.wait_for_function("typeof Chart !== 'undefined'"). - Google Fonts не загрузились — системный шрифт в PDF. Симптом: Inter/JetBrains Mono в браузере → Times New Roman или Arial в PDF. Причина:
wait_until="networkidle"не всегда гарантирует загрузку шрифтов до render. Фикс: добавитьpage.wait_for_timeout(2000)ПОСЛЕnetworkidle; или встроить шрифты как base64 в HTML (надёжнее, но увеличивает размер файла). - Клиент получает «fo-case pattern» — отчёт без контекста. Симптом: правильные цифры, но Executive Summary написан без понимания ситуации клиента — «портфель вырос на 4.7%» без объяснения почему и что делать. Причина: CC генерирует механически по шаблону; в memory нет описания контекста портфеля. Фикс: в memory прописать «Recommendations must include: action + rationale + deadline. Never write generic statements like "consider rebalancing". Always name specific protocol, specific action, specific amount.» Источник:
feedback/fo-case-pattern.mdв памяти Тимура. - Отчёт одностраничный — слишком компактный для клиента. Симптом: всё уместилось на 1–2 экрана в PDF, выглядит как краткая сводка, не как premium-документ. Причина: CC сгенерировал компактный HTML без структуры разделов; или все данные уместились в мини-таблицы. Фикс: в memory прописать минимальный объём: «Report must be 10–15 screens long when opened in browser at 1200px width. Each section on own screen. KPI cards must be large (min 80px height). Charts min 300px height.»; в промпте добавить «не сжимай». Источник:
feedback/pdf-one-page.mdв памяти Тимура.
memory/clients/client-X.md, который защищает от того же косяка на следующий месяц.12 часов → 30 минут = 24× ускорение
- Было 8–12 часов на один отчёт. Стало 30 минут — из которых 20 минут CC работает без тебя
- Была ручная сборка данных — copy-paste из DeBank, Etherscan, Dune в Excel. Стало: CC идёт сам через MCP
- Был бесконечный цикл объяснений — каждый месяц заново. Стало: memory-файл один раз на всё время
- Был кривой PDF из Word или Figma с расползающимися таблицами. Стало: HTML → Playwright SCALE=3 → premium-документ за 30 секунд
- Был рейт $125/час (при $1,000 за день работы). Стало: $2,000/час на том же клиенте без повышения цен
- Было ограничение по количеству клиентов — день на одного → потолок 20 клиентов в месяц при полной загрузке. Стало: 30 минут на одного → потолок 160 клиентов при той же загрузке (×8 масштаб)
- Был страх новых клиентов («ещё один — нет времени»). Стало: каждый новый клиент = 1 час на настройку + 30 минут в месяц
Маржа выросла не потому что ты поднял цену. Потому что ты перестал тратить время на работу, которую умеет делать машина. Твоё время теперь стоит в 16× дороже — при тех же деньгах от клиента.
Если взять $800 за Pro-отчёт и тратить 1.5 часа: $800 / 1.5 = $533/час. Добавь 10 таких клиентов ($8,000/мес) при суммарных 15 часах работы — это $533/час стабильного дохода без найма аналитиков и без ночных смен перед дедлайном.
Это не теория. Это арифметика: стоимость инструмента ($120/мес CC) несравнимо меньше добавленной стоимости ($8,000/мес возможный доход). Разницу — забираешь ты.
Забери memory-template + prompt + Playwright-скрипт + HTML-шаблон + пример PDF
Пришлю четыре файла: (1) полный memory-template клиента с заполненными разделами, (2) месячный prompt с переменными {{client_id}} {{month}}, (3) Python-скрипт html_to_pdf.py с SCALE=3, (4) HTML-шаблон отчёта с Chart.js — pie chart + line chart уже подключены. Забираешь и запускаешь на своём клиенте в тот же день.
Открыть в Telegram →