System Structure & Flow

QuansiftMarketData.jl データ基盤

Tiingo APIから正規化されたDataFrame、独立した3つの保存先、本番オーケストレーション、releaseとproduction deployまでを1枚にまとめた構造図です。

1. Collection → Normalization → Independent Sinks

  1. SOURCE

    Tiingo API

    Ticker universe、EOD、Daily Metrics。

  2. QUANSIFTMARKETDATA.JL

    HTTP & Validation

    検証、上限付きretry、安全なエラー報告。

  3. QUANSIFTMARKETDATA.JL

    Collectors

    collect_ticker_universe、collect_historical、collect_fundamentals。

  4. BOUNDARY

    Canonical DataFrames

    保存先に依存しない正規化データ。

↓ 用途に応じて独立に選択(複数選択可)

AUTHORITATIVE

System PostgreSQL

本番参照の正本かつ復旧基準。自然キーによる冪等upsert。

OPTIONAL

DuckDB

account termsで許可される場合の永続的な分析replica/高速OLAP cache。正本ではない。

ARCHIVE

Parquet

account termsで許可される場合の検証済みatomic local artifact。off-host公開後は全履歴archive/交換形式。

Data terms: sinkは技術的な選択肢であり、保存許可を与えるものではありません。Starter/Trial Planはcanonical DataFrameを一時的なmemory内で処理し、計算/操作完了直後に恒久的に削除し、かつ、いかなる場合でもprocess、job、user session終了前に削除します。local DuckDBまたはParquetはaccount termsまたは別途の書面契約が永続化を許可する場合だけ利用します。詳細はData terms and project identityを参照してください。

2. Responsibility Boundary

QuansiftMarketData.jl owns

  • HTTP access、response validation
  • Ticker universe、EOD、Daily Metrics collection
  • Canonical DataFrame normalization
  • PostgreSQL、DuckDB、Parquet persistence primitives

quansift_scheduler owns

  • Cron、stage orchestration、cross-stage retry
  • Splitのdurable per-ticker retry queue
  • SpacesとManaged PostgreSQLへのpublication
  • QuantScreener/TATSU sequencing

3. Production Flow

  1. Schedule
    quansift_schedulerがstock、ETF、Fundamentals stageを起動。
  2. Collect & normalize
    Tiingo API → HTTP validation → collector → canonical DataFrameの境界を通過。
  3. Commit authoritative data
    System PostgreSQLへ冪等に書き込み、本番正本を更新。
  4. Materialize optional analysis state
    必要なconsumerだけがDuckDB replica/cacheを更新。
  5. Archive & publish
    Parquetを検証・atomic writeし、schedulerがSpacesへ全履歴を公開。
  6. Serve downstream
    Managed PostgreSQLへrolling 3年を公開し、QuantScreener/TATSUを順序制御。

4. Fundamentals Flow

  1. Tiingo APIからFundamentals metadataとDaily Metricsを取得・検証。
  2. collect_fundamentalsがsecurity observationsとfundamental daily metricsへ正規化。
  3. System PostgreSQLの2つのcanonical tableへ冪等upsert。
  4. 必要に応じてDuckDB analysis replicaまたはverified Parquet artifactへ独立に書き込み。

5. Split Recovery — Durable Per-Ticker Retry

  1. refresh前にtickerをschedulerのpending queueへ永続化。
  2. 対象tickerの全履歴をQuansiftMarketData collectorで再取得。
  3. ticker単位のPostgreSQL transactionで履歴を置換しcommit。
  4. Optional: DuckDBが構成されている場合だけanalysis replicaを更新。
  5. scheduler自身が、PostgreSQL commit後、かつDuckDB構成時はその更新完了後にpending entryを削除。

失敗時: transactionをrollbackし、エラーを記録してpending entryを残す。他tickerは継続し、次回runで再試行する。

6. PostgreSQL → Parquet Snapshot

  1. AUTHORITATIVE

    PostgreSQL table

    snapshot元。

  2. EPHEMERAL SCANNER

    In-memory DuckDB

    postgres extensionでscan。永続storeにはしない。

  3. ARCHIVE

    Verified Parquet

    temporary fileを検証後、local atomic publication。

postgres extensionはbuild時にinstallします。runtime library codeはLOADのみを行い、downloadしません。

7. PostgreSQL Schema Migration

  1. migrate_postgres!がmigration advisory lockを取得。
  2. tiingojulia_schema_migrationsから現在versionを確認。
  3. 順序付きschema変更とledger rowを1 transaction内で適用。
  4. 成功時にcanonical schema version 1をcommit。

migration error時はschema変更とledger更新をまとめてrollbackし、直前versionを正本として維持する。

8. Package Release ≠ Production Deployment

Public package release

  1. Feature branch
  2. Optional staging integration
  3. PR → main、required CI pass
  4. Exact release commitをmainへmerge
  5. Exact main SHAに対するstrict release preflight
  6. Registratorを起動
  7. General registry PRのmergeを待つ
  8. TagBotがimmutable version tagとGitHub Releaseを作成

Pre-registration中はmanual tagを作らず、competing version tagも許可しない。

Production deployment

  1. QuansiftMarketDataとschedulerをmainで検証
  2. schedulerのQuansiftMarketData SHA pinを一致させる
  3. QuansiftMarketData → schedulerの順でproductionをfast-forward
  4. cron停止・idle確認・git pull --ff-only
  5. migration/health/pin確認後にcron復帰

9. Deprecated DuckDB-first Entry Points

DuckDB自体はdeprecatedではありません。full-historyをDuckDB経由に固定する次の7 entry pointだけが将来のmajor releaseで削除予定です。

DeprecatedReplacement
export_to_postgresPostgreSQL upsert_* overloads + write_parquet
update_historicalcollect_historical + caller-supplied writer
update_historical_parallelcollect_historical + caller-supplied writer
update_historical_sequentialcollect_historical + caller-supplied writer
download_tickers_duckdbcollect_ticker_universe + replace_ticker_universe
add_historical_datacollect_historical + caller-supplied writer
update_split_tickercollect_historical + caller-supplied writer

Legend