Skip to content

Switch CSV writer to per-ticker layout with overwrite guard #15

Description

@cswaney

Goal

Replace the current date-only, append-based CSV write strategy with a per-ticker, fresh-write layout plus an overwrite guard. This makes a parse run's output deterministic (independent of prior runs), prevents silent data accumulation, and gives tvi convert (#12) well-defined per-ticker inputs to combine.

Problem with current behavior

Each flush writes data/{kind}/{date}.csv opened create(true).append(true) (src/writer/csv.rs). The filename has no ticker component, so:

  • Re-running tvi parse on the same date with a different --tickers set appends, accumulating rows across runs with no warning.
  • What ends up in a CSV depends on run history, which makes the parquet skip rule in Add tvi convert subcommand (CSV → Parquet) #12 unsafe (a later run can yield a stale or subset parquet silently).

New layout

data/orders/{date}/{ticker}.csv
data/trades/{date}/{ticker}.csv
data/noii/{date}/{ticker}.csv
data/books/{date}/{ticker}.csv
  • Files written fresh (truncate), never appended.
  • --tickers * writes a single combined data/{kind}/{date}/_all.csv rather than fanning out to one file per (~8000) symbols. Per-ticker files are produced only when tickers are explicitly listed.

Overwrite guard

Before parsing, resolve the ticker set (known up front from --tickers) and stat the target {ticker}.csv files:

  • If any exist and --overwrite is not set → error, listing the colliding files. No partial work is done.
  • --overwrite is per-file (surgical): tvi parse --tickers MSFT --overwrite replaces only MSFT.csv, leaving AAPL.csv untouched.
  • For *, the guard checks {date}/_all.csv existence.

Add an --overwrite flag to tvi parse (src/main.rs Cli).

Scope of change

  • src/writer/csv.rs: path construction ({kind}/{date}/{ticker}.csv), open mode create_new/truncate instead of append, header always written (file is always fresh). The writer needs the ticker in scope per row/batch — currently it derives the filename from date only and serializes whichever ticker's messages arrive. Decide whether to (a) group messages by ticker before flush, or (b) key writers by ticker.
  • src/main.rs: add --overwrite, perform the up-front collision check, resolve the combined-file path for *.

Books caveat

Book CSVs are variable-width by levels_count / --depth (src/writer/csv.rs). Per-ticker book files in the same date dir written with different --depth across runs would disagree in width; the overwrite guard prevents the same-ticker case, but convert-combine (#12) must reconcile or refuse on width mismatch.

Backward incompatibility

Output directory structure changes ({date}.csv{date}/{ticker}.csv). Existing downstream consumers of the flat layout must be updated. Flag for the v0.2.0 notes.

Relationship

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions