Skip to main content

Data Model: YU07; Historical Tick Store

Storage layout​

Parquet files under a single root (gs://traderx-501015-tick-store/ticks, GCS Standard tier; research.md Decision 6), Hive-partitioned:

gs://traderx-501015-tick-store/ticks/source=<live|taq>/dt=<YYYY-MM-DD>/symbol=<SYM>/part-*.parquet

Read back with DuckDB's hive_partitioning=true, which reconstructs source, dt, symbol as query-able columns from the path; partition pruning applies directly to date-range and symbol-filtered queries without a separate index.

Unified ticks schema (every Parquet file, both source values)​

ColumnTypeNotes
symbolVARCHARTicker (SYM_ROOT for TAQ; the NATS subject's ticker for live).
event_typeVARCHARprice_tick (live pricing.*) / trade (live account trades or TAQ CT prints) / quote (TAQ CQ).
tsTIMESTAMPEvent time, microsecond precision. For TAQ, DATE+TIME_M truncated from nanoseconds (research.md Decision 4).
priceDOUBLE, nullableTrade/price-tick price. Null for quote rows.
sizeBIGINT, nullableTrade quantity. Null for price_tick/quote rows.
bid_priceDOUBLE, nullableTAQ BID. Null outside quote rows.
bid_sizeBIGINT, nullableTAQ BIDSIZ.
ask_priceDOUBLE, nullableTAQ ASK.
ask_sizeBIGINT, nullableTAQ ASKSIZ.
venueVARCHARTAQ EX (per-venue quote source); TRADERX for every live row.
sourceVARCHARlive / taq; also the top partition level.
seqBIGINTTAQ QU_SEQNUM; a per-process monotonic counter for live rows (ordering within a capture session, not comparable across sources).
ingested_atTIMESTAMPCapture/ingestion wall-clock (audit only, not an event-time field).

Source β†’ schema mapping​

Live capture; pricing.<TICKER> (NATS, wildcard pricing.*)​

Payload: {price, openPrice, closePrice, asOf, source} (price-publisher/src/main.js).

Source field→Column
ticker (parsed from subject)β†’symbol
price→price
asOf (ISO-8601)β†’ts
; β†’event_type='price_tick', venue='TRADERX', source='live'

Live capture; /accounts/<accountId>/trades (NATS, wildcard)​

Payload: {id, accountId, security, side, state, quantity, price, updated, created, settlementDate} (Trade entity, trade-processor).

Source field→Column
security→symbol
price→price
quantity→size
updated→ts
; β†’event_type='trade', venue='TRADERX', source='live'

TAQ quotes CSV (taq_quotes_YYYYMMDD_csv.zip, confirmed format)​

Header: DATE,TIME_M,EX,BID,BIDSIZ,ASK,ASKSIZ,QU_COND,QU_SEQNUM,NATBBO_IND,QU_CANCEL,QU_SOURCE,SYM_ROOT,SYM_SUFFIX

Source column→Column
SYM_ROOT→symbol
DATE + TIME_M (truncated to Β΅s)β†’ts
BID→bid_price
BIDSIZ→bid_size
ASK→ask_price
ASKSIZ→ask_size
EX→venue
QU_SEQNUM→seq
; β†’event_type='quote', source='taq'

QU_COND, NATBBO_IND, QU_CANCEL, QU_SOURCE, SYM_SUFFIX are read but not carried into the unified schema in this state; none of VWAP or return/scenario aggregation needs them, and every byte read from the source CSV is still available by re-running ingestion against the same file if a future consumer needs one.

TAQ trades CSV (taq_trades_<month><year>_csv.zip, confirmed format)​

Header: DATE,TIME_M,EX,SYM_ROOT,SYM_SUFFIX,TR_SCOND,SIZE,PRICE,TR_STOP_IND,TR_CORR,TR_SEQNUM,TR_ID,TR_SOURCE,TR_RF

Source column→Column
SYM_ROOT→symbol
DATE + TIME_M (truncated to Β΅s)β†’ts
PRICE→price
SIZE→size
EX→venue
TR_SEQNUM→seq
; β†’event_type='trade', source='taq', bid_price/bid_size/ask_price/ask_size=NULL

TR_SCOND, TR_STOP_IND, TR_CORR, TR_ID, TR_SOURCE, TR_RF, SYM_SUFFIX are read but not carried into the unified schema, same rationale as the quotes CSV's unused columns above.

Config (namespace tickstore.*, environment variables)​

KeyDefaultMeaning
TICKSTORE_NATS_URLnats://nats-broker:4222Broker connection for capture.py.
TICKSTORE_OUT_DIRgs://traderx-501015-tick-store/ticksParquet store root (capture and ingestion both write here). A local path also works unchanged (gcs.py's is_gcs_path gates the GCS setup, opt-in on the gs:// prefix).
TICKSTORE_FLUSH_INTERVAL_SECONDS30Capture batch flush cadence.
TICKSTORE_FLUSH_MAX_ROWS5000Capture batch flush size trigger (whichever of interval/rows hits first).
GCS_HMAC_KEY_ID(none; required when TICKSTORE_OUT_DIR is gs://)HMAC access key ID for the bucket-scoped tick-store-gcs service account (research.md Decision 6). Sourced from the tick-store-gcs-hmac k8s Secret, never committed.
GCS_HMAC_SECRET_ACCESS_KEY(none; required when TICKSTORE_OUT_DIR is gs://)HMAC secret for the same credential.

Reused, unchanged​

  • pricing.<TICKER> / /accounts/<accountId>/trades NATS subjects; no publisher change.
  • NATS broker (nats-broker); same connection every other consumer uses.