Skip to main content

apple_quant_algorithmic/price/
absolute.rs

1use std::{
2	ops::{Add, Deref, Sub},
3	fmt::Display,
4};
5
6use rust_decimal::Decimal;
7
8use crate::instrument::{AddDecimal, AsDecimal, InstrumentSpec, SubDecimal};
9
10use super::{ProtoabsolutePrice, RelativePrice};
11
12#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
13pub struct AbsolutePrice<IS: InstrumentSpec>(IS::PriceType);
14
15impl<IS: InstrumentSpec> AbsolutePrice<IS> {
16	pub fn new(
17		price: IS::PriceType,
18	) -> Self {
19		Self(price)
20	}
21
22	pub fn as_protoabsolute_price(
23		&self,
24	) -> ProtoabsolutePrice<IS> {
25		self.into()
26	}
27
28	pub fn into_protoabsolute_price(
29		self,
30	) -> ProtoabsolutePrice<IS> {
31		self.into()
32	}
33
34	pub fn as_decimal(
35		&self,
36	) -> Decimal {
37		self.0.as_decimal()
38	}
39
40	pub fn as_underlying(
41		&self,
42	) -> IS::PriceType {
43		self.0
44	}
45}
46
47impl<IS: InstrumentSpec> Deref for AbsolutePrice<IS> {
48	type Target = IS::PriceType;
49
50	fn deref(
51		&self,
52	) -> &Self::Target {
53		&self.0
54	}
55}
56
57impl<IS: InstrumentSpec> Display for AbsolutePrice<IS> {
58	fn fmt(
59		&self,
60		f: &mut std::fmt::Formatter<'_>,
61	) -> std::fmt::Result {
62		let price = self.as_decimal();
63		write!(f, "{}", price)
64	}
65}
66
67impl<IS: InstrumentSpec> std::fmt::Debug for AbsolutePrice<IS> {
68	fn fmt(
69		&self,
70		f: &mut std::fmt::Formatter<'_>,
71	) -> std::fmt::Result {
72		<Self as Display>::fmt(&self, f)
73	}
74}
75
76impl<IS: InstrumentSpec> Add<RelativePrice> for AbsolutePrice<IS> {
77	type Output = Self;
78
79	fn add(
80		mut self,
81		rhs: RelativePrice,
82	) -> Self::Output {
83		let price_type: IS::PriceType = rhs.into_subpoints().into();
84
85		self.0 += price_type;
86		self
87	}
88}
89
90impl<IS: InstrumentSpec> Add<&RelativePrice> for AbsolutePrice<IS> {
91	type Output = Self;
92
93	fn add(
94		self,
95		rhs: &RelativePrice,
96	) -> Self::Output {
97		self + *rhs
98	}
99}
100
101impl<IS: InstrumentSpec> Sub<RelativePrice> for AbsolutePrice<IS> {
102	type Output = Self;
103
104	fn sub(
105		mut self,
106		rhs: RelativePrice,
107	) -> Self::Output {
108		let price_type: IS::PriceType = rhs.into_subpoints().into();
109
110		self.0 -= price_type;
111		self
112	}
113}
114
115impl<IS: InstrumentSpec> Sub<&RelativePrice> for AbsolutePrice<IS> {
116	type Output = Self;
117
118	fn sub(
119		self,
120		rhs: &RelativePrice,
121	) -> Self::Output {
122		self - *rhs
123	}
124}
125
126impl<IS: InstrumentSpec> AddDecimal for AbsolutePrice<IS> {
127	fn add_decimal(
128		&mut self,
129		decimal: &Decimal,
130	) {
131		self.0.add_decimal(decimal);
132	}
133}
134
135impl<IS: InstrumentSpec> SubDecimal for AbsolutePrice<IS> {
136	fn sub_decimal(
137		&mut self,
138		decimal: &Decimal,
139	) {
140		self.0.sub_decimal(decimal);
141	}
142}
143
144impl<IS: InstrumentSpec> From<ProtoabsolutePrice<IS>> for Option<AbsolutePrice<IS>> {
145	fn from(
146		value: ProtoabsolutePrice<IS>,
147	) -> Self {
148		let ProtoabsolutePrice::Absolute(
149			absolute_price,
150		) = value else {
151			return None;
152		};
153
154		Some(absolute_price)
155	}
156}
157
158impl<
159	'a,
160	IS: InstrumentSpec,
161> From<&'a ProtoabsolutePrice<IS>> for Option<&'a AbsolutePrice<IS>> {
162	fn from(
163		value: &'a ProtoabsolutePrice<IS>,
164	) -> Self {
165		let ProtoabsolutePrice::Absolute(
166			absolute_price,
167		) = value else {
168			return None;
169		};
170
171		Some(absolute_price)
172	}
173}