from collections import deque from decimal import Decimal from typing import Deque, List from trade import Trade class FIFOQueue: """ Crypto trading FIFO queue. Will track trades. """ def __init__(self) -> None: self.queue: Deque[Trade] = deque() def add(self, amount: float|Decimal, total_cost: float|Decimal, date: str) -> None: """ Add a trade to the queue. """ trade = Trade(amount, total_cost, date) self.queue.append(trade) def remove(self, amount: float|Decimal) -> List[Trade]: """ Remove a specified amount from the queue, returning the trades used to buy. """ if amount <= 0: raise ValueError("The amount to remove must be positive.") amount = Decimal(amount) remaining: Decimal = amount entries: List[Trade] = [] while remaining > 0: if not self.queue: raise ValueError(f"Insufficient assets in queue to process sale of {amount}.") trade = self.queue[0] if trade.amount > remaining: trade.remove_coins(remaining) entries.append(Trade(remaining, trade.total_cost, trade.date)) remaining = Decimal(0) else: remaining -= trade.amount entries.append(trade) self.queue.popleft() return entries def get_remaining_amount(self) -> Decimal: """ Calculate the total remaining amount in the queue. """ return sum((trade.amount for trade in self.queue), Decimal(0))