Files
miti99bot/src/modules/trading
tiennm99 d040ce4161 feat(trading): add trade history and daily FIFO retention cron
- trading_trades table (migration 0001) persists every buy/sell via optional onTrade callback
- /history [n] command shows caller's last N trades (default 10, max 50), HTML-escaped
- daily cron at 0 17 * * * trims to 1000/user + 10000/global via FIFO delete
- persistence failure logs but does not fail the trade reply
2026-04-15 13:29:15 +07:00
..

Trading Module

Paper-trading system where each Telegram user manages a virtual portfolio. Currently supports VN stocks only — crypto, gold, and currency exchange coming later.

Commands

Command Action
/trade_topup <amount> Add VND to account. Tracks cumulative invested in meta.invested.
/trade_buy <qty> <TICKER> Buy VN stock at market price, deducting VND. Integer quantities only.
/trade_sell <qty> <TICKER> Sell stock holdings back to VND at market price.
/trade_convert Currency exchange (coming soon).
/trade_stats Portfolio breakdown with all assets valued in VND, plus P&L vs invested.

Symbol Resolution

Symbols are resolved dynamically — no hardcoded registry. When a user buys a ticker:

  1. Check KV cache (sym:<TICKER>) → if cached, use it
  2. Query TCBS API to verify the ticker exists and has price data
  3. Cache the resolution permanently in KV

Any valid VN stock ticker on TCBS "just works" without code changes.

Database

KV namespace prefix: trading:

Key Type Description
user:<telegramId> JSON Per-user portfolio
sym:<TICKER> JSON Cached symbol resolution
forex:latest JSON Cached BIDV forex rates

Schema: user:<telegramId>

{
  "currency": { "VND": 5000000 },
  "assets": { "TCB": 10, "FPT": 5, "VNM": 100 },
  "meta": { "invested": 10000000 }
}
  • currency — fiat balances (VND only for now)
  • assets — flat map of stock quantities keyed by ticker
  • meta.invested — cumulative VND value of all top-ups (cost basis for P&L)
  • Migrates old formats automatically on load (totalvndmeta.invested, stock/crypto/othersassets)

Schema: sym:<TICKER>

{ "symbol": "TCB", "category": "stock", "label": "TCB" }

Cached permanently after first successful TCBS lookup.

Price Source

API Purpose Auth
TCBS /stock-insight/v1/stock/bars-long-term VN stock close price (× 1000) None

Prices are fetched on demand per symbol (not batch-cached), since any ticker can be queried dynamically.

File Layout

src/modules/trading/
├── index.js          — module entry, wires handlers to commands
├── symbols.js        — dynamic symbol resolution via TCBS + KV cache
├── format.js         — VND/stock number formatters
├── portfolio.js      — per-user KV read/write, flat assets map
├── prices.js         — TCBS stock price fetch + BIDV forex (for future use)
├── handlers.js       — topup/buy/sell/convert handlers
└── stats-handler.js  — stats/P&L breakdown handler

Future

  • Crypto (CoinGecko), gold (PAX Gold), currency exchange (BIDV bid/ask rates)
  • Dynamic symbol resolution will extend to CoinGecko search for crypto