apple-quant-algorithmic 0.1.0

Apple Quant's algorithmic trading api
Documentation
use std::{
	ops::{Add, Sub},
	time::{SystemTime, UNIX_EPOCH},
};

use bevy::prelude::Deref;
use time::Duration;

use crate::timestamp::TradeTimestamp;

#[derive(Deref, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct TickTimestamp(Timestamp);

impl TickTimestamp {
	pub(crate) fn new(timestamp: Timestamp) -> Self {
		Self(timestamp)
	}

	pub(crate) fn now() -> Self {
		Self(Timestamp::now())
	}

	pub fn timestamp(&self) -> Timestamp {
		self.0
	}
}

#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ConstTimestamp(pub i128);

#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Timestamp(i128);

impl Timestamp {
	pub fn new(utc_ns: i128) -> Self {
		Self(utc_ns)
	}

	pub fn now() -> Self {
		let unix_epoch_ns = SystemTime::now()
			.duration_since(UNIX_EPOCH)
			.unwrap()
			.as_nanos();

		let unix_epoch_ns = i128::try_from(unix_epoch_ns).unwrap();
		Self(unix_epoch_ns)
	}

	pub fn duration_since(
		&self,
		timestamp: &Timestamp,
	) -> Duration {
		let diff_utc_ns = self.0 - timestamp.0;
		Duration::nanoseconds_i128(diff_utc_ns)
	}

	pub fn as_utc_nanos(&self) -> i128 {
		self.0
	}

	pub fn as_utc_micros(&self) -> i128 {
		self.0 / 1_000
	}

	pub fn as_utc_millis(&self) -> i64 {
		(self.0 / 1_000_000) as i64
	}

	pub fn as_utc_seconds(&self) -> i64 {
		(self.0 / 1_000_000_000) as i64
	}
}

impl From<TradeTimestamp> for Timestamp {
	fn from(value: TradeTimestamp) -> Self {
		*value
	}
}

impl From<i128> for Timestamp {
	fn from(value: i128) -> Self {
		Self::new(value)
	}
}

impl Add<Duration> for Timestamp {
	type Output = Self;

	fn add(
		self,
		rhs: Duration,
	) -> Self::Output {
		Self(self.0 + rhs.whole_nanoseconds())
	}
}

impl Add<&Duration> for Timestamp {
	type Output = Self;

	fn add(
		self,
		rhs: &Duration,
	) -> Self::Output {
		Self(self.0 + rhs.whole_nanoseconds())
	}
}

impl Sub<Duration> for Timestamp {
	type Output = Self;

	fn sub(
		self,
		rhs: Duration,
	) -> Self::Output {
		Self(self.0 - rhs.whole_nanoseconds())
	}
}

impl Sub<&Duration> for Timestamp {
	type Output = Self;

	fn sub(
		self,
		rhs: &Duration,
	) -> Self::Output {
		Self(self.0 - rhs.whole_nanoseconds())
	}
}