Skip to main content

tradingview/study/
result.rs

1//! Result container for study and fundamental data retrieval.
2
3use std::time::Duration;
4
5use chrono::{DateTime, Utc};
6use serde::{Deserialize, Serialize};
7
8use crate::chart::{DataPoint, SymbolInfo};
9
10/// The final result of a study data retrieval.
11#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct StudyResult {
13    /// Symbol metadata returned during symbol resolution.
14    pub symbol_info: SymbolInfo,
15    /// Collected and deduplicated data points for the study.
16    pub data: Vec<DataPoint>,
17    /// The unique study identifier used during retrieval.
18    pub study_id: String,
19    /// Total raw study data points received before deduplication.
20    pub total_points_received: usize,
21    /// Wall-clock duration elapsed during the retrieval.
22    pub elapsed: Duration,
23}
24
25impl StudyResult {
26    /// Number of data points in the result.
27    #[inline]
28    pub fn len(&self) -> usize {
29        self.data.len()
30    }
31
32    /// Whether any data points were received.
33    #[inline]
34    pub fn is_empty(&self) -> bool {
35        self.data.is_empty()
36    }
37
38    /// Slice of the collected study data points.
39    #[inline]
40    pub fn points(&self) -> &[DataPoint] {
41        &self.data
42    }
43
44    /// Mutable slice of the collected study data points.
45    #[inline]
46    pub fn points_mut(&mut self) -> &mut [DataPoint] {
47        &mut self.data
48    }
49
50    /// Consumes the result and returns the inner vector of data points.
51    #[inline]
52    pub fn into_points(self) -> Vec<DataPoint> {
53        self.data
54    }
55
56    /// Timestamp of the first data point, if available.
57    ///
58    /// Extracted directly from `value[0]` without assuming OHLCV structure.
59    #[inline]
60    pub fn first_timestamp(&self) -> Option<i64> {
61        self.data
62            .first()
63            .and_then(|dp| dp.value.first().copied().map(|v| v as i64))
64    }
65
66    /// Timestamp of the last data point, if available.
67    ///
68    /// Extracted directly from `value[0]` without assuming OHLCV structure.
69    #[inline]
70    pub fn last_timestamp(&self) -> Option<i64> {
71        self.data
72            .last()
73            .and_then(|dp| dp.value.first().copied().map(|v| v as i64))
74    }
75
76    /// UTC DateTime of the first data point, if available.
77    #[inline]
78    pub fn first_datetime(&self) -> Option<DateTime<Utc>> {
79        self.first_timestamp()
80            .and_then(|ts| DateTime::<Utc>::from_timestamp(ts, 0))
81    }
82
83    /// UTC DateTime of the last data point, if available.
84    #[inline]
85    pub fn last_datetime(&self) -> Option<DateTime<Utc>> {
86        self.last_timestamp()
87            .and_then(|ts| DateTime::<Utc>::from_timestamp(ts, 0))
88    }
89}