MAATRIX / Блог / Трейдер ведёт журнал сделок: своя база и статистика вместо чужого сервиса

Трейдер ведёт журнал сделок: своя база и статистика вместо чужого сервиса

MAATRIX

Каждая сделка, которую вы записываете в стороннем сервисе для ведения журнала, — это строчка в чужой базе данных: тикер, объём, точка входа и выхода, стоп, комментарий про то, почему вы вообще зашли в позицию. По отдельности это просто цифры. Но месяц истории — это уже читаемый портрет вашей стратегии, а год — почти точный слепок того, как вы принимаете решения и сколько на этом зарабатываете или теряете. Отдавать такой архив третьей стороне не обязательно, и бесплатные тарифы большинства журналов сделок всё равно упрутся в лимит по числу записей или отключат часть аналитики раньше, чем вы соберёте статистику, на которую можно опереться. Ниже — как поставить собственную базу для журнала сделок на своём сервере: без чужих серверов между вами и вашей историей, без лимитов и с полным контролем над тем, кто и что видит.

Почему сторонний сервис для журнала сделок — это компромисс, а не решение

Идея стороннего журнала сделок понятна: не надо ничего настраивать, открыл вкладку — и вносишь сделку. Но у этого удобства есть цена, и она не только в деньгах за подписку.

Во-первых, ваша история сделок физически лежит на серверах компании, которую вы не выбирали и не контролируете. Даже если в её политике написано, что данные не передаются третьим лицам, вы полагаетесь на честность и на качество защиты чужой инфраструктуры. Утечка базы данных такого сервиса — не гипотетический сценарий, а рутинная новость индустрии: рано или поздно почти любой облачный сервис с пользовательскими данными оказывается в заголовке про взлом. Для трейдера это означает, что детальная картина его сделок — какие инструменты он торгует, с каким объёмом, как часто ошибается, в какие часы наиболее активен — может оказаться доступна кому-то ещё.

Во-вторых, бесплатные и даже недорогие платные тарифы таких сервисов почти всегда режут функциональность именно там, где она нужнее всего: ограничивают число сделок в месяц, урезают историю до последних 90 дней, прячут часть статистики — просадку по инструментам, распределение прибыли по времени суток, корреляцию между размером позиции и результатом — за более дорогим тарифом. В итоге вы либо платите за подписку, конфигурация которой продиктована не вашей торговлей, а прайсом поставщика, либо постоянно упираетесь в потолок и выгружаете данные вручную, чтобы досчитать статистику в Excel.

В-третьих — и это то, что обычно замечают позже всего, — стороннее приложение задаёт структуру данных так, как удобно ему, а не так, как удобно вам. Если вы торгуете на нескольких биржах, используете нестандартные типы ордеров, ведёте заметки по психологии сделки или хотите добавить свой набор тегов для разбора ошибок — вы либо подстраиваетесь под чужую схему, либо упираетесь в то, что нужного поля просто нет.

Своя база на своём сервере снимает все три проблемы разом: данные физически там, где решаете вы, лимитов по числу записей нет в принципе, а схему данных вы проектируете под свою торговлю, а не под чужой продукт.

Что такое «свой журнал сделок» технически

Речь не о том, чтобы писать сложное приложение с нуля. Журнал сделок — это, по сути, одна хорошо спроектированная таблица в реляционной базе данных плюс инструмент для просмотра и построения графиков поверх неё. Компонентов три:

  1. База данных — PostgreSQL, поднятый на вашем сервере. Хранит саму историю сделок: время открытия и закрытия, инструмент, направление, объём, цену входа и выхода, комиссию, стоп и тейк, теги и текстовые заметки.
  2. Инструмент ввода данных — то, чем вы будете заносить сделки. Это может быть простая веб-форма, скрипт импорта из CSV-выгрузки брокера, или даже psql через SSH, если вы не против командной строки.
  3. Инструмент аналитики и визуализации — дашборд поверх базы, который считает статистику: винрейт, средний R (соотношение прибыли к риску), просадку, распределение сделок по инструментам и по времени.

Все три компонента отлично работают на одном недорогом VPS. База данных для журнала сделок — это десятки тысяч записей за годы активной торговли, а не миллиарды строк, так что требования к железу скромные: 1-2 vCPU и пара гигабайт памяти хватает с запасом. Раздел про установку PostgreSQL с нуля есть в отдельном руководстве: как установить и настроить PostgreSQL на VPS.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Проектируем схему таблицы под реальную торговлю

Прежде чем разворачивать что-либо, стоит продумать структуру данных — от неё зависит, какую статистику вы вообще сможете считать позже. Минимальная, но рабочая схема для одной сделки выглядит так:

CREATE TABLE trades (
    id SERIAL PRIMARY KEY,
    symbol VARCHAR(20) NOT NULL,
    side VARCHAR(5) NOT NULL CHECK (side IN ('long', 'short')),
    opened_at TIMESTAMPTZ NOT NULL,
    closed_at TIMESTAMPTZ,
    entry_price NUMERIC(18,6) NOT NULL,
    exit_price NUMERIC(18,6),
    quantity NUMERIC(18,6) NOT NULL,
    stop_loss NUMERIC(18,6),
    take_profit NUMERIC(18,6),
    fees NUMERIC(18,6) DEFAULT 0,
    pnl NUMERIC(18,6),
    strategy_tag VARCHAR(50),
    setup_tag VARCHAR(50),
    notes TEXT,
    created_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX idx_trades_symbol ON trades (symbol);
CREATE INDEX idx_trades_opened_at ON trades (opened_at);
CREATE INDEX idx_trades_strategy_tag ON trades (strategy_tag);

Несколько моментов, о которых легко забыть на старте:

  • pnl лучше не считать на лету в каждом запросе, а сохранять при закрытии сделки. Это избавляет от лишних вычислений в дашбордах и упрощает построение графиков накопленной доходности.
  • Теги стратегии и сетапа — отдельные поля, а не общий текст. Если вы торгуете несколько стратегий одновременно (например, пробой уровня и возврат к средней), раздельные теги позволят потом сравнить их статистику независимо друг от друга.
  • closed_at и exit_price допускают NULL — это нужно, чтобы можно было заносить открытую позицию сразу при входе, а не только постфактум.
  • Если вы торгуете с частичными закрытиями (вышли из половины позиции, потом из остатка), одна строка на сделку уже не подойдёт — придётся вести отдельную таблицу исполнений (executions) и агрегировать её в trades представлением (VIEW). Это усложняет схему, но точнее отражает реальность рынка.

Отдельная таблица для комментариев по психологии сделки — тоже разумное решение, если вы ведёте разбор ошибок: trade_id, emotion_tag (например, «вошёл на FOMO», «пересидел стоп»), review_notes. Статистика по эмоциональным тегам часто оказывается интереснее статистики по инструментам — там обычно и находится настоящая утечка денег.

Импорт истории сделок из выгрузки брокера

Если вы уже торговали и у брокера или биржи есть экспорт истории в CSV — переносить всё вручную не нужно. Практическая схема:

  1. Выгружаете историю сделок из личного кабинета брокера в CSV.
  2. Пишете небольшой скрипт на Python, который читает CSV и приводит поля к схеме вашей таблицы trades.
  3. Загружаете результат через COPY или psycopg2.

Пример минимального скрипта импорта:

import csv
import psycopg2

conn = psycopg2.connect(
    host="localhost", dbname="journal",
    user="trader", password="ваш_пароль"
)
cur = conn.cursor()

with open("broker_export.csv", encoding="utf-8") as f:
    reader = csv.DictReader(f)
    for row in reader:
        cur.execute("""
            INSERT INTO trades (symbol, side, opened_at, closed_at,
                entry_price, exit_price, quantity, fees, pnl)
            VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)
        """, (
            row["symbol"], row["side"].lower(),
            row["opened_at"], row["closed_at"],
            row["entry_price"], row["exit_price"],
            row["quantity"], row["fees"], row["pnl"]
        ))

conn.commit()
cur.close()
conn.close()

У каждого брокера свой формат CSV, поэтому этот скрипт — заготовка, а не готовое решение: названия колонок, формат дат и знак у pnl для коротких позиций почти наверняка придётся подстроить под конкретную выгрузку. Но сам подход — распарсить, привести типы, загрузить одним проходом — работает одинаково для любого источника.

Статистика: считаем то, что действительно важно

Ради этого всё и затевалось — журнал сделок без статистики просто архив. Разница между «своим» и «чужим» журналом здесь особенно заметна: вы считаете именно те метрики, которые важны для вашей стратегии, а не тот набор, который решил показать разработчик стороннего сервиса.

Базовые запросы, которые стоит держать под рукой:

-- Винрейт и средний результат по стратегиям
SELECT
    strategy_tag,
    COUNT(*) AS total_trades,
    COUNT(*) FILTER (WHERE pnl > 0) AS wins,
    ROUND(100.0 * COUNT(*) FILTER (WHERE pnl > 0) / COUNT(*), 1) AS winrate,
    ROUND(AVG(pnl), 2) AS avg_pnl,
    ROUND(SUM(pnl), 2) AS total_pnl
FROM trades
WHERE closed_at IS NOT NULL
GROUP BY strategy_tag
ORDER BY total_pnl DESC;
-- Просадка по накопленной кривой доходности
WITH running AS (
    SELECT closed_at, SUM(pnl) OVER (ORDER BY closed_at) AS equity
    FROM trades
    WHERE closed_at IS NOT NULL
)
SELECT closed_at, equity,
    equity - MAX(equity) OVER (ORDER BY closed_at) AS drawdown
FROM running
ORDER BY closed_at;
-- Распределение сделок по часам открытия — где вы наиболее и наименее эффективны
SELECT
    EXTRACT(HOUR FROM opened_at) AS hour,
    COUNT(*) AS trades,
    ROUND(AVG(pnl), 2) AS avg_pnl
FROM trades
WHERE closed_at IS NOT NULL
GROUP BY hour
ORDER BY hour;

Голый SQL удобен для разовой проверки, но для регулярного взгляда на статистику нагляднее дашборд с графиками. Поверх PostgreSQL для этого хорошо ложится Metabase — он умеет строить дашборды прямо из SQL-запросов без написания фронтенда, и его несложно развернуть на том же сервере. Пошаговая установка описана здесь: как установить и настроить Metabase на VPS. Подключаете Metabase к базе journal, сохраняете такие запросы как «вопросы» и собираете из них дашборд: кривая эквити, винрейт по стратегиям, тепловая карта по часам и дням недели, распределение результата по объёму позиции. Обновляется автоматически при каждом заходе — никаких скриншотов и ручного копирования цифр.

Доступ, резервное копирование и шифрование

Журнал сделок бесполезен, если заносить сделки неудобно, и рискован, если данные не защищены на трёх уровнях сразу: доступ, бэкап, диск.

Доступ. Два рабочих варианта. Первый — лёгкое веб-приложение на сервере (например, на Flask или FastAPI) с формой ввода сделки поверх той же таблицы trades, открывается в браузере с телефона или ноутбука. Второй — прямой SQL-клиент: psql по SSH-туннелю или GUI вроде DBeaver через VPN до сервера, без лишней прослойки. В обоих случаях сервер не должен смотреть портами базы и веб-формы напролом в интернет — разумная схема - поднять свой VPN (WireGuard) и открывать доступ только через туннель. Типовая схема такого VPN для личного и небольшого командного доступа описана здесь: VPN для удалённой команды: типовая схема. Для одного трейдера конфигурация даже проще — один клиент, один сервер.

Резервное копирование. Минимальная схема — ежедневный pg_dump базы journal с ротацией копий и хранением части архивов вне самого сервера. Настройка автоматизации бэкапов PostgreSQL с cron и ротацией разобрана здесь: резервное копирование баз данных: автоматизация. Объём копии для журнала сделок обычно небольшой — десятки мегабайт даже за несколько лет активной торговли, — так что ежедневный дамп не создаёт заметной нагрузки на сервер.

Шифрование диска. Если сервер физически или в панели провайдера доступен третьим лицам, шифрование диска на уровне ОС (LUKS) защищает данные в состоянии покоя: без ключа расшифровки прочитать базу с изъятого или скопированного диска не получится. Что именно закрывает шифрование диска, а что нет — разобрано отдельно: шифрование дисков: что защищает. Для журнала сделок трейдера это не паранойя, а логичное продолжение той же идеи, ради которой вы вообще уходите от стороннего сервиса: данные о ваших сделках должны быть недоступны никому, кроме вас, на каждом уровне — от сетевого доступа до содержимого диска.

Что вы теряете, отказавшись от готового сервиса

Честности ради: собственный журнал сделок — не бесплатный обед, и вот что стоит понимать заранее.

  • Настройка занимает время. Готовый сервис даёт рабочий интерфейс за пять минут регистрации. Своя схема, импорт, дашборд и защита сервера — это часы работы на старте, даже если каждый отдельный шаг прост.
  • Нет готовых интеграций с брокерами. Некоторые коммерческие журналы сделок автоматически синхронизируются с API брокера. Со своей базой такую интеграцию, если она нужна, придётся писать самостоятельно под конкретного брокера.
  • Мобильное приложение — тоже ваша задача. Если вам критично заносить сделки с телефона в один тап, это отдельная разработка, а не то, что появляется само.
  • Вы сами себе техподдержка. Если база не отвечает в разгар торговой сессии, чинить её будете вы, а не саппорт стороннего сервиса.

Для трейдера, который ведёт десятки сделок в месяц и всерьёз анализирует статистику, это разумный обмен: чуть больше настройки на старте взамен полного контроля над данными и статистикой без искусственных ограничений. Для того, кто заносит одну сделку в неделю и не планирует копать глубоко в аналитику, готовый бесплатный сервис вполне может остаться проще и достаточно.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Не проще ли просто вести журнал в Excel или Google Таблицах?

Для десятка сделок в месяц — вполне рабочий вариант. Но как только счёт идёт на сотни записей и вы хотите считать просадку, распределение по времени или сравнивать стратегии между собой, реляционная база с индексами и SQL-запросами становится намного удобнее и быстрее электронной таблицы, а Google Таблицы к тому же означают, что история сделок опять лежит в чужом облаке.

Нужен ли мощный сервер под такую базу?

Нет. Журнал сделок одного трейдера — это десятки тысяч записей за много лет, а не большие данные. Недорогого VPS с 1-2 vCPU и 2 ГБ памяти хватает с большим запасом даже вместе с дашбордом Metabase на том же сервере.

Что если я торгую на нескольких биржах и у брокеров разный формат экспорта?

Пишете отдельный скрипт нормализации под каждый источник — все они в итоге приводят данные к одной и той же схеме таблицы trades. Это разовая работа на каждого брокера, а не постоянная рутина.

Безопасно ли держать такую чувствительную базу на арендованном сервере, а не дома?

Да, если соблюдать базовую гигиену: доступ только через VPN или SSH-туннель, закрытые снаружи порты базы данных, регулярные бэкапы и шифрование диска. Арендованный сервер с этими мерами защищён лучше, чем домашний компьютер без выделенного IP и без резервного копирования.

Можно ли совместить журнал сделок с учётом инвестиционного портфеля?

Технически да — обе задачи опираются на одну и ту же PostgreSQL и один и тот же подход к дашбордам, но схемы данных у них разные: журнал сделок фиксирует отдельные операции, а учёт портфеля — текущие позиции и их динамику во времени. Разумнее вести их как две отдельные базы или хотя бы отдельные схемы в одной базе, чем пытаться уместить в одну таблицу.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →