From bc5149fd3541687842570ba6e195c5deb7e0573a Mon Sep 17 00:00:00 2001
From: uvok
Date: Sun, 13 Apr 2025 16:19:55 +0200
Subject: Tax report

---
 bla.py | 61 +++++++++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 47 insertions(+), 14 deletions(-)

diff --git a/bla.py b/bla.py
index 91bbd78..a1d6578 100644
--- a/bla.py
+++ b/bla.py
@@ -1,31 +1,62 @@
 import csv
 from collections import defaultdict, deque
+from datetime import datetime
 
 class FIFOQueue:
     def __init__(self):
         self.queue = deque()
 
-    def add(self, amount, cost):
-        self.queue.append((amount, cost))
+    def add(self, amount, cost, date):
+        self.queue.append((amount, cost, date))
 
     def remove(self, amount):
         remaining = amount
         cost_basis = 0
+        date_acquired = None
 
+        entries = []
         while remaining > 0:
             if not self.queue:
                 raise ValueError(f"Insufficient assets in queue to process sale of {amount}.")
-            quantity, cost = self.queue[0]
+            quantity, cost, date = self.queue[0]
             if quantity > remaining:
                 cost_basis += remaining * cost
-                self.queue[0] = (quantity - remaining, cost)
+                self.queue[0] = (quantity - remaining, cost, date)
+                entries.append((remaining, cost, date))
                 remaining = 0
             else:
                 cost_basis += quantity * cost
                 remaining -= quantity
+                entries.append((quantity, cost, date))
                 self.queue.popleft()
 
-        return cost_basis
+        return cost_basis, entries
+
+def generate_report(sale_entries, proceeds, crypto_asset, date_sold):
+    report = []
+    sell_date = datetime.strptime(date_sold, "%Y-%m-%d").strftime("%d.%m.%Y")
+
+    for amount, cost, buy_date in sale_entries:
+        buy_date_formatted = datetime.strptime(buy_date, "%Y-%m-%d").strftime("%d.%m.%Y")
+        holding_period = (datetime.strptime(date_sold, "%Y-%m-%d") - datetime.strptime(buy_date, "%Y-%m-%d")).days
+        short_or_long = "Short" if holding_period < 365 else "Long"
+        cost_basis = amount * cost
+        gain_or_loss = proceeds - cost_basis
+
+        report.append({
+            "Amount": f"{amount:.8f}",
+            "Currency": crypto_asset,
+            "Date Sold": sell_date,
+            "Date Acquired": buy_date_formatted,
+            "Short/Long": short_or_long,
+            "Buy/Input at": "Kraken",
+            "Sell/Output at": "Kraken",
+            "Proceeds": f"{proceeds:.2f}",
+            "Cost Basis": f"{cost_basis:.2f}",
+            "Gain/Loss": f"{gain_or_loss:.2f}",
+        })
+
+    return report
 
 def process_ledger(file_path):
     fifo_queues = {}  # Separate FIFO queue per cryptocurrency
@@ -45,7 +76,8 @@ def process_ledger(file_path):
                 fifo_queues.setdefault(currency, FIFOQueue())
                 amount = float(row["amount"])
                 price = 0  # Deposits typically have no associated cost basis
-                fifo_queues[currency].add(amount, price)
+                date = row["time"].split(" ")[0]
+                fifo_queues[currency].add(amount, price, date)
 
         # Process grouped trades
         for refid, trades in trades_by_refid.items():
@@ -61,15 +93,16 @@ def process_ledger(file_path):
                     crypto_fee = float(crypto_trade["fee"])
                     fifo_queues.setdefault(crypto_asset, FIFOQueue())
 
+                    date_sold = eur_trade["time"].split(" ")[0]
+
                     if eur_amount < 0:  # Purchase of cryptocurrency
                         stake_amount = -eur_amount - eur_fee  # Account for EUR fees
                         crypto_amount -= crypto_fee  # Adjust for crypto fees
-                        fifo_queues[crypto_asset].add(crypto_amount, stake_amount)
+                        fifo_queues[crypto_asset].add(crypto_amount, stake_amount, date_sold)
                     elif eur_amount > 0:  # Sale of cryptocurrency
-                        sale_proceeds = eur_amount - eur_fee  # Account for EUR fees
-                        cost_basis = fifo_queues[crypto_asset].remove(crypto_amount)
-                        profit_or_loss = sale_proceeds - cost_basis
-                        report.append((eur_trade["time"], crypto_asset, profit_or_loss))
+                        proceeds = eur_amount - eur_fee  # Account for EUR fees
+                        cost_basis, sale_entries = fifo_queues[crypto_asset].remove(crypto_amount)
+                        report.extend(generate_report(sale_entries, proceeds, crypto_asset, date_sold))
                 else:
                     raise ValueError(f"Unexpected trade grouping for refid {refid}")
             else:
@@ -79,6 +112,6 @@ def process_ledger(file_path):
 
 # Usage
 ledger_path = "kraken_ledger.csv"  # Replace with your file path
-profit_and_loss_report = process_ledger(ledger_path)
-for entry in profit_and_loss_report:
-    print(entry)
+tax_report = process_ledger(ledger_path)
+for entry in tax_report:
+    print(",".join(f"{key}={value}" for key, value in entry.items()))
-- 
cgit v1.2.3