95 lines
2.4 KiB
Rust
95 lines
2.4 KiB
Rust
use crate::{
|
|
config::{Config, ALPACA_API_BASE},
|
|
database,
|
|
};
|
|
use log::info;
|
|
use qrust::{
|
|
alpaca,
|
|
types::{self, Calendar},
|
|
utils::{backoff, duration_until},
|
|
};
|
|
use std::sync::Arc;
|
|
use time::OffsetDateTime;
|
|
use tokio::{join, sync::mpsc, time::sleep};
|
|
|
|
pub enum Status {
|
|
Open,
|
|
Closed,
|
|
}
|
|
|
|
pub struct Message {
|
|
pub status: Status,
|
|
pub next_switch: OffsetDateTime,
|
|
}
|
|
|
|
impl From<types::alpaca::api::incoming::clock::Clock> for Message {
|
|
fn from(clock: types::alpaca::api::incoming::clock::Clock) -> Self {
|
|
if clock.is_open {
|
|
Self {
|
|
status: Status::Open,
|
|
next_switch: clock.next_close,
|
|
}
|
|
} else {
|
|
Self {
|
|
status: Status::Closed,
|
|
next_switch: clock.next_open,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub async fn run(config: Arc<Config>, sender: mpsc::Sender<Message>) {
|
|
loop {
|
|
let clock_future = async {
|
|
alpaca::clock::get(
|
|
&config.alpaca_client,
|
|
&config.alpaca_rate_limiter,
|
|
Some(backoff::infinite()),
|
|
&ALPACA_API_BASE,
|
|
)
|
|
.await
|
|
.unwrap()
|
|
};
|
|
|
|
let calendar_future = async {
|
|
alpaca::calendar::get(
|
|
&config.alpaca_client,
|
|
&config.alpaca_rate_limiter,
|
|
&types::alpaca::api::outgoing::calendar::Calendar::default(),
|
|
Some(backoff::infinite()),
|
|
&ALPACA_API_BASE,
|
|
)
|
|
.await
|
|
.unwrap()
|
|
.into_iter()
|
|
.map(Calendar::from)
|
|
.collect::<Vec<_>>()
|
|
};
|
|
|
|
let (clock, calendar) = join!(clock_future, calendar_future);
|
|
|
|
let sleep_until = duration_until(if clock.is_open {
|
|
info!("Market is open, will close at {}.", clock.next_close);
|
|
clock.next_close
|
|
} else {
|
|
info!("Market is closed, will reopen at {}.", clock.next_open);
|
|
clock.next_open
|
|
});
|
|
|
|
let sleep_future = sleep(sleep_until);
|
|
|
|
let calendar_future = async {
|
|
database::calendar::upsert_batch_and_delete(
|
|
&config.clickhouse_client,
|
|
&config.clickhouse_concurrency_limiter,
|
|
&calendar,
|
|
)
|
|
.await
|
|
.unwrap();
|
|
};
|
|
|
|
join!(sleep_future, calendar_future);
|
|
sender.send(clock.into()).await.unwrap();
|
|
}
|
|
}
|