apple-quant-algorithmic 0.4.0

Apple Quant's algorithmic library.
Documentation
use std::{
	ops::{Add, Deref, Sub},
	fmt::Display,
};

use rust_decimal::Decimal;

use crate::instrument::{AddDecimal, AsDecimal, InstrumentSpec, SubDecimal};

use super::{ProtoabsolutePrice, RelativePrice};

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub struct AbsolutePrice<IS: InstrumentSpec>(IS::PriceType);

impl<IS: InstrumentSpec> AbsolutePrice<IS> {
	pub fn new(
		price: IS::PriceType,
	) -> Self {
		Self(price)
	}

	pub fn as_protoabsolute_price(
		&self,
	) -> ProtoabsolutePrice<IS> {
		self.into()
	}

	pub fn into_protoabsolute_price(
		self,
	) -> ProtoabsolutePrice<IS> {
		self.into()
	}

	pub fn as_decimal(
		&self,
	) -> Decimal {
		self.0.as_decimal()
	}

	pub fn as_underlying(
		&self,
	) -> IS::PriceType {
		self.0
	}
}

impl<IS: InstrumentSpec> Deref for AbsolutePrice<IS> {
	type Target = IS::PriceType;

	fn deref(
		&self,
	) -> &Self::Target {
		&self.0
	}
}

impl<IS: InstrumentSpec> Display for AbsolutePrice<IS> {
	fn fmt(
		&self,
		f: &mut std::fmt::Formatter<'_>,
	) -> std::fmt::Result {
		let price = self.as_decimal();
		write!(f, "{}", price)
	}
}

impl<IS: InstrumentSpec> std::fmt::Debug for AbsolutePrice<IS> {
	fn fmt(
		&self,
		f: &mut std::fmt::Formatter<'_>,
	) -> std::fmt::Result {
		<Self as Display>::fmt(&self, f)
	}
}

impl<IS: InstrumentSpec> Add<RelativePrice> for AbsolutePrice<IS> {
	type Output = Self;

	fn add(
		mut self,
		rhs: RelativePrice,
	) -> Self::Output {
		let price_type: IS::PriceType = rhs.into_subpoints().into();

		self.0 += price_type;
		self
	}
}

impl<IS: InstrumentSpec> Add<&RelativePrice> for AbsolutePrice<IS> {
	type Output = Self;

	fn add(
		self,
		rhs: &RelativePrice,
	) -> Self::Output {
		self + *rhs
	}
}

impl<IS: InstrumentSpec> Sub<RelativePrice> for AbsolutePrice<IS> {
	type Output = Self;

	fn sub(
		mut self,
		rhs: RelativePrice,
	) -> Self::Output {
		let price_type: IS::PriceType = rhs.into_subpoints().into();

		self.0 -= price_type;
		self
	}
}

impl<IS: InstrumentSpec> Sub<&RelativePrice> for AbsolutePrice<IS> {
	type Output = Self;

	fn sub(
		self,
		rhs: &RelativePrice,
	) -> Self::Output {
		self - *rhs
	}
}

impl<IS: InstrumentSpec> AddDecimal for AbsolutePrice<IS> {
	fn add_decimal(
		&mut self,
		decimal: &Decimal,
	) {
		self.0.add_decimal(decimal);
	}
}

impl<IS: InstrumentSpec> SubDecimal for AbsolutePrice<IS> {
	fn sub_decimal(
		&mut self,
		decimal: &Decimal,
	) {
		self.0.sub_decimal(decimal);
	}
}

impl<IS: InstrumentSpec> From<ProtoabsolutePrice<IS>> for Option<AbsolutePrice<IS>> {
	fn from(
		value: ProtoabsolutePrice<IS>,
	) -> Self {
		let ProtoabsolutePrice::Absolute(
			absolute_price,
		) = value else {
			return None;
		};

		Some(absolute_price)
	}
}

impl<
	'a,
	IS: InstrumentSpec,
> From<&'a ProtoabsolutePrice<IS>> for Option<&'a AbsolutePrice<IS>> {
	fn from(
		value: &'a ProtoabsolutePrice<IS>,
	) -> Self {
		let ProtoabsolutePrice::Absolute(
			absolute_price,
		) = value else {
			return None;
		};

		Some(absolute_price)
	}
}