Add get price data helper
This commit is contained in:
@@ -325,6 +325,26 @@ pub struct DailySnapshotBundle {
|
||||
pub corporate_actions: Vec<CorporateAction>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct PriceBar {
|
||||
#[serde(with = "date_format")]
|
||||
pub date: NaiveDate,
|
||||
pub timestamp: Option<String>,
|
||||
pub symbol: String,
|
||||
pub frequency: String,
|
||||
pub open: f64,
|
||||
pub high: f64,
|
||||
pub low: f64,
|
||||
pub close: f64,
|
||||
pub last_price: f64,
|
||||
pub volume: u64,
|
||||
pub amount: f64,
|
||||
pub bid1: f64,
|
||||
pub ask1: f64,
|
||||
pub bid1_volume: u64,
|
||||
pub ask1_volume: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct EligibleUniverseSnapshot {
|
||||
pub symbol: String,
|
||||
@@ -959,6 +979,45 @@ impl DataSet {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_price(
|
||||
&self,
|
||||
symbol: &str,
|
||||
start: NaiveDate,
|
||||
end: NaiveDate,
|
||||
frequency: &str,
|
||||
) -> Vec<PriceBar> {
|
||||
if start > end {
|
||||
return Vec::new();
|
||||
}
|
||||
match normalize_history_frequency(frequency).as_deref() {
|
||||
Some("1d") => self
|
||||
.market_by_date
|
||||
.range(start..=end)
|
||||
.flat_map(|(_, rows)| rows.iter())
|
||||
.filter(|row| row.symbol == symbol)
|
||||
.map(daily_market_price_bar)
|
||||
.collect(),
|
||||
Some("1m") | Some("tick") => {
|
||||
let mut bars = self
|
||||
.execution_quotes_index
|
||||
.iter()
|
||||
.filter(|((date, quote_symbol), _)| {
|
||||
quote_symbol == symbol && *date >= start && *date <= end
|
||||
})
|
||||
.flat_map(|(_, rows)| rows.iter())
|
||||
.map(intraday_quote_price_bar)
|
||||
.collect::<Vec<_>>();
|
||||
bars.sort_by(|left, right| {
|
||||
left.date
|
||||
.cmp(&right.date)
|
||||
.then_with(|| left.timestamp.cmp(&right.timestamp))
|
||||
});
|
||||
bars
|
||||
}
|
||||
_ => Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn price(&self, date: NaiveDate, symbol: &str, field: PriceField) -> Option<f64> {
|
||||
let snapshot = self.market(date, symbol)?;
|
||||
Some(snapshot.price(field))
|
||||
@@ -1416,6 +1475,46 @@ fn intraday_quote_visible(
|
||||
}
|
||||
}
|
||||
|
||||
fn daily_market_price_bar(snapshot: &DailyMarketSnapshot) -> PriceBar {
|
||||
PriceBar {
|
||||
date: snapshot.date,
|
||||
timestamp: snapshot.timestamp.clone(),
|
||||
symbol: snapshot.symbol.clone(),
|
||||
frequency: "1d".to_string(),
|
||||
open: snapshot.open,
|
||||
high: snapshot.high,
|
||||
low: snapshot.low,
|
||||
close: snapshot.close,
|
||||
last_price: snapshot.last_price,
|
||||
volume: snapshot.volume,
|
||||
amount: 0.0,
|
||||
bid1: snapshot.bid1,
|
||||
ask1: snapshot.ask1,
|
||||
bid1_volume: snapshot.bid1_volume,
|
||||
ask1_volume: snapshot.ask1_volume,
|
||||
}
|
||||
}
|
||||
|
||||
fn intraday_quote_price_bar(snapshot: &IntradayExecutionQuote) -> PriceBar {
|
||||
PriceBar {
|
||||
date: snapshot.date,
|
||||
timestamp: Some(snapshot.timestamp.format("%Y-%m-%d %H:%M:%S").to_string()),
|
||||
symbol: snapshot.symbol.clone(),
|
||||
frequency: "tick".to_string(),
|
||||
open: snapshot.last_price,
|
||||
high: snapshot.last_price,
|
||||
low: snapshot.last_price,
|
||||
close: snapshot.last_price,
|
||||
last_price: snapshot.last_price,
|
||||
volume: snapshot.volume_delta,
|
||||
amount: snapshot.amount_delta,
|
||||
bid1: snapshot.bid1,
|
||||
ask1: snapshot.ask1,
|
||||
bid1_volume: snapshot.bid1_volume,
|
||||
ask1_volume: snapshot.ask1_volume,
|
||||
}
|
||||
}
|
||||
|
||||
fn normalize_field(field: &str) -> String {
|
||||
field
|
||||
.trim()
|
||||
|
||||
Reference in New Issue
Block a user