summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bla.py53
-rw-r--r--test_trade_queue.py67
-rw-r--r--trade.py8
-rw-r--r--trade_queue.py48
4 files changed, 125 insertions, 51 deletions
diff --git a/bla.py b/bla.py
index f9de595..6c2a4c2 100644
--- a/bla.py
+++ b/bla.py
@@ -1,58 +1,9 @@
import csv
-from collections import defaultdict, deque
+from collections import defaultdict
from datetime import datetime
-class Trade:
- def __init__(self, amount, total_cost, date):
- self.amount = amount
- self.total_cost = total_cost
- self.date = date
+from trade_queue import FIFOQueue
- def __repr__(self):
- return f"Trade(amount={self.amount}, total_cost={self.total_cost}, date={self.date})"
-
-class FIFOQueue:
- """
- Crypto trading FIFO queue.
-
- Will track trades.
- """
- def __init__(self):
- self.queue = deque()
-
- def add(self, amount, total_cost, date):
- """
- Add a trade to the queue.
- """
- trade = Trade(amount, total_cost, date)
- self.queue.append(trade)
-
- def remove(self, amount):
- """
- 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.")
-
- remaining = amount
- entries = []
-
- 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.amount -= remaining
- entries.append(Trade(remaining, trade.total_cost, trade.date))
- remaining = 0
- else:
- remaining -= trade.amount
- entries.append(trade)
- self.queue.popleft()
-
- return entries
def generate_report(sale_entries, proceeds, crypto_asset, date_sold):
report = []
diff --git a/test_trade_queue.py b/test_trade_queue.py
new file mode 100644
index 0000000..958b830
--- /dev/null
+++ b/test_trade_queue.py
@@ -0,0 +1,67 @@
+import unittest
+from datetime import datetime
+
+from trade_queue import FIFOQueue
+
+class TestFIFOQueue(unittest.TestCase):
+ def setUp(self):
+ """
+ Set up a FIFOQueue instance and some test trades.
+ """
+ self.queue = FIFOQueue()
+ self.queue.add(10.0, 100.0, "2025-04-14")
+ self.queue.add(20.0, 200.0, "2025-04-15")
+ self.queue.add(30.0, 300.0, "2025-04-16")
+
+ def test_add(self):
+ """
+ Test adding trades to the queue.
+ """
+ self.assertEqual(len(self.queue.queue), 3) # There should be 3 trades in the queue
+ self.assertEqual(self.queue.queue[0].amount, 10.0) # Check the first trade's amount
+ self.assertEqual(self.queue.queue[1].date, "2025-04-15") # Check the second trade's date
+
+ def test_remove_exact_amount(self):
+ """
+ Test removing an exact amount from the queue.
+ """
+ trades = self.queue.remove(10.0)
+ self.assertEqual(len(trades), 1) # One trade should be returned
+ self.assertEqual(trades[0].amount, 10.0) # Amount should match the request
+ self.assertEqual(len(self.queue.queue), 2) # Two trades should remain in the queue
+
+ def test_remove_partial_trade(self):
+ """
+ Test removing an amount that partially consumes a trade.
+ """
+ trades = self.queue.remove(5.0)
+ self.assertEqual(len(trades), 1) # One partial trade should be returned
+ self.assertEqual(trades[0].amount, 5.0) # Amount should match the request
+ self.assertEqual(self.queue.queue[0].amount, 5.0) # Remaining trade amount should update
+
+ def test_remove_multiple_trades(self):
+ """
+ Test removing an amount that spans multiple trades.
+ """
+ trades = self.queue.remove(25.0)
+ self.assertEqual(len(trades), 2) # Two trades should be returned
+ self.assertEqual(trades[0].amount, 10.0) # The first trade should be fully consumed
+ self.assertEqual(trades[1].amount, 15.0) # The second trade should be partially consumed
+ self.assertEqual(self.queue.queue[0].amount, 5.0) # Remaining trade in queue should update
+
+ def test_remove_insufficient_amount(self):
+ """
+ Test trying to remove more than is available in the queue.
+ """
+ with self.assertRaises(ValueError):
+ self.queue.remove(100.0) # This should raise an exception
+
+ def test_remove_negative_amount(self):
+ """
+ Test trying to remove a negative amount.
+ """
+ with self.assertRaises(ValueError):
+ self.queue.remove(-5.0) # This should raise an exception
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/trade.py b/trade.py
new file mode 100644
index 0000000..f4f0870
--- /dev/null
+++ b/trade.py
@@ -0,0 +1,8 @@
+class Trade:
+ def __init__(self, amount: float, total_cost: float, date: str) -> None:
+ self.amount: float = amount
+ self.total_cost: float = total_cost
+ self.date: str = date
+
+ def __repr__(self) -> str:
+ return f"Trade(amount={self.amount}, total_cost={self.total_cost}, date={self.date})"
diff --git a/trade_queue.py b/trade_queue.py
new file mode 100644
index 0000000..b8c594b
--- /dev/null
+++ b/trade_queue.py
@@ -0,0 +1,48 @@
+from collections import deque
+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, total_cost: float, date: str) -> None:
+ """
+ Add a trade to the queue.
+ """
+ trade = Trade(amount, total_cost, date)
+ self.queue.append(trade)
+
+ def remove(self, amount: float) -> 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.")
+
+ remaining: float = 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.amount -= remaining
+ entries.append(Trade(remaining, trade.total_cost, trade.date))
+ remaining = 0
+ else:
+ remaining -= trade.amount
+ entries.append(trade)
+ self.queue.popleft()
+
+ return entries