From d833d386d0c907f4f5124484f36a1de297ccc212 Mon Sep 17 00:00:00 2001 From: kjh2064 Date: Sun, 12 Jul 2026 12:11:18 +0900 Subject: [PATCH] feat: add postgres market time series schema --- docs/db/quantengine.dbml | 30 ++++++++++++++++ spec/60_quant_engine_wbs.yaml | 4 +-- .../Migrations/V6__Add_Market_Time_Series.sql | 36 +++++++++++++++++++ 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 src/dotnet/QuantEngine.Infrastructure/Migrations/V6__Add_Market_Time_Series.sql diff --git a/docs/db/quantengine.dbml b/docs/db/quantengine.dbml index eccaec53..faa3a089 100644 --- a/docs/db/quantengine.dbml +++ b/docs/db/quantengine.dbml @@ -385,6 +385,36 @@ Table engine_history.market_vs_engine_gap_history { // Schema: engine_history (V5 normalized learning history) // ============================================================================= +Table quantengine.price_history_daily { + ticker TEXT [not null] + trade_date DATE [not null] + open NUMERIC [not null] + high NUMERIC [not null] + low NUMERIC [not null] + close NUMERIC [not null] + volume BIGINT [not null] + source TEXT [not null] + collected_at TIMESTAMPTZ [not null, default: "NOW()"] + provenance JSONB [not null, default: "'{}'::jsonb"] + + indexes { + (ticker, trade_date) [pk] + } +} + +Table quantengine.macro_history_daily { + symbol TEXT [not null] + trade_date DATE [not null] + value NUMERIC [not null] + source TEXT [not null] + collected_at TIMESTAMPTZ [not null, default: "NOW()"] + provenance JSONB [not null, default: "'{}'::jsonb"] + + indexes { + (symbol, trade_date) [pk] + } +} + Table engine_history.source_observation { observation_id UUID [pk] observed_at TIMESTAMPTZ [not null] diff --git a/spec/60_quant_engine_wbs.yaml b/spec/60_quant_engine_wbs.yaml index 75456fe8..cd0c5f86 100644 --- a/spec/60_quant_engine_wbs.yaml +++ b/spec/60_quant_engine_wbs.yaml @@ -375,11 +375,11 @@ tasks: # M2 — 히스토리 시계열 저장소 # --------------------------------------------------------------------------- QE-M2-01: - title: "V4 마이그레이션: price_history_daily + macro_history_daily" + title: "V6 마이그레이션: price_history_daily + macro_history_daily" status: PENDING depends_on: [QE-M1-01] owner_files: - - src/dotnet/QuantEngine.Infrastructure/Migrations/V4__Add_Price_History.sql + - src/dotnet/QuantEngine.Infrastructure/Migrations/V6__Add_Market_Time_Series.sql notes: > price_history_daily(ticker, trade_date, open/high/low/close numeric, volume bigint, source text, collected_at timestamptz, PK(ticker, trade_date)); diff --git a/src/dotnet/QuantEngine.Infrastructure/Migrations/V6__Add_Market_Time_Series.sql b/src/dotnet/QuantEngine.Infrastructure/Migrations/V6__Add_Market_Time_Series.sql new file mode 100644 index 00000000..d753047f --- /dev/null +++ b/src/dotnet/QuantEngine.Infrastructure/Migrations/V6__Add_Market_Time_Series.sql @@ -0,0 +1,36 @@ +-- V6__Add_Market_Time_Series.sql +-- Canonical PostgreSQL daily series for point-in-time factor calculations. + +CREATE SCHEMA IF NOT EXISTS quantengine; + +CREATE TABLE IF NOT EXISTS quantengine.price_history_daily ( + ticker TEXT NOT NULL, + trade_date DATE NOT NULL, + open NUMERIC NOT NULL, + high NUMERIC NOT NULL, + low NUMERIC NOT NULL, + close NUMERIC NOT NULL, + volume BIGINT NOT NULL, + source TEXT NOT NULL, + collected_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + provenance JSONB NOT NULL DEFAULT '{}'::jsonb, + PRIMARY KEY (ticker, trade_date), + CONSTRAINT price_history_daily_ohlc_order CHECK (high >= low AND high >= open AND high >= close AND low <= open AND low <= close), + CONSTRAINT price_history_daily_volume_nonnegative CHECK (volume >= 0) +); + +CREATE INDEX IF NOT EXISTS idx_price_history_daily_date + ON quantengine.price_history_daily (trade_date DESC, ticker); + +CREATE TABLE IF NOT EXISTS quantengine.macro_history_daily ( + symbol TEXT NOT NULL, + trade_date DATE NOT NULL, + value NUMERIC NOT NULL, + source TEXT NOT NULL, + collected_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + provenance JSONB NOT NULL DEFAULT '{}'::jsonb, + PRIMARY KEY (symbol, trade_date) +); + +CREATE INDEX IF NOT EXISTS idx_macro_history_daily_date + ON quantengine.macro_history_daily (trade_date DESC, symbol);