use borsh::{BorshDeserialize, BorshSerialize};
use bytemuck::{Pod, Zeroable};
use crate::math::quantities::{
BaseLots, QuoteLotsPerBaseLot, SequenceNumberU8, SignedBaseLots, SignedQuoteLots,
SignedQuoteLotsI56, SignedQuoteLotsPerBaseLot,
};
#[repr(C)]
#[derive(
Pod, Zeroable, Debug, Default, Copy, Clone, PartialEq, BorshDeserialize, BorshSerialize, Eq,
)]
pub struct TraderPosition {
pub base_lot_position: SignedBaseLots,
pub virtual_quote_lot_position: SignedQuoteLots,
pub cumulative_funding_snapshot: SignedQuoteLotsPerBaseLot,
pub position_sequence_number: SequenceNumberU8,
pub accumulated_funding_for_active_position: SignedQuoteLotsI56,
}
impl TraderPosition {
pub fn new() -> Self {
Self {
base_lot_position: SignedBaseLots::ZERO,
virtual_quote_lot_position: SignedQuoteLots::ZERO,
cumulative_funding_snapshot: SignedQuoteLotsPerBaseLot::ZERO,
position_sequence_number: SequenceNumberU8::default(),
accumulated_funding_for_active_position: SignedQuoteLotsI56::default(),
}
}
pub fn effective_entry_price(&self) -> Option<QuoteLotsPerBaseLot> {
if self.base_lot_position == SignedBaseLots::ZERO {
None
} else {
self.virtual_quote_lot_position
.abs_as_unsigned()
.checked_div_by_base_lots(self.base_lot_position.abs_as_unsigned())
}
}
pub fn is_long(&self) -> bool {
self.base_lot_position > SignedBaseLots::ZERO
}
pub fn is_short(&self) -> bool {
self.base_lot_position < SignedBaseLots::ZERO
}
pub fn is_neutral(&self) -> bool {
self.base_lot_position == SignedBaseLots::ZERO
}
pub fn abs_size(&self) -> BaseLots {
self.base_lot_position.abs_as_unsigned()
}
}