8f13bb4a48
- PostgreSQL history contract와 schema/validator를 추가했습니다. - .NET history store, snapshot reader, repository, migration을 연결했습니다. - history-first 운영 모델 문서와 daily signal tracking 문구를 정리했습니다.
93 lines
3.8 KiB
C#
93 lines
3.8 KiB
C#
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using QuantEngine.Core.Domain;
|
|
using QuantEngine.Core.Interfaces;
|
|
|
|
namespace QuantEngine.Application.Services
|
|
{
|
|
public class HistoryIngestionService
|
|
{
|
|
private readonly IPostgresqlHistoryStore _store;
|
|
|
|
public HistoryIngestionService(IPostgresqlHistoryStore store)
|
|
{
|
|
_store = store;
|
|
}
|
|
|
|
public Task<int> AppendDecisionAsync(IDictionary<string, object?> payload)
|
|
=> _store.AppendAsync("decision_result_history", payload);
|
|
|
|
public Task<int> AppendFactorOutputAsync(IDictionary<string, object?> payload)
|
|
=> _store.AppendAsync("factor_output_history", payload);
|
|
|
|
public Task<int> AppendMarketRawAsync(IDictionary<string, object?> payload)
|
|
=> _store.AppendAsync("market_raw_history", payload);
|
|
|
|
public Task<int> AppendGapAsync(IDictionary<string, object?> payload)
|
|
=> _store.AppendAsync("market_vs_engine_gap_history", payload);
|
|
|
|
public Task<int> AppendDecisionAsync(
|
|
FinalDecisionResult decision,
|
|
SellDecisionResult? sellDecision = null,
|
|
TimingDecisionResult? timingDecision = null,
|
|
string? instrumentId = null,
|
|
string? sourceVersion = null,
|
|
string? gate = null)
|
|
{
|
|
var payload = new Dictionary<string, object?>
|
|
{
|
|
["decision_id"] = Guid.NewGuid().ToString("N"),
|
|
["decided_at"] = DateTimeOffset.UtcNow,
|
|
["instrument_id"] = instrumentId ?? string.Empty,
|
|
["action"] = decision.FinalAction,
|
|
["gate"] = gate ?? (string.IsNullOrWhiteSpace(sellDecision?.Validation) ? "PASS" : sellDecision.Validation),
|
|
["score"] = decision.PriorityScore,
|
|
["source_version"] = sourceVersion ?? decision.DecisionSource,
|
|
["provenance"] = new Dictionary<string, object?>
|
|
{
|
|
["final_action"] = decision.FinalAction,
|
|
["action_priority"] = decision.ActionPriority,
|
|
["priority_score"] = decision.PriorityScore,
|
|
["decision_source"] = decision.DecisionSource,
|
|
["sell_action"] = sellDecision?.Action,
|
|
["sell_validation"] = sellDecision?.Validation,
|
|
["timing_action"] = timingDecision?.Action,
|
|
["timing_reason"] = timingDecision?.Reason
|
|
}
|
|
};
|
|
|
|
return _store.AppendAsync("decision_result_history", payload);
|
|
}
|
|
|
|
public Task<int> AppendFactorOutputAsync(
|
|
string factorId,
|
|
string factorVersion,
|
|
double outputValue,
|
|
string outputGate,
|
|
string? sourceVersion = null,
|
|
DateTimeOffset? observedAt = null)
|
|
{
|
|
var payload = new Dictionary<string, object?>
|
|
{
|
|
["factor_output_id"] = Guid.NewGuid().ToString("N"),
|
|
["observed_at"] = observedAt ?? DateTimeOffset.UtcNow,
|
|
["factor_id"] = factorId,
|
|
["factor_version"] = factorVersion,
|
|
["output_value"] = outputValue,
|
|
["output_gate"] = outputGate,
|
|
["source_version"] = sourceVersion ?? factorVersion,
|
|
["provenance"] = new Dictionary<string, object?>
|
|
{
|
|
["factor_id"] = factorId,
|
|
["factor_version"] = factorVersion,
|
|
["output_value"] = outputValue,
|
|
["output_gate"] = outputGate,
|
|
["source_version"] = sourceVersion ?? factorVersion
|
|
}
|
|
};
|
|
|
|
return _store.AppendAsync("factor_output_history", payload);
|
|
}
|
|
}
|
|
}
|