1use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6
7#[derive(Debug, Clone)]
9pub struct QueryResult {
10 pub query_type: QueryType,
12
13 pub matches: Option<Vec<PatternMatch>>,
15
16 pub statistics: Option<StatisticalAnalysis>,
18
19 pub alert: Option<AlertResult>,
21
22 pub summary: Option<SummaryMetrics>,
24
25 pub data: Option<QueryData>,
27
28 pub metadata: QueryMetadata,
30}
31
32#[derive(Debug, Clone, Serialize, Deserialize)]
33pub enum QueryType {
34 Find,
35 Scan,
36 Analyze,
37 Simulate,
38 Alert,
39 Value,
40 With,
41 Backtest,
42}
43
44#[derive(Debug, Clone, Serialize, Deserialize)]
46pub struct StatisticalAnalysis {
47 pub total_occurrences: usize,
49
50 pub success_rate: f64,
52
53 pub outcome_distribution: HashMap<String, f64>,
55
56 pub time_stats: TimeStatistics,
58
59 pub magnitude_stats: MagnitudeStatistics,
61
62 pub custom_metrics: HashMap<String, f64>,
64}
65
66#[derive(Debug, Clone, Serialize, Deserialize)]
67pub struct TimeStatistics {
68 pub avg_time_to_outcome: f64,
70
71 pub hourly_distribution: Vec<HourlyStats>,
73
74 pub daily_distribution: Vec<DailyStats>,
76
77 pub seasonality: Option<SeasonalityMetrics>,
79}
80
81#[derive(Debug, Clone, Serialize, Deserialize)]
82pub struct HourlyStats {
83 pub hour: u8,
84 pub occurrences: usize,
85 pub success_rate: f64,
86 pub avg_magnitude: f64,
87}
88
89#[derive(Debug, Clone, Serialize, Deserialize)]
90pub struct DailyStats {
91 pub day: String,
92 pub occurrences: usize,
93 pub success_rate: f64,
94 pub avg_magnitude: f64,
95}
96
97#[derive(Debug, Clone, Serialize, Deserialize)]
98pub struct SeasonalityMetrics {
99 pub monthly_pattern: Vec<f64>,
100 pub quarterly_pattern: Vec<f64>,
101 pub yearly_trend: Vec<f64>,
102}
103
104#[derive(Debug, Clone, Serialize, Deserialize)]
105pub struct MagnitudeStatistics {
106 pub average: f64,
107 pub median: f64,
108 pub std_dev: f64,
109 pub min: f64,
110 pub max: f64,
111 pub percentiles: HashMap<String, f64>, }
113
114#[derive(Debug, Clone, Serialize, Deserialize)]
116pub struct AlertResult {
117 pub id: String,
118 pub active: bool,
119 pub message: String,
120 pub level: String,
121 pub timestamp: DateTime<Utc>,
122}
123
124#[derive(Debug, Clone, Serialize, Deserialize)]
126pub struct SummaryMetrics {
127 pub pattern_frequency: f64, pub pattern_reliability: f64, pub confidence_score: f64, pub average_outcome: f64,
136 pub expectancy: f64,
137}
138
139#[derive(Debug, Clone, Serialize, Deserialize)]
141pub struct QueryData {
142 pub time_series: Vec<TimeSeriesPoint>,
144
145 pub distributions: HashMap<String, Vec<f64>>,
147
148 pub correlations: HashMap<String, Vec<Vec<f64>>>,
150
151 pub tables: HashMap<String, DataTable>,
153}
154
155#[derive(Debug, Clone, Serialize, Deserialize)]
156pub struct TimeSeriesPoint {
157 pub timestamp: DateTime<Utc>,
158 pub values: HashMap<String, f64>,
159}
160
161#[derive(Debug, Clone, Serialize, Deserialize)]
162pub struct DataTable {
163 pub columns: Vec<String>,
164 pub rows: Vec<Vec<serde_json::Value>>,
165}
166
167#[derive(Debug, Clone, Serialize, Deserialize)]
169pub struct QueryMetadata {
170 pub execution_time_ms: u64,
171 pub data_points_analyzed: usize,
172 pub timeframe: String,
173 pub id: String,
174 pub date_range: (DateTime<Utc>, DateTime<Utc>),
175 pub query_hash: String, pub warnings: Vec<String>,
177}
178
179#[derive(Debug, Clone, Serialize, Deserialize)]
181pub struct PatternMatch {
182 pub pattern_name: String,
183 pub index: usize,
184 pub timestamp: DateTime<Utc>,
185 pub confidence: f64,
186 pub id: String,
187 pub metadata: serde_json::Value,
188}
189
190impl QueryResult {
191 pub fn new(query_type: QueryType, id: String, timeframe: String) -> Self {
193 Self {
194 query_type,
195 matches: None,
196 statistics: None,
197 alert: None,
198 summary: None,
199 data: None,
200 metadata: QueryMetadata {
201 execution_time_ms: 0,
202 data_points_analyzed: 0,
203 timeframe,
204 id,
205 date_range: (Utc::now(), Utc::now()),
206 query_hash: String::new(),
207 warnings: Vec::new(),
208 },
209 }
210 }
211
212 pub fn with_statistics(mut self, stats: StatisticalAnalysis) -> Self {
214 self.statistics = Some(stats);
215 self
216 }
217
218 pub fn with_alert(mut self, alert: AlertResult) -> Self {
220 self.alert = Some(alert);
221 self
222 }
223
224 pub fn calculate_summary(&mut self) {
226 let mut summary = SummaryMetrics {
227 pattern_frequency: 0.0,
228 pattern_reliability: 0.0,
229 confidence_score: 0.0,
230 average_outcome: 0.0,
231 expectancy: 0.0,
232 };
233
234 if let Some(ref stats) = self.statistics {
236 summary.pattern_frequency = if self.metadata.data_points_analyzed > 0 {
237 stats.total_occurrences as f64 / self.metadata.data_points_analyzed as f64
238 } else {
239 0.0
240 };
241 summary.pattern_reliability = stats.success_rate;
242 summary.average_outcome = stats.magnitude_stats.average;
243 summary.expectancy = stats.success_rate * stats.magnitude_stats.average;
244 }
245
246 summary.confidence_score = calculate_confidence_score(&summary, &self.statistics);
248
249 self.summary = Some(summary);
250 }
251
252 pub fn format_summary(&self) -> String {
254 if let Some(ref summary) = self.summary {
255 format!(
256 "Frequency: {:.4}, Reliability: {:.2}%, Confidence: {:.1}/100",
257 summary.pattern_frequency,
258 summary.pattern_reliability * 100.0,
259 summary.confidence_score
260 )
261 } else {
262 "No summary available".to_string()
263 }
264 }
265}
266
267fn calculate_confidence_score(
269 _summary: &SummaryMetrics,
270 stats: &Option<StatisticalAnalysis>,
271) -> f64 {
272 let mut score: f64 = 50.0; if let Some(stats) = stats {
276 if stats.total_occurrences > 100 {
277 score += 10.0; }
279 if stats.success_rate > 0.6 {
280 score += 10.0;
281 }
282 }
283
284 score.clamp(0.0, 100.0)
285}