Skip to main content

surge_network/network/
market_data.rs

1// SPDX-License-Identifier: LicenseRef-PolyForm-Noncommercial-1.0.0
2//! IEC 62325 Energy Market Data types — market participants, time series,
3//! bids/offers, energy schedules, and transmission capacity allocations.
4
5use chrono::{DateTime, Utc};
6use serde::{Deserialize, Serialize};
7
8/// Market participant identity.
9#[derive(Debug, Clone, Default, Serialize, Deserialize)]
10pub struct MarketParticipant {
11    pub mrid: String,
12    pub name: String,
13    pub role: Option<String>,
14}
15
16/// A single time-series point (one interval).
17#[derive(Debug, Clone, Default, Serialize, Deserialize)]
18pub struct MarketPoint {
19    pub position: u32,
20    pub quantity: Option<f64>,
21    pub price: Option<f64>,
22    pub secondary_quantity: Option<f64>,
23}
24
25/// A period within a time series.
26#[derive(Debug, Clone, Default, Serialize, Deserialize)]
27pub struct MarketPeriod {
28    pub start: Option<DateTime<Utc>>,
29    pub end: Option<DateTime<Utc>>,
30    pub resolution: Option<String>,
31    pub points: Vec<MarketPoint>,
32}
33
34/// A complete time series from IEC 62325.
35#[derive(Debug, Clone, Default, Serialize, Deserialize)]
36pub struct MarketTimeSeries {
37    pub mrid: String,
38    pub business_type: Option<String>,
39    pub in_domain: Option<String>,
40    pub out_domain: Option<String>,
41    pub registered_resource: Option<String>,
42    pub quantity_unit: Option<String>,
43    pub currency: Option<String>,
44    pub curve_type: Option<String>,
45    pub periods: Vec<MarketPeriod>,
46}
47
48/// Energy schedule for a generator or area.
49#[derive(Debug, Clone, Default, Serialize, Deserialize)]
50pub struct EnergySchedule {
51    pub resource_mrid: String,
52    /// `(timestamp, mw_value)` pairs.
53    pub schedule: Vec<(DateTime<Utc>, f64)>,
54}
55
56/// Bid/offer curve.
57#[derive(Debug, Clone, Default, Serialize, Deserialize)]
58pub struct BidOffer {
59    pub resource_mrid: String,
60    pub business_type: Option<String>,
61    /// `(quantity_mw, price)` segments.
62    pub segments: Vec<(f64, f64)>,
63    pub period_start: Option<DateTime<Utc>>,
64}
65
66/// Transmission capacity allocation.
67#[derive(Debug, Clone, Default, Serialize, Deserialize)]
68pub struct TransmissionAllocation {
69    pub from_domain: String,
70    pub to_domain: String,
71    /// `(timestamp, mw_value)` pairs.
72    pub allocations: Vec<(DateTime<Utc>, f64)>,
73}
74
75/// Complete market data container parsed from IEC 62325 ESMP XML.
76#[derive(Debug, Clone, Default, Serialize, Deserialize)]
77pub struct MarketData {
78    pub document_mrid: Option<String>,
79    pub document_type: Option<String>,
80    pub sender: Option<MarketParticipant>,
81    pub receiver: Option<MarketParticipant>,
82    pub participants: Vec<MarketParticipant>,
83    pub time_series: Vec<MarketTimeSeries>,
84    pub energy_schedules: Vec<EnergySchedule>,
85    pub bid_offers: Vec<BidOffer>,
86    pub transmission_allocations: Vec<TransmissionAllocation>,
87}
88
89impl MarketData {
90    /// Returns `true` when no market data has been populated.
91    pub fn is_empty(&self) -> bool {
92        self.time_series.is_empty()
93            && self.participants.is_empty()
94            && self.energy_schedules.is_empty()
95            && self.bid_offers.is_empty()
96            && self.transmission_allocations.is_empty()
97    }
98}