feat: postgres history-first 계약과 적재 경로 추가

- PostgreSQL history contract와 schema/validator를 추가했습니다.
- .NET history store, snapshot reader, repository, migration을 연결했습니다.
- history-first 운영 모델 문서와 daily signal tracking 문구를 정리했습니다.
This commit is contained in:
2026-06-26 14:17:04 +09:00
parent 7e0c0b6c8f
commit 8f13bb4a48
17 changed files with 707 additions and 17 deletions
@@ -156,6 +156,87 @@ namespace QuantEngine.Infrastructure.Data
PRIMARY KEY (domain, target_ref)
);
");
// 10. engine_history schema and tables
conn.Execute(@"
CREATE SCHEMA IF NOT EXISTS engine_history;
");
conn.Execute(@"
CREATE TABLE IF NOT EXISTS engine_history.market_raw_history (
id BIGSERIAL PRIMARY KEY,
source_id TEXT NOT NULL,
observed_at TEXT NOT NULL,
source_name TEXT NOT NULL,
instrument_id TEXT NOT NULL,
field_name TEXT NOT NULL,
field_value TEXT NOT NULL,
unit TEXT NOT NULL,
provenance JSONB NOT NULL DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_market_raw_history_created_at ON engine_history.market_raw_history (created_at DESC);
");
conn.Execute(@"
CREATE TABLE IF NOT EXISTS engine_history.factor_version_history (
id BIGSERIAL PRIMARY KEY,
factor_id TEXT NOT NULL,
factor_version TEXT NOT NULL,
effective_from TEXT NOT NULL,
effective_to TEXT NOT NULL,
formula_id TEXT NOT NULL,
source_version TEXT NOT NULL,
provenance JSONB NOT NULL DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_factor_version_history_created_at ON engine_history.factor_version_history (created_at DESC);
");
conn.Execute(@"
CREATE TABLE IF NOT EXISTS engine_history.factor_output_history (
id BIGSERIAL PRIMARY KEY,
factor_output_id TEXT NOT NULL,
observed_at TEXT NOT NULL,
factor_id TEXT NOT NULL,
factor_version TEXT NOT NULL,
output_value TEXT NOT NULL,
output_gate TEXT NOT NULL,
source_version TEXT NOT NULL,
provenance JSONB NOT NULL DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_factor_output_history_created_at ON engine_history.factor_output_history (created_at DESC);
");
conn.Execute(@"
CREATE TABLE IF NOT EXISTS engine_history.decision_result_history (
id BIGSERIAL PRIMARY KEY,
decision_id TEXT NOT NULL,
decided_at TEXT NOT NULL,
instrument_id TEXT NOT NULL,
action TEXT NOT NULL,
gate TEXT NOT NULL,
score TEXT NOT NULL,
source_version TEXT NOT NULL,
provenance JSONB NOT NULL DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_decision_result_history_created_at ON engine_history.decision_result_history (created_at DESC);
");
conn.Execute(@"
CREATE TABLE IF NOT EXISTS engine_history.market_vs_engine_gap_history (
id BIGSERIAL PRIMARY KEY,
gap_id TEXT NOT NULL,
observed_at TEXT NOT NULL,
instrument_id TEXT NOT NULL,
metric_name TEXT NOT NULL,
market_value TEXT NOT NULL,
engine_value TEXT NOT NULL,
gap_value TEXT NOT NULL,
gap_pct TEXT NOT NULL,
source_version TEXT NOT NULL,
provenance JSONB NOT NULL DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_market_vs_engine_gap_history_created_at ON engine_history.market_vs_engine_gap_history (created_at DESC);
");
}
}
}