Skip to main content

infer_periods_per_year

Function infer_periods_per_year 

Source
pub fn infer_periods_per_year(timestamps: &[NaiveDateTime]) -> Option<f64>
Expand description

Bars a year implied by the spacing of timestamps, for ResearchPipelineConfig::periods_per_year.

Takes the median gap Δ between consecutive strictly increasing timestamps (gaps that are zero or negative are skipped, so ties and unordered pairs do not count) and maps it with the convention of the module documentation:

  • intraday, Δ under 20 hours: 252 * 390 / Δ_minutes bars a year, i.e. a 390-minute session on 252 days (one-minute bars: 98,280; hourly: 1,638). Bars that trade around the clock (futures, crypto) keep this session convention; pass an explicit value instead if you want a 24-hour one.
  • daily, Δ from 20 hours to under 4 days (so weekends and holidays inside a daily series do not matter): 252.
  • longer, Δ of 4 days or more: 365.25 / Δ_days (weekly bars: 52.2, monthly bars of 30.44 days: 12).

The median makes it robust to overnight and weekend gaps in intraday data and to the odd missing bar. For bars sampled on activity (tick, volume or dollar bars) it gives the typical bar rate, which is only an approximation; pass the value yourself when you know it.

Returns None when fewer than two timestamps strictly increase, i.e. there is no gap to measure.

§Example

use chrono::{Datelike, Duration, NaiveDate, Weekday};
use openquant::pipeline::{infer_periods_per_year, MINUTE_BARS_PER_YEAR};

let open = NaiveDate::from_ymd_opt(2024, 1, 2).unwrap().and_hms_opt(9, 30, 0).unwrap();
let minutes: Vec<_> = (0..390).map(|i| open + Duration::minutes(i)).collect();
assert_eq!(infer_periods_per_year(&minutes), Some(MINUTE_BARS_PER_YEAR));
assert_eq!(MINUTE_BARS_PER_YEAR, 98_280.0);

// Weekdays only: the weekend gaps are outliers the median ignores.
let days: Vec<_> = (0..14)
    .map(|d| open + Duration::days(d))
    .filter(|t| !matches!(t.weekday(), Weekday::Sat | Weekday::Sun))
    .collect();
assert_eq!(infer_periods_per_year(&days), Some(252.0));

assert_eq!(infer_periods_per_year(&minutes[..1]), None);