Crypto Bot Trade Logging Setup with P&L Reports

You launch a trading bot on Binance, after a month of trading you try to calculate P&L, but your logs only show 'Buy 0.1 BTC at 30000'. No fees, no slippage, no strategy context. Sound familiar? **Configuring crypto bot trade logging with structured JSON logs using pino, stored in PostgreSQL+Timesca

Blockchain Development Services

Frequently Asked Questions

Latest works

  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1309
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1269
  • image_logo-advance_0.webp
    B2B Advance company logo design
    719
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    1009
  • image_logo-aider_0.webp
    AIDER company logo development
    954
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    1062

You launch a trading bot on Binance, after a month of trading you try to calculate P&L, but your logs only show 'Buy 0.1 BTC at 30000'. No fees, no slippage, no strategy context. Sound familiar? Configuring crypto bot trade logging with structured JSON logs using pino, stored in PostgreSQL+TimescaleDB, and building P&L dashboards in seconds solves this. Our engineers with 5+ years of blockchain development experience set this up in 1–3 days. Order the setup and get full audit of every trade.

Why structured logging is critical for audit

Logs in JSON format are parsable by tools; plain text is not. Compare:

Criteria Plain text (console.log) JSON (pino/winston)
Search by field grep through text (error-prone) SQL query on JSONB
P&L analysis manually extract numbers SUM(realizedPnl) in seconds
Filter by strategy no metadata WHERE strategy = 'grid'
Processing speed for 1M records hours milliseconds

JSON is 50+ times faster for analysis—confirmed by benchmarks. In one project, we discovered that 23% of trades lost profit due to inflated fees invisible in plain logs. Savings from a single such finding can exceed $1000.

How to configure crypto bot trade logging end-to-end

What to log

Minimum set of events:

type TradeEvent = | { type: "order_placed"; orderId: string; symbol: string; side: "buy" | "sell"; quantity: number; price: number; orderType: "market" | "limit"; timestamp: number; } | { type: "order_filled"; orderId: string; executedQty: number; executedPrice: number; fee: number; feeCurrency: string; timestamp: number; } | { type: "order_cancelled"; orderId: string; reason: string; timestamp: number; } | { type: "position_opened"; positionId: string; entryPrice: number; size: number; leverage: number; timestamp: number; } | { type: "position_closed"; positionId: string; exitPrice: number; realizedPnl: number; timestamp: number; } | { type: "signal_generated"; strategy: string; signal: string; params: Record<string, unknown>; timestamp: number; } | { type: "error"; code: string; message: string; context: Record<string, unknown>; timestamp: number; }; 

Every event must include strategy, exchange, sessionId to filter logs by specific run. Below are mandatory fields per type:

Event Type Mandatory Fields
order_placed orderId, symbol, side, quantity, price, orderType
order_filled orderId, executedQty, executedPrice, fee, feeCurrency
order_cancelled orderId, reason
position_opened positionId, entryPrice, size, leverage
position_closed positionId, exitPrice, realizedPnl
signal_generated strategy, signal, params
error code, message, context

Step-by-step pino configuration

  1. Replace console.log with pino using JSON format.
  2. Add base fields (strategy, exchange, sessionId) to every call.
  3. Configure transport: pino-pretty for dev, JSON for production.
  4. Connect async writer to stdout or file.
  5. Integrate log shipping to PostgreSQL via logstash or direct writer.

Minimal configuration example:

import pino from "pino"; const logger = pino({ level: process.env.LOG_LEVEL ?? "info", base: { strategy: process.env.STRATEGY_NAME, exchange: process.env.EXCHANGE, sessionId: process.env.SESSION_ID ?? Date.now().toString(36), }, transport: process.env.NODE_ENV === "development" ? { target: "pino-pretty" } : undefined, }); logger.info({ type: "order_filled", orderId, executedQty, executedPrice, fee }, "Order filled"); 

Storage: PostgreSQL + TimescaleDB

TimescaleDB automatically partitions data by time (hypertables), giving millisecond query speed on millions of rows. Plain PostgreSQL without the extension slows down on logs exceeding 100 events/second.

CREATE TABLE trade_events ( id BIGSERIAL, session_id TEXT NOT NULL, strategy TEXT NOT NULL, exchange TEXT NOT NULL, event_type TEXT NOT NULL, payload JSONB NOT NULL, ts TIMESTAMPTZ NOT NULL DEFAULT now(), PRIMARY KEY (id, ts) ); SELECT create_hypertable('trade_events', 'ts'); CREATE INDEX ON trade_events (session_id, ts DESC); CREATE INDEX ON trade_events USING GIN (payload); 

With TimescaleDB the query "all trades of strategy X in the past week" executes in milliseconds even on millions of rows.

How to set up P&L analysis from logs

SELECT strategy, date_trunc('day', ts) AS day, COUNT(*) FILTER (WHERE event_type = 'order_filled') AS trades, SUM((payload->>'executedQty')::numeric * (payload->>'executedPrice')::numeric) FILTER (WHERE payload->>'side' = 'sell') AS gross_revenue, SUM((payload->>'fee')::numeric) FILTER (WHERE event_type = 'order_filled') AS total_fees, SUM((payload->>'realizedPnl')::numeric) FILTER (WHERE event_type = 'position_closed') AS realized_pnl FROM trade_events WHERE ts > now() - interval '30 days' GROUP BY strategy, day ORDER BY day DESC; 

This query delivers daily P&L by strategy, accounting for fees—what typically goes missing in simple logs.

Alerts for anomalies

Logging is useless without reaction. Simple monitoring via periodic query:

async function checkAnomalies() { const recentErrors = await db.countEvents({ type: "error", since: minutesAgo(5) }); if (recentErrors > 10) await alertService.send("High error rate: " + recentErrors + " errors in 5m"); const lastFill = await db.lastEventTime({ type: "order_filled" }); if (minutesSince(lastFill) > 60 && isMarketHours()) { await alertService.send("No fills in 60 minutes — bot may be stuck"); } } 

Add a Telegram alert when errors exceed N or fills stop. A slippage of just 0.1% can cost $500 per day—timely notification saves the budget.

What's included in the work

  • Replace console.log with pino/winston using JSON format
  • Add sessionId, strategy, exchange to all events
  • Create trade_events table in PostgreSQL with indexes and TimescaleDB
  • Async writer (buffered batch inserts, does not block the trading loop)
  • Basic daily P&L SQL query
  • Telegram alert when errors > N per period
  • Documentation of log schema and query examples
  • Deploy to your server or cloud

Why choose us

  • 5+ years of blockchain development experience (Ethereum, Solana, BNB Chain)
  • 50+ projects for trading bots and DeFi
  • Setup guarantee: if something doesn't work after a month, we fix it free of charge
  • We use only proven tools: pino, TimescaleDB, Telegram Bot API
  • Remote and in-office work (Minsk, BY)

Timeline and cost

Basic setup takes 1 to 3 days. Cost is calculated individually based on strategy complexity and log volume. One timely discovered error can save up to $2000, so the project pays for itself within 1–2 weeks.

For an accurate estimate, describe your bot and logging requirements. We will prepare a commercial proposal within 24 hours. Contact us via Telegram or email to discuss details. Don't put it off—order the setup now.