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